mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2025-12-22 22:20:02 +00:00
fix: mysql binary date type and multi-lang ci tests (#7291)
* fix: mysql binary date type Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * test: add unit test Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix: typo Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * ci: add multi lang integration tests ci Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix: path and branch Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * ci: prevent resuse runner Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix: ci Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * ci: Multi-language Integration Tests trigged only when pushing to main Signed-off-by: Dennis Zhuang <killme2008@gmail.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
This commit is contained in:
172
.github/workflows/multi-lang-tests.yml
vendored
Normal file
172
.github/workflows/multi-lang-tests.yml
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
name: Multi-language Integration Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-greptimedb:
|
||||
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||
name: Build GreptimeDB binary
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: arduino/setup-protoc@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
shared-key: "multi-lang-build"
|
||||
cache-all-crates: "true"
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
- name: Install cargo-gc-bin
|
||||
shell: bash
|
||||
run: cargo install cargo-gc-bin --force
|
||||
- name: Build greptime binary
|
||||
shell: bash
|
||||
run: cargo gc -- --bin greptime --features "pg_kvbackend,mysql_kvbackend"
|
||||
- name: Pack greptime binary
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir bin && \
|
||||
mv ./target/debug/greptime bin
|
||||
- name: Print greptime binary info
|
||||
run: ls -lh bin
|
||||
- name: Upload greptime binary
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: greptime-bin
|
||||
path: bin/
|
||||
retention-days: 1
|
||||
|
||||
run-multi-lang-tests:
|
||||
name: Run Multi-language SDK Tests
|
||||
needs: build-greptimedb
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout greptimedb-tests repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: GreptimeTeam/greptimedb-tests
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download pre-built greptime binary
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: greptime-bin
|
||||
path: bin
|
||||
|
||||
- name: Setup greptime binary
|
||||
run: |
|
||||
chmod +x ./bin/greptime
|
||||
ls -lh ./bin/greptime
|
||||
./bin/greptime --version
|
||||
|
||||
- name: Setup Java 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
cache: 'maven'
|
||||
|
||||
- name: Setup Python 3.8
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.8'
|
||||
|
||||
- name: Setup Go 1.24
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
cache-dependency-path: go-tests/go.sum
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
pip install mysql-connector-python psycopg2-binary
|
||||
python3 -c "import mysql.connector; print(f'mysql-connector-python {mysql.connector.__version__}')"
|
||||
python3 -c "import psycopg2; print(f'psycopg2 {psycopg2.__version__}')"
|
||||
|
||||
- name: Install Go dependencies
|
||||
working-directory: go-tests
|
||||
run: |
|
||||
go mod download
|
||||
go mod verify
|
||||
go version
|
||||
|
||||
- name: Kill existing GreptimeDB processes
|
||||
run: |
|
||||
pkill -f greptime || true
|
||||
sleep 2
|
||||
|
||||
- name: Start GreptimeDB standalone
|
||||
run: |
|
||||
./bin/greptime standalone start \
|
||||
--http-addr 0.0.0.0:4000 \
|
||||
--rpc-addr 0.0.0.0:4001 \
|
||||
--mysql-addr 0.0.0.0:4002 \
|
||||
--postgres-addr 0.0.0.0:4003 \
|
||||
--user-provider=static_user_provider:cmd:greptime_user=greptime_pwd > /tmp/greptimedb.log 2>&1 &
|
||||
|
||||
- name: Wait for GreptimeDB to be ready
|
||||
run: |
|
||||
echo "Waiting for GreptimeDB..."
|
||||
for i in {1..60}; do
|
||||
if curl -sf http://localhost:4000/health > /dev/null; then
|
||||
echo "✅ GreptimeDB is ready"
|
||||
exit 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
echo "❌ GreptimeDB failed to start"
|
||||
cat /tmp/greptimedb.log
|
||||
exit 1
|
||||
|
||||
- name: Run multi-language tests
|
||||
env:
|
||||
DB_NAME: test_db
|
||||
MYSQL_HOST: localhost
|
||||
MYSQL_PORT: 4002
|
||||
POSTGRES_HOST: localhost
|
||||
POSTGRES_PORT: 4003
|
||||
HTTP_PORT: 4000
|
||||
GREPTIME_USERNAME: greptime_user
|
||||
GREPTIME_PASSWORD: greptime_pwd
|
||||
run: |
|
||||
chmod +x ./run_tests.sh
|
||||
./run_tests.sh
|
||||
|
||||
- name: Collect logs on failure
|
||||
if: failure()
|
||||
run: |
|
||||
echo "=== GreptimeDB Logs ==="
|
||||
cat /tmp/greptimedb.log || true
|
||||
|
||||
- name: Upload test logs on failure
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-logs
|
||||
path: |
|
||||
/tmp/greptimedb.log
|
||||
java-tests/target/surefire-reports/
|
||||
python-tests/.pytest_cache/
|
||||
go-tests/*.log
|
||||
**/test-output/
|
||||
retention-days: 7
|
||||
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
run: |
|
||||
pkill -f greptime || true
|
||||
@@ -18,7 +18,7 @@ use std::time::Duration;
|
||||
use chrono::NaiveDate;
|
||||
use common_query::prelude::ScalarValue;
|
||||
use common_sql::convert::sql_value_to_value;
|
||||
use common_time::Timestamp;
|
||||
use common_time::{Date, Timestamp};
|
||||
use datafusion_common::tree_node::{Transformed, TreeNode};
|
||||
use datafusion_expr::LogicalPlan;
|
||||
use datatypes::prelude::ConcreteDataType;
|
||||
@@ -210,7 +210,8 @@ pub fn convert_value(param: &ParamValue, t: &ConcreteDataType) -> Result<ScalarV
|
||||
}
|
||||
}
|
||||
ConcreteDataType::Binary(_) => Ok(ScalarValue::Binary(Some(b.to_vec()))),
|
||||
ConcreteDataType::Timestamp(ts_type) => covert_bytes_to_timestamp(b, ts_type),
|
||||
ConcreteDataType::Timestamp(ts_type) => convert_bytes_to_timestamp(b, ts_type),
|
||||
ConcreteDataType::Date(_) => convert_bytes_to_date(b),
|
||||
_ => error::PreparedStmtTypeMismatchSnafu {
|
||||
expected: t,
|
||||
actual: param.coltype,
|
||||
@@ -285,7 +286,7 @@ pub fn convert_expr_to_scalar_value(param: &Expr, t: &ConcreteDataType) -> Resul
|
||||
}
|
||||
}
|
||||
|
||||
fn covert_bytes_to_timestamp(bytes: &[u8], ts_type: &TimestampType) -> Result<ScalarValue> {
|
||||
fn convert_bytes_to_timestamp(bytes: &[u8], ts_type: &TimestampType) -> Result<ScalarValue> {
|
||||
let ts = Timestamp::from_str_utc(&String::from_utf8_lossy(bytes))
|
||||
.map_err(|e| {
|
||||
error::MysqlValueConversionSnafu {
|
||||
@@ -314,6 +315,17 @@ fn covert_bytes_to_timestamp(bytes: &[u8], ts_type: &TimestampType) -> Result<Sc
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_bytes_to_date(bytes: &[u8]) -> Result<ScalarValue> {
|
||||
let date = Date::from_str_utc(&String::from_utf8_lossy(bytes)).map_err(|e| {
|
||||
error::MysqlValueConversionSnafu {
|
||||
err_msg: e.to_string(),
|
||||
}
|
||||
.build()
|
||||
})?;
|
||||
|
||||
Ok(ScalarValue::Date32(Some(date.val())))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use datatypes::types::{
|
||||
@@ -512,8 +524,28 @@ mod tests {
|
||||
];
|
||||
|
||||
for (input, ts_type, expected) in test_cases {
|
||||
let result = covert_bytes_to_timestamp(input.as_bytes(), &ts_type).unwrap();
|
||||
let result = convert_bytes_to_timestamp(input.as_bytes(), &ts_type).unwrap();
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_bytes_to_date() {
|
||||
let test_cases = vec![
|
||||
// Standard date format: YYYY-MM-DD
|
||||
("1970-01-01", ScalarValue::Date32(Some(0))),
|
||||
("1969-12-31", ScalarValue::Date32(Some(-1))),
|
||||
("2024-02-29", ScalarValue::Date32(Some(19782))),
|
||||
("2024-01-01", ScalarValue::Date32(Some(19723))),
|
||||
("2024-12-31", ScalarValue::Date32(Some(20088))),
|
||||
("2001-01-02", ScalarValue::Date32(Some(11324))),
|
||||
("2050-06-14", ScalarValue::Date32(Some(29384))),
|
||||
("2020-03-15", ScalarValue::Date32(Some(18336))),
|
||||
];
|
||||
|
||||
for (input, expected) in test_cases {
|
||||
let result = convert_bytes_to_date(input.as_bytes()).unwrap();
|
||||
assert_eq!(result, expected, "Failed for input: {}", input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user