Skip to content

Commit cb4f636

Browse files
authored
leveldb_snappy_test.cc: run the test on iOS as well, and other improvements (#896)
1 parent 0a0c4fc commit cb4f636

File tree

2 files changed

+107
-45
lines changed

2 files changed

+107
-45
lines changed

firestore/integration_test_internal/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,14 @@ else()
333333
${FIREBASE_INTEGRATION_TEST_SRCS}
334334
)
335335

336+
# Set a preprocessor define so that tests can distinguish between tests for
337+
# the desktop platforms (e.g. Windows, macOS, or Linux) and mobile platforms
338+
# (e.g. Android, iOS).
339+
target_compile_definitions(${integration_test_target_name}
340+
PRIVATE
341+
FIREBASE_TESTS_TARGET_DESKTOP
342+
)
343+
336344
if(APPLE)
337345
set(ADDITIONAL_LIBS
338346
gssapi_krb5

firestore/integration_test_internal/src/leveldb_snappy_test.cc

Lines changed: 99 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <array>
2424
#include <fstream>
25+
#include <functional>
2526
#include <iostream>
2627
#include <memory>
2728
#include <string>
@@ -30,7 +31,6 @@
3031
#include "Firestore/core/src/util/filesystem.h"
3132
#include "Firestore/core/src/util/path.h"
3233

33-
#include "firebase_test_framework.h"
3434
#include "gtest/gtest.h"
3535
#include "leveldb/db.h"
3636

@@ -49,36 +49,109 @@ using ::firebase::firestore::util::Path;
4949
// with reason "corruption".
5050
Path CreateLevelDbDatabaseThatUsesSnappyCompression();
5151

52-
// This test ensures that we don't accidentally regress having added in Snappy
53-
// compression support (https://github.com/firebase/firebase-ios-sdk/pull/9596).
54-
TEST(LevelDbSnappy, LevelDbHasSnappySupportCompiledIn) {
55-
// Do not run this test on iOS because LevelDb in iOS does not support Snappy.
56-
SKIP_TEST_ON_IOS;
52+
// Creates and opens a LevelDb database that contains at least one block that
53+
// is compressed with Snappy compression, then iterates over it, invoking the
54+
// given callback with the status at each point in the iteration. Once the
55+
// callback is invoked with a `status` where `status.ok()` is not true, then
56+
// iteration will stop and the callback will not be invoked again.
57+
void IterateOverLevelDbDatabaseThatUsesSnappyCompression(
58+
std::function<void(const leveldb::Status&)>);
5759

58-
Path leveldb_path = CreateLevelDbDatabaseThatUsesSnappyCompression();
59-
if (HasFatalFailure()) return;
60+
#if FIREBASE_TESTS_TARGET_DESKTOP
6061

61-
leveldb::Options options;
62-
options.create_if_missing = false;
62+
// Ensure that LevelDb is compiled with Snappy compression support.
63+
// See https://github.com/firebase/firebase-ios-sdk/pull/9596 for details.
64+
TEST(LevelDbSnappy, LevelDbSupportsSnappy) {
65+
IterateOverLevelDbDatabaseThatUsesSnappyCompression(
66+
[](const leveldb::Status& status) {
67+
ASSERT_TRUE(status.ok()) << ConvertStatus(status);
68+
});
69+
}
70+
71+
#else // FIREBASE_TESTS_TARGET_DESKTOP
72+
73+
// Ensure that LevelDb is NOT compiled with Snappy compression support.
74+
TEST(LevelDbSnappy, LevelDbDoesNotSupportSnappy) {
75+
bool got_failed_status = false;
76+
IterateOverLevelDbDatabaseThatUsesSnappyCompression(
77+
[&](const leveldb::Status& status) {
78+
if (!status.ok()) {
79+
got_failed_status = true;
80+
ASSERT_TRUE(status.IsCorruption()) << ConvertStatus(status);
81+
}
82+
});
6383

84+
if (!HasFailure()) {
85+
ASSERT_TRUE(got_failed_status)
86+
<< "Reading a Snappy-compressed LevelDb database was successful; "
87+
"however, it should NOT have been successful "
88+
"since Snappy support is expected to NOT be available.";
89+
}
90+
}
91+
92+
#endif // FIREBASE_TESTS_TARGET_DESKTOP
93+
94+
void IterateOverLevelDbDatabaseThatUsesSnappyCompression(
95+
std::function<void(const leveldb::Status&)> callback) {
6496
std::unique_ptr<leveldb::DB> db;
6597
{
98+
Path leveldb_path = CreateLevelDbDatabaseThatUsesSnappyCompression();
99+
if (leveldb_path.empty()) {
100+
return;
101+
}
102+
103+
leveldb::Options options;
104+
options.create_if_missing = false;
105+
66106
leveldb::DB* db_ptr;
67107
leveldb::Status status =
68108
leveldb::DB::Open(options, leveldb_path.ToUtf8String(), &db_ptr);
69-
ASSERT_TRUE(status.ok());
109+
110+
ASSERT_TRUE(status.ok())
111+
<< "Opening LevelDb database " << leveldb_path.ToUtf8String()
112+
<< " failed: " << ConvertStatus(status);
113+
70114
db.reset(db_ptr);
71115
}
72116

73-
// One of the assertions below will fail when LevelDb attempts to read a block
74-
// that is compressed with Snappy and Snappy compression support is not
75-
// compiled in.
76117
std::unique_ptr<leveldb::Iterator> it(
77118
db->NewIterator(leveldb::ReadOptions()));
78119
for (it->SeekToFirst(); it->Valid(); it->Next()) {
79-
ASSERT_TRUE(it->status().ok()) << ConvertStatus(it->status());
120+
callback(it->status());
121+
if (!it->status().ok()) {
122+
return;
123+
}
124+
}
125+
126+
// Invoke the callback on the final status.
127+
callback(it->status());
128+
}
129+
130+
template <typename T>
131+
void WriteFile(const Path& dir,
132+
const std::string& file_name,
133+
const T& data_array) {
134+
Filesystem* fs = Filesystem::Default();
135+
{
136+
auto status = fs->RecursivelyCreateDir(dir);
137+
if (!status.ok()) {
138+
FAIL() << "Creating directory failed: " << dir.ToUtf8String() << " ("
139+
<< status.error_message() << ")";
140+
}
141+
}
142+
143+
Path file = dir.AppendUtf8(file_name);
144+
std::ofstream out_file(file.native_value(), std::ios::binary);
145+
if (!out_file) {
146+
FAIL() << "Unable to open file for writing: " << file.ToUtf8String();
147+
}
148+
149+
out_file.write(reinterpret_cast<const char*>(data_array.data()),
150+
data_array.size());
151+
out_file.close();
152+
if (!out_file) {
153+
FAIL() << "Writing to file failed: " << file.ToUtf8String();
80154
}
81-
ASSERT_TRUE(it->status().ok()) << ConvertStatus(it->status());
82155
}
83156

84157
const std::array<unsigned char, 0x00000165> LevelDbSnappyFile_000005_ldb{
@@ -196,54 +269,35 @@ const std::array<unsigned char, 0x000000C2> LevelDbSnappyFile_MANIFEST_000084{
196269
0x04, 0x0D,
197270
};
198271

199-
template <typename T>
200-
void WriteFile(const Path& dir,
201-
const std::string& file_name,
202-
const T& data_array) {
203-
Filesystem* fs = Filesystem::Default();
204-
{
205-
auto status = fs->RecursivelyCreateDir(dir);
206-
if (!status.ok()) {
207-
FAIL() << "Creating directory failed: " << dir.ToUtf8String() << " ("
208-
<< status.error_message() << ")";
209-
}
210-
}
211-
212-
Path file = dir.AppendUtf8(file_name);
213-
std::ofstream out_file(file.native_value(), std::ios::binary);
214-
if (!out_file) {
215-
FAIL() << "Unable to open file for writing: " << file.ToUtf8String();
216-
}
217-
218-
out_file.write(reinterpret_cast<const char*>(data_array.data()),
219-
data_array.size());
220-
out_file.close();
221-
if (!out_file) {
222-
FAIL() << "Writing to file failed: " << file.ToUtf8String();
223-
}
224-
}
225-
226272
Path LevelDbDir() {
227273
Filesystem* fs = Filesystem::Default();
228-
Path dir = fs->TempDir().AppendUtf8("PersistenceTesting");
274+
Path dir = fs->TempDir().AppendUtf8("LevelDbSnappyTest");
229275

230276
// Delete the directory first to ensure isolation between runs.
231277
auto status = fs->RecursivelyRemove(dir);
232-
EXPECT_TRUE(status.ok()) << "Failed to clean up leveldb in dir "
278+
EXPECT_TRUE(status.ok()) << "Failed to clean up leveldb in directory "
233279
<< dir.ToUtf8String() << ": " << status.ToString();
280+
if (!status.ok()) {
281+
return {};
282+
}
234283

235284
return dir;
236285
}
237286

238287
Path CreateLevelDbDatabaseThatUsesSnappyCompression() {
239288
Path leveldb_dir = LevelDbDir();
289+
if (leveldb_dir.empty()) {
290+
return {};
291+
}
292+
240293
WriteFile(leveldb_dir, "000005.ldb", LevelDbSnappyFile_000005_ldb);
241294
WriteFile(leveldb_dir, "000017.ldb", LevelDbSnappyFile_000017_ldb);
242295
WriteFile(leveldb_dir, "000085.ldb", LevelDbSnappyFile_000085_ldb);
243296
WriteFile(leveldb_dir, "CURRENT", LevelDbSnappyFile_CURRENT);
244297
WriteFile(leveldb_dir, "LOG.old", LevelDbSnappyFile_LOG_old);
245298
WriteFile(leveldb_dir, "LOG", LevelDbSnappyFile_LOG);
246299
WriteFile(leveldb_dir, "MANIFEST-000084", LevelDbSnappyFile_MANIFEST_000084);
300+
247301
return leveldb_dir;
248302
}
249303

0 commit comments

Comments
 (0)