1 | // Copyright (c) 2018 The LevelDB Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
4 | |
5 | #include "util/logging.h" |
6 | |
7 | #include <limits> |
8 | #include <string> |
9 | |
10 | #include "gtest/gtest.h" |
11 | #include "leveldb/slice.h" |
12 | |
13 | namespace leveldb { |
14 | |
15 | TEST(Logging, NumberToString) { |
16 | ASSERT_EQ("0" , NumberToString(0)); |
17 | ASSERT_EQ("1" , NumberToString(1)); |
18 | ASSERT_EQ("9" , NumberToString(9)); |
19 | |
20 | ASSERT_EQ("10" , NumberToString(10)); |
21 | ASSERT_EQ("11" , NumberToString(11)); |
22 | ASSERT_EQ("19" , NumberToString(19)); |
23 | ASSERT_EQ("99" , NumberToString(99)); |
24 | |
25 | ASSERT_EQ("100" , NumberToString(100)); |
26 | ASSERT_EQ("109" , NumberToString(109)); |
27 | ASSERT_EQ("190" , NumberToString(190)); |
28 | ASSERT_EQ("123" , NumberToString(123)); |
29 | ASSERT_EQ("12345678" , NumberToString(12345678)); |
30 | |
31 | static_assert(std::numeric_limits<uint64_t>::max() == 18446744073709551615U, |
32 | "Test consistency check" ); |
33 | ASSERT_EQ("18446744073709551000" , NumberToString(18446744073709551000U)); |
34 | ASSERT_EQ("18446744073709551600" , NumberToString(18446744073709551600U)); |
35 | ASSERT_EQ("18446744073709551610" , NumberToString(18446744073709551610U)); |
36 | ASSERT_EQ("18446744073709551614" , NumberToString(18446744073709551614U)); |
37 | ASSERT_EQ("18446744073709551615" , NumberToString(18446744073709551615U)); |
38 | } |
39 | |
40 | void ConsumeDecimalNumberRoundtripTest(uint64_t number, |
41 | const std::string& padding = "" ) { |
42 | std::string decimal_number = NumberToString(number); |
43 | std::string input_string = decimal_number + padding; |
44 | Slice input(input_string); |
45 | Slice output = input; |
46 | uint64_t result; |
47 | ASSERT_TRUE(ConsumeDecimalNumber(&output, &result)); |
48 | ASSERT_EQ(number, result); |
49 | ASSERT_EQ(decimal_number.size(), output.data() - input.data()); |
50 | ASSERT_EQ(padding.size(), output.size()); |
51 | } |
52 | |
53 | TEST(Logging, ConsumeDecimalNumberRoundtrip) { |
54 | ConsumeDecimalNumberRoundtripTest(0); |
55 | ConsumeDecimalNumberRoundtripTest(1); |
56 | ConsumeDecimalNumberRoundtripTest(9); |
57 | |
58 | ConsumeDecimalNumberRoundtripTest(10); |
59 | ConsumeDecimalNumberRoundtripTest(11); |
60 | ConsumeDecimalNumberRoundtripTest(19); |
61 | ConsumeDecimalNumberRoundtripTest(99); |
62 | |
63 | ConsumeDecimalNumberRoundtripTest(100); |
64 | ConsumeDecimalNumberRoundtripTest(109); |
65 | ConsumeDecimalNumberRoundtripTest(190); |
66 | ConsumeDecimalNumberRoundtripTest(123); |
67 | ASSERT_EQ("12345678" , NumberToString(12345678)); |
68 | |
69 | for (uint64_t i = 0; i < 100; ++i) { |
70 | uint64_t large_number = std::numeric_limits<uint64_t>::max() - i; |
71 | ConsumeDecimalNumberRoundtripTest(large_number); |
72 | } |
73 | } |
74 | |
75 | TEST(Logging, ConsumeDecimalNumberRoundtripWithPadding) { |
76 | ConsumeDecimalNumberRoundtripTest(0, " " ); |
77 | ConsumeDecimalNumberRoundtripTest(1, "abc" ); |
78 | ConsumeDecimalNumberRoundtripTest(9, "x" ); |
79 | |
80 | ConsumeDecimalNumberRoundtripTest(10, "_" ); |
81 | ConsumeDecimalNumberRoundtripTest(11, std::string("\0\0\0" , 3)); |
82 | ConsumeDecimalNumberRoundtripTest(19, "abc" ); |
83 | ConsumeDecimalNumberRoundtripTest(99, "padding" ); |
84 | |
85 | ConsumeDecimalNumberRoundtripTest(100, " " ); |
86 | |
87 | for (uint64_t i = 0; i < 100; ++i) { |
88 | uint64_t large_number = std::numeric_limits<uint64_t>::max() - i; |
89 | ConsumeDecimalNumberRoundtripTest(large_number, "pad" ); |
90 | } |
91 | } |
92 | |
93 | void ConsumeDecimalNumberOverflowTest(const std::string& input_string) { |
94 | Slice input(input_string); |
95 | Slice output = input; |
96 | uint64_t result; |
97 | ASSERT_EQ(false, ConsumeDecimalNumber(&output, &result)); |
98 | } |
99 | |
100 | TEST(Logging, ConsumeDecimalNumberOverflow) { |
101 | static_assert(std::numeric_limits<uint64_t>::max() == 18446744073709551615U, |
102 | "Test consistency check" ); |
103 | ConsumeDecimalNumberOverflowTest("18446744073709551616" ); |
104 | ConsumeDecimalNumberOverflowTest("18446744073709551617" ); |
105 | ConsumeDecimalNumberOverflowTest("18446744073709551618" ); |
106 | ConsumeDecimalNumberOverflowTest("18446744073709551619" ); |
107 | ConsumeDecimalNumberOverflowTest("18446744073709551620" ); |
108 | ConsumeDecimalNumberOverflowTest("18446744073709551621" ); |
109 | ConsumeDecimalNumberOverflowTest("18446744073709551622" ); |
110 | ConsumeDecimalNumberOverflowTest("18446744073709551623" ); |
111 | ConsumeDecimalNumberOverflowTest("18446744073709551624" ); |
112 | ConsumeDecimalNumberOverflowTest("18446744073709551625" ); |
113 | ConsumeDecimalNumberOverflowTest("18446744073709551626" ); |
114 | |
115 | ConsumeDecimalNumberOverflowTest("18446744073709551700" ); |
116 | |
117 | ConsumeDecimalNumberOverflowTest("99999999999999999999" ); |
118 | } |
119 | |
120 | void ConsumeDecimalNumberNoDigitsTest(const std::string& input_string) { |
121 | Slice input(input_string); |
122 | Slice output = input; |
123 | uint64_t result; |
124 | ASSERT_EQ(false, ConsumeDecimalNumber(&output, &result)); |
125 | ASSERT_EQ(input.data(), output.data()); |
126 | ASSERT_EQ(input.size(), output.size()); |
127 | } |
128 | |
129 | TEST(Logging, ConsumeDecimalNumberNoDigits) { |
130 | ConsumeDecimalNumberNoDigitsTest("" ); |
131 | ConsumeDecimalNumberNoDigitsTest(" " ); |
132 | ConsumeDecimalNumberNoDigitsTest("a" ); |
133 | ConsumeDecimalNumberNoDigitsTest(" 123" ); |
134 | ConsumeDecimalNumberNoDigitsTest("a123" ); |
135 | ConsumeDecimalNumberNoDigitsTest(std::string("\000123" , 4)); |
136 | ConsumeDecimalNumberNoDigitsTest(std::string("\177123" , 4)); |
137 | ConsumeDecimalNumberNoDigitsTest(std::string("\377123" , 4)); |
138 | } |
139 | |
140 | } // namespace leveldb |
141 | |