Repository: tikv/tikv
File: tests/failpoints/cases/test_transfer_leader.rs (Rust)

Code before:
    );
    pd_client.transfer_leader(
        left_region.get_id(),
        left_region_peer_on_store4.clone(),
        vec![],
    );
    pd_client.region_leader_must_be(left_region.get_id(), left_region_peer_on_store4);
    sleep_ms(300);

    let left_region_peer_on_store2 = new_peer(
        left_region.get_peers()[1].store_id,
        left_region.get_peers()[1].id,
    );
    pd_client.transfer_leader(
        left_region.get_id(),
        left_region_peer_on_store2.clone(),
        vec![],
    );
    pd_client.region_leader_must_be(left_region.get_id(), left_region_peer_on_store2);
    sleep_ms(300);

    assert_eq!(pd_client.get_regions_number(), 1);
}

// This test verifies that a leader transfer is allowed when the transferee
// has been applied a witness switch but the leader has not yet applied.
#[test]
fn test_when_applied_witness_switch_on_transferee_pessimistic_lock() {
    init_log_for_test();
    let mut cluster = new_server_cluster(0, 3);
    let pd_client = cluster.pd_client.clone();
    pd_client.disable_default_operator();
    let region_id = cluster.run_conf_change();
    pd_client.must_add_peer(region_id, new_peer(2, 2));
    pd_client.must_add_peer(region_id, new_peer(3, 3));
    pd_client.transfer_leader(region_id, new_peer(2, 2), vec![]);
    pd_client.region_leader_must_be(region_id, new_peer(2, 2));

    // Pause applying on the current leader (peer-2).
    fail::cfg("before_exec_batch_switch_witness", "pause").unwrap();
    fail::cfg("propose_locks_before_transfer_leader", "return").unwrap();

    // Demote peer-3 to be a witness.
    pd_client.switch_witnesses(region_id, vec![3], vec![true]);
    sleep_ms(300);

    pd_client.transfer_leader(region_id, new_peer(3, 3), vec![]);
    sleep_ms(300);
    assert_eq!(
        pd_client.check_region_leader(region_id, new_peer(3, 3)),
        false

Review comment (suggestion):
```suggestion
// has applied a witness switch but the leader has not yet applied.
```

Code after:
    pd_client.transfer_leader(
        left_region.get_id(),
        left_region_peer_on_store4.clone(),
        vec![],
    );
    pd_client.region_leader_must_be(left_region.get_id(), left_region_peer_on_store4);
    sleep_ms(300);

    let left_region_peer_on_store2 = new_peer(
        left_region.get_peers()[1].store_id,
        left_region.get_peers()[1].id,
    );
    pd_client.transfer_leader(
        left_region.get_id(),
        left_region_peer_on_store2.clone(),
        vec![],
    );
    pd_client.region_leader_must_be(left_region.get_id(), left_region_peer_on_store2);
    sleep_ms(300);

    assert_eq!(pd_client.get_regions_number(), 1);
}

// This test verifies that a leader transfer is allowed when the transferee
// has applied a witness switch but the leader has not yet applied.
#[test]
fn test_when_applied_witness_switch_on_transferee_pessimistic_lock() {
    let mut cluster = new_server_cluster(0, 3);
    let pd_client = cluster.pd_client.clone();
    pd_client.disable_default_operator();
    let region_id = cluster.run_conf_change();
    pd_client.must_add_peer(region_id, new_peer(2, 2));
    pd_client.must_add_peer(region_id, new_peer(3, 3));
    pd_client.transfer_leader(region_id, new_peer(2, 2), vec![]);
    pd_client.region_leader_must_be(region_id, new_peer(2, 2));

    // Pause applying on the current leader (peer-2).
    fail::cfg("before_exec_batch_switch_witness", "pause").unwrap();
    fail::cfg("propose_locks_before_transfer_leader", "return").unwrap();

    // Demote peer-3 to be a witness.
    pd_client.switch_witnesses(region_id, vec![3], vec![true]);
    sleep_ms(300);

    pd_client.transfer_leader(region_id, new_peer(3, 3), vec![]);
    sleep_ms(300);
    assert_eq!(
        pd_client.check_region_leader(region_id, new_peer(3, 3)),
        false
    );