From 1ac58323fab1251cdb7b0d91f418435a8189c8c8 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 30 Jan 2023 00:11:47 +0800 Subject: [PATCH 1/7] test: run sqlness test in distributed mode --- .github/workflows/release.yml | 19 ++++ Cargo.lock | 1 + .../parser/operator_precedence.result | 88 +++++++++++++++ .../parser/operator_precedence.sql | 21 ++++ tests/cases/distributed/select/dummy.result | 36 +++++++ tests/cases/distributed/select/dummy.sql | 11 ++ tests/runner/Cargo.toml | 1 + tests/runner/src/env.rs | 100 +++++++++++++++++- 8 files changed, 274 insertions(+), 3 deletions(-) create mode 100644 tests/cases/distributed/parser/operator_precedence.result create mode 100644 tests/cases/distributed/parser/operator_precedence.sql create mode 100644 tests/cases/distributed/select/dummy.result create mode 100644 tests/cases/distributed/select/dummy.sql diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8a7d94ee10b3..5a6f1270d774 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -69,6 +69,25 @@ jobs: run: | brew install protobuf + - name: Install etcd for linux + if: contains(matrix.arch, 'linux') && endsWith(matrix.arch, '-gnu') + run: | + ETCD_VER=v3.5.7 + DOWNLOAD_URL=https://github.com/etcd-io/etcd/releases/download + curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz + mkdir -p /tmp/etcd-download + tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download --strip-components=1 && cd /tmp/etcd-download + rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz + + sudo cp -a etcd etcdctl /usr/local/bin/ + nohup etcd >/tmp/etcd.log 2>&1 & + + - name: Install etcd for macos + if: contains(matrix.arch, 'darwin') + run: | + brew install etcd + brew services start etcd + - name: Install dependencies for linux if: contains(matrix.arch, 'linux') && endsWith(matrix.arch, '-gnu') run: | diff --git a/Cargo.lock b/Cargo.lock index 18a8164c01c5..cc584361c5cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6910,6 +6910,7 @@ dependencies = [ "common-query", "sqlness", "tokio", + "tokio-stream", ] [[package]] diff --git a/tests/cases/distributed/parser/operator_precedence.result b/tests/cases/distributed/parser/operator_precedence.result new file mode 100644 index 000000000000..2f1d756026ce --- /dev/null +++ b/tests/cases/distributed/parser/operator_precedence.result @@ -0,0 +1,88 @@ +SELECT 2*3+1; + ++--------------------------------+ +| Int64(2) * Int64(3) + Int64(1) | ++--------------------------------+ +| 7 | ++--------------------------------+ + +SELECT 1+2*3; + ++--------------------------------+ +| Int64(1) + Int64(2) * Int64(3) | ++--------------------------------+ +| 7 | ++--------------------------------+ + +SELECT 2^2 + 1; + ++--------------------------------+ +| Int64(2) # Int64(2) + Int64(1) | ++--------------------------------+ +| 1 | ++--------------------------------+ + +SELECT 1+2^2; + ++--------------------------------+ +| Int64(1) + Int64(2) # Int64(2) | ++--------------------------------+ +| 1 | ++--------------------------------+ + +SELECT 2*4 / 2; + ++--------------------------------+ +| Int64(2) * Int64(4) / Int64(2) | ++--------------------------------+ +| 4 | ++--------------------------------+ + +SELECT 2*(4 / 2); + ++--------------------------------+ +| Int64(2) * Int64(4) / Int64(2) | ++--------------------------------+ +| 4 | ++--------------------------------+ + +SELECT 16/2*4; + ++---------------------------------+ +| Int64(16) / Int64(2) * Int64(4) | ++---------------------------------+ +| 32 | ++---------------------------------+ + +SELECT (16/2)*4; + ++---------------------------------+ +| Int64(16) / Int64(2) * Int64(4) | ++---------------------------------+ +| 32 | ++---------------------------------+ + +SELECT 2*3*2; + ++--------------------------------+ +| Int64(2) * Int64(3) * Int64(2) | ++--------------------------------+ +| 12 | ++--------------------------------+ + +SELECT 2^3*2; + ++--------------------------------+ +| Int64(2) # Int64(3) * Int64(2) | ++--------------------------------+ +| 4 | ++--------------------------------+ + +SELECT 2*3^2; + ++--------------------------------+ +| Int64(2) * Int64(3) # Int64(2) | ++--------------------------------+ +| 4 | ++--------------------------------+ + diff --git a/tests/cases/distributed/parser/operator_precedence.sql b/tests/cases/distributed/parser/operator_precedence.sql new file mode 100644 index 000000000000..93f23cf38ee9 --- /dev/null +++ b/tests/cases/distributed/parser/operator_precedence.sql @@ -0,0 +1,21 @@ +SELECT 2*3+1; + +SELECT 1+2*3; + +SELECT 2^2 + 1; + +SELECT 1+2^2; + +SELECT 2*4 / 2; + +SELECT 2*(4 / 2); + +SELECT 16/2*4; + +SELECT (16/2)*4; + +SELECT 2*3*2; + +SELECT 2^3*2; + +SELECT 2*3^2; diff --git a/tests/cases/distributed/select/dummy.result b/tests/cases/distributed/select/dummy.result new file mode 100644 index 000000000000..1130dc41018b --- /dev/null +++ b/tests/cases/distributed/select/dummy.result @@ -0,0 +1,36 @@ +select 1; + ++----------+ +| Int64(1) | ++----------+ +| 1 | ++----------+ + +select 2 + 3; + ++---------------------+ +| Int64(2) + Int64(3) | ++---------------------+ +| 5 | ++---------------------+ + +select 4 + 0.5; + ++-------------------------+ +| Int64(4) + Float64(0.5) | ++-------------------------+ +| 4.5 | ++-------------------------+ + +select "a"; + +Error: 3000(PlanQuery), Schema error: No field named 'a'. Valid fields are . + +select "A"; + +Error: 3000(PlanQuery), Schema error: No field named 'A'. Valid fields are . + +select * where "a" = "A"; + +Error: 3000(PlanQuery), Schema error: No field named 'a'. Valid fields are . + diff --git a/tests/cases/distributed/select/dummy.sql b/tests/cases/distributed/select/dummy.sql new file mode 100644 index 000000000000..97d975b2e2c7 --- /dev/null +++ b/tests/cases/distributed/select/dummy.sql @@ -0,0 +1,11 @@ +select 1; + +select 2 + 3; + +select 4 + 0.5; + +select "a"; + +select "A"; + +select * where "a" = "A"; diff --git a/tests/runner/Cargo.toml b/tests/runner/Cargo.toml index 8945d12896ae..cf2665e7b237 100644 --- a/tests/runner/Cargo.toml +++ b/tests/runner/Cargo.toml @@ -13,3 +13,4 @@ common-grpc = { path = "../../src/common/grpc" } common-query = { path = "../../src/common/query" } sqlness = "0.1" tokio.workspace = true +tokio-stream = "0.1" diff --git a/tests/runner/src/env.rs b/tests/runner/src/env.rs index 6f8d2a02dad9..d655acf50ec6 100644 --- a/tests/runner/src/env.rs +++ b/tests/runner/src/env.rs @@ -25,11 +25,17 @@ use common_error::snafu::ErrorCompat; use common_query::Output; use sqlness::{Database, EnvController}; use tokio::process::{Child, Command}; +use tokio_stream::StreamExt; use crate::util; +const DATANODE_ADDR: &str = "127.0.0.1:4100"; +const METASRV_ADDR: &str = "127.0.0.1:3002"; const SERVER_ADDR: &str = "127.0.0.1:4001"; const SERVER_LOG_FILE: &str = "/tmp/greptime-sqlness.log"; +const METASRV_LOG_FILE: &str = "/tmp/greptime-sqlness-metasrv.log"; +const FRONTEND_LOG_FILE: &str = "/tmp/greptime-sqlness-frontend.log"; +const DATANODE_LOG_FILE: &str = "/tmp/greptime-sqlness-datanode.log"; pub struct Env {} @@ -48,8 +54,16 @@ impl EnvController for Env { /// Stop one [`Database`]. #[allow(clippy::print_stdout)] async fn stop(&self, _mode: &str, mut database: Self::DB) { - database.server_process.kill().await.unwrap(); - let _ = database.server_process.wait().await; + let mut server = database.server_process; + Env::stop_server(&mut server).await; + if database.metasrv_process.is_some() { + let mut metasrv = database.metasrv_process.take().unwrap(); + Env::stop_server(&mut metasrv).await; + } + if database.datanode_process.is_some() { + let mut datanode = database.datanode_process.take().unwrap(); + Env::stop_server(&mut datanode).await; + } println!("Stopped DB."); } } @@ -98,18 +112,98 @@ impl Env { GreptimeDB { server_process, + metasrv_process: None, + datanode_process: None, client, db, } } pub async fn start_distributed() -> GreptimeDB { - todo!() + let cargo_build_result = Command::new("cargo") + .current_dir(util::get_workspace_root()) + .args(["build", "--bin", "greptime"]) + .stdout(Stdio::null()) + .output() + .await + .expect("Failed to start GreptimeDB") + .status; + if !cargo_build_result.success() { + panic!("Failed to build GreptimeDB (`cargo build` fails)"); + } + + // start a distributed GreptimeDB + let mut meta_server = Env::start_server("metasrv"); + // wait for election + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + let mut frontend = Env::start_server("frontend"); + let mut datanode = Env::start_server("datanode"); + + let mut stream = tokio_stream::iter(&[DATANODE_ADDR, METASRV_ADDR, SERVER_ADDR]); + while let Some(addr) = stream.next().await { + let is_up = util::check_port(addr.parse().unwrap(), Duration::from_secs(10)).await; + if !is_up { + Env::stop_server(&mut meta_server).await; + Env::stop_server(&mut frontend).await; + Env::stop_server(&mut datanode).await; + panic!("Server {addr} doesn't up in 10 seconds, quit.") + } + } + + let client = Client::with_urls(vec![SERVER_ADDR]); + let db = DB::new("greptime", client.clone()); + + GreptimeDB { + server_process: frontend, + metasrv_process: Some(meta_server), + datanode_process: Some(datanode), + client, + db, + } + } + + async fn stop_server(process: &mut Child) { + process.kill().await.unwrap(); + let _ = process.wait().await; + } + + fn start_server(subcommand: &str) -> Child { + let log_file_name = match subcommand { + "datanode" => DATANODE_LOG_FILE, + "frontend" => FRONTEND_LOG_FILE, + "metasrv" => METASRV_LOG_FILE, + _ => panic!("Unexpected subcommand: {subcommand}"), + }; + let log_file = OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(log_file_name) + .unwrap_or_else(|_| panic!("Cannot open log file at {log_file_name}")); + + let mut args = vec![subcommand, "start"]; + if subcommand == "frontend" { + args.push("--metasrv-addr=0.0.0.0:3002"); + } else if subcommand == "datanode" { + args.push("--rpc-addr=0.0.0.0:4100"); + args.push("--metasrv-addr=0.0.0.0:3002"); + args.push("--node-id=1"); + } + + let process = Command::new("./greptime") + .current_dir(util::get_binary_dir("debug")) + .args(args) + .stdout(log_file) + .spawn() + .expect("Failed to start the DB"); + process } } pub struct GreptimeDB { server_process: Child, + metasrv_process: Option, + datanode_process: Option, #[allow(dead_code)] client: Client, db: DB, From ffaf98a02ec7798b8b96f6e096379730eda4eac9 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 30 Jan 2023 13:32:00 +0800 Subject: [PATCH 2/7] chore: improve the code --- tests/runner/src/env.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/runner/src/env.rs b/tests/runner/src/env.rs index d655acf50ec6..ebc48080cd60 100644 --- a/tests/runner/src/env.rs +++ b/tests/runner/src/env.rs @@ -56,12 +56,10 @@ impl EnvController for Env { async fn stop(&self, _mode: &str, mut database: Self::DB) { let mut server = database.server_process; Env::stop_server(&mut server).await; - if database.metasrv_process.is_some() { - let mut metasrv = database.metasrv_process.take().unwrap(); + if let Some(mut metasrv) = database.metasrv_process.take() { Env::stop_server(&mut metasrv).await; } - if database.datanode_process.is_some() { - let mut datanode = database.datanode_process.take().unwrap(); + if let Some(mut datanode) = database.datanode_process.take() { Env::stop_server(&mut datanode).await; } println!("Stopped DB."); @@ -188,6 +186,8 @@ impl Env { args.push("--rpc-addr=0.0.0.0:4100"); args.push("--metasrv-addr=0.0.0.0:3002"); args.push("--node-id=1"); + args.push("--data-dir=/tmp/greptimedb_node_1/data"); + args.push("--wal-dir=/tmp/greptimedb_node_1/wal"); } let process = Command::new("./greptime") From 33b29845db092dec211b3abd1353cb94c7fb2d1c Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 31 Jan 2023 12:06:35 +0800 Subject: [PATCH 3/7] chore: fix ci test --- .github/workflows/develop.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index e4f9f10528fe..103d79d066b3 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -127,7 +127,25 @@ jobs: - name: Rust Cache uses: Swatinem/rust-cache@v2 - name: Run sqlness - run: cargo run --bin sqlness-runner + run: | + ETCD_VER=v3.5.7 + DOWNLOAD_URL=https://github.com/etcd-io/etcd/releases/download + curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz + mkdir -p /tmp/etcd-download + tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download --strip-components=1 && cd /tmp/etcd-download + rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz + + sudo cp -a etcd etcdctl /usr/local/bin/ + nohup etcd >/tmp/etcd.log 2>&1 & + + cargo run --bin sqlness-runner + ls /tmp + - name: Upload sqlness logs + uses: actions/upload-artifact@v3 + with: + name: sqlness-logs + path: /tmp/greptime-*.log + retention-days: 3 fmt: name: Rustfmt From 9fe3b5ae2a61a886116bbec42247620e1d8a15a0 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 31 Jan 2023 12:10:31 +0800 Subject: [PATCH 4/7] chore: fix ci test --- .github/workflows/develop.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index 103d79d066b3..da8e172f89d5 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -132,10 +132,10 @@ jobs: DOWNLOAD_URL=https://github.com/etcd-io/etcd/releases/download curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz mkdir -p /tmp/etcd-download - tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download --strip-components=1 && cd /tmp/etcd-download + tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download --strip-components=1 rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz - sudo cp -a etcd etcdctl /usr/local/bin/ + sudo cp -a /tmp/etcd-download/etcd* /usr/local/bin/ nohup etcd >/tmp/etcd.log 2>&1 & cargo run --bin sqlness-runner From a4ed054a97cadfc7094e9ffc47ebdb026e765607 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 31 Jan 2023 12:25:40 +0800 Subject: [PATCH 5/7] chore: improve the ci yaml --- .github/workflows/develop.yml | 8 ++++---- .github/workflows/release.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index da8e172f89d5..736ac61e33c7 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -126,7 +126,7 @@ jobs: toolchain: ${{ env.RUST_TOOLCHAIN }} - name: Rust Cache uses: Swatinem/rust-cache@v2 - - name: Run sqlness + - name: Run etcd run: | ETCD_VER=v3.5.7 DOWNLOAD_URL=https://github.com/etcd-io/etcd/releases/download @@ -134,12 +134,12 @@ jobs: mkdir -p /tmp/etcd-download tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download --strip-components=1 rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz - + sudo cp -a /tmp/etcd-download/etcd* /usr/local/bin/ nohup etcd >/tmp/etcd.log 2>&1 & - + - name: Run sqlness + run: | cargo run --bin sqlness-runner - ls /tmp - name: Upload sqlness logs uses: actions/upload-artifact@v3 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a6f1270d774..24e3fa854c43 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -76,10 +76,10 @@ jobs: DOWNLOAD_URL=https://github.com/etcd-io/etcd/releases/download curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz mkdir -p /tmp/etcd-download - tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download --strip-components=1 && cd /tmp/etcd-download + tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download --strip-components=1 rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz - sudo cp -a etcd etcdctl /usr/local/bin/ + sudo cp -a /tmp/etcd-download/etcd* /usr/local/bin/ nohup etcd >/tmp/etcd.log 2>&1 & - name: Install etcd for macos From f70075b84280db29433870bcf67b16b38f5939d4 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 31 Jan 2023 12:35:51 +0800 Subject: [PATCH 6/7] chore: improve the code --- Cargo.lock | 1 - tests/runner/Cargo.toml | 1 - tests/runner/src/env.rs | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc584361c5cf..18a8164c01c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6910,7 +6910,6 @@ dependencies = [ "common-query", "sqlness", "tokio", - "tokio-stream", ] [[package]] diff --git a/tests/runner/Cargo.toml b/tests/runner/Cargo.toml index cf2665e7b237..8945d12896ae 100644 --- a/tests/runner/Cargo.toml +++ b/tests/runner/Cargo.toml @@ -13,4 +13,3 @@ common-grpc = { path = "../../src/common/grpc" } common-query = { path = "../../src/common/query" } sqlness = "0.1" tokio.workspace = true -tokio-stream = "0.1" diff --git a/tests/runner/src/env.rs b/tests/runner/src/env.rs index ebc48080cd60..fc5c38179c87 100644 --- a/tests/runner/src/env.rs +++ b/tests/runner/src/env.rs @@ -25,7 +25,6 @@ use common_error::snafu::ErrorCompat; use common_query::Output; use sqlness::{Database, EnvController}; use tokio::process::{Child, Command}; -use tokio_stream::StreamExt; use crate::util; @@ -137,8 +136,7 @@ impl Env { let mut frontend = Env::start_server("frontend"); let mut datanode = Env::start_server("datanode"); - let mut stream = tokio_stream::iter(&[DATANODE_ADDR, METASRV_ADDR, SERVER_ADDR]); - while let Some(addr) = stream.next().await { + for addr in [DATANODE_ADDR, METASRV_ADDR, SERVER_ADDR].iter() { let is_up = util::check_port(addr.parse().unwrap(), Duration::from_secs(10)).await; if !is_up { Env::stop_server(&mut meta_server).await; From a6bc32142530d63123e6245b0417bf2e502ec6ac Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 31 Jan 2023 14:36:59 +0800 Subject: [PATCH 7/7] chore: fix conflicts --- .github/workflows/develop.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index 736ac61e33c7..3987b8835689 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -138,8 +138,7 @@ jobs: sudo cp -a /tmp/etcd-download/etcd* /usr/local/bin/ nohup etcd >/tmp/etcd.log 2>&1 & - name: Run sqlness - run: | - cargo run --bin sqlness-runner + run: cargo run --bin sqlness-runner && ls /tmp - name: Upload sqlness logs uses: actions/upload-artifact@v3 with: