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