Skip to content

Commit 7a057de

Browse files
committed
leveldb_snappy_test.cc added
1 parent 7898b46 commit 7a057de

File tree

2 files changed

+245
-0
lines changed

2 files changed

+245
-0
lines changed

firestore/integration_test_internal/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ set(FIREBASE_INTEGRATION_TEST_PORTABLE_TEST_SRCS
8888
src/fields_test.cc
8989
src/firestore_test.cc
9090
src/includes_test.cc
91+
src/leveldb_snappy_test.cc
9192
src/listener_registration_test.cc
9293
src/numeric_transforms_test.cc
9394
src/query_network_test.cc
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#if !defined(ANDROID)
18+
19+
#include <array>
20+
#include <fstream>
21+
#include <iostream>
22+
#include <memory>
23+
#include <string>
24+
25+
#include "Firestore/core/src/local/leveldb_util.h"
26+
#include "Firestore/core/src/util/filesystem.h"
27+
#include "Firestore/core/src/util/path.h"
28+
29+
#include "gtest/gtest.h"
30+
#include "leveldb/db.h"
31+
32+
// TODO(dconeybe) Reference this test in the iOS SDK instead of making a
33+
// copy of it here in the C++ SDK.
34+
35+
namespace {
36+
37+
using ::firebase::firestore::local::ConvertStatus;
38+
using ::firebase::firestore::util::Filesystem;
39+
using ::firebase::firestore::util::Path;
40+
41+
// Creates a LevelDb database that uses Snappy compression for at least one of
42+
// its blocks. Attempting to iterate over this database using a LevelDb library
43+
// that does not have Snappy compression compiled in will return a failed status
44+
// with reason "corruption".
45+
Path CreateLevelDbDatabaseThatUsesSnappyCompression();
46+
47+
// This test ensures that we don't accidentally regress having added in Snappy
48+
// compression support (https://github.com/firebase/firebase-ios-sdk/pull/9596).
49+
TEST(LevelDbSnappy, LevelDbHasSnappySupportCompiledIn) {
50+
Path leveldb_path = CreateLevelDbDatabaseThatUsesSnappyCompression();
51+
if (HasFatalFailure()) return;
52+
53+
leveldb::Options options;
54+
options.create_if_missing = false;
55+
56+
std::unique_ptr<leveldb::DB> db;
57+
{
58+
leveldb::DB* db_ptr;
59+
leveldb::Status status =
60+
leveldb::DB::Open(options, leveldb_path.ToUtf8String(), &db_ptr);
61+
ASSERT_TRUE(status.ok());
62+
db.reset(db_ptr);
63+
}
64+
65+
// One of the assertions below will fail when LevelDb attempts to read a block
66+
// that is compressed with Snappy and Snappy compression support is not
67+
// compiled in.
68+
std::unique_ptr<leveldb::Iterator> it(
69+
db->NewIterator(leveldb::ReadOptions()));
70+
for (it->SeekToFirst(); it->Valid(); it->Next()) {
71+
ASSERT_TRUE(it->status().ok()) << ConvertStatus(it->status());
72+
}
73+
ASSERT_TRUE(it->status().ok()) << ConvertStatus(it->status());
74+
}
75+
76+
const std::array<unsigned char, 0x00000165> LevelDbSnappyFile_000005_ldb{
77+
0x84, 0x03, 0x80, 0x00, 0x42, 0x00, 0x85, 0x71, 0x75, 0x65, 0x72, 0x79,
78+
0x5F, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x01, 0x8B, 0x43, 0x6F,
79+
0x6C, 0x41, 0x2F, 0x44, 0x6F, 0x63, 0x41, 0x2F, 0x43, 0x6F, 0x6C, 0x42,
80+
0x01, 0x0A, 0x68, 0x42, 0x7C, 0x66, 0x3A, 0x7C, 0x6F, 0x62, 0x3A, 0x5F,
81+
0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x5F, 0x61, 0x73, 0x63, 0x00, 0x01,
82+
0x8C, 0x82, 0x80, 0x01, 0x07, 0x00, 0x05, 0x01, 0x08, 0x01, 0x13, 0x50,
83+
0x11, 0x3E, 0x01, 0x16, 0x00, 0x0A, 0x05, 0x15, 0xF0, 0x3C, 0x00, 0x08,
84+
0x02, 0x20, 0x05, 0x32, 0x4A, 0x12, 0x48, 0x70, 0x72, 0x6F, 0x6A, 0x65,
85+
0x63, 0x74, 0x73, 0x2F, 0x54, 0x65, 0x73, 0x74, 0x54, 0x65, 0x72, 0x6D,
86+
0x69, 0x6E, 0x61, 0x74, 0x65, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
87+
0x73, 0x65, 0x73, 0x2F, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74,
88+
0x29, 0x2F, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x01,
89+
0x7B, 0x3E, 0x85, 0x00, 0x0C, 0x0D, 0x07, 0x50, 0x08, 0x15, 0x5A, 0x00,
90+
0x03, 0xFE, 0x5A, 0x00, 0x2E, 0x5A, 0x00, 0x38, 0x07, 0x12, 0x06, 0x5F,
91+
0x67, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x00, 0x01, 0x80, 0x01, 0x0B, 0x11,
92+
0x65, 0x1C, 0x10, 0x05, 0x20, 0x01, 0x12, 0x07, 0x06, 0x09, 0x15, 0x10,
93+
0x00, 0x03, 0x01, 0x10, 0x04, 0x00, 0x01, 0x09, 0x10, 0x24, 0x01, 0x12,
94+
0x01, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x01, 0x35, 0x00, 0x06,
95+
0x09, 0x15, 0x10, 0x37, 0x0C, 0x07, 0x01, 0x05, 0x09, 0x0B, 0x10, 0x36,
96+
0x0C, 0x07, 0x01, 0x04, 0x09, 0x0B, 0x10, 0x35, 0x0C, 0x07, 0x01, 0x03,
97+
0x09, 0x0B, 0x4C, 0x34, 0x0C, 0x07, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00,
98+
0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
99+
0x2C, 0x6E, 0xE0, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
100+
0x00, 0xC0, 0xF2, 0xA1, 0xB0, 0x00, 0x09, 0x03, 0x86, 0x01, 0xFF, 0xFF,
101+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x87, 0x02, 0x00, 0x00, 0x00, 0x00,
102+
0x01, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC2, 0x94, 0x06, 0x8C, 0x02, 0x08,
103+
0x99, 0x02, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106+
0x00, 0x57, 0xFB, 0x80, 0x8B, 0x24, 0x75, 0x47, 0xDB,
107+
};
108+
const std::array<unsigned char, 0x000000E8> LevelDbSnappyFile_000017_ldb{
109+
0x00, 0x14, 0x50, 0x85, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x01,
110+
0x8C, 0x82, 0x80, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
111+
0x02, 0x20, 0x0A, 0x32, 0x4A, 0x12, 0x48, 0x70, 0x72, 0x6F, 0x6A, 0x65,
112+
0x63, 0x74, 0x73, 0x2F, 0x54, 0x65, 0x73, 0x74, 0x54, 0x65, 0x72, 0x6D,
113+
0x69, 0x6E, 0x61, 0x74, 0x65, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
114+
0x73, 0x65, 0x73, 0x2F, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74,
115+
0x29, 0x2F, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x2F,
116+
0x43, 0x6F, 0x6C, 0x41, 0x2F, 0x44, 0x6F, 0x63, 0x41, 0x2F, 0x43, 0x6F,
117+
0x6C, 0x42, 0x2F, 0x44, 0x6F, 0x63, 0x42, 0x07, 0x12, 0x06, 0x5F, 0x67,
118+
0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x00, 0x01, 0x80, 0x01, 0x0D, 0x00, 0x00,
119+
0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x10, 0x0A, 0x20, 0x01, 0x00, 0x00,
120+
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCD, 0xE0, 0x39, 0x00,
121+
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF2, 0xA1, 0xB0,
122+
0x00, 0x09, 0x03, 0x86, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123+
0x00, 0x8A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
124+
0xE4, 0xA7, 0x7E, 0x74, 0x8F, 0x01, 0x08, 0x9C, 0x01, 0x17, 0x00, 0x00,
125+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xFB, 0x80, 0x8B,
128+
0x24, 0x75, 0x47, 0xDB,
129+
};
130+
const std::array<unsigned char, 0x00000000> LevelDbSnappyFile_000085_ldb{};
131+
const std::array<unsigned char, 0x00000010> LevelDbSnappyFile_CURRENT{
132+
0x4D, 0x41, 0x4E, 0x49, 0x46, 0x45, 0x53, 0x54,
133+
0x2D, 0x30, 0x30, 0x30, 0x30, 0x38, 0x34, 0x0A,
134+
};
135+
const std::array<unsigned char, 0x000000B5> LevelDbSnappyFile_LOG_old{
136+
0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D, 0x31,
137+
0x31, 0x3A, 0x33, 0x39, 0x3A, 0x34, 0x36, 0x2E, 0x32, 0x35, 0x37, 0x32,
138+
0x35, 0x31, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x35, 0x33,
139+
0x31, 0x34, 0x30, 0x30, 0x30, 0x20, 0x52, 0x65, 0x63, 0x6F, 0x76, 0x65,
140+
0x72, 0x69, 0x6E, 0x67, 0x20, 0x6C, 0x6F, 0x67, 0x20, 0x23, 0x38, 0x31,
141+
0x0A, 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D,
142+
0x31, 0x31, 0x3A, 0x33, 0x39, 0x3A, 0x34, 0x36, 0x2E, 0x33, 0x30, 0x34,
143+
0x35, 0x35, 0x32, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x35,
144+
0x33, 0x31, 0x34, 0x30, 0x30, 0x30, 0x20, 0x44, 0x65, 0x6C, 0x65, 0x74,
145+
0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x33, 0x20, 0x23, 0x38, 0x30,
146+
0x0A, 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D,
147+
0x31, 0x31, 0x3A, 0x33, 0x39, 0x3A, 0x34, 0x36, 0x2E, 0x33, 0x30, 0x35,
148+
0x30, 0x36, 0x34, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x35,
149+
0x33, 0x31, 0x34, 0x30, 0x30, 0x30, 0x20, 0x44, 0x65, 0x6C, 0x65, 0x74,
150+
0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x30, 0x20, 0x23, 0x38, 0x31,
151+
0x0A,
152+
};
153+
const std::array<unsigned char, 0x000000B5> LevelDbSnappyFile_LOG{
154+
0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D, 0x31,
155+
0x31, 0x3A, 0x35, 0x36, 0x3A, 0x35, 0x36, 0x2E, 0x34, 0x39, 0x33, 0x31,
156+
0x34, 0x32, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x61, 0x32,
157+
0x35, 0x34, 0x30, 0x30, 0x30, 0x20, 0x52, 0x65, 0x63, 0x6F, 0x76, 0x65,
158+
0x72, 0x69, 0x6E, 0x67, 0x20, 0x6C, 0x6F, 0x67, 0x20, 0x23, 0x38, 0x33,
159+
0x0A, 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D,
160+
0x31, 0x31, 0x3A, 0x35, 0x36, 0x3A, 0x35, 0x36, 0x2E, 0x35, 0x33, 0x34,
161+
0x37, 0x34, 0x35, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x61,
162+
0x32, 0x35, 0x34, 0x30, 0x30, 0x30, 0x20, 0x44, 0x65, 0x6C, 0x65, 0x74,
163+
0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x33, 0x20, 0x23, 0x38, 0x32,
164+
0x0A, 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D,
165+
0x31, 0x31, 0x3A, 0x35, 0x36, 0x3A, 0x35, 0x36, 0x2E, 0x35, 0x33, 0x35,
166+
0x32, 0x34, 0x32, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x61,
167+
0x32, 0x35, 0x34, 0x30, 0x30, 0x30, 0x20, 0x44, 0x65, 0x6C, 0x65, 0x74,
168+
0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x30, 0x20, 0x23, 0x38, 0x33,
169+
0x0A,
170+
};
171+
const std::array<unsigned char, 0x000000C2> LevelDbSnappyFile_MANIFEST_000084{
172+
0x45, 0x63, 0x9F, 0xDD, 0xAC, 0x00, 0x01, 0x01, 0x1A, 0x6C, 0x65, 0x76,
173+
0x65, 0x6C, 0x64, 0x62, 0x2E, 0x42, 0x79, 0x74, 0x65, 0x77, 0x69, 0x73,
174+
0x65, 0x43, 0x6F, 0x6D, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6F, 0x72, 0x07,
175+
0x00, 0x05, 0xE5, 0x02, 0x42, 0x85, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5F,
176+
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x01, 0x8B, 0x43, 0x6F, 0x6C,
177+
0x41, 0x2F, 0x44, 0x6F, 0x63, 0x41, 0x2F, 0x43, 0x6F, 0x6C, 0x42, 0x2F,
178+
0x44, 0x6F, 0x63, 0x42, 0x7C, 0x66, 0x3A, 0x7C, 0x6F, 0x62, 0x3A, 0x5F,
179+
0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x5F, 0x61, 0x73, 0x63, 0x00, 0x01,
180+
0x8C, 0x82, 0x80, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
181+
0x85, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x01, 0x80, 0x01,
182+
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x11, 0xE8, 0x01,
183+
0x14, 0x85, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x01, 0x8C, 0x82,
184+
0x80, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x85, 0x74,
185+
0x61, 0x72, 0x67, 0x65, 0x74, 0x5F, 0x67, 0x6C, 0x6F, 0x62, 0x61, 0x6C,
186+
0x00, 0x01, 0x80, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1,
187+
0x03, 0xAC, 0xBA, 0x08, 0x00, 0x01, 0x02, 0x55, 0x09, 0x00, 0x03, 0x56,
188+
0x04, 0x0D,
189+
};
190+
191+
template <typename T>
192+
void WriteFile(const Path& dir,
193+
const std::string& file_name,
194+
const T& data_array) {
195+
Filesystem* fs = Filesystem::Default();
196+
{
197+
auto status = fs->RecursivelyCreateDir(dir);
198+
if (!status.ok()) {
199+
FAIL() << "Creating directory failed: " << dir.ToUtf8String() << " ("
200+
<< status.error_message() << ")";
201+
}
202+
}
203+
204+
Path file = dir.AppendUtf8(file_name);
205+
std::ofstream out_file(file.native_value(), std::ios::binary);
206+
if (!out_file) {
207+
FAIL() << "Unable to open file for writing: " << file.ToUtf8String();
208+
}
209+
210+
out_file.write(reinterpret_cast<const char*>(data_array.data()),
211+
data_array.size());
212+
out_file.close();
213+
if (!out_file) {
214+
FAIL() << "Writing to file failed: " << file.ToUtf8String();
215+
}
216+
}
217+
218+
Path LevelDbDir() {
219+
Filesystem* fs = Filesystem::Default();
220+
Path dir = fs->TempDir().AppendUtf8("PersistenceTesting");
221+
222+
// Delete the directory first to ensure isolation between runs.
223+
auto status = fs->RecursivelyRemove(dir);
224+
EXPECT_TRUE(status.ok()) << "Failed to clean up leveldb in dir "
225+
<< dir.ToUtf8String() << ": " << status.ToString();
226+
227+
return dir;
228+
}
229+
230+
Path CreateLevelDbDatabaseThatUsesSnappyCompression() {
231+
Path leveldb_dir = LevelDbDir();
232+
WriteFile(leveldb_dir, "000005.ldb", LevelDbSnappyFile_000005_ldb);
233+
WriteFile(leveldb_dir, "000017.ldb", LevelDbSnappyFile_000017_ldb);
234+
WriteFile(leveldb_dir, "000085.ldb", LevelDbSnappyFile_000085_ldb);
235+
WriteFile(leveldb_dir, "CURRENT", LevelDbSnappyFile_CURRENT);
236+
WriteFile(leveldb_dir, "LOG.old", LevelDbSnappyFile_LOG_old);
237+
WriteFile(leveldb_dir, "LOG", LevelDbSnappyFile_LOG);
238+
WriteFile(leveldb_dir, "MANIFEST-000084", LevelDbSnappyFile_MANIFEST_000084);
239+
return leveldb_dir;
240+
}
241+
242+
} // namespace
243+
244+
#endif // !defined(ANDROID)

0 commit comments

Comments
 (0)