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
13namespace leveldb {
14
15TEST(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
40void 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
53TEST(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
75TEST(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
93void 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
100TEST(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
120void 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
129TEST(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