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