YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/util/coding_test.cc
Line
Count
Source
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under the BSD-style license found in the
3
//  LICENSE file in the root directory of this source tree. An additional grant
4
//  of patent rights can be found in the PATENTS file in the same directory.
5
//
6
// The following only applies to changes made to this file as part of YugaByte development.
7
//
8
// Portions Copyright (c) YugaByte, Inc.
9
//
10
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
11
// in compliance with the License.  You may obtain a copy of the License at
12
//
13
// http://www.apache.org/licenses/LICENSE-2.0
14
//
15
// Unless required by applicable law or agreed to in writing, software distributed under the License
16
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17
// or implied.  See the License for the specific language governing permissions and limitations
18
// under the License.
19
//
20
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
21
// Use of this source code is governed by a BSD-style license that can be
22
// found in the LICENSE file. See the AUTHORS file for names of contributors.
23
24
#include "yb/rocksdb/util/coding.h"
25
26
#include <string>
27
#include <gtest/gtest.h>
28
29
namespace rocksdb {
30
31
class Coding { };
32
33
1
TEST(Coding, Fixed32) {
34
1
  std::string s;
35
100k
  for (uint32_t v = 0; v < 100000; v++) {
36
100k
    PutFixed32(&s, v);
37
100k
  }
38
39
1
  const char* p = s.data();
40
100k
  for (uint32_t v = 0; v < 100000; v++) {
41
100k
    uint32_t actual = DecodeFixed32(p);
42
100k
    ASSERT_EQ(v, actual);
43
100k
    p += sizeof(uint32_t);
44
100k
  }
45
1
}
46
47
1
TEST(Coding, Fixed64) {
48
1
  std::string s;
49
65
  for (int power = 0; power <= 63; power++) {
50
64
    uint64_t v = static_cast<uint64_t>(1) << power;
51
64
    PutFixed64(&s, v - 1);
52
64
    PutFixed64(&s, v + 0);
53
64
    PutFixed64(&s, v + 1);
54
64
  }
55
56
1
  const char* p = s.data();
57
65
  for (int power = 0; power <= 63; power++) {
58
64
    uint64_t v = static_cast<uint64_t>(1) << power;
59
64
    uint64_t actual = 0;
60
64
    actual = DecodeFixed64(p);
61
64
    ASSERT_EQ(v-1, actual);
62
64
    p += sizeof(uint64_t);
63
64
64
    actual = DecodeFixed64(p);
65
64
    ASSERT_EQ(v+0, actual);
66
64
    p += sizeof(uint64_t);
67
68
64
    actual = DecodeFixed64(p);
69
64
    ASSERT_EQ(v+1, actual);
70
64
    p += sizeof(uint64_t);
71
64
  }
72
1
}
73
74
// Test that encoding routines generate little-endian encodings
75
1
TEST(Coding, EncodingOutput) {
76
1
  std::string dst;
77
1
  PutFixed32(&dst, 0x04030201);
78
1
  ASSERT_EQ(4U, dst.size());
79
1
  ASSERT_EQ(0x01, static_cast<int>(dst[0]));
80
1
  ASSERT_EQ(0x02, static_cast<int>(dst[1]));
81
1
  ASSERT_EQ(0x03, static_cast<int>(dst[2]));
82
1
  ASSERT_EQ(0x04, static_cast<int>(dst[3]));
83
84
1
  dst.clear();
85
1
  PutFixed64(&dst, 0x0807060504030201ull);
86
1
  ASSERT_EQ(8U, dst.size());
87
1
  ASSERT_EQ(0x01, static_cast<int>(dst[0]));
88
1
  ASSERT_EQ(0x02, static_cast<int>(dst[1]));
89
1
  ASSERT_EQ(0x03, static_cast<int>(dst[2]));
90
1
  ASSERT_EQ(0x04, static_cast<int>(dst[3]));
91
1
  ASSERT_EQ(0x05, static_cast<int>(dst[4]));
92
1
  ASSERT_EQ(0x06, static_cast<int>(dst[5]));
93
1
  ASSERT_EQ(0x07, static_cast<int>(dst[6]));
94
1
  ASSERT_EQ(0x08, static_cast<int>(dst[7]));
95
1
}
96
97
1
TEST(Coding, Varint32) {
98
1
  std::string s;
99
1.02k
  for (uint32_t i = 0; i < (32 * 32); i++) {
100
1.02k
    uint32_t v = (i / 32) << (i % 32);
101
1.02k
    PutVarint32(&s, v);
102
1.02k
  }
103
104
1
  const char* p = s.data();
105
1
  const char* limit = p + s.size();
106
1.02k
  for (uint32_t i = 0; i < (32 * 32); i++) {
107
1.02k
    uint32_t expected = (i / 32) << (i % 32);
108
1.02k
    uint32_t actual = 0;
109
1.02k
    const char* start = p;
110
1.02k
    p = GetVarint32Ptr(p, limit, &actual);
111
1.02k
    ASSERT_TRUE(p != nullptr);
112
1.02k
    ASSERT_EQ(expected, actual);
113
1.02k
    ASSERT_EQ(VarintLength(actual), p - start);
114
1.02k
  }
115
1
  ASSERT_EQ(p, s.data() + s.size());
116
1
}
117
118
1
TEST(Coding, Varint64) {
119
  // Construct the list of values to check
120
1
  std::vector<uint64_t> values;
121
  // Some special values
122
1
  values.push_back(0);
123
1
  values.push_back(100);
124
1
  values.push_back(~static_cast<uint64_t>(0));
125
1
  values.push_back(~static_cast<uint64_t>(0) - 1);
126
65
  for (uint32_t k = 0; k < 64; k++) {
127
    // Test values near powers of two
128
64
    const uint64_t power = 1ull << k;
129
64
    values.push_back(power);
130
64
    values.push_back(power-1);
131
64
    values.push_back(power+1);
132
64
  }
133
134
1
  std::string s;
135
197
  for (unsigned int i = 0; i < values.size(); i++) {
136
196
    PutVarint64(&s, values[i]);
137
196
    FastPutVarint64(&s, values[i]);
138
196
  }
139
140
1
  const char* p = s.data();
141
1
  const char* limit = p + s.size();
142
197
  for (unsigned int i = 0; i < values.size(); i++) {
143
    // Check decoding of both PutVarint64 and FastPutVarint64.
144
588
    for (int j = 0; j < 2; ++j) {
145
392
      ASSERT_TRUE(p < limit);
146
392
      uint64_t actual = 0;
147
392
      const char* start = p;
148
392
      p = GetVarint64Ptr(p, limit, &actual);
149
392
      ASSERT_TRUE(p != nullptr);
150
392
      ASSERT_EQ(values[i], actual);
151
392
      ASSERT_EQ(VarintLength(actual), p - start);
152
392
    }
153
196
  }
154
1
  ASSERT_EQ(p, limit);
155
156
1
}
157
158
1
TEST(Coding, Varint32Overflow) {
159
1
  uint32_t result;
160
1
  std::string input("\x81\x82\x83\x84\x85\x11");
161
1
  ASSERT_TRUE(GetVarint32Ptr(input.data(), input.data() + input.size(), &result)
162
1
              == nullptr);
163
1
}
164
165
1
TEST(Coding, Varint32Truncation) {
166
1
  uint32_t large_value = (1u << 31) + 100;
167
1
  std::string s;
168
1
  PutVarint32(&s, large_value);
169
1
  uint32_t result;
170
5
  for (unsigned int len = 0; len < s.size() - 1; len++) {
171
4
    ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + len, &result) == nullptr);
172
4
  }
173
1
  ASSERT_TRUE(
174
1
      GetVarint32Ptr(s.data(), s.data() + s.size(), &result) != nullptr);
175
1
  ASSERT_EQ(large_value, result);
176
1
}
177
178
1
TEST(Coding, Varint64Overflow) {
179
1
  uint64_t result;
180
1
  std::string input("\x81\x82\x83\x84\x85\x81\x82\x83\x84\x85\x11");
181
1
  ASSERT_TRUE(GetVarint64Ptr(input.data(), input.data() + input.size(), &result)
182
1
              == nullptr);
183
1
}
184
185
1
TEST(Coding, Varint64Truncation) {
186
1
  uint64_t large_value = (1ull << 63) + 100ull;
187
1
  std::string s;
188
1
  PutVarint64(&s, large_value);
189
1
  uint64_t result;
190
10
  for (unsigned int len = 0; len < s.size() - 1; len++) {
191
9
    ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + len, &result) == nullptr);
192
9
  }
193
1
  ASSERT_TRUE(
194
1
      GetVarint64Ptr(s.data(), s.data() + s.size(), &result) != nullptr);
195
1
  ASSERT_EQ(large_value, result);
196
1
}
197
198
1
TEST(Coding, Strings) {
199
1
  std::string s;
200
1
  PutLengthPrefixedSlice(&s, Slice(""));
201
1
  PutLengthPrefixedSlice(&s, Slice("foo"));
202
1
  PutLengthPrefixedSlice(&s, Slice("bar"));
203
1
  PutLengthPrefixedSlice(&s, Slice(std::string(200, 'x')));
204
205
1
  Slice input(s);
206
1
  Slice v;
207
1
  ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));
208
1
  ASSERT_EQ("", v.ToString());
209
1
  ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));
210
1
  ASSERT_EQ("foo", v.ToString());
211
1
  ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));
212
1
  ASSERT_EQ("bar", v.ToString());
213
1
  ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));
214
1
  ASSERT_EQ(std::string(200, 'x'), v.ToString());
215
1
  ASSERT_EQ("", input.ToString());
216
1
}
217
218
}  // namespace rocksdb
219
220
13.2k
int main(int argc, char** argv) {
221
13.2k
  ::testing::InitGoogleTest(&argc, argv);
222
13.2k
  return RUN_ALL_TESTS();
223
13.2k
}