Otherwise, it may trip an assertion when the nuderlying file is closed, as seen in e.g.: https://jenkins.scylladb.com/view/master/job/scylla-master/job/next/4318/artifact/testlog/x86_64_release/sstable_3_x_test.test_read_rows_only_index.4174.log ``` test/boost/sstable_3_x_test.cc(0): Entering test case "test_read_rows_only_index" sstable_3_x_test: ./seastar/src/core/fstream.cc:205: virtual seastar::file_data_source_impl::~file_data_source_impl(): Assertion `_reads_in_progress == 0' failed. Aborting on shard 0. Backtrace: 0x22557e8 0x2286842 0x7f2799e99a1f /lib64/libc.so.6+0x3d2a1 /lib64/libc.so.6+0x268a3 /lib64/libc.so.6+0x26788 /lib64/libc.so.6+0x35a15 0x222c53d 0x222c548 0xb929cc 0xc0b23b 0xa84bbf 0x24d0111 ``` Decoded: ``` __GI___assert_fail at :? ~file_data_source_impl at ./build/release/seastar/./seastar/src/core/fstream.cc:205 ~file_data_source_impl at ./build/release/seastar/./seastar/src/core/fstream.cc:202 std::default_delete<seastar::data_source_impl>::operator()(seastar::data_source_impl*) const at /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/unique_ptr.h:85 (inlined by) ~unique_ptr at /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/unique_ptr.h:361 (inlined by) ~data_source at ././seastar/include/seastar/core/iostream.hh:55 (inlined by) ~input_stream at ././seastar/include/seastar/core/iostream.hh:254 (inlined by) ~continuous_data_consumer at ././sstables/consumer.hh:484 (inlined by) ~index_consume_entry_context at ././sstables/index_reader.hh:116 (inlined by) std::default_delete<sstables::index_consume_entry_context<sstables::index_consumer> >::operator()(sstables::index_consume_entry_context<sstables::index_consumer>*) const at /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/unique_ptr.h:85 (inlined by) ~unique_ptr at /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/unique_ptr.h:361 (inlined by) ~index_bound at ././sstables/index_reader.hh:395 (inlined by) ~index_reader at ././sstables/index_reader.hh:435 std::default_delete<sstables::index_reader>::operator()(sstables::index_reader*) const at /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/unique_ptr.h:85 (inlined by) ~unique_ptr at /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/unique_ptr.h:361 (inlined by) ~index_reader_assertions at ././test/lib/index_reader_assertions.hh:31 (inlined by) operator() at ./test/boost/sstable_3_x_test.cc:4630 ``` Test: unit(dev), sstable_3_x_test.test_read_rows_only_index(release X 10000) Signed-off-by: Benny Halevy <bhalevy@scylladb.com> Message-Id: <20211222132858.2155227-1-bhalevy@scylladb.com>
96 lines
3.1 KiB
C++
96 lines
3.1 KiB
C++
/*
|
|
* Copyright (C) 2017-present 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
#include "dht/i_partitioner.hh"
|
|
#include "schema.hh"
|
|
#include "sstables/index_reader.hh"
|
|
#include "reader_concurrency_semaphore.hh"
|
|
|
|
class index_reader_assertions {
|
|
std::unique_ptr<sstables::index_reader> _r;
|
|
public:
|
|
// Must be called from a seastar thread
|
|
~index_reader_assertions() {
|
|
close().get();
|
|
}
|
|
|
|
index_reader_assertions(std::unique_ptr<sstables::index_reader> r)
|
|
: _r(std::move(r))
|
|
{ }
|
|
|
|
index_reader_assertions& has_monotonic_positions(const schema& s) {
|
|
tests::reader_concurrency_semaphore_wrapper semaphore;
|
|
auto pos_cmp = sstables::promoted_index_block_compare(s);
|
|
auto rp_cmp = dht::ring_position_comparator(s);
|
|
auto prev = dht::ring_position::min();
|
|
_r->read_partition_data().get();
|
|
while (!_r->eof()) {
|
|
auto k = _r->get_partition_key();
|
|
auto rp = dht::ring_position(dht::decorate_key(s, k));
|
|
|
|
if (rp_cmp(prev, rp) >= 0) {
|
|
BOOST_FAIL(format("Partitions have invalid order: {} >= {}", prev, rp));
|
|
}
|
|
|
|
prev = rp;
|
|
|
|
sstables::clustered_index_cursor* cur = _r->current_clustered_cursor();
|
|
std::optional<sstables::promoted_index_block_position> prev_end;
|
|
while (auto ei_opt = cur->next_entry().get0()) {
|
|
sstables::clustered_index_cursor::entry_info& ei = *ei_opt;
|
|
if (prev_end && pos_cmp(ei.start, sstables::to_view(*prev_end))) {
|
|
BOOST_FAIL(format("Index blocks are not monotonic: {} > {}", *prev_end, ei.start));
|
|
}
|
|
prev_end = sstables::materialize(ei.end);
|
|
}
|
|
_r->advance_to_next_partition().get();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
index_reader_assertions& is_empty(const schema& s) {
|
|
_r->read_partition_data().get();
|
|
while (!_r->eof()) {
|
|
BOOST_REQUIRE(_r->get_promoted_index_size() == 0);
|
|
_r->advance_to_next_partition().get();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
future<> close() noexcept {
|
|
if (_r) {
|
|
auto r = std::move(_r);
|
|
auto f = r->close();
|
|
return f.then([r = std::move(r)] {});
|
|
}
|
|
return make_ready_future<>();
|
|
}
|
|
};
|
|
|
|
inline
|
|
index_reader_assertions assert_that(std::unique_ptr<sstables::index_reader> r) {
|
|
return { std::move(r) };
|
|
}
|