YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/integration-tests/kv_table_ts_failover-test.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#include <atomic>
15
#include <memory>
16
#include <vector>
17
18
#include "yb/client/client.h"
19
#include "yb/client/table.h"
20
21
#include "yb/integration-tests/cluster_verifier.h"
22
#include "yb/integration-tests/external_mini_cluster.h"
23
#include "yb/integration-tests/load_generator.h"
24
#include "yb/integration-tests/yb_table_test_base.h"
25
26
#include "yb/util/test_util.h"
27
28
DEFINE_int32(test_num_iter,
29
             1,
30
             "Number of iterations for key-value table tablet server failover test");
31
32
namespace yb {
33
34
using std::unique_ptr;
35
36
using client::YBClient;
37
using client::YBClientBuilder;
38
using client::YBTable;
39
using std::shared_ptr;
40
41
using integration_tests::YBTableTestBase;
42
43
class KVTableTsFailoverTest : public YBTableTestBase {
44
 public:
45
3
  bool use_external_mini_cluster() override { return true; }
46
47
1
  bool enable_ysql() override { return NonTsanVsTsan(true, false); }
48
};
49
50
1
TEST_F(KVTableTsFailoverTest, KillTabletServerUnderLoad) {
51
1
  for (int i = 1; i <= FLAGS_test_num_iter; ++i) {
52
1
    std::atomic_bool stop_requested_flag(false);
53
1
    int rows = 1000000;
54
1
    int start_key = 0;
55
1
    int writer_threads = 4;
56
1
    int reader_threads = 4;
57
1
    int value_size_bytes = 16;
58
1
    int max_write_errors = 0;
59
1
    int max_read_errors = 0;
60
61
    // Create two separate clients for read and writes.
62
1
    auto write_client = CreateYBClient();
63
1
    auto read_client = CreateYBClient();
64
1
    yb::load_generator::YBSessionFactory write_session_factory(write_client.get(), &table_);
65
1
    yb::load_generator::YBSessionFactory read_session_factory(read_client.get(), &table_);
66
67
1
    yb::load_generator::MultiThreadedWriter writer(rows, start_key, writer_threads,
68
1
                                                   &write_session_factory, &stop_requested_flag,
69
1
                                                   value_size_bytes, max_write_errors);
70
1
    yb::load_generator::MultiThreadedReader reader(rows, reader_threads, &read_session_factory,
71
1
                                                   writer.InsertionPoint(), writer.InsertedKeys(),
72
1
                                                   writer.FailedKeys(), &stop_requested_flag,
73
1
                                                   value_size_bytes, max_read_errors);
74
75
1
    writer.Start();
76
    // Having separate write requires adding in write client id to the reader.
77
1
    reader.set_client_id(write_session_factory.ClientId());
78
1
    reader.Start();
79
80
1
    for (int i = 0; i < 3; ++i) {
81
0
      SleepFor(MonoDelta::FromSeconds(5));
82
0
      LOG(INFO) << "Killing tablet server #" << i;
83
0
      external_mini_cluster()->tablet_server(i)->Shutdown();
84
0
      LOG(INFO) << "Re-starting tablet server #" << i;
85
0
      ASSERT_OK(external_mini_cluster()->tablet_server(i)->Restart());
86
0
      ASSERT_OK(external_mini_cluster()->WaitForTabletServerCount(3, MonoDelta::FromSeconds(20)));
87
0
    }
88
89
1
    stop_requested_flag.store(true);  // stop both reader and writer
90
1
    writer.WaitForCompletion();
91
1
    LOG(INFO) << "Writing complete";
92
93
1
    reader.WaitForCompletion();
94
1
    LOG(INFO) << "Reading complete";
95
96
1
    if (FLAGS_test_num_iter > 1) {
97
0
      LOG(INFO) << "Completed iteration " << i << " of the test";
98
0
    }
99
100
1
    ASSERT_NO_FATALS(writer.AssertSucceeded());
101
0
    ASSERT_NO_FATALS(reader.AssertSucceeded());
102
103
    // Assuming every thread has time to do at least 50 writes. Had to lower this from 100 after
104
    // enabling TSAN.
105
0
    LOG(INFO) << "Reads: " << reader.num_reads() << ", writes: " << writer.num_writes();
106
0
    ASSERT_GE(writer.num_writes(), writer_threads * 50);
107
    // Assuming at least 100 reads and 100 writes.
108
0
    ASSERT_GE(reader.num_reads(), 100);
109
0
    ASSERT_GE(writer.num_writes(), 100);
110
111
0
    ClusterVerifier cluster_verifier(external_mini_cluster());
112
0
    ASSERT_NO_FATALS(cluster_verifier.CheckCluster());
113
0
    ASSERT_NO_FATALS(cluster_verifier.CheckRowCount(table_->name(), ClusterVerifier::EXACTLY,
114
0
        writer.num_writes()));
115
0
  }
116
1
}
117
118
}  // namespace yb