1 // Copyright 2018 The Chromium 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.
4
5 #include "components/services/storage/indexed_db/scopes/leveldb_scopes_coding.h"
6
7 #include <ostream>
8
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace leveldb {
operator <<(std::ostream & os,const leveldb::Slice & slice)12 std::ostream& operator<<(std::ostream& os, const leveldb::Slice& slice) {
13 os << "0x";
14 for (size_t i = 0; i < slice.size(); ++i) {
15 const char c = slice[i];
16 os << std::hex << std::setfill('0') << std::setw(2) << (int)c;
17 }
18 return os;
19 }
20 } // namespace leveldb
21
22 namespace content {
23 namespace {
24
TEST(LevelDBScopesCodingTest,GlobalMetadataKey)25 TEST(LevelDBScopesCodingTest, GlobalMetadataKey) {
26 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
27 ScopesEncoder encoder;
28
29 std::string expected = "AB";
30 expected.push_back(0x00);
31 EXPECT_EQ(leveldb::Slice(expected), encoder.GlobalMetadataKey(scopes_prefix));
32 }
33
TEST(LevelDBScopesCodingTest,ScopeMetadataKey)34 TEST(LevelDBScopesCodingTest, ScopeMetadataKey) {
35 const static int kScopeNumber = 0x0201;
36 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
37 ScopesEncoder encoder;
38
39 std::string expected = "AB\x01\x81\x04";
40 EXPECT_EQ(leveldb::Slice(expected),
41 encoder.ScopeMetadataKey(scopes_prefix, kScopeNumber));
42 }
43
TEST(LevelDBScopesCodingTest,ScopeMetadataPrefix)44 TEST(LevelDBScopesCodingTest, ScopeMetadataPrefix) {
45 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
46 ScopesEncoder encoder;
47
48 std::string expected = "AB\x01";
49 EXPECT_EQ(leveldb::Slice(expected),
50 encoder.ScopeMetadataPrefix(scopes_prefix));
51 }
52
TEST(LevelDBScopesCodingTest,TasksKeyPrefix)53 TEST(LevelDBScopesCodingTest, TasksKeyPrefix) {
54 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
55 ScopesEncoder encoder;
56
57 std::string expected = "AB\x02";
58 EXPECT_EQ(leveldb::Slice(expected), encoder.TasksKeyPrefix(scopes_prefix));
59 }
60
TEST(LevelDBScopesCodingTest,TasksKeyWithScopePrefix)61 TEST(LevelDBScopesCodingTest, TasksKeyWithScopePrefix) {
62 const static int kScopeNumber = 0x0401;
63 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
64 ScopesEncoder encoder;
65
66 std::string expected = "AB\x02\x81\x08";
67 EXPECT_EQ(leveldb::Slice(expected),
68 encoder.TasksKeyPrefix(scopes_prefix, kScopeNumber));
69 }
70
TEST(LevelDBScopesCodingTest,UndoTaskKeyPrefix)71 TEST(LevelDBScopesCodingTest, UndoTaskKeyPrefix) {
72 const static int kScopeNumber = 0x0401;
73 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
74 ScopesEncoder encoder;
75
76 std::string expected = "AB\x02\x81\x08";
77 expected.push_back(0x00);
78 EXPECT_EQ(leveldb::Slice(expected),
79 encoder.UndoTaskKeyPrefix(scopes_prefix, kScopeNumber));
80 }
81
TEST(LevelDBScopesCodingTest,CleanupTaskKeyPrefix)82 TEST(LevelDBScopesCodingTest, CleanupTaskKeyPrefix) {
83 const static int kScopeNumber = 0x0401;
84 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
85 ScopesEncoder encoder;
86
87 std::string expected = "AB\x02\x81\x08\x01";
88 EXPECT_EQ(leveldb::Slice(expected),
89 encoder.CleanupTaskKeyPrefix(scopes_prefix, kScopeNumber));
90 }
91
TEST(LevelDBScopesCodingTest,UndoTaskKey)92 TEST(LevelDBScopesCodingTest, UndoTaskKey) {
93 const static int kScopeNumber = 0x0401;
94 const static int kSequenceNumber = 0x0401;
95 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
96 ScopesEncoder encoder;
97
98 std::string expected = "AB\x02\x81\x08";
99 // Add the 'undo' type.
100 expected.push_back(0x00);
101 // Encode the big endian fixed length nunber.
102 for (size_t i = 0; i < 6; ++i)
103 expected.push_back(0x00);
104 expected += "\x04\x01";
105 EXPECT_EQ(leveldb::Slice(expected),
106 encoder.UndoTaskKey(scopes_prefix, kScopeNumber, kSequenceNumber));
107 }
108
TEST(LevelDBScopesCodingTest,CleanupTaskKey)109 TEST(LevelDBScopesCodingTest, CleanupTaskKey) {
110 const static int kScopeNumber = 0x0401;
111 const static int kSequenceNumber = 0x0401;
112 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
113 ScopesEncoder encoder;
114
115 std::string expected = "AB\x02\x81\x08\x01";
116 // Encode the big endian fixed length nunber.
117 for (size_t i = 0; i < 6; ++i)
118 expected.push_back(0x00);
119 expected += "\x04\x01";
120 EXPECT_EQ(
121 leveldb::Slice(expected),
122 encoder.CleanupTaskKey(scopes_prefix, kScopeNumber, kSequenceNumber));
123 }
124
TEST(LevelDBScopesCodingTest,ParseScopeMetadataId)125 TEST(LevelDBScopesCodingTest, ParseScopeMetadataId) {
126 const static int kScopeNumber = 0x0401;
127 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
128 bool success = false;
129 int64_t scope_id;
130
131 std::string on_disk = "AB\x01\x81\x08";
132 std::tie(success, scope_id) =
133 leveldb_scopes::ParseScopeMetadataId(on_disk, scopes_prefix);
134 EXPECT_TRUE(success);
135 EXPECT_EQ(kScopeNumber, scope_id);
136 }
137
TEST(LevelDBScopesCodingTest,InvalidMetadataByte)138 TEST(LevelDBScopesCodingTest, InvalidMetadataByte) {
139 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
140 bool success = false;
141 int64_t scope_id;
142
143 // Wrong metadata byte.
144 std::string on_disk = "AB\x02\x81\x08";
145 std::tie(success, scope_id) =
146 leveldb_scopes::ParseScopeMetadataId(on_disk, scopes_prefix);
147 EXPECT_FALSE(success);
148 }
149
TEST(LevelDBScopesCodingTest,InvalidVarInt)150 TEST(LevelDBScopesCodingTest, InvalidVarInt) {
151 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
152 bool success = false;
153 int64_t scope_id;
154
155 // Invalid varint
156 std::string on_disk = "AB\x01\xFF";
157 std::tie(success, scope_id) =
158 leveldb_scopes::ParseScopeMetadataId(on_disk, scopes_prefix);
159 EXPECT_FALSE(success);
160 on_disk = "AB\x01";
161 std::tie(success, scope_id) =
162 leveldb_scopes::ParseScopeMetadataId(on_disk, scopes_prefix);
163 EXPECT_FALSE(success);
164 }
165
TEST(LevelDBScopesCodingTest,InvalidPrefix)166 TEST(LevelDBScopesCodingTest, InvalidPrefix) {
167 std::vector<uint8_t> scopes_prefix = {'A', 'B'};
168
169 bool success = false;
170 int64_t scope_id;
171 // Invalid prefix
172 std::string on_disk = "XX\x01\x81\x08";
173 std::tie(success, scope_id) =
174 leveldb_scopes::ParseScopeMetadataId(on_disk, scopes_prefix);
175 EXPECT_FALSE(success);
176 on_disk = "A";
177 std::tie(success, scope_id) =
178 leveldb_scopes::ParseScopeMetadataId(on_disk, scopes_prefix);
179 EXPECT_FALSE(success);
180 }
181
182 } // namespace
183 } // namespace content
184