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