1 /*
2  *  Copyright (c) 2022, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "test_platform.h"
30 
31 #include <openthread/config.h>
32 
33 #include "test_util.h"
34 #include "common/code_utils.hpp"
35 #include "common/num_utils.hpp"
36 #include "common/numeric_limits.hpp"
37 #include "common/preference.hpp"
38 #include "common/serial_number.hpp"
39 
40 namespace ot {
41 
TestSerialNumber(const char * aName)42 template <typename UintType> void TestSerialNumber(const char *aName)
43 {
44     static constexpr UintType kMax = NumericLimits<UintType>::kMax;
45     static constexpr UintType kMid = kMax / 2;
46 
47     static const UintType kNumbers[] = {0, 1, 20, kMid - 1, kMid, kMid + 1, kMax - 20, kMax - 1, kMax};
48 
49     for (UintType number : kNumbers)
50     {
51         VerifyOrQuit(!SerialNumber::IsGreater<UintType>(number, number));
52         VerifyOrQuit(!SerialNumber::IsLess<UintType>(number, number));
53 
54         VerifyOrQuit(SerialNumber::IsGreater<UintType>(number + 1, number));
55         VerifyOrQuit(SerialNumber::IsGreater<UintType>(number + kMid - 1, number));
56         VerifyOrQuit(SerialNumber::IsGreater<UintType>(number + kMid, number));
57         VerifyOrQuit(!SerialNumber::IsGreater<UintType>(number + kMid + 2, number));
58         VerifyOrQuit(!SerialNumber::IsGreater<UintType>(number + kMax - 1, number));
59 
60         VerifyOrQuit(SerialNumber::IsLess<UintType>(number - 1, number));
61         VerifyOrQuit(SerialNumber::IsLess<UintType>(number - kMid + 1, number));
62         VerifyOrQuit(SerialNumber::IsLess<UintType>(number - kMid, number));
63         VerifyOrQuit(!SerialNumber::IsLess<UintType>(number - kMid - 2, number));
64         VerifyOrQuit(!SerialNumber::IsLess<UintType>(number - kMax + 1, number));
65     }
66 
67     printf("TestSerialNumber<%s>() passed\n", aName);
68 }
69 
TestNumUtils(void)70 void TestNumUtils(void)
71 {
72     uint16_t u16;
73     uint32_t u32;
74 
75     VerifyOrQuit(Min<uint8_t>(1, 2) == 1);
76     VerifyOrQuit(Min<uint8_t>(2, 1) == 1);
77     VerifyOrQuit(Min<uint8_t>(1, 1) == 1);
78 
79     VerifyOrQuit(Max<uint8_t>(1, 2) == 2);
80     VerifyOrQuit(Max<uint8_t>(2, 1) == 2);
81     VerifyOrQuit(Max<uint8_t>(1, 1) == 1);
82 
83     VerifyOrQuit(Clamp<uint8_t>(1, 5, 10) == 5);
84     VerifyOrQuit(Clamp<uint8_t>(5, 5, 10) == 5);
85     VerifyOrQuit(Clamp<uint8_t>(7, 5, 10) == 7);
86     VerifyOrQuit(Clamp<uint8_t>(10, 5, 10) == 10);
87     VerifyOrQuit(Clamp<uint8_t>(12, 5, 10) == 10);
88 
89     VerifyOrQuit(Clamp<uint8_t>(10, 10, 10) == 10);
90     VerifyOrQuit(Clamp<uint8_t>(9, 10, 10) == 10);
91     VerifyOrQuit(Clamp<uint8_t>(11, 10, 10) == 10);
92 
93     u16 = 100;
94     VerifyOrQuit(ClampToUint8(u16) == 100);
95     u16 = 255;
96     VerifyOrQuit(ClampToUint8(u16) == 255);
97     u16 = 256;
98     VerifyOrQuit(ClampToUint8(u16) == 255);
99     u16 = 400;
100     VerifyOrQuit(ClampToUint8(u16) == 255);
101 
102     u32 = 100;
103     VerifyOrQuit(ClampToUint16(u32) == 100);
104     u32 = 256;
105     VerifyOrQuit(ClampToUint16(u32) == 256);
106     u32 = 0xffff;
107     VerifyOrQuit(ClampToUint16(u32) == 0xffff);
108     u32 = 0x10000;
109     VerifyOrQuit(ClampToUint16(u32) == 0xffff);
110     u32 = 0xfff0000;
111     VerifyOrQuit(ClampToUint16(u32) == 0xffff);
112 
113     VerifyOrQuit(ThreeWayCompare<uint8_t>(2, 2) == 0);
114     VerifyOrQuit(ThreeWayCompare<uint8_t>(2, 1) > 0);
115     VerifyOrQuit(ThreeWayCompare<uint8_t>(1, 2) < 0);
116 
117     VerifyOrQuit(ThreeWayCompare<bool>(false, false) == 0);
118     VerifyOrQuit(ThreeWayCompare<bool>(true, true) == 0);
119     VerifyOrQuit(ThreeWayCompare<bool>(true, false) > 0);
120     VerifyOrQuit(ThreeWayCompare<bool>(false, true) < 0);
121 
122     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(2, 1) == 2);
123     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(1, 3) == 0);
124     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(1, 2) == 1);
125     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(2, 3) == 1);
126     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(3, 2) == 2);
127     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(4, 2) == 2);
128 
129     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(0, 10) == 0);
130     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(4, 10) == 0);
131     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(5, 10) == 1);
132     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(9, 10) == 1);
133     VerifyOrQuit(DivideAndRoundToClosest<uint8_t>(10, 10) == 1);
134 
135     VerifyOrQuit(CountBitsInMask<uint8_t>(0) == 0);
136     VerifyOrQuit(CountBitsInMask<uint8_t>(1) == 1);
137     VerifyOrQuit(CountBitsInMask<uint8_t>(2) == 1);
138     VerifyOrQuit(CountBitsInMask<uint8_t>(3) == 2);
139     VerifyOrQuit(CountBitsInMask<uint8_t>(4) == 1);
140     VerifyOrQuit(CountBitsInMask<uint8_t>(7) == 3);
141     VerifyOrQuit(CountBitsInMask<uint8_t>(11) == 3);
142     VerifyOrQuit(CountBitsInMask<uint8_t>(15) == 4);
143     VerifyOrQuit(CountBitsInMask<uint8_t>(0x11) == 2);
144     VerifyOrQuit(CountBitsInMask<uint8_t>(0xef) == 7);
145     VerifyOrQuit(CountBitsInMask<uint8_t>(0xff) == 8);
146 
147     VerifyOrQuit(CountBitsInMask<uint16_t>(0) == 0);
148     VerifyOrQuit(CountBitsInMask<uint16_t>(0xff00) == 8);
149     VerifyOrQuit(CountBitsInMask<uint16_t>(0xff) == 8);
150     VerifyOrQuit(CountBitsInMask<uint16_t>(0xaa55) == 8);
151     VerifyOrQuit(CountBitsInMask<uint16_t>(0xffff) == 16);
152 
153     printf("TestNumUtils() passed\n");
154 }
155 
TestPreference(void)156 void TestPreference(void)
157 {
158     VerifyOrQuit(Preference::kHigh == 1);
159     VerifyOrQuit(Preference::kMedium == 0);
160     VerifyOrQuit(Preference::kLow == -1);
161 
162     // To2BitUint()
163     VerifyOrQuit(Preference::To2BitUint(Preference::kHigh) == 0x1);
164     VerifyOrQuit(Preference::To2BitUint(Preference::kMedium) == 0x0);
165     VerifyOrQuit(Preference::To2BitUint(Preference::kLow) == 0x3);
166     VerifyOrQuit(Preference::To2BitUint(2) == 0x1);
167     VerifyOrQuit(Preference::To2BitUint(-2) == 0x3);
168     VerifyOrQuit(Preference::To2BitUint(127) == 0x1);
169     VerifyOrQuit(Preference::To2BitUint(-128) == 0x3);
170 
171     // From2BitUint()
172     VerifyOrQuit(Preference::From2BitUint(0x1) == Preference::kHigh);
173     VerifyOrQuit(Preference::From2BitUint(0x0) == Preference::kMedium);
174     VerifyOrQuit(Preference::From2BitUint(0x3) == Preference::kLow);
175     VerifyOrQuit(Preference::From2BitUint(0x2) == Preference::kMedium);
176 
177     VerifyOrQuit(Preference::From2BitUint(0x1 | 4) == Preference::kHigh);
178     VerifyOrQuit(Preference::From2BitUint(0x0 | 4) == Preference::kMedium);
179     VerifyOrQuit(Preference::From2BitUint(0x3 | 4) == Preference::kLow);
180     VerifyOrQuit(Preference::From2BitUint(0x2 | 4) == Preference::kMedium);
181 
182     VerifyOrQuit(Preference::From2BitUint(0x1 | 0xfc) == Preference::kHigh);
183     VerifyOrQuit(Preference::From2BitUint(0x0 | 0xfc) == Preference::kMedium);
184     VerifyOrQuit(Preference::From2BitUint(0x3 | 0xfc) == Preference::kLow);
185     VerifyOrQuit(Preference::From2BitUint(0x2 | 0xfc) == Preference::kMedium);
186 
187     // IsValid()
188     VerifyOrQuit(Preference::IsValid(Preference::kHigh));
189     VerifyOrQuit(Preference::IsValid(Preference::kMedium));
190     VerifyOrQuit(Preference::IsValid(Preference::kLow));
191 
192     VerifyOrQuit(!Preference::IsValid(2));
193     VerifyOrQuit(!Preference::IsValid(-2));
194     VerifyOrQuit(!Preference::IsValid(127));
195     VerifyOrQuit(!Preference::IsValid(-128));
196 
197     // Is2BitUintValid
198     VerifyOrQuit(Preference::Is2BitUintValid(0x1));
199     VerifyOrQuit(Preference::Is2BitUintValid(0x0));
200     VerifyOrQuit(Preference::Is2BitUintValid(0x3));
201     VerifyOrQuit(!Preference::Is2BitUintValid(0x2));
202 
203     VerifyOrQuit(Preference::Is2BitUintValid(0x1 | 4));
204     VerifyOrQuit(Preference::Is2BitUintValid(0x0 | 4));
205     VerifyOrQuit(Preference::Is2BitUintValid(0x3 | 4));
206     VerifyOrQuit(!Preference::Is2BitUintValid(0x2 | 4));
207 
208     VerifyOrQuit(Preference::Is2BitUintValid(0x1 | 0xfc));
209     VerifyOrQuit(Preference::Is2BitUintValid(0x0 | 0xfc));
210     VerifyOrQuit(Preference::Is2BitUintValid(0x3 | 0xfc));
211     VerifyOrQuit(!Preference::Is2BitUintValid(0x2 | 0xfc));
212 
213     printf("TestPreference() passed\n");
214 }
215 
216 } // namespace ot
217 
main(void)218 int main(void)
219 {
220     ot::TestSerialNumber<uint8_t>("uint8_t");
221     ot::TestSerialNumber<uint16_t>("uint16_t");
222     ot::TestSerialNumber<uint32_t>("uint32_t");
223     ot::TestSerialNumber<uint64_t>("uint64_t");
224     ot::TestNumUtils();
225     ot::TestPreference();
226     printf("\nAll tests passed.\n");
227     return 0;
228 }
229