Skip to content

Commit 142325a

Browse files
committed
leveldb_snappy_test.cc: also verify NO snappy support on iOS
1 parent 99f4ed9 commit 142325a

File tree

1 file changed

+85
-44
lines changed

1 file changed

+85
-44
lines changed

Firestore/core/test/unit/local/leveldb_snappy_test.cc

Lines changed: 85 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <array>
1818
#include <fstream>
19+
#include <functional>
1920
#include <iostream>
2021
#include <memory>
2122
#include <string>
@@ -40,39 +41,106 @@ using ::firebase::firestore::util::Path;
4041
// with reason "corruption".
4142
Path CreateLevelDbDatabaseThatUsesSnappyCompression();
4243

43-
// This test ensures that we don't accidentally regress having added in Snappy
44-
// compression support (https://github.com/firebase/firebase-ios-sdk/pull/9596).
45-
TEST(LevelDbSnappy, LevelDbHasSnappySupportCompiledIn) {
46-
// Only run this test in cmake builds, since Snappy support is not included
47-
// when pulling in LevelDb via CocoaPods or Swift Package Manager.
44+
// Creates and opens a LevelDb database that contains at least one block that
45+
// is compressed with Snappy compression, then iterates over it, invoking the
46+
// given callback with the status at each point in the iteration. Once the
47+
// callback is invoked with a `status` where `status.ok()` is not true, then
48+
// iteration will stop and the callback will not be invoked again.
49+
void IterateOverLevelDbDatabaseThatUsesSnappyCompression(
50+
std::function<void(const leveldb::Status&)>);
51+
4852
#if FIRESTORE_TESTS_CMAKE_BUILD
49-
GTEST_SKIP() << "Snappy support is only present in cmake builds";
50-
#endif
5153

52-
Path leveldb_path = CreateLevelDbDatabaseThatUsesSnappyCompression();
53-
if (HasFatalFailure()) return;
54+
// Ensure that LevelDb is compiled with Snappy compression support.
55+
// See https://github.com/firebase/firebase-ios-sdk/pull/9596 for details.
56+
TEST(LevelDbSnappy, LevelDbSupportsSnappy) {
57+
IterateOverLevelDbDatabaseThatUsesSnappyCompression(
58+
[](const leveldb::Status& status) {
59+
ASSERT_TRUE(status.ok()) << ConvertStatus(status);
60+
});
61+
}
62+
63+
#else // FIRESTORE_TESTS_CMAKE_BUILD
5464

55-
leveldb::Options options;
56-
options.create_if_missing = false;
65+
// Ensure that LevelDb is NOT compiled with Snappy compression support.
66+
TEST(LevelDbSnappy, LevelDbDoesNotSupportSnappy) {
67+
bool got_failed_status = false;
68+
IterateOverLevelDbDatabaseThatUsesSnappyCompression(
69+
[&](const leveldb::Status& status) {
70+
if (!status.ok()) {
71+
got_failed_status = true;
72+
ASSERT_TRUE(status.IsCorruption()) << ConvertStatus(status);
73+
}
74+
});
5775

76+
if (!HasFailure()) {
77+
ASSERT_TRUE(got_failed_status)
78+
<< "Reading a Snappy-compressed LevelDb database was successful; "
79+
"however, it should NOT have been successful "
80+
"since Snappy support is expected to NOT be available.";
81+
}
82+
}
83+
84+
#endif // FIRESTORE_TESTS_CMAKE_BUILD
85+
86+
void IterateOverLevelDbDatabaseThatUsesSnappyCompression(
87+
std::function<void(const leveldb::Status&)> callback) {
5888
std::unique_ptr<leveldb::DB> db;
5989
{
90+
Path leveldb_path = CreateLevelDbDatabaseThatUsesSnappyCompression();
91+
92+
leveldb::Options options;
93+
options.create_if_missing = false;
94+
6095
leveldb::DB* db_ptr;
6196
leveldb::Status status =
6297
leveldb::DB::Open(options, leveldb_path.ToUtf8String(), &db_ptr);
63-
ASSERT_TRUE(status.ok());
98+
99+
ASSERT_TRUE(status.ok())
100+
<< "Opening LevelDb database " << leveldb_path.ToUtf8String()
101+
<< " failed: " << ConvertStatus(status);
102+
64103
db.reset(db_ptr);
65104
}
66105

67-
// One of the assertions below will fail when LevelDb attempts to read a block
68-
// that is compressed with Snappy and Snappy compression support is not
69-
// compiled in.
70106
std::unique_ptr<leveldb::Iterator> it(
71107
db->NewIterator(leveldb::ReadOptions()));
72108
for (it->SeekToFirst(); it->Valid(); it->Next()) {
73-
ASSERT_TRUE(it->status().ok()) << ConvertStatus(it->status());
109+
callback(it->status());
110+
if (!it->status().ok()) {
111+
return;
112+
}
113+
}
114+
115+
// Invoke the callback on the final status.
116+
callback(it->status());
117+
}
118+
119+
template <typename T>
120+
void WriteFile(const Path& dir,
121+
const std::string& file_name,
122+
const T& data_array) {
123+
Filesystem* fs = Filesystem::Default();
124+
{
125+
auto status = fs->RecursivelyCreateDir(dir);
126+
if (!status.ok()) {
127+
FAIL() << "Creating directory failed: " << dir.ToUtf8String() << " ("
128+
<< status.error_message() << ")";
129+
}
130+
}
131+
132+
Path file = dir.AppendUtf8(file_name);
133+
std::ofstream out_file(file.native_value(), std::ios::binary);
134+
if (!out_file) {
135+
FAIL() << "Unable to open file for writing: " << file.ToUtf8String();
136+
}
137+
138+
out_file.write(reinterpret_cast<const char*>(data_array.data()),
139+
data_array.size());
140+
out_file.close();
141+
if (!out_file) {
142+
FAIL() << "Writing to file failed: " << file.ToUtf8String();
74143
}
75-
ASSERT_TRUE(it->status().ok()) << ConvertStatus(it->status());
76144
}
77145

78146
const std::array<unsigned char, 0x00000165> LevelDbSnappyFile_000005_ldb{
@@ -190,33 +258,6 @@ const std::array<unsigned char, 0x000000C2> LevelDbSnappyFile_MANIFEST_000084{
190258
0x04, 0x0D,
191259
};
192260

193-
template <typename T>
194-
void WriteFile(const Path& dir,
195-
const std::string& file_name,
196-
const T& data_array) {
197-
Filesystem* fs = Filesystem::Default();
198-
{
199-
auto status = fs->RecursivelyCreateDir(dir);
200-
if (!status.ok()) {
201-
FAIL() << "Creating directory failed: " << dir.ToUtf8String() << " ("
202-
<< status.error_message() << ")";
203-
}
204-
}
205-
206-
Path file = dir.AppendUtf8(file_name);
207-
std::ofstream out_file(file.native_value(), std::ios::binary);
208-
if (!out_file) {
209-
FAIL() << "Unable to open file for writing: " << file.ToUtf8String();
210-
}
211-
212-
out_file.write(reinterpret_cast<const char*>(data_array.data()),
213-
data_array.size());
214-
out_file.close();
215-
if (!out_file) {
216-
FAIL() << "Writing to file failed: " << file.ToUtf8String();
217-
}
218-
}
219-
220261
Path CreateLevelDbDatabaseThatUsesSnappyCompression() {
221262
Path leveldb_dir = ::firebase::firestore::local::LevelDbDir();
222263
WriteFile(leveldb_dir, "000005.ldb", LevelDbSnappyFile_000005_ldb);

0 commit comments

Comments
 (0)