1 // Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7 #include <config.h>
8
9 #include <util/memory_segment.h>
10
11 #include <exceptions/exceptions.h>
12
13 #include <gtest/gtest.h>
14
15 #include <cstring>
16 #include <stdint.h>
17
18 namespace isc {
19 namespace util {
20 namespace test {
21
22 void
checkSegmentNamedAddress(MemorySegment & segment,bool out_of_segment_ok)23 checkSegmentNamedAddress(MemorySegment& segment, bool out_of_segment_ok) {
24 // NULL name is not allowed.
25 EXPECT_THROW(segment.getNamedAddress(NULL), InvalidParameter);
26
27 // If the name does not exist, false should be returned.
28 EXPECT_FALSE(segment.getNamedAddress("test address").first);
29
30 // Now set it
31 void* ptr32 = segment.allocate(sizeof(uint32_t));
32 const uint32_t test_val = 42;
33 *static_cast<uint32_t*>(ptr32) = test_val;
34 EXPECT_FALSE(segment.setNamedAddress("test address", ptr32));
35
36 // NULL name isn't allowed.
37 EXPECT_THROW(segment.setNamedAddress(NULL, ptr32), InvalidParameter);
38 EXPECT_THROW(segment.getNamedAddress(NULL), InvalidParameter);
39 EXPECT_THROW(segment.clearNamedAddress(NULL), InvalidParameter);
40
41 // Empty names are not allowed.
42 EXPECT_THROW(segment.setNamedAddress("", ptr32), InvalidParameter);
43 EXPECT_THROW(segment.getNamedAddress(""), InvalidParameter);
44 EXPECT_THROW(segment.clearNamedAddress(""), InvalidParameter);
45
46 // Names beginning with _ are not allowed.
47 EXPECT_THROW(segment.setNamedAddress("_foo", ptr32), InvalidParameter);
48 EXPECT_THROW(segment.getNamedAddress("_foo"), InvalidParameter);
49 EXPECT_THROW(segment.clearNamedAddress("_foo"), InvalidParameter);
50
51 // we can now get it; the stored value should be intact.
52 MemorySegment::NamedAddressResult result =
53 segment.getNamedAddress("test address");
54 EXPECT_TRUE(result.first);
55 EXPECT_EQ(test_val, *static_cast<const uint32_t*>(result.second));
56
57 // Override it.
58 void* ptr16 = segment.allocate(sizeof(uint16_t));
59 const uint16_t test_val16 = 4200;
60 *static_cast<uint16_t*>(ptr16) = test_val16;
61 EXPECT_FALSE(segment.setNamedAddress("test address", ptr16));
62 result = segment.getNamedAddress("test address");
63 EXPECT_TRUE(result.first);
64 EXPECT_EQ(test_val16, *static_cast<const uint16_t*>(result.second));
65
66 // Clear it. Then we won't be able to find it any more.
67 EXPECT_TRUE(segment.clearNamedAddress("test address"));
68 EXPECT_FALSE(segment.getNamedAddress("test address").first);
69
70 // duplicate attempt of clear will result in false as it doesn't exist.
71 EXPECT_FALSE(segment.clearNamedAddress("test address"));
72
73 // Setting NULL is okay.
74 EXPECT_FALSE(segment.setNamedAddress("null address", NULL));
75 result = segment.getNamedAddress("null address");
76 EXPECT_TRUE(result.first);
77 EXPECT_FALSE(result.second);
78
79 // If the underlying implementation performs explicit check against
80 // out-of-segment address, confirm the behavior.
81 if (!out_of_segment_ok) {
82 uint8_t ch = 'A';
83 EXPECT_THROW(segment.setNamedAddress("local address", &ch),
84 MemorySegmentError);
85 }
86
87 // clean them up all
88 segment.deallocate(ptr32, sizeof(uint32_t));
89 EXPECT_FALSE(segment.allMemoryDeallocated()); // not fully deallocated
90 segment.deallocate(ptr16, sizeof(uint16_t)); // not yet
91 EXPECT_FALSE(segment.allMemoryDeallocated());
92 EXPECT_TRUE(segment.clearNamedAddress("null address"));
93 // null name isn't allowed:
94 EXPECT_THROW(segment.clearNamedAddress(NULL), InvalidParameter);
95 EXPECT_TRUE(segment.allMemoryDeallocated()); // now everything is gone
96 }
97
98 }
99 }
100 }
101