Divide WriteCallbackTest.WriteWithCallbackTest (#7037)

Summary:
WriteCallbackTest.WriteWithCallbackTest has a deep for-loop and in some cases runs very long. Parameterimized it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/7037

Test Plan: Run the test and see it passes.

Reviewed By: ltamasi

Differential Revision: D22269259

fbshipit-source-id: a1b6687b5bf4609754833d14cf383d68bc7ab27a
main
sdong 5 years ago committed by Facebook GitHub Bot
parent 2d1d51d385
commit 80b107a0a9
  1. 2
      db/db_impl/db_impl.h
  2. 113
      db/write_callback_test.cc

@ -1199,7 +1199,7 @@ class DBImpl : public DB {
friend class StatsHistoryTest_PersistentStatsCreateColumnFamilies_Test; friend class StatsHistoryTest_PersistentStatsCreateColumnFamilies_Test;
#ifndef NDEBUG #ifndef NDEBUG
friend class DBTest2_ReadCallbackTest_Test; friend class DBTest2_ReadCallbackTest_Test;
friend class WriteCallbackTest_WriteWithCallbackTest_Test; friend class WriteCallbackPTest_WriteWithCallbackTest_Test;
friend class XFTransactionWriteHandler; friend class XFTransactionWriteHandler;
friend class DBBlobIndexTest; friend class DBBlobIndexTest;
friend class WriteUnpreparedTransactionTest_RecoveryTest_Test; friend class WriteUnpreparedTransactionTest_RecoveryTest_Test;

@ -84,7 +84,28 @@ class MockWriteCallback : public WriteCallback {
bool AllowWriteBatching() override { return allow_batching_; } bool AllowWriteBatching() override { return allow_batching_; }
}; };
TEST_F(WriteCallbackTest, WriteWithCallbackTest) { class WriteCallbackPTest
: public WriteCallbackTest,
public ::testing::WithParamInterface<
std::tuple<bool, bool, bool, bool, bool, bool, bool>> {
public:
WriteCallbackPTest() {
std::tie(unordered_write_, seq_per_batch_, two_queues_, allow_parallel_,
allow_batching_, enable_WAL_, enable_pipelined_write_) =
GetParam();
}
protected:
bool unordered_write_;
bool seq_per_batch_;
bool two_queues_;
bool allow_parallel_;
bool allow_batching_;
bool enable_WAL_;
bool enable_pipelined_write_;
};
TEST_P(WriteCallbackPTest, WriteWithCallbackTest) {
struct WriteOP { struct WriteOP {
WriteOP(bool should_fail = false) { callback_.should_fail_ = should_fail; } WriteOP(bool should_fail = false) { callback_.should_fail_ = should_fail; }
@ -124,29 +145,21 @@ TEST_F(WriteCallbackTest, WriteWithCallbackTest) {
{false, false, true, false, true}, {false, false, true, false, true},
}; };
for (auto& unordered_write : {true, false}) {
for (auto& seq_per_batch : {true, false}) {
for (auto& two_queues : {true, false}) {
for (auto& allow_parallel : {true, false}) {
for (auto& allow_batching : {true, false}) {
for (auto& enable_WAL : {true, false}) {
for (auto& enable_pipelined_write : {true, false}) {
for (auto& write_group : write_scenarios) { for (auto& write_group : write_scenarios) {
Options options; Options options;
options.create_if_missing = true; options.create_if_missing = true;
options.unordered_write = unordered_write; options.unordered_write = unordered_write_;
options.allow_concurrent_memtable_write = allow_parallel; options.allow_concurrent_memtable_write = allow_parallel_;
options.enable_pipelined_write = enable_pipelined_write; options.enable_pipelined_write = enable_pipelined_write_;
options.two_write_queues = two_queues; options.two_write_queues = two_queues_;
// Skip unsupported combinations // Skip unsupported combinations
if (options.enable_pipelined_write && seq_per_batch) { if (options.enable_pipelined_write && seq_per_batch_) {
continue; continue;
} }
if (options.enable_pipelined_write && options.two_write_queues) { if (options.enable_pipelined_write && options.two_write_queues) {
continue; continue;
} }
if (options.unordered_write && if (options.unordered_write && !options.allow_concurrent_memtable_write) {
!options.allow_concurrent_memtable_write) {
continue; continue;
} }
if (options.unordered_write && options.enable_pipelined_write) { if (options.unordered_write && options.enable_pipelined_write) {
@ -165,9 +178,8 @@ TEST_F(WriteCallbackTest, WriteWithCallbackTest) {
column_families.push_back( column_families.push_back(
ColumnFamilyDescriptor(kDefaultColumnFamilyName, cf_options)); ColumnFamilyDescriptor(kDefaultColumnFamilyName, cf_options));
std::vector<ColumnFamilyHandle*> handles; std::vector<ColumnFamilyHandle*> handles;
auto open_s = auto open_s = DBImpl::Open(db_options, dbname, column_families, &handles,
DBImpl::Open(db_options, dbname, column_families, &handles, &db, seq_per_batch_, true /* batch_per_txn */);
&db, seq_per_batch, true /* batch_per_txn */);
ASSERT_OK(open_s); ASSERT_OK(open_s);
assert(handles.size() == 1); assert(handles.size() == 1);
delete handles[0]; delete handles[0];
@ -214,8 +226,7 @@ TEST_F(WriteCallbackTest, WriteWithCallbackTest) {
ASSERT_TRUE(writer->state == ASSERT_TRUE(writer->state ==
WriteThread::State::STATE_GROUP_LEADER); WriteThread::State::STATE_GROUP_LEADER);
} else { } else {
ASSERT_TRUE(writer->state == ASSERT_TRUE(writer->state == WriteThread::State::STATE_INIT);
WriteThread::State::STATE_INIT);
} }
// (meta test) the first WriteOP should indeed be the first // (meta test) the first WriteOP should indeed be the first
@ -241,17 +252,15 @@ TEST_F(WriteCallbackTest, WriteWithCallbackTest) {
// check my state // check my state
auto* writer = reinterpret_cast<WriteThread::Writer*>(arg); auto* writer = reinterpret_cast<WriteThread::Writer*>(arg);
if (!allow_batching) { if (!allow_batching_) {
// no batching so everyone should be a leader // no batching so everyone should be a leader
ASSERT_TRUE(writer->state == ASSERT_TRUE(writer->state ==
WriteThread::State::STATE_GROUP_LEADER); WriteThread::State::STATE_GROUP_LEADER);
} else if (!allow_parallel) { } else if (!allow_parallel_) {
ASSERT_TRUE(writer->state == ASSERT_TRUE(writer->state == WriteThread::State::STATE_COMPLETED ||
WriteThread::State::STATE_COMPLETED || (enable_pipelined_write_ &&
(enable_pipelined_write &&
writer->state == writer->state ==
WriteThread::State:: WriteThread::State::STATE_MEMTABLE_WRITER_LEADER));
STATE_MEMTABLE_WRITER_LEADER));
} }
}); });
@ -275,7 +284,7 @@ TEST_F(WriteCallbackTest, WriteWithCallbackTest) {
auto& write_op = write_group.at(i); auto& write_op = write_group.at(i);
write_op.Clear(); write_op.Clear();
write_op.callback_.allow_batching_ = allow_batching; write_op.callback_.allow_batching_ = allow_batching_;
// insert some keys // insert some keys
for (uint32_t j = 0; j < rnd.Next() % 50; j++) { for (uint32_t j = 0; j < rnd.Next() % 50; j++) {
@ -286,41 +295,39 @@ TEST_F(WriteCallbackTest, WriteWithCallbackTest) {
string sval(10, my_key); string sval(10, my_key);
write_op.Put(skey, sval); write_op.Put(skey, sval);
if (!write_op.callback_.should_fail_ && !seq_per_batch) { if (!write_op.callback_.should_fail_ && !seq_per_batch_) {
seq.fetch_add(1); seq.fetch_add(1);
} }
} }
if (!write_op.callback_.should_fail_ && seq_per_batch) { if (!write_op.callback_.should_fail_ && seq_per_batch_) {
seq.fetch_add(1); seq.fetch_add(1);
} }
WriteOptions woptions; WriteOptions woptions;
woptions.disableWAL = !enable_WAL; woptions.disableWAL = !enable_WAL_;
woptions.sync = enable_WAL; woptions.sync = enable_WAL_;
Status s; Status s;
if (seq_per_batch) { if (seq_per_batch_) {
class PublishSeqCallback : public PreReleaseCallback { class PublishSeqCallback : public PreReleaseCallback {
public: public:
PublishSeqCallback(DBImpl* db_impl_in) PublishSeqCallback(DBImpl* db_impl_in) : db_impl_(db_impl_in) {}
: db_impl_(db_impl_in) {} Status Callback(SequenceNumber last_seq, bool /*not used*/, uint64_t,
Status Callback(SequenceNumber last_seq, bool /*not used*/, size_t /*index*/, size_t /*total*/) override {
uint64_t, size_t /*index*/,
size_t /*total*/) override {
db_impl_->SetLastPublishedSequence(last_seq); db_impl_->SetLastPublishedSequence(last_seq);
return Status::OK(); return Status::OK();
} }
DBImpl* db_impl_; DBImpl* db_impl_;
} publish_seq_callback(db_impl); } publish_seq_callback(db_impl);
// seq_per_batch requires a natural batch separator or Noop // seq_per_batch_ requires a natural batch separator or Noop
WriteBatchInternal::InsertNoop(&write_op.write_batch_); WriteBatchInternal::InsertNoop(&write_op.write_batch_);
const size_t ONE_BATCH = 1; const size_t ONE_BATCH = 1;
s = db_impl->WriteImpl( s = db_impl->WriteImpl(woptions, &write_op.write_batch_,
woptions, &write_op.write_batch_, &write_op.callback_, &write_op.callback_, nullptr, 0, false, nullptr,
nullptr, 0, false, nullptr, ONE_BATCH, ONE_BATCH,
two_queues ? &publish_seq_callback : nullptr); two_queues_ ? &publish_seq_callback : nullptr);
} else { } else {
s = db_impl->WriteWithCallback( s = db_impl->WriteWithCallback(woptions, &write_op.write_batch_,
woptions, &write_op.write_batch_, &write_op.callback_); &write_op.callback_);
} }
if (write_op.callback_.should_fail_) { if (write_op.callback_.should_fail_) {
@ -349,8 +356,7 @@ TEST_F(WriteCallbackTest, WriteWithCallbackTest) {
ASSERT_TRUE(w.callback_.was_called_.load()); ASSERT_TRUE(w.callback_.was_called_.load());
for (auto& kvp : w.kvs_) { for (auto& kvp : w.kvs_) {
if (w.callback_.should_fail_) { if (w.callback_.should_fail_) {
ASSERT_TRUE( ASSERT_TRUE(db->Get(read_options, kvp.first, &value).IsNotFound());
db->Get(read_options, kvp.first, &value).IsNotFound());
} else { } else {
ASSERT_OK(db->Get(read_options, kvp.first, &value)); ASSERT_OK(db->Get(read_options, kvp.first, &value));
ASSERT_EQ(value, kvp.second); ASSERT_EQ(value, kvp.second);
@ -363,15 +369,14 @@ TEST_F(WriteCallbackTest, WriteWithCallbackTest) {
delete db; delete db;
DestroyDB(dbname, options); DestroyDB(dbname, options);
} }
}
}
}
}
}
}
}
} }
INSTANTIATE_TEST_CASE_P(WriteCallbackPTest, WriteCallbackPTest,
::testing::Combine(::testing::Bool(), ::testing::Bool(),
::testing::Bool(), ::testing::Bool(),
::testing::Bool(), ::testing::Bool(),
::testing::Bool()));
TEST_F(WriteCallbackTest, WriteCallBackTest) { TEST_F(WriteCallbackTest, WriteCallBackTest) {
Options options; Options options;
WriteOptions write_options; WriteOptions write_options;

Loading…
Cancel
Save