1 /*
2 * Copyright (C) 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <cstdint>
18 #include <limits>
19
20 #include "android-base/stringprintf.h"
21 #include "gtest/gtest.h"
22
23 #include "wifilogd/local_utils.h"
24
25 namespace android {
26 namespace wifilogd {
27
28 using local_utils::CastEnumToInteger;
29 using local_utils::CopyFromBufferOrDie;
30 using local_utils::GetMaxVal;
31 using local_utils::IsAsciiPrintable;
32
TEST(LocalUtilsTest,CastEnumToIntegerWorksForValidEnumValues)33 TEST(LocalUtilsTest, CastEnumToIntegerWorksForValidEnumValues) {
34 enum class basic_enum { VALUE0, VALUE1 };
35 EXPECT_EQ(0, CastEnumToInteger(basic_enum::VALUE0));
36 EXPECT_EQ(1, CastEnumToInteger(basic_enum::VALUE1));
37 }
38
TEST(LocalUtilsTest,CastEnumToIntegerWorksForInvalidEnumValues)39 TEST(LocalUtilsTest, CastEnumToIntegerWorksForInvalidEnumValues) {
40 enum class basic_enum : int { VALUE0, VALUE1 };
41 constexpr int invalid_enum_value = 2;
42 EXPECT_EQ(0, CastEnumToInteger(basic_enum::VALUE0));
43 EXPECT_EQ(1, CastEnumToInteger(basic_enum::VALUE1));
44 EXPECT_EQ(2, CastEnumToInteger(CopyFromBufferOrDie<basic_enum>(
45 &invalid_enum_value, sizeof(invalid_enum_value))));
46 }
47
TEST(LocalUtilsTest,CopyFromBufferOrDieCopiesData)48 TEST(LocalUtilsTest, CopyFromBufferOrDieCopiesData) {
49 struct Message {
50 int a;
51 char b;
52 };
53 const Message original{5, 'c'};
54 const auto& duplicate =
55 CopyFromBufferOrDie<Message>(&original, sizeof(original));
56 EXPECT_EQ(original.a, duplicate.a);
57 EXPECT_EQ(original.b, duplicate.b);
58 }
59
TEST(LocalUtilsTest,GetMaxValFromTypeIsCorrectForUnsignedTypes)60 TEST(LocalUtilsTest, GetMaxValFromTypeIsCorrectForUnsignedTypes) {
61 EXPECT_EQ(std::numeric_limits<uint8_t>::max(), GetMaxVal<uint8_t>());
62 EXPECT_EQ(std::numeric_limits<uint16_t>::max(), GetMaxVal<uint16_t>());
63 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), GetMaxVal<uint32_t>());
64 EXPECT_EQ(std::numeric_limits<uint64_t>::max(), GetMaxVal<uint64_t>());
65 }
66
TEST(LocalUtilsTest,GetMaxValFromTypeIsCorrectForSignedTypes)67 TEST(LocalUtilsTest, GetMaxValFromTypeIsCorrectForSignedTypes) {
68 EXPECT_EQ(std::numeric_limits<int8_t>::max(), GetMaxVal<int8_t>());
69 EXPECT_EQ(std::numeric_limits<int16_t>::max(), GetMaxVal<int16_t>());
70 EXPECT_EQ(std::numeric_limits<int32_t>::max(), GetMaxVal<int32_t>());
71 EXPECT_EQ(std::numeric_limits<int64_t>::max(), GetMaxVal<int64_t>());
72 }
73
TEST(LocalUtilsTest,GetMaxValFromInstanceIsCorrectForUnsignedTypes)74 TEST(LocalUtilsTest, GetMaxValFromInstanceIsCorrectForUnsignedTypes) {
75 EXPECT_EQ(std::numeric_limits<uint8_t>::max(), GetMaxVal(uint8_t{}));
76 EXPECT_EQ(std::numeric_limits<uint16_t>::max(), GetMaxVal(uint16_t{}));
77 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), GetMaxVal(uint32_t{}));
78 EXPECT_EQ(std::numeric_limits<uint64_t>::max(), GetMaxVal(uint64_t{}));
79 }
80
TEST(LocalUtilsTest,GetMaxValFromInstanceIsCorrectForSignedTypes)81 TEST(LocalUtilsTest, GetMaxValFromInstanceIsCorrectForSignedTypes) {
82 EXPECT_EQ(std::numeric_limits<int8_t>::max(), GetMaxVal(int8_t{}));
83 EXPECT_EQ(std::numeric_limits<int16_t>::max(), GetMaxVal(int16_t{}));
84 EXPECT_EQ(std::numeric_limits<int32_t>::max(), GetMaxVal(int32_t{}));
85 EXPECT_EQ(std::numeric_limits<int64_t>::max(), GetMaxVal(int64_t{}));
86 }
87
TEST(LocalUtilsTest,IsAsciiPrintableReturnsTrueForAlphabeticCharacters)88 TEST(LocalUtilsTest, IsAsciiPrintableReturnsTrueForAlphabeticCharacters) {
89 for (const char c : {'a', 'z', 'A', 'Z'}) {
90 EXPECT_TRUE(IsAsciiPrintable(c)) << "Failed with: c == '" << c << "'";
91 }
92 }
93
TEST(LocalUtilsTest,IsAsciiPrintableReturnsTrueForNumericCharacters)94 TEST(LocalUtilsTest, IsAsciiPrintableReturnsTrueForNumericCharacters) {
95 for (const char c : {'0', '9'}) {
96 EXPECT_TRUE(IsAsciiPrintable(c)) << "Failed with: c == '" << c << "'";
97 }
98 }
99
TEST(LocalUtilsTest,IsAsciiPrintableReturnsTrueForPrintableSpaces)100 TEST(LocalUtilsTest, IsAsciiPrintableReturnsTrueForPrintableSpaces) {
101 for (const char c : {'\n', '\t', ' '}) {
102 EXPECT_TRUE(IsAsciiPrintable(c))
103 << base::StringPrintf("Failed with: c == 0x%02d", c);
104 }
105 }
106
TEST(LocalUtilsTest,IsAsciiPrintableReturnsTrueForMaximalPrintable)107 TEST(LocalUtilsTest, IsAsciiPrintableReturnsTrueForMaximalPrintable) {
108 EXPECT_TRUE(IsAsciiPrintable('~'));
109 }
110
TEST(LocalUtilsTest,IsAsciiPrintableReturnsFalseForUnprintableSpaces)111 TEST(LocalUtilsTest, IsAsciiPrintableReturnsFalseForUnprintableSpaces) {
112 for (const char c : {'\f', '\r', '\v'}) {
113 EXPECT_FALSE(IsAsciiPrintable(c))
114 << base::StringPrintf("Failed with: c == 0x%02d", c);
115 }
116 }
117
TEST(LocalUtilsTest,IsAsciiPrintableReturnsFalseForNeighborsOfPrintables)118 TEST(LocalUtilsTest, IsAsciiPrintableReturnsFalseForNeighborsOfPrintables) {
119 for (const char c : {char{0x1f}, char{0x7f}}) {
120 EXPECT_FALSE(IsAsciiPrintable(c))
121 << base::StringPrintf("Failed with: c == 0x%02d", c);
122 }
123 }
124
TEST(LocalUtilsTest,IsAsciiPrintableReturnsFalseForMinimalAndMaximalChars)125 TEST(LocalUtilsTest, IsAsciiPrintableReturnsFalseForMinimalAndMaximalChars) {
126 using uchar = unsigned char;
127 for (const uchar c : {uchar{0x00}, uchar{0xff}}) {
128 EXPECT_FALSE(IsAsciiPrintable(c))
129 << base::StringPrintf("Failed with: c == 0x%02d", c);
130 }
131 }
132
TEST(LocalUtilsTest,SafelyClampWorksForSameTypeClamping)133 TEST(LocalUtilsTest, SafelyClampWorksForSameTypeClamping) {
134 EXPECT_EQ(int8_t{0}, (SAFELY_CLAMP(int8_t{-1}, int8_t, 0, 2)));
135 EXPECT_EQ(int8_t{0}, (SAFELY_CLAMP(int8_t{0}, int8_t, 0, 2)));
136 EXPECT_EQ(int8_t{1}, (SAFELY_CLAMP(int8_t{1}, int8_t, 0, 2)));
137 EXPECT_EQ(int8_t{2}, (SAFELY_CLAMP(int8_t{2}, int8_t, 0, 2)));
138 EXPECT_EQ(int8_t{2}, (SAFELY_CLAMP(int8_t{3}, int8_t, 0, 2)));
139 }
140
TEST(LocalUtilsTest,SafelyClampWorksForSignedToUnsigned)141 TEST(LocalUtilsTest, SafelyClampWorksForSignedToUnsigned) {
142 static_assert(std::numeric_limits<int8_t>::max() == 127,
143 "upper bound is set incorrectly");
144 EXPECT_EQ(uint8_t{0}, (SAFELY_CLAMP(int8_t{-1}, uint8_t, 0, 127)));
145 EXPECT_EQ(uint8_t{0}, (SAFELY_CLAMP(int8_t{0}, uint8_t, 0, 127)));
146 EXPECT_EQ(uint8_t{1}, (SAFELY_CLAMP(int8_t{1}, uint8_t, 0, 127)));
147 EXPECT_EQ(uint8_t{127}, (SAFELY_CLAMP(int8_t{127}, uint8_t, 0, 127)));
148 }
149
TEST(LocalUtilsTest,SafelyClampWorksForUnsignedToSigned)150 TEST(LocalUtilsTest, SafelyClampWorksForUnsignedToSigned) {
151 static_assert(std::numeric_limits<int8_t>::max() == 127,
152 "upper bound is set incorrectly");
153 EXPECT_EQ(int8_t{0}, (SAFELY_CLAMP(uint8_t{0}, int8_t, 0, 127)));
154 EXPECT_EQ(int8_t{1}, (SAFELY_CLAMP(uint8_t{1}, int8_t, 0, 127)));
155 EXPECT_EQ(int8_t{127}, (SAFELY_CLAMP(uint8_t{127}, int8_t, 0, 127)));
156 EXPECT_EQ(int8_t{127}, (SAFELY_CLAMP(uint8_t{128}, int8_t, 0, 127)));
157 }
158
159 // Per
160 // github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#death-tests,
161 // death tests should be specially named.
162
TEST(LocalUtilsDeathTest,CopyFromBufferOrDieWithShortBufferCausesDeath)163 TEST(LocalUtilsDeathTest, CopyFromBufferOrDieWithShortBufferCausesDeath) {
164 struct Message {
165 int a;
166 char b;
167 };
168 const Message original{5, 'c'};
169 EXPECT_DEATH((CopyFromBufferOrDie<Message>(&original, sizeof(original) - 1)),
170 "Check failed");
171 }
172
173 } // namespace wifilogd
174 } // namespace android
175