mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-20 00:20:47 +00:00
Merge 'test: add test_sstable_clone_preserves_staging_state' from Benny Halevy
Add a test that verifies filesystem_storage::clone preserves the sstable state: an sstable in staging is cloned to a new generation, the clone is re-loaded from the staging directory, and its state is asserted to still be staging. The change proves that https://scylladb.atlassian.net/browse/SCYLLADB-1205 is invalid, and can be closed. * No functional change and no backport needed Closes scylladb/scylladb#29209 * github.com:scylladb/scylladb: test: add test_sstable_clone_preserves_staging_state test: derive sstable state from directory in test_env::make_sstable sstables: log debug message in filesystem_storage::clone
This commit is contained in:
@@ -449,6 +449,7 @@ future<> filesystem_storage::snapshot(const sstable& sst, sstring name) const {
|
||||
co_await create_links_common(sst, snapshot_dir.native(), sst._generation, link_mode::default_mode);
|
||||
}
|
||||
future<> filesystem_storage::clone(const sstable& sst, generation_type gen, bool leave_unsealed) const {
|
||||
sstlog.debug("Cloning {} dir={} generation={} leave_unsealed={}", sst.get_filename(), _dir.path().native(), gen, leave_unsealed);
|
||||
co_await create_links_common(sst, _dir.path().native(), std::move(gen), leave_unsealed ? link_mode::leave_unsealed : link_mode::default_mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "utils/lister.hh"
|
||||
#include "test/lib/tmpdir.hh"
|
||||
#include "test/lib/sstable_test_env.hh"
|
||||
#include "test/lib/sstable_utils.hh"
|
||||
#include "test/lib/simple_schema.hh"
|
||||
#include "sstable_test.hh"
|
||||
|
||||
using namespace sstables;
|
||||
@@ -140,3 +142,37 @@ SEASTAR_THREAD_TEST_CASE(test_sstable_move_exists_failure) {
|
||||
dst_sst->close_files().get();
|
||||
BOOST_REQUIRE_THROW(test(src_sst).move_to_new_dir(new_dir, gen_2).get(), malformed_sstable_exception);
|
||||
}
|
||||
|
||||
// Test that filesystem_storage::clone preserves the input sstable state.
|
||||
// An sstable in staging is cloned and re-loaded; the re-loaded clone should still
|
||||
// be in staging (i.e. state() == staging and requires_view_building() == true).
|
||||
SEASTAR_THREAD_TEST_CASE(test_sstable_clone_preserves_staging_state) {
|
||||
auto scf = make_sstable_compressor_factory_for_tests_in_thread();
|
||||
test_env env({}, *scf);
|
||||
auto stop_env = defer([&env] { env.stop().get(); });
|
||||
|
||||
simple_schema ss;
|
||||
auto schema = ss.schema();
|
||||
|
||||
// Create an sstable in normal state.
|
||||
auto sst = make_sstable_containing(env.make_sst_factory(schema), {ss.new_mutation("key1")});
|
||||
|
||||
// Move it to staging state.
|
||||
sst->change_state(sstable_state::staging).get();
|
||||
BOOST_REQUIRE(sst->state() == sstable_state::staging);
|
||||
|
||||
// Clone the staging sstable to a new generation. The clone should land in the
|
||||
// same (staging) directory as the source.
|
||||
auto clone_gen = env.new_generation();
|
||||
sst->clone(clone_gen).get();
|
||||
|
||||
// Load the cloned sstable from the staging directory. We use the storage
|
||||
// prefix of the source (which is the staging sub-directory) so that the
|
||||
// loader can find the files, mirroring what distributed_loader does.
|
||||
auto staging_dir = sst->get_storage().prefix();
|
||||
auto cloned_sst = env.reusable_sst(schema, staging_dir, clone_gen).get();
|
||||
|
||||
// Assert that the cloned sstable preserves the staging state.
|
||||
BOOST_REQUIRE(cloned_sst->state() == sstable_state::staging);
|
||||
BOOST_REQUIRE(cloned_sst->requires_view_building());
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "utils/assert.hh"
|
||||
#include "utils/overloaded_functor.hh"
|
||||
#include <boost/program_options.hpp>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <fmt/ranges.h>
|
||||
#include <seastar/util/defer.hh>
|
||||
@@ -390,12 +391,24 @@ test_env::make_sstable(schema_ptr schema, sstring dir, sstables::generation_type
|
||||
size_t buffer_size, db_clock::time_point now) {
|
||||
// FIXME -- most of the callers work with _impl->dir's path, so
|
||||
// test_env can initialize the .dir/.prefix only once, when constructed
|
||||
sstables::sstable_state state = sstables::sstable_state::normal;
|
||||
auto filename = std::filesystem::path(dir).filename().native();
|
||||
if (filename == sstables::staging_dir) {
|
||||
state = sstables::sstable_state::staging;
|
||||
} else if (filename == sstables::upload_dir) {
|
||||
state = sstables::sstable_state::upload;
|
||||
} else if (filename == sstables::quarantine_dir) {
|
||||
state = sstables::sstable_state::quarantine;
|
||||
}
|
||||
if (state != sstables::sstable_state::normal) {
|
||||
dir = std::filesystem::path(dir).parent_path().native();
|
||||
}
|
||||
auto storage = _impl->storage;
|
||||
std::visit(overloaded_functor {
|
||||
[&dir] (data_dictionary::storage_options::local& o) { o.dir = dir; },
|
||||
[&schema] (data_dictionary::storage_options::object_storage& o) { o.location = schema->id(); },
|
||||
}, storage.value);
|
||||
return _impl->mgr.make_sstable(std::move(schema), storage, generation, sstables::sstable_state::normal, v, f, now, default_io_error_handler_gen(), buffer_size);
|
||||
return _impl->mgr.make_sstable(std::move(schema), storage, generation, state, v, f, now, default_io_error_handler_gen(), buffer_size);
|
||||
}
|
||||
|
||||
shared_sstable
|
||||
|
||||
Reference in New Issue
Block a user