Skip to content

Commit 71d47ef

Browse files
authored
Merge pull request #268 from ekexium/multi-reigon-test
Support multi-reigon test
2 parents 3f91f32 + 69b6879 commit 71d47ef

File tree

11 files changed

+260
-114
lines changed

11 files changed

+260
-114
lines changed

.travis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@ script:
4343
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "stable" ]]; then cargo clippy -- -D clippy::all; fi
4444
- cargo build --all
4545
- cargo build --examples
46-
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then cargo doc --workspace --exclude tikv-client-proto --document-private-items --no-deps; fi
46+
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then make doc; fi
4747
- if [[ $TRAVIS_RUST_VERSION == "nightly" ]]; then cargo test --all -- --nocapture; fi
4848
# For now we only run full integration tests on Linux. Here's why:
4949
# * Docker on OS X is not supported by Travis.
5050
# * Docker on Windows seems to not have the correct binary at `"/c/Program Files/Docker/Docker/DockerCli.exe" to switch it to Linux containers.
51-
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then docker run -d --net=host --name pd --rm pingcap/pd --name "pd" --data-dir "pd" --client-urls "http://127.0.0.1:2379" --advertise-client-urls "http://127.0.0.1:2379"; fi
52-
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then docker run -d --net=host --name kv --rm --ulimit nofile=90000:90000 pingcap/tikv --pd-endpoints "127.0.0.1:2379" --addr "127.0.0.1:2378" --data-dir "kv"; fi
51+
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then make docker-pd; fi
52+
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then make docker-kv; fi
5353
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then docker ps; fi
5454
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then docker logs pd; fi
5555
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then docker logs kv; fi
5656
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then sleep 60; fi
57-
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then PD_ADDRS="127.0.0.1:2379" cargo test --all --features integration-tests -- --nocapture; fi
57+
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then MULTI_REGION=1 make integration-test; fi
5858
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then cargo run --example raw -- --pd="127.0.0.1:2379"; fi
5959
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then cargo run --example transaction -- --pd="127.0.0.1:2379"; fi
6060
- if [[ $TRAVIS_OS_NAME == "linux" && $TRAVIS_RUST_VERSION == "nightly" ]]; then cargo run --example pessimistic -- --pd="127.0.0.1:2379"; fi

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ derive-new = "0.5"
2323
fail = "0.4"
2424
futures = { version = "0.3", features = ["async-await", "thread-pool"] }
2525
futures-timer = "3.0"
26-
grpcio = { version = "0.8", features = [ "secure", "prost-codec", "use-bindgen" ], default-features = false }
26+
grpcio = { version = "0.8", features = [ "secure", "prost-codec", "use-bindgen", "openssl-vendored" ], default-features = false }
2727
lazy_static = "1"
2828
log = "0.4"
2929
prometheus = { version = "0.12", features = [ "push", "process" ], default-features = false }
@@ -49,6 +49,8 @@ proptest-derive = "0.3"
4949
serial_test = "0.5.0"
5050
simple_logger = "1"
5151
tokio = { version = "1.0", features = [ "sync", "rt-multi-thread", "macros" ] }
52+
reqwest = {version = "0.11", default-features = false, features = ["native-tls-vendored"]}
53+
serde_json = "1"
5254

5355
[workspace]
5456
members = [

Makefile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
.PHONY: default check unit-test integration-tests test doc docker-pd docker-kv docker all
2+
3+
default: check
4+
5+
check:
6+
cargo check --all
7+
cargo fmt -- --check
8+
cargo clippy -- -D clippy::all
9+
10+
unit-test:
11+
cargo test --all
12+
13+
integration-test:
14+
# MULTI_REGION shall be set manually if needed
15+
PD_ADDRS="127.0.0.1:2379" cargo test txn_ --all --features integration-tests -- --nocapture
16+
PD_ADDRS="127.0.0.1:2379" cargo test raw_ --all --features integration-tests -- --nocapture
17+
PD_ADDRS="127.0.0.1:2379" cargo test misc_ --all --features integration-tests -- --nocapture
18+
19+
test: unit-test integration-test
20+
21+
doc:
22+
cargo doc --workspace --exclude tikv-client-proto --document-private-items --no-deps
23+
24+
docker-pd:
25+
docker run -d -v $(shell pwd)/config:/config --net=host --name pd --rm pingcap/pd:latest --name "pd" --data-dir "pd" --client-urls "http://127.0.0.1:2379" --advertise-client-urls "http://127.0.0.1:2379" --config /config/pd.toml
26+
27+
docker-kv:
28+
docker run -d -v $(shell pwd)/config:/config --net=host --name kv --rm --ulimit nofile=90000:90000 pingcap/tikv:latest --pd-endpoints "127.0.0.1:2379" --addr "127.0.0.1:2378" --data-dir "kv" --config /config/tikv.toml
29+
30+
docker: docker-pd docker-kv
31+
32+
all: check doc test

config/pd.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[schedule]
2+
max-merge-region-size = 1
3+
max-merge-region-keys = 3

config/tikv.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[coprocessor]
2+
region-max-keys = 5
3+
region-split-keys = 3
4+
batch-split-limit = 100
5+
6+
[raftstore]
7+
region-split-check-diff = "0KB"
8+
pd-heartbeat-tick-interval = "2s"
9+
pd-store-heartbeat-tick-interval = "5s"
10+
split-region-check-tick-interval = "1s"

src/pd/retry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use tokio::sync::RwLock;
2525
// FIXME: these numbers and how they are used are all just cargo-culted in, there
2626
// may be more optimal values.
2727
const RECONNECT_INTERVAL_SEC: u64 = 1;
28-
const MAX_REQUEST_COUNT: usize = 3;
28+
const MAX_REQUEST_COUNT: usize = 5;
2929
const LEADER_CHANGE_RETRY: usize = 10;
3030

3131
/// Client for communication with a PD cluster. Has the facility to reconnect to the cluster.

src/util/iter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ mod test {
7474
.into_iter()
7575
.flat_map_ok(|i| Some(i).into_iter())
7676
.collect();
77-
assert_eq!(result.unwrap(), vec![]);
77+
assert_eq!(result.unwrap(), Vec::<i32>::new());
7878

7979
let result: Result<Vec<i32>, ()> = vec![Result::<i32, ()>::Ok(0), Ok(1), Ok(2)]
8080
.into_iter()

tests/common/ctl.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0.
2+
//! The module provides some utility functions to control and get information
3+
//! from PD, using its HTTP API.
4+
5+
use super::pd_addrs;
6+
use tikv_client_common::{Error, Result};
7+
8+
pub async fn get_region_count() -> Result<u64> {
9+
let res = reqwest::get(format!("http://{}/pd/api/v1/regions", pd_addrs()[0]))
10+
.await
11+
.map_err(|e| Error::StringError(e.to_string()))?;
12+
13+
let body = res
14+
.text()
15+
.await
16+
.map_err(|e| Error::StringError(e.to_string()))?;
17+
let value: serde_json::Value = serde_json::from_str(body.as_ref()).unwrap();
18+
value["count"]
19+
.as_u64()
20+
.ok_or_else(|| Error::StringError("pd region count does not return an integer".to_owned()))
21+
}
22+
23+
#[tokio::test]
24+
#[ignore]
25+
async fn test_get_region_count() -> Result<()> {
26+
println!("{}", get_region_count().await?);
27+
Ok(())
28+
}

tests/common/mod.rs

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1-
use std::env;
2-
use tikv_client::{ColumnFamily, RawClient};
1+
mod ctl;
2+
3+
use futures_timer::Delay;
4+
use log::{info, warn};
5+
use std::{env, time::Duration};
6+
use tikv_client::{ColumnFamily, Key, RawClient, Result, TransactionClient};
7+
8+
const ENV_PD_ADDRS: &str = "PD_ADDRS";
9+
const ENV_ENABLE_MULIT_REGION: &str = "MULTI_REGION";
10+
const REGION_SPLIT_TIME_LIMIT: Duration = Duration::from_secs(15);
311

412
// Delete all entries in TiKV to leave a clean space for following tests.
513
pub async fn clear_tikv() {
@@ -14,7 +22,69 @@ pub async fn clear_tikv() {
1422
}
1523
}
1624

17-
const ENV_PD_ADDRS: &str = "PD_ADDRS";
25+
// To test with multiple regions, prewrite some data. Tests that hope to test
26+
// with multiple regions should use keys in the corresponding ranges.
27+
pub async fn init() -> Result<()> {
28+
// ignore SetLoggerError
29+
let _ = simple_logger::SimpleLogger::new()
30+
.with_level(log::LevelFilter::Warn)
31+
.init();
32+
33+
if env::var(ENV_ENABLE_MULIT_REGION).is_ok() {
34+
// 1000 keys: 0..1000
35+
let keys_1 = std::iter::successors(Some(0u32), |x| Some(x + 1))
36+
.take(1000)
37+
.map(|x| x.to_be_bytes().to_vec());
38+
// 1024 keys: 0..u32::MAX
39+
let count = 1024;
40+
let step = u32::MAX / count;
41+
let keys_2 = std::iter::successors(Some(0u32), |x| Some(x + step))
42+
.take(count as usize - 1)
43+
.map(|x| x.to_be_bytes().to_vec());
44+
45+
ensure_region_split(keys_1.chain(keys_2), 100).await?;
46+
}
47+
48+
clear_tikv().await;
49+
Ok(())
50+
}
51+
52+
async fn ensure_region_split(
53+
keys: impl IntoIterator<Item = impl Into<Key>>,
54+
region_count: u32,
55+
) -> Result<()> {
56+
if ctl::get_region_count().await? as u32 >= region_count {
57+
return Ok(());
58+
}
59+
60+
// 1. write plenty transactional keys
61+
// 2. wait until regions split
62+
63+
let client = TransactionClient::new(pd_addrs()).await?;
64+
let mut txn = client.begin_optimistic().await?;
65+
for key in keys.into_iter() {
66+
txn.put(key.into(), vec![0, 0, 0, 0]).await?;
67+
}
68+
txn.commit().await?;
69+
let mut txn = client.begin_optimistic().await?;
70+
let _ = txn.scan(vec![].., 2048).await?;
71+
txn.commit().await?;
72+
73+
info!("splitting regions...");
74+
let start_time = std::time::Instant::now();
75+
loop {
76+
if ctl::get_region_count().await? as u32 >= region_count {
77+
break;
78+
}
79+
if start_time.elapsed() > REGION_SPLIT_TIME_LIMIT {
80+
warn!("Stop splitting regions: time limit exceeded");
81+
break;
82+
}
83+
Delay::new(Duration::from_millis(200)).await;
84+
}
85+
86+
Ok(())
87+
}
1888

1989
pub fn pd_addrs() -> Vec<String> {
2090
env::var(ENV_PD_ADDRS)

tests/failpoint_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#![cfg(feature = "integration-tests")]
22

33
mod common;
4-
use common::{clear_tikv, pd_addrs};
4+
use common::{init, pd_addrs};
55
use fail::FailScenario;
66
use serial_test::serial;
77
use tikv_client::{Result, TransactionClient, TransactionOptions};
88

99
#[tokio::test]
1010
#[serial]
11-
async fn optimistic_heartbeat() -> Result<()> {
12-
clear_tikv().await;
11+
async fn txn_optimistic_heartbeat() -> Result<()> {
12+
init().await?;
1313
let scenario = FailScenario::setup();
1414
fail::cfg("after-prewrite", "sleep(10000)").unwrap();
1515

0 commit comments

Comments
 (0)