-
Notifications
You must be signed in to change notification settings - Fork 316
tests: Add SQLite integration coverage from canonical sources #2002
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
02c86dd
tests: integration: add `sqlite` submodule
thedataking 6effa8d
tests: integration: add `sqlite` transpile support
thedataking dcbc1e0
tests: integration: add `sqlite` refactor support
thedataking 4ccf7fd
tests: integration: add `sqlite` test support
thedataking 98b8a8e
tests: integration: enable `sqlite` in CI
thedataking File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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,40 @@ | ||
| # SQLite | ||
|
|
||
| The source submodule is pinned to SQLite 3.53.4 from the official Git mirror. | ||
| Initialize it with: | ||
|
|
||
| ```sh | ||
| git submodule update --init --checkout tests/integration/tests/sqlite/repo | ||
| ``` | ||
|
|
||
| Run from the C2Rust checkout with the integration harness prerequisites and `jq` | ||
| installed: | ||
|
|
||
| ```sh | ||
| export PATH="$PWD/target/release:$PWD/c2rust-postprocess:$PATH" | ||
| export C2RUST_DIR="$PWD" | ||
| ./tests/integration/test.py sqlite | ||
| ``` | ||
|
|
||
| The build uses `--disable-amalgamation` and the `libsqlite3.a` target to compile | ||
| the library's individual translation units. SQLite's `sqlite3` and `speedtest1` | ||
| make targets compile the amalgamation even with that configure option, so they | ||
| are deliberately not used. Source generation runs before Bear to exclude build | ||
| tools from the compilation database. R-tree support is enabled for its workload. | ||
|
|
||
| After transpilation and again after refactoring, `test.sh` compiles SQLite's | ||
| upstream `test/speedtest1.c` against each of the native and translated static | ||
| libraries. It runs the `main`, `cte`, `orm`, `fp`, and `rtree` workloads with | ||
| `--size 1 --verify` on temporary on-disk databases. | ||
| Each workload must exit successfully and produce the same result byte count and | ||
| verification hash as native SQLite. Timing output is ignored. The C test driver | ||
| stays native so the same caller exercises both libraries' public C ABI. | ||
| The Rust archive's native link dependencies come from rustc's | ||
| `--print native-static-libs` output. | ||
|
|
||
| `smoke.c` also checks fixed SQL results, transaction/savepoint rollback, triggers, | ||
| foreign keys, blobs, JSON/JSONB operations, numeric parsing (including large | ||
| integers and floating-point values), window functions, data and WAL journal-mode | ||
| persistence after reopening, and an integrity check. The upstream `json` and | ||
| `parsenumber` workloads do not hash result rows, and `parsenumber` ignores SQL | ||
| errors, so JSON and numeric parsing use these explicit assertions instead. |
This file contains hidden or 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,29 @@ | ||
| requirements: | ||
| generic: | ||
| programs: | ||
| in_path: | ||
| - jq | ||
| ubuntu: | ||
| apt: | ||
| packages: | ||
| - jq | ||
|
|
||
| transpile: | ||
| autogen: true | ||
| tflags: --reorganize-definitions --disable-refactoring | ||
|
|
||
| cargo.transpile: | ||
| autogen: true | ||
|
|
||
| refactor: | ||
| autogen: true | ||
| transforms: | ||
| - rename_unnamed | ||
| - reorganize_definitions | ||
| - shorten_imported_paths | ||
| - remove_unused_labels | ||
| - remove_redundant_casts | ||
| - remove_literal_suffixes | ||
|
|
||
| cargo.refactor: | ||
| autogen: true |
This file contains hidden or 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 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| cd "$SCRIPT_DIR/repo" | ||
|
|
||
| # Compile separate translation units to exercise cross-file translation. | ||
| ./configure --disable-amalgamation --disable-shared --disable-readline \ | ||
| --disable-tcl --enable-rtree 2>&1 | tee "$SCRIPT_DIR/$(basename "$0").log" | ||
This file contains hidden or 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,14 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| cd "$SCRIPT_DIR" | ||
|
|
||
| { | ||
| make -C repo clean | ||
| rm -f compile_commands.json | ||
| # Generate the parser, opcodes and headers before recording compilation, | ||
| # so host tools such as lemon are not included in the translated library. | ||
| make -C repo -j"$(nproc)" .target_source | ||
| bear -- make -C repo -j"$(nproc)" libsqlite3.a | ||
| } 2>&1 | tee "$SCRIPT_DIR/$(basename "$0").log" |
This file contains hidden or 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,91 @@ | ||
| #include "sqlite3.h" | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
|
|
||
| #define CHECK(condition) do { \ | ||
| if (!(condition)) { \ | ||
| fprintf(stderr, "%s:%d: %s failed\n", __FILE__, __LINE__, #condition); \ | ||
| exit(1); \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| static void exec(sqlite3 *db, const char *sql) { | ||
| char *error = NULL; | ||
| if (sqlite3_exec(db, sql, NULL, NULL, &error) != SQLITE_OK) { | ||
| fprintf(stderr, "%s: %s\n", sql, error); | ||
| sqlite3_free(error); | ||
| exit(1); | ||
| } | ||
| } | ||
|
|
||
| static void expect_int(sqlite3 *db, const char *sql, int expected) { | ||
| sqlite3_stmt *stmt = NULL; | ||
| CHECK(sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK); | ||
| CHECK(sqlite3_step(stmt) == SQLITE_ROW); | ||
| int actual = sqlite3_column_int(stmt, 0); | ||
| if (actual != expected) { | ||
| fprintf(stderr, "%s: expected %d, got %d\n", sql, expected, actual); | ||
| exit(1); | ||
| } | ||
| CHECK(sqlite3_step(stmt) == SQLITE_DONE); | ||
| CHECK(sqlite3_finalize(stmt) == SQLITE_OK); | ||
| } | ||
|
|
||
| int main(int argc, char **argv) { | ||
| CHECK(argc == 2); | ||
| sqlite3 *db = NULL; | ||
| CHECK(sqlite3_open(argv[1], &db) == SQLITE_OK); | ||
| exec(db, | ||
| "PRAGMA journal_mode=WAL;" | ||
| "PRAGMA foreign_keys=ON;" | ||
| "CREATE TABLE parent(id INTEGER PRIMARY KEY);" | ||
| "CREATE TABLE child(id INTEGER REFERENCES parent, value TEXT, data BLOB);" | ||
| "CREATE TABLE audit(value TEXT);" | ||
| "CREATE TRIGGER inserted AFTER INSERT ON child BEGIN " | ||
| " INSERT INTO audit VALUES(new.value); END;" | ||
| "BEGIN;" | ||
| "INSERT INTO parent VALUES(1);" | ||
| "INSERT INTO child VALUES(1, 'hello', x'00ff80');" | ||
| "SAVEPOINT s;" | ||
| "INSERT INTO child VALUES(1, 'rolled back', NULL);" | ||
| "ROLLBACK TO s;" | ||
| "RELEASE s;" | ||
| "COMMIT;"); | ||
| expect_int(db, "SELECT journal_mode = 'wal' FROM pragma_journal_mode", 1); | ||
| expect_int(db, "SELECT count(*) FROM audit", 1); | ||
| expect_int(db, "SELECT hex(data) = '00FF80' AND value = 'hello' FROM child", 1); | ||
| CHECK(sqlite3_exec(db, "INSERT INTO child VALUES(2, 'invalid', NULL)", | ||
| NULL, NULL, NULL) == SQLITE_CONSTRAINT); | ||
| expect_int(db, "SELECT json_extract('{\"a\":[1,2,3]}', '$.a[2]')", 3); | ||
| expect_int(db, | ||
| "SELECT json(jsonb_set(jsonb('{\"a\":[1,2,3]}'), '$.a[1]', 9)) " | ||
| "= '{\"a\":[1,9,3]}'", 1); | ||
| expect_int(db, | ||
| "SELECT json(jsonb_remove(jsonb_insert(jsonb('{}'), '$.x', 7, '$.y', 8), '$.x')) " | ||
| "= '{\"y\":8}'", 1); | ||
| expect_int(db, | ||
| "WITH t(x) AS (VALUES(1),(2),(3)) " | ||
| "SELECT json(jsonb_group_array(x)) = '[1,2,3]' FROM t", 1); | ||
| expect_int(db, "SELECT CAST('1_000' AS INTEGER)", 1); | ||
| expect_int(db, "SELECT 1_000 + CAST('2.5e2' AS INTEGER)", 1002); | ||
| expect_int(db, "SELECT CAST(CAST('2.5e2' AS REAL) AS INTEGER)", 250); | ||
| expect_int(db, | ||
| "SELECT printf('%lld', 8_227_256_643_844_975_616) = '8227256643844975616' " | ||
| "AND printf('%lld', -9223372036854775808) = '-9223372036854775808'", 1); | ||
| expect_int(db, | ||
| "SELECT printf('%.6f', 8.227256643844975616) = '8.227257' " | ||
| "AND printf('%.8f', CAST('1.23456e-3' AS REAL)) = '0.00123456' " | ||
| "AND printf('%.4f', 1_234.5_6e-2) = '12.3456'", 1); | ||
| expect_int(db, | ||
| "WITH t(x) AS (VALUES(1),(2),(3)) " | ||
| "SELECT sum(s) FROM (SELECT sum(x) OVER (ORDER BY x) AS s FROM t)", 10); | ||
| CHECK(sqlite3_close(db) == SQLITE_OK); | ||
|
|
||
| CHECK(sqlite3_open(argv[1], &db) == SQLITE_OK); | ||
| expect_int(db, "SELECT journal_mode = 'wal' FROM pragma_journal_mode", 1); | ||
| expect_int(db, "SELECT count(*) FROM audit", 1); | ||
| expect_int(db, "SELECT integrity_check = 'ok' FROM pragma_integrity_check", 1); | ||
| CHECK(sqlite3_close(db) == SQLITE_OK); | ||
| puts("SQLite SQL and persistence checks passed"); | ||
| return 0; | ||
| } |
This file contains hidden or 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,58 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| cd "$SCRIPT_DIR/repo" | ||
|
|
||
| { | ||
| TARGET_DIR=$(cargo ${TOOLCHAIN:+"$TOOLCHAIN"} metadata --no-deps --format-version 1 \ | ||
|
thedataking marked this conversation as resolved.
|
||
| | jq -er .target_directory) | ||
| RUST_ARCHIVE="$TARGET_DIR/release/librepo.a" | ||
| if [[ ! -f "$RUST_ARCHIVE" ]]; then | ||
| echo "Rust archive not found: $RUST_ARCHIVE" >&2 | ||
| exit 1 | ||
| fi | ||
| WORK_DIR=$(mktemp -d) | ||
| trap 'rm -rf "$WORK_DIR"' EXIT | ||
|
|
||
| # Ask rustc for the native dependencies of this static archive. | ||
| RUSTFLAGS="${RUSTFLAGS:--Awarnings}" cargo ${TOOLCHAIN:+"$TOOLCHAIN"} rustc \ | ||
| --release --lib --color never -- --print native-static-libs \ | ||
| 2>&1 | tee "$WORK_DIR/native-libs.log" | ||
| LIBS=$(sed -n 's/^note: native-static-libs: //p' "$WORK_DIR/native-libs.log") | ||
| if [[ -z "$LIBS" ]]; then | ||
| echo "rustc did not report native static libraries" >&2 | ||
| exit 1 | ||
| fi | ||
| read -r -a RUST_LIBS <<< "$LIBS" | ||
|
|
||
| # Explicit archives keep both C callers from picking up a system SQLite. | ||
| for implementation in native rust; do | ||
| if [[ "$implementation" == native ]]; then | ||
| archive="$SCRIPT_DIR/repo/libsqlite3.a" | ||
| libs=(-lm -ldl -lpthread) | ||
| else | ||
| archive="$RUST_ARCHIVE" | ||
| libs=("${RUST_LIBS[@]}") | ||
| fi | ||
| cc -O2 -I. "$SCRIPT_DIR/smoke.c" "$archive" "${libs[@]}" \ | ||
| -o "$WORK_DIR/smoke-$implementation" | ||
| cc -O2 -DSQLITE_ENABLE_RTREE -I. test/speedtest1.c "$archive" "${libs[@]}" \ | ||
| -o "$WORK_DIR/$implementation" | ||
| "$WORK_DIR/smoke-$implementation" "$WORK_DIR/smoke-$implementation.db" | ||
| done | ||
|
|
||
| # Only these workloads hash result rows. JSON and numeric parsing have | ||
| # explicit assertions in smoke.c instead of comparisons of empty hashes. | ||
| for testset in main cte orm fp rtree; do | ||
| for implementation in native rust; do | ||
| "$WORK_DIR/$implementation" --size 1 --verify --testset "$testset" \ | ||
| "$WORK_DIR/$implementation.db" \ | ||
| | tee "$WORK_DIR/$implementation.out" | ||
| # Timings differ; the result count and verification hash must match. | ||
| grep '^Verification Hash: ' "$WORK_DIR/$implementation.out" \ | ||
| > "$WORK_DIR/$implementation.hash" | ||
| done | ||
| diff -u "$WORK_DIR/native.hash" "$WORK_DIR/rust.hash" | ||
| done | ||
| } 2>&1 | tee "$SCRIPT_DIR/$(basename "$0").log" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.