blob: dff366f4cd6dcd75cda85bfe9a8930bddb41d313 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "kudu/integration-tests/cluster_itest_util.h"
#include "kudu/integration-tests/ts_itest-base.h"
#include "kudu/util/countdown_latch.h"
#include "kudu/util/status.h"
namespace kudu {
class MonoDelta;
namespace cluster {
class ExternalTabletServer;
}
namespace tserver {
class TabletServerServiceProxy;
// Integration test for the raft consensus implementation.
// Uses the whole tablet server stack with ExternalMiniCluster.
class RaftConsensusITestBase : public TabletServerIntegrationTestBase {
public:
// Behavior for the tablet server hosting the fall-behind-WAL-GC replica.
enum BehindWalGcBehavior {
STOP_CONTINUE, // Send SIGSTOP and then SIGCONT to the affected tserver.
SHUTDOWN_RESTART, // Shutdown and then restart the affected tserver.
SHUTDOWN, // Shutdown the affected tserver, don't start it back up.
DO_NOT_TAMPER, // Leave the affected tserver alone, running or not.
};
RaftConsensusITestBase();
void SetUp() override;
void ScanReplica(TabletServerServiceProxy* replica_proxy,
std::vector<std::string>* results);
void InsertTestRowsRemoteThread(
int first_row, int count, int num_batches,
const std::vector<std::unique_ptr<CountDownLatch>>& latches = {});
protected:
// Retrieve the current term of the first tablet on this tablet server.
static Status GetTermMetricValue(cluster::ExternalTabletServer* ts,
int64_t* term);
// Flags needed for CauseFollowerToFallBehindLogGC() to work well.
static void AddFlagsForLogRolls(std::vector<std::string>* extra_tserver_flags);
// Pause/shutdown the tserver hosting one of the follower tablet replicas and
// write enough data to the remaining replicas to cause log GC. Then
// resume/restart/leave-shutdown the affected tserver. On success,
// 'leader_uuid' will be set to the UUID of the leader, 'orig_term'
// will be set to the term of the leader before un-pausing the follower and
// 'fell_behind_uuid' will be set to the UUID of the follower that was
// paused/shutdown and caused to fall behind. These can be used for
// verification purposes. The optional 'tserver_behavior' dictates what
// whether the affected tserver will be paused/resumed, shutdown/restarted,
// and so on.
//
// Certain flags should be set. You can add the required flags with
// AddFlagsForLogRolls() before starting the cluster.
void CauseFollowerToFallBehindLogGC(
const itest::TabletServerMap& tablet_servers,
std::string* leader_uuid = nullptr,
int64_t* orig_term = nullptr,
std::string* fell_behind_uuid = nullptr,
BehindWalGcBehavior tserver_behavior = BehindWalGcBehavior::STOP_CONTINUE,
const MonoDelta& pre_workload_delay = {});
// Same as above, but the follower to fail is chosen in advance.
void CauseSpecificFollowerToFallBehindLogGC(
const itest::TabletServerMap& tablet_servers,
const std::string& follower_uuid_to_fail,
std::string* leader_uuid = nullptr,
int64_t* orig_term = nullptr,
BehindWalGcBehavior tserver_behavior = BehindWalGcBehavior::STOP_CONTINUE,
const MonoDelta& pre_workload_delay = {});
CountDownLatch inserters_;
};
} // namespace tserver
} // namespace kudu