|
|
@@ -0,0 +1,295 @@
|
|
|
+/*
|
|
|
+ * Copyright 2022 Google LLC
|
|
|
+ *
|
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
+ * you may not use this file except in compliance with the License.
|
|
|
+ * You may obtain a copy of the License at
|
|
|
+ *
|
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+ *
|
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+ * See the License for the specific language governing permissions and
|
|
|
+ * limitations under the License.
|
|
|
+ */
|
|
|
+
|
|
|
+#include <array>
|
|
|
+#include <fstream>
|
|
|
+#include <functional>
|
|
|
+#include <iostream>
|
|
|
+#include <memory>
|
|
|
+#include <string>
|
|
|
+
|
|
|
+#include "Firestore/core/src/local/leveldb_util.h"
|
|
|
+#include "Firestore/core/src/util/filesystem.h"
|
|
|
+#include "Firestore/core/src/util/path.h"
|
|
|
+
|
|
|
+#include "gtest/gtest.h"
|
|
|
+#include "leveldb/db.h"
|
|
|
+
|
|
|
+namespace {
|
|
|
+
|
|
|
+using ::firebase::firestore::local::ConvertStatus;
|
|
|
+using ::firebase::firestore::util::Filesystem;
|
|
|
+using ::firebase::firestore::util::Path;
|
|
|
+
|
|
|
+// Creates a LevelDb database that uses Snappy compression for at least one of
|
|
|
+// its blocks. Attempting to iterate over this database using a LevelDb library
|
|
|
+// that does not have Snappy compression compiled in will return a failed status
|
|
|
+// with reason "corruption".
|
|
|
+Path CreateLevelDbDatabaseThatUsesSnappyCompression();
|
|
|
+
|
|
|
+// Creates and opens a LevelDb database that contains at least one block that
|
|
|
+// is compressed with Snappy compression, then iterates over it, invoking the
|
|
|
+// given callback with the status at each point in the iteration. Once the
|
|
|
+// callback is invoked with a `status` where `status.ok()` is not true, then
|
|
|
+// iteration will stop and the callback will not be invoked again.
|
|
|
+void IterateOverLevelDbDatabaseThatUsesSnappyCompression(
|
|
|
+ std::function<void(const leveldb::Status&)>);
|
|
|
+
|
|
|
+#if FIREBASE_TESTS_BUILT_BY_CMAKE
|
|
|
+
|
|
|
+// Ensure that LevelDb is compiled with Snappy compression support.
|
|
|
+// See https://github.com/firebase/firebase-ios-sdk/pull/9596 for details.
|
|
|
+TEST(LevelDbSnappy, LevelDbSupportsSnappy) {
|
|
|
+ IterateOverLevelDbDatabaseThatUsesSnappyCompression(
|
|
|
+ [](const leveldb::Status& status) {
|
|
|
+ ASSERT_TRUE(status.ok()) << ConvertStatus(status);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+#else // FIREBASE_TESTS_BUILT_BY_CMAKE
|
|
|
+
|
|
|
+// Ensure that LevelDb is NOT compiled with Snappy compression support.
|
|
|
+TEST(LevelDbSnappy, LevelDbDoesNotSupportSnappy) {
|
|
|
+ bool got_failed_status = false;
|
|
|
+ IterateOverLevelDbDatabaseThatUsesSnappyCompression(
|
|
|
+ [&](const leveldb::Status& status) {
|
|
|
+ if (!status.ok()) {
|
|
|
+ got_failed_status = true;
|
|
|
+ ASSERT_TRUE(status.IsCorruption()) << ConvertStatus(status);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!HasFailure()) {
|
|
|
+ ASSERT_TRUE(got_failed_status)
|
|
|
+ << "Reading a Snappy-compressed LevelDb database was successful; "
|
|
|
+ "however, it should NOT have been successful "
|
|
|
+ "since Snappy support is expected to NOT be available.";
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#endif // FIREBASE_TESTS_BUILT_BY_CMAKE
|
|
|
+
|
|
|
+void IterateOverLevelDbDatabaseThatUsesSnappyCompression(
|
|
|
+ std::function<void(const leveldb::Status&)> callback) {
|
|
|
+ std::unique_ptr<leveldb::DB> db;
|
|
|
+ {
|
|
|
+ Path leveldb_path = CreateLevelDbDatabaseThatUsesSnappyCompression();
|
|
|
+ if (leveldb_path.empty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ leveldb::Options options;
|
|
|
+ options.create_if_missing = false;
|
|
|
+
|
|
|
+ leveldb::DB* db_ptr;
|
|
|
+ leveldb::Status status =
|
|
|
+ leveldb::DB::Open(options, leveldb_path.ToUtf8String(), &db_ptr);
|
|
|
+
|
|
|
+ ASSERT_TRUE(status.ok())
|
|
|
+ << "Opening LevelDb database " << leveldb_path.ToUtf8String()
|
|
|
+ << " failed: " << ConvertStatus(status);
|
|
|
+
|
|
|
+ db.reset(db_ptr);
|
|
|
+ }
|
|
|
+
|
|
|
+ std::unique_ptr<leveldb::Iterator> it(
|
|
|
+ db->NewIterator(leveldb::ReadOptions()));
|
|
|
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
|
|
+ callback(it->status());
|
|
|
+ if (!it->status().ok()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Invoke the callback on the final status.
|
|
|
+ callback(it->status());
|
|
|
+}
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+void WriteFile(const Path& dir,
|
|
|
+ const std::string& file_name,
|
|
|
+ const T& data_array) {
|
|
|
+ Filesystem* fs = Filesystem::Default();
|
|
|
+ {
|
|
|
+ auto status = fs->RecursivelyCreateDir(dir);
|
|
|
+ if (!status.ok()) {
|
|
|
+ FAIL() << "Creating directory failed: " << dir.ToUtf8String() << " ("
|
|
|
+ << status.error_message() << ")";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Path file = dir.AppendUtf8(file_name);
|
|
|
+ std::ofstream out_file(file.native_value(), std::ios::binary);
|
|
|
+ if (!out_file) {
|
|
|
+ FAIL() << "Unable to open file for writing: " << file.ToUtf8String();
|
|
|
+ }
|
|
|
+
|
|
|
+ out_file.write(reinterpret_cast<const char*>(data_array.data()),
|
|
|
+ data_array.size());
|
|
|
+ out_file.close();
|
|
|
+ if (!out_file) {
|
|
|
+ FAIL() << "Writing to file failed: " << file.ToUtf8String();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const std::array<unsigned char, 0x00000165> LevelDbSnappyFile_000005_ldb{
|
|
|
+ 0x84, 0x03, 0x80, 0x00, 0x42, 0x00, 0x85, 0x71, 0x75, 0x65, 0x72, 0x79,
|
|
|
+ 0x5F, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x01, 0x8B, 0x43, 0x6F,
|
|
|
+ 0x6C, 0x41, 0x2F, 0x44, 0x6F, 0x63, 0x41, 0x2F, 0x43, 0x6F, 0x6C, 0x42,
|
|
|
+ 0x01, 0x0A, 0x68, 0x42, 0x7C, 0x66, 0x3A, 0x7C, 0x6F, 0x62, 0x3A, 0x5F,
|
|
|
+ 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x5F, 0x61, 0x73, 0x63, 0x00, 0x01,
|
|
|
+ 0x8C, 0x82, 0x80, 0x01, 0x07, 0x00, 0x05, 0x01, 0x08, 0x01, 0x13, 0x50,
|
|
|
+ 0x11, 0x3E, 0x01, 0x16, 0x00, 0x0A, 0x05, 0x15, 0xF0, 0x3C, 0x00, 0x08,
|
|
|
+ 0x02, 0x20, 0x05, 0x32, 0x4A, 0x12, 0x48, 0x70, 0x72, 0x6F, 0x6A, 0x65,
|
|
|
+ 0x63, 0x74, 0x73, 0x2F, 0x54, 0x65, 0x73, 0x74, 0x54, 0x65, 0x72, 0x6D,
|
|
|
+ 0x69, 0x6E, 0x61, 0x74, 0x65, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
|
|
|
+ 0x73, 0x65, 0x73, 0x2F, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74,
|
|
|
+ 0x29, 0x2F, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x01,
|
|
|
+ 0x7B, 0x3E, 0x85, 0x00, 0x0C, 0x0D, 0x07, 0x50, 0x08, 0x15, 0x5A, 0x00,
|
|
|
+ 0x03, 0xFE, 0x5A, 0x00, 0x2E, 0x5A, 0x00, 0x38, 0x07, 0x12, 0x06, 0x5F,
|
|
|
+ 0x67, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x00, 0x01, 0x80, 0x01, 0x0B, 0x11,
|
|
|
+ 0x65, 0x1C, 0x10, 0x05, 0x20, 0x01, 0x12, 0x07, 0x06, 0x09, 0x15, 0x10,
|
|
|
+ 0x00, 0x03, 0x01, 0x10, 0x04, 0x00, 0x01, 0x09, 0x10, 0x24, 0x01, 0x12,
|
|
|
+ 0x01, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x01, 0x35, 0x00, 0x06,
|
|
|
+ 0x09, 0x15, 0x10, 0x37, 0x0C, 0x07, 0x01, 0x05, 0x09, 0x0B, 0x10, 0x36,
|
|
|
+ 0x0C, 0x07, 0x01, 0x04, 0x09, 0x0B, 0x10, 0x35, 0x0C, 0x07, 0x01, 0x03,
|
|
|
+ 0x09, 0x0B, 0x4C, 0x34, 0x0C, 0x07, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
|
|
+ 0x2C, 0x6E, 0xE0, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
|
+ 0x00, 0xC0, 0xF2, 0xA1, 0xB0, 0x00, 0x09, 0x03, 0x86, 0x01, 0xFF, 0xFF,
|
|
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x87, 0x02, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC2, 0x94, 0x06, 0x8C, 0x02, 0x08,
|
|
|
+ 0x99, 0x02, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0x00, 0x57, 0xFB, 0x80, 0x8B, 0x24, 0x75, 0x47, 0xDB,
|
|
|
+};
|
|
|
+const std::array<unsigned char, 0x000000E8> LevelDbSnappyFile_000017_ldb{
|
|
|
+ 0x00, 0x14, 0x50, 0x85, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x01,
|
|
|
+ 0x8C, 0x82, 0x80, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
|
|
+ 0x02, 0x20, 0x0A, 0x32, 0x4A, 0x12, 0x48, 0x70, 0x72, 0x6F, 0x6A, 0x65,
|
|
|
+ 0x63, 0x74, 0x73, 0x2F, 0x54, 0x65, 0x73, 0x74, 0x54, 0x65, 0x72, 0x6D,
|
|
|
+ 0x69, 0x6E, 0x61, 0x74, 0x65, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
|
|
|
+ 0x73, 0x65, 0x73, 0x2F, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74,
|
|
|
+ 0x29, 0x2F, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x2F,
|
|
|
+ 0x43, 0x6F, 0x6C, 0x41, 0x2F, 0x44, 0x6F, 0x63, 0x41, 0x2F, 0x43, 0x6F,
|
|
|
+ 0x6C, 0x42, 0x2F, 0x44, 0x6F, 0x63, 0x42, 0x07, 0x12, 0x06, 0x5F, 0x67,
|
|
|
+ 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x00, 0x01, 0x80, 0x01, 0x0D, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x10, 0x0A, 0x20, 0x01, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCD, 0xE0, 0x39, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF2, 0xA1, 0xB0,
|
|
|
+ 0x00, 0x09, 0x03, 0x86, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
+ 0x00, 0x8A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0xE4, 0xA7, 0x7E, 0x74, 0x8F, 0x01, 0x08, 0x9C, 0x01, 0x17, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xFB, 0x80, 0x8B,
|
|
|
+ 0x24, 0x75, 0x47, 0xDB,
|
|
|
+};
|
|
|
+const std::array<unsigned char, 0x00000000> LevelDbSnappyFile_000085_ldb{};
|
|
|
+const std::array<unsigned char, 0x00000010> LevelDbSnappyFile_CURRENT{
|
|
|
+ 0x4D, 0x41, 0x4E, 0x49, 0x46, 0x45, 0x53, 0x54,
|
|
|
+ 0x2D, 0x30, 0x30, 0x30, 0x30, 0x38, 0x34, 0x0A,
|
|
|
+};
|
|
|
+const std::array<unsigned char, 0x000000B5> LevelDbSnappyFile_LOG_old{
|
|
|
+ 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D, 0x31,
|
|
|
+ 0x31, 0x3A, 0x33, 0x39, 0x3A, 0x34, 0x36, 0x2E, 0x32, 0x35, 0x37, 0x32,
|
|
|
+ 0x35, 0x31, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x35, 0x33,
|
|
|
+ 0x31, 0x34, 0x30, 0x30, 0x30, 0x20, 0x52, 0x65, 0x63, 0x6F, 0x76, 0x65,
|
|
|
+ 0x72, 0x69, 0x6E, 0x67, 0x20, 0x6C, 0x6F, 0x67, 0x20, 0x23, 0x38, 0x31,
|
|
|
+ 0x0A, 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D,
|
|
|
+ 0x31, 0x31, 0x3A, 0x33, 0x39, 0x3A, 0x34, 0x36, 0x2E, 0x33, 0x30, 0x34,
|
|
|
+ 0x35, 0x35, 0x32, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x35,
|
|
|
+ 0x33, 0x31, 0x34, 0x30, 0x30, 0x30, 0x20, 0x44, 0x65, 0x6C, 0x65, 0x74,
|
|
|
+ 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x33, 0x20, 0x23, 0x38, 0x30,
|
|
|
+ 0x0A, 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D,
|
|
|
+ 0x31, 0x31, 0x3A, 0x33, 0x39, 0x3A, 0x34, 0x36, 0x2E, 0x33, 0x30, 0x35,
|
|
|
+ 0x30, 0x36, 0x34, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x35,
|
|
|
+ 0x33, 0x31, 0x34, 0x30, 0x30, 0x30, 0x20, 0x44, 0x65, 0x6C, 0x65, 0x74,
|
|
|
+ 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x30, 0x20, 0x23, 0x38, 0x31,
|
|
|
+ 0x0A,
|
|
|
+};
|
|
|
+const std::array<unsigned char, 0x000000B5> LevelDbSnappyFile_LOG{
|
|
|
+ 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D, 0x31,
|
|
|
+ 0x31, 0x3A, 0x35, 0x36, 0x3A, 0x35, 0x36, 0x2E, 0x34, 0x39, 0x33, 0x31,
|
|
|
+ 0x34, 0x32, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x61, 0x32,
|
|
|
+ 0x35, 0x34, 0x30, 0x30, 0x30, 0x20, 0x52, 0x65, 0x63, 0x6F, 0x76, 0x65,
|
|
|
+ 0x72, 0x69, 0x6E, 0x67, 0x20, 0x6C, 0x6F, 0x67, 0x20, 0x23, 0x38, 0x33,
|
|
|
+ 0x0A, 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D,
|
|
|
+ 0x31, 0x31, 0x3A, 0x35, 0x36, 0x3A, 0x35, 0x36, 0x2E, 0x35, 0x33, 0x34,
|
|
|
+ 0x37, 0x34, 0x35, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x61,
|
|
|
+ 0x32, 0x35, 0x34, 0x30, 0x30, 0x30, 0x20, 0x44, 0x65, 0x6C, 0x65, 0x74,
|
|
|
+ 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x33, 0x20, 0x23, 0x38, 0x32,
|
|
|
+ 0x0A, 0x32, 0x30, 0x32, 0x32, 0x2F, 0x30, 0x34, 0x2F, 0x30, 0x34, 0x2D,
|
|
|
+ 0x31, 0x31, 0x3A, 0x35, 0x36, 0x3A, 0x35, 0x36, 0x2E, 0x35, 0x33, 0x35,
|
|
|
+ 0x32, 0x34, 0x32, 0x20, 0x30, 0x78, 0x37, 0x30, 0x30, 0x30, 0x30, 0x61,
|
|
|
+ 0x32, 0x35, 0x34, 0x30, 0x30, 0x30, 0x20, 0x44, 0x65, 0x6C, 0x65, 0x74,
|
|
|
+ 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x30, 0x20, 0x23, 0x38, 0x33,
|
|
|
+ 0x0A,
|
|
|
+};
|
|
|
+const std::array<unsigned char, 0x000000C2> LevelDbSnappyFile_MANIFEST_000084{
|
|
|
+ 0x45, 0x63, 0x9F, 0xDD, 0xAC, 0x00, 0x01, 0x01, 0x1A, 0x6C, 0x65, 0x76,
|
|
|
+ 0x65, 0x6C, 0x64, 0x62, 0x2E, 0x42, 0x79, 0x74, 0x65, 0x77, 0x69, 0x73,
|
|
|
+ 0x65, 0x43, 0x6F, 0x6D, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6F, 0x72, 0x07,
|
|
|
+ 0x00, 0x05, 0xE5, 0x02, 0x42, 0x85, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5F,
|
|
|
+ 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x01, 0x8B, 0x43, 0x6F, 0x6C,
|
|
|
+ 0x41, 0x2F, 0x44, 0x6F, 0x63, 0x41, 0x2F, 0x43, 0x6F, 0x6C, 0x42, 0x2F,
|
|
|
+ 0x44, 0x6F, 0x63, 0x42, 0x7C, 0x66, 0x3A, 0x7C, 0x6F, 0x62, 0x3A, 0x5F,
|
|
|
+ 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x5F, 0x61, 0x73, 0x63, 0x00, 0x01,
|
|
|
+ 0x8C, 0x82, 0x80, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
|
|
|
+ 0x85, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x01, 0x80, 0x01,
|
|
|
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x11, 0xE8, 0x01,
|
|
|
+ 0x14, 0x85, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x01, 0x8C, 0x82,
|
|
|
+ 0x80, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x85, 0x74,
|
|
|
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x5F, 0x67, 0x6C, 0x6F, 0x62, 0x61, 0x6C,
|
|
|
+ 0x00, 0x01, 0x80, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1,
|
|
|
+ 0x03, 0xAC, 0xBA, 0x08, 0x00, 0x01, 0x02, 0x55, 0x09, 0x00, 0x03, 0x56,
|
|
|
+ 0x04, 0x0D,
|
|
|
+};
|
|
|
+
|
|
|
+Path LevelDbDir() {
|
|
|
+ Filesystem* fs = Filesystem::Default();
|
|
|
+ Path dir = fs->TempDir().AppendUtf8("LevelDbSnappyTest");
|
|
|
+
|
|
|
+ // Delete the directory first to ensure isolation between runs.
|
|
|
+ auto status = fs->RecursivelyRemove(dir);
|
|
|
+ EXPECT_TRUE(status.ok()) << "Failed to clean up leveldb in directory "
|
|
|
+ << dir.ToUtf8String() << ": " << status.ToString();
|
|
|
+ if (!status.ok()) {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+
|
|
|
+ return dir;
|
|
|
+}
|
|
|
+
|
|
|
+Path CreateLevelDbDatabaseThatUsesSnappyCompression() {
|
|
|
+ Path leveldb_dir = LevelDbDir();
|
|
|
+ if (leveldb_dir.empty()) {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+
|
|
|
+ WriteFile(leveldb_dir, "000005.ldb", LevelDbSnappyFile_000005_ldb);
|
|
|
+ WriteFile(leveldb_dir, "000017.ldb", LevelDbSnappyFile_000017_ldb);
|
|
|
+ WriteFile(leveldb_dir, "000085.ldb", LevelDbSnappyFile_000085_ldb);
|
|
|
+ WriteFile(leveldb_dir, "CURRENT", LevelDbSnappyFile_CURRENT);
|
|
|
+ WriteFile(leveldb_dir, "LOG.old", LevelDbSnappyFile_LOG_old);
|
|
|
+ WriteFile(leveldb_dir, "LOG", LevelDbSnappyFile_LOG);
|
|
|
+ WriteFile(leveldb_dir, "MANIFEST-000084", LevelDbSnappyFile_MANIFEST_000084);
|
|
|
+
|
|
|
+ return leveldb_dir;
|
|
|
+}
|
|
|
+
|
|
|
+} // namespace
|