/* * Copyright (C) 2015 ScyllaDB */ /* * This file is part of Scylla. * * Scylla is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Scylla is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Scylla. If not, see . */ #define BOOST_TEST_DYN_LINK #include #include "utils/UUID_gen.hh" #include "tests/test-utils.hh" #include "schema_builder.hh" #include "core/thread.hh" #include "memtable.hh" #include "mutation_source_test.hh" #include "mutation_reader_assertions.hh" #include "disk-error-handler.hh" thread_local disk_error_signal_type commit_error; thread_local disk_error_signal_type general_disk_error; static api::timestamp_type next_timestamp() { static thread_local api::timestamp_type next_timestamp = 1; return next_timestamp++; } static bytes make_unique_bytes() { return to_bytes(utils::UUID_gen::get_time_UUID().to_sstring()); } static void set_column(mutation& m, const sstring& column_name) { assert(m.schema()->get_column_definition(to_bytes(column_name))->type == bytes_type); auto value = data_value(make_unique_bytes()); m.set_clustered_cell(clustering_key::make_empty(), to_bytes(column_name), value, next_timestamp()); } static mutation make_unique_mutation(schema_ptr s) { return mutation(partition_key::from_single_value(*s, make_unique_bytes()), s); } // Returns a vector of empty mutations in ring order std::vector make_ring(schema_ptr s, int n_mutations) { std::vector ring; for (int i = 0; i < n_mutations; ++i) { ring.push_back(make_unique_mutation(s)); } std::sort(ring.begin(), ring.end(), mutation_decorated_key_less_comparator()); return ring; } SEASTAR_TEST_CASE(test_memtable_conforms_to_mutation_source) { return seastar::async([] { run_mutation_source_tests([](schema_ptr s, const std::vector& partitions) { auto mt = make_lw_shared(s); for (auto&& m : partitions) { mt->apply(m); } logalloc::shard_tracker().full_compaction(); return mt->as_data_source(); }); }); } SEASTAR_TEST_CASE(test_adding_a_column_during_reading_doesnt_affect_read_result) { return seastar::async([] { auto common_builder = schema_builder("ks", "cf") .with_column("pk", bytes_type, column_kind::partition_key); auto s1 = common_builder .with_column("v2", bytes_type, column_kind::regular_column) .build(); auto s2 = common_builder .with_column("v1", bytes_type, column_kind::regular_column) // new column .with_column("v2", bytes_type, column_kind::regular_column) .build(); auto mt = make_lw_shared(s1); std::vector ring = make_ring(s1, 3); for (auto&& m : ring) { set_column(m, "v2"); mt->apply(m); } auto check_rd_s1 = assert_that(mt->make_reader(s1)); auto check_rd_s2 = assert_that(mt->make_reader(s2)); check_rd_s1.next_mutation().has_schema(s1).is_equal_to(ring[0]); check_rd_s2.next_mutation().has_schema(s2).is_equal_to(ring[0]); mt->set_schema(s2); check_rd_s1.next_mutation().has_schema(s1).is_equal_to(ring[1]); check_rd_s2.next_mutation().has_schema(s2).is_equal_to(ring[1]); check_rd_s1.next_mutation().has_schema(s1).is_equal_to(ring[2]); check_rd_s2.next_mutation().has_schema(s2).is_equal_to(ring[2]); check_rd_s1.produces_end_of_stream(); check_rd_s2.produces_end_of_stream(); assert_that(mt->make_reader(s1)) .produces(ring[0]) .produces(ring[1]) .produces(ring[2]) .produces_end_of_stream(); assert_that(mt->make_reader(s2)) .produces(ring[0]) .produces(ring[1]) .produces(ring[2]) .produces_end_of_stream(); }); }