1 // Copyright (C) 2011-2021 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 /// \brief Test of asiolink utilities
8 ///
9 /// Tests the functionality of the asiolink utilities code by comparing them
10 /// with the equivalent methods in isc::dns::[Input/Output]Buffer.
11
12 #include <config.h>
13
14 #include <cstddef>
15
16 #include <arpa/inet.h>
17 #include <gtest/gtest.h>
18
19 #include <util/buffer.h>
20 #include <util/io_utilities.h>
21
22 using namespace isc::util;
23
TEST(asioutil,readUint16)24 TEST(asioutil, readUint16) {
25
26 // Reference buffer
27 uint8_t data[2] = {0, 0};
28 InputBuffer buffer(data, sizeof(data));
29
30 // Avoid possible compiler warnings by only setting uint8_t variables to
31 // uint8_t values.
32 uint8_t i8 = 0;
33 uint8_t j8 = 0;
34 for (int i = 0; i < (2 << 8); ++i, ++i8) {
35 for (int j = 0; j < (2 << 8); ++j, ++j8) {
36 data[0] = i8;
37 data[1] = j8;
38 buffer.setPosition(0);
39 EXPECT_EQ(buffer.readUint16(), readUint16(data, sizeof(data)));
40 }
41 }
42 }
43
TEST(asioutil,readUint16OutOfRange)44 TEST(asioutil, readUint16OutOfRange) {
45 uint8_t data;
46 EXPECT_THROW(readUint16(&data, sizeof(data)), isc::OutOfRange);
47 }
48
TEST(asioutil,writeUint16)49 TEST(asioutil, writeUint16) {
50
51 // Reference buffer
52 OutputBuffer buffer(2);
53 uint8_t test[2];
54
55 // Avoid possible compiler warnings by only setting uint16_t variables to
56 // uint16_t values.
57 uint16_t i16 = 0;
58 for (uint32_t i = 0; i < (2 << 16); ++i, ++i16) {
59
60 // Write the reference data
61 buffer.clear();
62 buffer.writeUint16(i16);
63
64 // ... and the test data
65 writeUint16(i16, test, sizeof(test));
66
67 // ... and compare
68 const uint8_t* ref = static_cast<const uint8_t*>(buffer.getData());
69 EXPECT_EQ(ref[0], test[0]);
70 EXPECT_EQ(ref[1], test[1]);
71 }
72 }
73
TEST(asioutil,writeUint16OutOfRange)74 TEST(asioutil, writeUint16OutOfRange) {
75 uint16_t i16 = 42;
76 uint8_t data;
77 EXPECT_THROW(writeUint16(i16, &data, sizeof(data)), isc::OutOfRange);
78 }
79
80 // test data shared amount readUint32 and writeUint32 tests
81 const static uint32_t test32[] = {
82 0,
83 1,
84 2000,
85 0x80000000,
86 0xffffffff
87 };
88
TEST(asioutil,readUint32)89 TEST(asioutil, readUint32) {
90 uint8_t data[8];
91
92 // make sure that we can read data, regardless of
93 // the memory alignment. That' why we need to repeat
94 // it 4 times.
95 for (int offset=0; offset < 4; offset++) {
96 for (int i=0; i < sizeof(test32)/sizeof(uint32_t); i++) {
97 uint32_t tmp = htonl(test32[i]);
98 memcpy(&data[offset], &tmp, sizeof(uint32_t));
99
100 EXPECT_EQ(test32[i], readUint32(&data[offset], sizeof(uint32_t)));
101 }
102 }
103 }
104
TEST(asioutil,readUint32OutOfRange)105 TEST(asioutil, readUint32OutOfRange) {
106 uint8_t data[3];
107 EXPECT_THROW(readUint32(data, sizeof(data)), isc::OutOfRange);
108 }
109
TEST(asioutil,writeUint32)110 TEST(asioutil, writeUint32) {
111 uint8_t data[8];
112
113 // make sure that we can write data, regardless of
114 // the memory alignment. That's why we need to repeat
115 // it 4 times.
116 for (int offset=0; offset < 4; offset++) {
117 for (int i=0; i < sizeof(test32)/sizeof(uint32_t); i++) {
118 uint8_t* ptr = writeUint32(test32[i], &data[offset],
119 sizeof(uint32_t));
120
121 EXPECT_EQ(&data[offset]+sizeof(uint32_t), ptr);
122
123 uint32_t tmp = htonl(test32[i]);
124
125 EXPECT_EQ(0, memcmp(&tmp, &data[offset], sizeof(uint32_t)));
126 }
127 }
128 }
129
TEST(asioutil,writeUint32OutOfRange)130 TEST(asioutil, writeUint32OutOfRange) {
131 uint32_t i32 = 28;
132 uint8_t data[3];
133 EXPECT_THROW(writeUint32(i32, data, sizeof(data)), isc::OutOfRange);
134 }
135
136 // Tests whether uint64 can be read from a buffer properly.
TEST(asioutil,readUint64)137 TEST(asioutil, readUint64) {
138
139 uint8_t buf[8];
140 for (int offset = 0; offset < sizeof(buf); offset++) {
141 buf[offset] = offset+1;
142 }
143
144 // Let's do some simple sanity checks first.
145 EXPECT_THROW(readUint64(NULL, 0), isc::OutOfRange);
146 EXPECT_THROW(readUint64(buf, 7), isc::OutOfRange);
147
148 // Now check if a real value could be read.
149 const uint64_t exp_val = 0x0102030405060708ul;
150 uint64_t val;
151
152 EXPECT_NO_THROW(val = readUint64(buf, 8));
153 EXPECT_EQ(val, exp_val);
154
155 // Now check if there are no buffer overflows.
156 memset(buf, 0xff, 8);
157
158 EXPECT_NO_THROW(val = readUint64(buf, 8));
159 EXPECT_EQ(0xfffffffffffffffful, val);
160 }
161