forked from apecloud/myduckserver
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add mysql client compatibility tests (apecloud#111)
- Loading branch information
1 parent
be94e37
commit 37a0adf
Showing
20 changed files
with
1,818 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
name: Compatibility Test for Clients | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
- compatibility | ||
- test | ||
pull_request: | ||
branches: [ "main" ] | ||
|
||
jobs: | ||
test-mysql: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: '1.23' | ||
|
||
- name: Set up Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: '16' | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.10' | ||
|
||
- name: Install dependencies | ||
run: | | ||
go get . | ||
pip3 install "sqlglot[rs]" | ||
curl -LJO https://github.com/duckdb/duckdb/releases/download/v1.1.3/duckdb_cli-linux-amd64.zip | ||
unzip duckdb_cli-linux-amd64.zip | ||
chmod +x duckdb | ||
sudo mv duckdb /usr/local/bin | ||
duckdb -c 'INSTALL json from core' | ||
duckdb -c 'SELECT extension_name, loaded, install_path FROM duckdb_extensions() where installed' | ||
sudo apt-get update | ||
sudo apt-get install --yes --no-install-recommends bats cpanminus | ||
cd compatibility/mysql/ | ||
sudo apt-get install --yes --no-install-recommends libmysqlclient-dev dotnet-sdk-8.0 dotnet-runtime-8.0 | ||
curl -L -o ./java/mysql-connector-java-8.0.30.jar https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.30/mysql-connector-java-8.0.30.jar | ||
npm install mysql | ||
sudo apt-get install --yes --no-install-recommends php-mysql | ||
sudo cpanm DBD::mysql | ||
pip3 install mysql-connector-python | ||
sudo apt-get install --yes --no-install-recommends r-base-core | ||
sudo R -e "install.packages('RMySQL', repos='http://cran.r-project.org')" | ||
sudo gem install mysql2 | ||
- name: Build | ||
run: go build -v | ||
|
||
- name: Start MyDuck Server | ||
run: | | ||
./myduckserver & | ||
sleep 5 | ||
- name: Run the Compatibility Test for MySQL Client | ||
run: | | ||
bats ./compatibility/mysql/test.bats | ||
test-postgresql: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: '1.23' | ||
|
||
- name: Set up Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: '16' | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.10' | ||
|
||
- name: Install dependencies | ||
run: | | ||
go get . | ||
pip3 install "sqlglot[rs]" | ||
curl -LJO https://github.com/duckdb/duckdb/releases/download/v1.1.3/duckdb_cli-linux-amd64.zip | ||
unzip duckdb_cli-linux-amd64.zip | ||
chmod +x duckdb | ||
sudo mv duckdb /usr/local/bin | ||
duckdb -c 'INSTALL json from core' | ||
duckdb -c 'SELECT extension_name, loaded, install_path FROM duckdb_extensions() where installed' | ||
sudo apt-get update | ||
sudo apt-get install --yes --no-install-recommends bats cpanminus | ||
cd compatibility/pg/ | ||
sudo apt-get install --yes --no-install-recommends postgresql-client dotnet-sdk-8.0 dotnet-runtime-8.0 | ||
curl -L -o ./java/postgresql-42.7.4.jar https://jdbc.postgresql.org/download/postgresql-42.7.3.jar | ||
npm install pg | ||
sudo cpanm DBD::Pg | ||
pip3 install psycopg2 | ||
sudo apt-get install --yes --no-install-recommends r-base-core | ||
sudo R -e "install.packages('RPostgres', repos='http://cran.r-project.org')" | ||
sudo gem install pg | ||
- name: Build | ||
run: go build -v | ||
|
||
- name: Start MyDuck Server | ||
run: | | ||
./myduckserver & | ||
sleep 5 | ||
- name: Run the Compatibility Test for PostgreSQL Client | ||
run: | | ||
bats ./compatibility/pg/test.bats |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Client Compatibility Test | ||
|
||
This contains a set of tests to verify the compatibility of the client libraries for the different databases. | ||
|
||
You should not run `tests.bats` directly, instead use github actions (or act) to run the tests. | ||
|
||
## MySQL Client Compatibility Test | ||
|
||
## PostgreSQL Client Compatibility Test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <mysql/mysql.h> | ||
#include <string.h> | ||
|
||
typedef struct { | ||
char *query; | ||
char **expectedResults; | ||
int expectedRows; | ||
int expectedCols; | ||
} Test; | ||
|
||
typedef struct { | ||
MYSQL *conn; | ||
Test *tests; | ||
int testCount; | ||
} MySQLTest; | ||
|
||
void connectDB(MySQLTest *mysqlTest, const char *ip, int port, const char *user, const char *password) { | ||
mysqlTest->conn = mysql_init(NULL); | ||
if (mysqlTest->conn == NULL) { | ||
printf("mysql_init() failed\n"); | ||
exit(1); | ||
} | ||
|
||
if (mysql_real_connect(mysqlTest->conn, ip, user, password, NULL, port, NULL, 0) == NULL) { | ||
printf("mysql_real_connect() failed\n"); | ||
mysql_close(mysqlTest->conn); | ||
exit(1); | ||
} | ||
} | ||
|
||
void disconnectDB(MySQLTest *mysqlTest) { | ||
mysql_close(mysqlTest->conn); | ||
} | ||
|
||
void addTest(MySQLTest *mysqlTest, const char *query, char **expectedResults, int expectedRows, int expectedCols) { | ||
mysqlTest->tests = realloc(mysqlTest->tests, sizeof(Test) * (mysqlTest->testCount + 1)); | ||
mysqlTest->tests[mysqlTest->testCount].query = strdup(query); | ||
mysqlTest->tests[mysqlTest->testCount].expectedResults = expectedResults; | ||
mysqlTest->tests[mysqlTest->testCount].expectedRows = expectedRows; | ||
mysqlTest->tests[mysqlTest->testCount].expectedCols = expectedCols; | ||
mysqlTest->testCount++; | ||
} | ||
|
||
int runTests(MySQLTest *mysqlTest) { | ||
for (int i = 0; i < mysqlTest->testCount; i++) { | ||
Test *test = &mysqlTest->tests[i]; | ||
printf("Running test: %s\n", test->query); | ||
if (mysql_query(mysqlTest->conn, test->query)) { | ||
printf("Query failed: %s\n", mysql_error(mysqlTest->conn)); | ||
return 0; | ||
} | ||
|
||
MYSQL_RES *res = mysql_store_result(mysqlTest->conn); | ||
if (res) { | ||
int rows = mysql_num_rows(res); | ||
int cols = mysql_num_fields(res); | ||
if (cols != test->expectedCols) { | ||
printf("Expected %d columns, got %d\n", test->expectedCols, cols); | ||
mysql_free_result(res); | ||
return 0; | ||
} | ||
MYSQL_ROW row; | ||
int r = 0; | ||
while ((row = mysql_fetch_row(res))) { | ||
for (int c = 0; c < cols; c++) { | ||
if (strcmp(row[c], test->expectedResults[r * cols + c]) != 0) { | ||
printf("Expected: '%s', got: '%s'\n", test->expectedResults[r * cols + c], row[c]); | ||
mysql_free_result(res); | ||
return 0; | ||
} | ||
} | ||
r++; | ||
} | ||
if (rows != test->expectedRows) { | ||
printf("Expected %d rows, got %d\n", test->expectedRows, rows); | ||
mysql_free_result(res); | ||
return 0; | ||
} | ||
mysql_free_result(res); | ||
} | ||
} | ||
return 1; | ||
} | ||
|
||
size_t removeNewline(char *line) { | ||
size_t len = strlen(line); | ||
while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) { | ||
line[--len] = '\0'; | ||
} | ||
return len; | ||
} | ||
|
||
void readTestsFromFile(MySQLTest *mysqlTest, const char *filename) { | ||
FILE *file = fopen(filename, "r"); | ||
if (!file) { | ||
perror("Failed to open test data file"); | ||
exit(1); | ||
} | ||
|
||
char line[1024]; | ||
while (fgets(line, sizeof(line), file)) { | ||
size_t len = removeNewline(line); | ||
if (len == 0) continue; | ||
|
||
char *query = strdup(line); | ||
char **expectedResults = NULL; | ||
int expectedRows = 0, expectedCols = 0; | ||
|
||
while (fgets(line, sizeof(line), file)) { | ||
len = removeNewline(line); | ||
if (len == 0) break; | ||
|
||
char *token = strtok(line, ","); | ||
int col = 0; | ||
while (token) { | ||
expectedResults = realloc(expectedResults, sizeof(char*) * (expectedRows * expectedCols + col + 1)); | ||
expectedResults[expectedRows * expectedCols + col] = strdup(token); | ||
token = strtok(NULL, ","); | ||
col++; | ||
} | ||
expectedRows++; | ||
if (expectedCols == 0) expectedCols = col; | ||
} | ||
addTest(mysqlTest, query, expectedResults, expectedRows, expectedCols); | ||
} | ||
|
||
fclose(file); | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
if (argc != 6) { | ||
printf("Usage: %s <ip> <port> <user> <password> <testFile>\n", argv[0]); | ||
return 1; | ||
} | ||
|
||
MySQLTest mysqlTest = {0}; | ||
connectDB(&mysqlTest, argv[1], atoi(argv[2]), argv[3], argv[4]); | ||
|
||
readTestsFromFile(&mysqlTest, argv[5]); | ||
|
||
int result = runTests(&mysqlTest); | ||
disconnectDB(&mysqlTest); | ||
free(mysqlTest.tests); | ||
return result ? 0 : 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/bash | ||
|
||
rm -rf ./c/mysql_test \ | ||
./csharp/bin ./csharp/obj \ | ||
./go/mysql \ | ||
./java/*.class \ | ||
./rust/target ./rust/Cargo.lock |
Oops, something went wrong.