YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/utilities/document/json_document_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
21
#ifndef ROCKSDB_LITE
22
23
#include <map>
24
#include <set>
25
#include <string>
26
27
#include "yb/rocksdb/utilities/json_document.h"
28
29
#include "yb/rocksdb/util/testutil.h"
30
#include "yb/rocksdb/util/testharness.h"
31
32
#include "yb/util/test_util.h"
33
34
namespace rocksdb {
35
namespace {
36
3
void AssertField(const JSONDocument& json, const std::string& field) {
37
3
  ASSERT_TRUE(json.Contains(field));
38
3
  ASSERT_TRUE(json[field].IsNull());
39
3
}
40
41
void AssertField(const JSONDocument& json, const std::string& field,
42
9
                 const std::string& expected) {
43
9
  ASSERT_TRUE(json.Contains(field));
44
9
  ASSERT_TRUE(json[field].IsString());
45
9
  ASSERT_EQ(expected, json[field].GetString());
46
9
}
47
48
void AssertField(const JSONDocument& json, const std::string& field,
49
3
                 int64_t expected) {
50
3
  ASSERT_TRUE(json.Contains(field));
51
3
  ASSERT_TRUE(json[field].IsInt64());
52
3
  ASSERT_EQ(expected, json[field].GetInt64());
53
3
}
54
55
void AssertField(const JSONDocument& json, const std::string& field,
56
3
                 bool expected) {
57
3
  ASSERT_TRUE(json.Contains(field));
58
3
  ASSERT_TRUE(json[field].IsBool());
59
3
  ASSERT_EQ(expected, json[field].GetBool());
60
3
}
61
62
void AssertField(const JSONDocument& json, const std::string& field,
63
3
                 double expected) {
64
3
  ASSERT_TRUE(json.Contains(field));
65
3
  ASSERT_TRUE(json[field].IsDouble());
66
3
  ASSERT_EQ(expected, json[field].GetDouble());
67
3
}
68
}  // namespace
69
70
class JSONDocumentTest : public RocksDBTest {
71
 public:
72
  JSONDocumentTest()
73
  : rnd_(101)
74
11
  {}
75
76
3
  void AssertSampleJSON(const JSONDocument& json) {
77
3
    AssertField(json, "title", std::string("json"));
78
3
    AssertField(json, "type", std::string("object"));
79
    // properties
80
3
    ASSERT_TRUE(json.Contains("properties"));
81
3
    ASSERT_TRUE(json["properties"].Contains("flags"));
82
3
    ASSERT_TRUE(json["properties"]["flags"].IsArray());
83
3
    ASSERT_EQ(3u, json["properties"]["flags"].Count());
84
3
    ASSERT_TRUE(json["properties"]["flags"][0].IsInt64());
85
3
    ASSERT_EQ(10, json["properties"]["flags"][0].GetInt64());
86
3
    ASSERT_TRUE(json["properties"]["flags"][1].IsString());
87
3
    ASSERT_EQ("parse", json["properties"]["flags"][1].GetString());
88
3
    ASSERT_TRUE(json["properties"]["flags"][2].IsObject());
89
3
    AssertField(json["properties"]["flags"][2], "tag", std::string("no"));
90
3
    AssertField(json["properties"]["flags"][2], std::string("status"));
91
3
    AssertField(json["properties"], "age", 110.5e-4);
92
3
    AssertField(json["properties"], "depth", static_cast<int64_t>(-10));
93
    // test iteration
94
3
    std::set<std::string> expected({"flags", "age", "depth"});
95
9
    for (auto item : json["properties"].Items()) {
96
9
      auto iter = expected.find(item.first);
97
9
      ASSERT_TRUE(iter != expected.end());
98
9
      expected.erase(iter);
99
9
    }
100
3
    ASSERT_EQ(0U, expected.size());
101
3
    ASSERT_TRUE(json.Contains("latlong"));
102
3
    ASSERT_TRUE(json["latlong"].IsArray());
103
3
    ASSERT_EQ(2u, json["latlong"].Count());
104
3
    ASSERT_TRUE(json["latlong"][0].IsDouble());
105
3
    ASSERT_EQ(53.25, json["latlong"][0].GetDouble());
106
3
    ASSERT_TRUE(json["latlong"][1].IsDouble());
107
3
    ASSERT_EQ(43.75, json["latlong"][1].GetDouble());
108
3
    AssertField(json, "enabled", true);
109
3
  }
110
111
  const std::string kSampleJSON =
112
      "{ \"title\" : \"json\", \"type\" : \"object\", \"properties\" : { "
113
      "\"flags\": [10, \"parse\", {\"tag\": \"no\", \"status\": null}], "
114
      "\"age\": 110.5e-4, \"depth\": -10 }, \"latlong\": [53.25, 43.75], "
115
      "\"enabled\": true }";
116
117
  const std::string kSampleJSONDifferent =
118
      "{ \"title\" : \"json\", \"type\" : \"object\", \"properties\" : { "
119
      "\"flags\": [10, \"parse\", {\"tag\": \"no\", \"status\": 2}], "
120
      "\"age\": 110.5e-4, \"depth\": -10 }, \"latlong\": [53.25, 43.75], "
121
      "\"enabled\": true }";
122
123
  Random rnd_;
124
};
125
126
1
TEST_F(JSONDocumentTest, MakeNullTest) {
127
1
  JSONDocument x;
128
1
  ASSERT_TRUE(x.IsNull());
129
1
  ASSERT_TRUE(x.IsOwner());
130
1
  ASSERT_TRUE(!x.IsBool());
131
1
}
132
133
1
TEST_F(JSONDocumentTest, MakeBoolTest) {
134
1
  {
135
1
    JSONDocument x(true);
136
1
    ASSERT_TRUE(x.IsOwner());
137
1
    ASSERT_TRUE(x.IsBool());
138
1
    ASSERT_TRUE(!x.IsInt64());
139
1
    ASSERT_EQ(x.GetBool(), true);
140
1
  }
141
142
1
  {
143
1
    JSONDocument x(false);
144
1
    ASSERT_TRUE(x.IsOwner());
145
1
    ASSERT_TRUE(x.IsBool());
146
1
    ASSERT_TRUE(!x.IsInt64());
147
1
    ASSERT_EQ(x.GetBool(), false);
148
1
  }
149
1
}
150
151
1
TEST_F(JSONDocumentTest, MakeInt64Test) {
152
1
  JSONDocument x(static_cast<int64_t>(16));
153
1
  ASSERT_TRUE(x.IsInt64());
154
1
  ASSERT_TRUE(x.IsInt64());
155
1
  ASSERT_TRUE(!x.IsBool());
156
1
  ASSERT_TRUE(x.IsOwner());
157
1
  ASSERT_EQ(x.GetInt64(), 16);
158
1
}
159
160
1
TEST_F(JSONDocumentTest, MakeStringTest) {
161
1
  JSONDocument x("string");
162
1
  ASSERT_TRUE(x.IsOwner());
163
1
  ASSERT_TRUE(x.IsString());
164
1
  ASSERT_TRUE(!x.IsBool());
165
1
  ASSERT_EQ(x.GetString(), "string");
166
1
}
167
168
1
TEST_F(JSONDocumentTest, MakeDoubleTest) {
169
1
  JSONDocument x(5.6);
170
1
  ASSERT_TRUE(x.IsOwner());
171
1
  ASSERT_TRUE(x.IsDouble());
172
1
  ASSERT_TRUE(!x.IsBool());
173
1
  ASSERT_EQ(x.GetDouble(), 5.6);
174
1
}
175
176
1
TEST_F(JSONDocumentTest, MakeByTypeTest) {
177
1
  {
178
1
    JSONDocument x(JSONDocument::kNull);
179
1
    ASSERT_TRUE(x.IsNull());
180
1
  }
181
1
  {
182
1
    JSONDocument x(JSONDocument::kBool);
183
1
    ASSERT_TRUE(x.IsBool());
184
1
  }
185
1
  {
186
1
    JSONDocument x(JSONDocument::kString);
187
1
    ASSERT_TRUE(x.IsString());
188
1
  }
189
1
  {
190
1
    JSONDocument x(JSONDocument::kInt64);
191
1
    ASSERT_TRUE(x.IsInt64());
192
1
  }
193
1
  {
194
1
    JSONDocument x(JSONDocument::kDouble);
195
1
    ASSERT_TRUE(x.IsDouble());
196
1
  }
197
1
  {
198
1
    JSONDocument x(JSONDocument::kObject);
199
1
    ASSERT_TRUE(x.IsObject());
200
1
  }
201
1
  {
202
1
    JSONDocument x(JSONDocument::kArray);
203
1
    ASSERT_TRUE(x.IsArray());
204
1
  }
205
1
}
206
207
1
TEST_F(JSONDocumentTest, Parsing) {
208
1
  std::unique_ptr<JSONDocument> parsed_json(
209
1
          JSONDocument::ParseJSON(kSampleJSON.c_str()));
210
1
  ASSERT_TRUE(parsed_json->IsOwner());
211
1
  ASSERT_TRUE(parsed_json != nullptr);
212
1
  AssertSampleJSON(*parsed_json);
213
214
  // test deep copying
215
1
  JSONDocument copied_json_document(*parsed_json);
216
1
  AssertSampleJSON(copied_json_document);
217
1
  ASSERT_TRUE(copied_json_document == *parsed_json);
218
219
1
  std::unique_ptr<JSONDocument> parsed_different_sample(
220
1
      JSONDocument::ParseJSON(kSampleJSONDifferent.c_str()));
221
1
  ASSERT_TRUE(parsed_different_sample != nullptr);
222
1
  ASSERT_TRUE(!(*parsed_different_sample == copied_json_document));
223
224
  // parse error
225
1
  const std::string kFaultyJSON =
226
1
      kSampleJSON.substr(0, kSampleJSON.size() - 10);
227
1
  ASSERT_TRUE(JSONDocument::ParseJSON(kFaultyJSON.c_str()) == nullptr);
228
1
}
229
230
1
TEST_F(JSONDocumentTest, Serialization) {
231
1
  std::unique_ptr<JSONDocument> parsed_json(
232
1
            JSONDocument::ParseJSON(kSampleJSON.c_str()));
233
1
  ASSERT_TRUE(parsed_json != nullptr);
234
1
  ASSERT_TRUE(parsed_json->IsOwner());
235
1
  std::string serialized;
236
1
  parsed_json->Serialize(&serialized);
237
238
1
  std::unique_ptr<JSONDocument> deserialized_json(
239
1
            JSONDocument::Deserialize(Slice(serialized)));
240
1
  ASSERT_TRUE(deserialized_json != nullptr);
241
1
  AssertSampleJSON(*deserialized_json);
242
243
  // deserialization failure
244
1
  ASSERT_TRUE(JSONDocument::Deserialize(
245
1
                  Slice(serialized.data(), serialized.size() - 10)) == nullptr);
246
1
}
247
248
1
TEST_F(JSONDocumentTest, OperatorEqualsTest) {
249
  // kNull
250
1
  ASSERT_TRUE(JSONDocument() == JSONDocument());
251
252
  // kBool
253
1
  ASSERT_TRUE(JSONDocument(false) != JSONDocument());
254
1
  ASSERT_TRUE(JSONDocument(false) == JSONDocument(false));
255
1
  ASSERT_TRUE(JSONDocument(true) == JSONDocument(true));
256
1
  ASSERT_TRUE(JSONDocument(false) != JSONDocument(true));
257
258
  // kString
259
1
  ASSERT_TRUE(JSONDocument("test") != JSONDocument());
260
1
  ASSERT_TRUE(JSONDocument("test") == JSONDocument("test"));
261
262
  // kInt64
263
1
  ASSERT_TRUE(JSONDocument(static_cast<int64_t>(15)) != JSONDocument());
264
1
  ASSERT_TRUE(JSONDocument(static_cast<int64_t>(15)) !=
265
1
              JSONDocument(static_cast<int64_t>(14)));
266
1
  ASSERT_TRUE(JSONDocument(static_cast<int64_t>(15)) ==
267
1
              JSONDocument(static_cast<int64_t>(15)));
268
269
1
  unique_ptr<JSONDocument> arrayWithInt8Doc(JSONDocument::ParseJSON("[8]"));
270
1
  ASSERT_TRUE(arrayWithInt8Doc != nullptr);
271
1
  ASSERT_TRUE(arrayWithInt8Doc->IsArray());
272
1
  ASSERT_TRUE((*arrayWithInt8Doc)[0].IsInt64());
273
1
  ASSERT_TRUE((*arrayWithInt8Doc)[0] == JSONDocument(static_cast<int64_t>(8)));
274
275
1
  unique_ptr<JSONDocument> arrayWithInt16Doc(JSONDocument::ParseJSON("[512]"));
276
1
  ASSERT_TRUE(arrayWithInt16Doc != nullptr);
277
1
  ASSERT_TRUE(arrayWithInt16Doc->IsArray());
278
1
  ASSERT_TRUE((*arrayWithInt16Doc)[0].IsInt64());
279
1
  ASSERT_TRUE((*arrayWithInt16Doc)[0] ==
280
1
              JSONDocument(static_cast<int64_t>(512)));
281
282
1
  unique_ptr<JSONDocument> arrayWithInt32Doc(
283
1
    JSONDocument::ParseJSON("[1000000]"));
284
1
  ASSERT_TRUE(arrayWithInt32Doc != nullptr);
285
1
  ASSERT_TRUE(arrayWithInt32Doc->IsArray());
286
1
  ASSERT_TRUE((*arrayWithInt32Doc)[0].IsInt64());
287
1
  ASSERT_TRUE((*arrayWithInt32Doc)[0] ==
288
1
               JSONDocument(static_cast<int64_t>(1000000)));
289
290
  // kDouble
291
1
  ASSERT_TRUE(JSONDocument(15.) != JSONDocument());
292
1
  ASSERT_TRUE(JSONDocument(15.) != JSONDocument(14.));
293
1
  ASSERT_TRUE(JSONDocument(15.) == JSONDocument(15.));
294
1
}
295
296
1
TEST_F(JSONDocumentTest, JSONDocumentBuilderTest) {
297
1
  unique_ptr<JSONDocument> parsedArray(
298
1
    JSONDocument::ParseJSON("[1, [123, \"a\", \"b\"], {\"b\":\"c\"}]"));
299
1
  ASSERT_TRUE(parsedArray != nullptr);
300
301
1
  JSONDocumentBuilder builder;
302
1
  ASSERT_TRUE(builder.WriteStartArray());
303
1
  ASSERT_TRUE(builder.WriteJSONDocument(1));
304
305
1
  ASSERT_TRUE(builder.WriteStartArray());
306
1
    ASSERT_TRUE(builder.WriteJSONDocument(123));
307
1
    ASSERT_TRUE(builder.WriteJSONDocument("a"));
308
1
    ASSERT_TRUE(builder.WriteJSONDocument("b"));
309
1
  ASSERT_TRUE(builder.WriteEndArray());
310
311
1
  ASSERT_TRUE(builder.WriteStartObject());
312
1
    ASSERT_TRUE(builder.WriteKeyValue("b", "c"));
313
1
  ASSERT_TRUE(builder.WriteEndObject());
314
315
1
  ASSERT_TRUE(builder.WriteEndArray());
316
317
1
  ASSERT_TRUE(*parsedArray == builder.GetJSONDocument());
318
1
}
319
320
1
TEST_F(JSONDocumentTest, OwnershipTest) {
321
1
  std::unique_ptr<JSONDocument> parsed(
322
1
          JSONDocument::ParseJSON(kSampleJSON.c_str()));
323
1
  ASSERT_TRUE(parsed != nullptr);
324
1
  ASSERT_TRUE(parsed->IsOwner());
325
326
  // Copy constructor from owner -> owner
327
1
  JSONDocument copy_constructor(*parsed);
328
1
  ASSERT_TRUE(copy_constructor.IsOwner());
329
330
  // Copy constructor from non-owner -> non-owner
331
1
  JSONDocument non_owner((*parsed)["properties"]);
332
1
  ASSERT_TRUE(!non_owner.IsOwner());
333
334
  // Move constructor from owner -> owner
335
1
  JSONDocument moved_from_owner(std::move(copy_constructor));
336
1
  ASSERT_TRUE(moved_from_owner.IsOwner());
337
338
  // Move constructor from non-owner -> non-owner
339
1
  JSONDocument moved_from_non_owner(std::move(non_owner));
340
1
  ASSERT_TRUE(!moved_from_non_owner.IsOwner());
341
1
}
342
343
}  //  namespace rocksdb
344
345
13.2k
int main(int argc, char** argv) {
346
13.2k
  ::testing::InitGoogleTest(&argc, argv);
347
13.2k
  return RUN_ALL_TESTS();
348
13.2k
}
349
350
#else
351
#include <stdio.h>
352
353
int main(int argc, char** argv) {
354
  fprintf(stderr, "SKIPPED as JSONDocument is not supported in ROCKSDB_LITE\n");
355
  return 0;
356
}
357
358
#endif  // !ROCKSDB_LITE