mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 17:05:36 +01:00
update test
This commit is contained in:
12
Makefile
12
Makefile
@@ -66,7 +66,7 @@ uv-sync:
|
||||
uv sync --all-packages
|
||||
.PHONE: uv-sync
|
||||
|
||||
test: limbo uv-sync test-compat test-vector test-sqlite3 test-shell test-extensions test-memory test-writes
|
||||
test: limbo uv-sync test-compat test-vector test-sqlite3 test-shell test-extensions test-memory test-write test-update
|
||||
.PHONY: test
|
||||
|
||||
test-extensions: limbo uv-sync
|
||||
@@ -102,9 +102,13 @@ test-memory:
|
||||
SQLITE_EXEC=$(SQLITE_EXEC) ./testing/cli_tests/memory.py
|
||||
.PHONY: test-memory
|
||||
|
||||
test-writes: limbo uv-sync
|
||||
SQLITE_EXEC=$(SQLITE_EXEC) uv run --project limbo_test test-writes
|
||||
.PHONY: test-writes
|
||||
test-write: limbo uv-sync
|
||||
SQLITE_EXEC=$(SQLITE_EXEC) uv run --project limbo_test test-write
|
||||
.PHONY: test-write
|
||||
|
||||
test-update: limbo uv-sync
|
||||
SQLITE_EXEC=$(SQLITE_EXEC) uv run --project limbo_test test-update
|
||||
.PHONY: test-update
|
||||
|
||||
clickbench:
|
||||
./perf/clickbench/benchmark.sh
|
||||
|
||||
135
testing/cli_tests/update.py
Normal file
135
testing/cli_tests/update.py
Normal file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
from cli_tests.test_limbo_cli import TestLimboShell
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
sqlite_flags = os.getenv("SQLITE_FLAGS", "-q").split(" ")
|
||||
|
||||
|
||||
class UpdateTest(BaseModel):
|
||||
name: str
|
||||
db_schema: str = "CREATE TABLE test (key INTEGER, t1 BLOB, t2 INTEGER, t3 TEXT);"
|
||||
blob_size: int = 1024
|
||||
vals: int = 1000
|
||||
updates: int = 1
|
||||
db_path: str = "testing/update.db"
|
||||
|
||||
def init_db(self):
|
||||
with TestLimboShell(
|
||||
init_commands="",
|
||||
exec_name="sqlite3",
|
||||
flags=f"{self.db_path}",
|
||||
) as sqlite:
|
||||
sqlite.execute_dot(f".open {self.db_path}")
|
||||
zero_blob = "0" * self.blob_size * 2
|
||||
t2_val = "1"
|
||||
t3_val = "2"
|
||||
stmt = [self.db_schema]
|
||||
stmt = stmt + [
|
||||
f"INSERT INTO test (key, t1, t2, t3) VALUES ({i} ,zeroblob({self.blob_size}), {t2_val}, {t3_val});"
|
||||
for i in range(self.vals)
|
||||
]
|
||||
stmt.append("SELECT count(*) FROM test;")
|
||||
|
||||
sqlite.run_test(
|
||||
"Init Update Db in Sqlite",
|
||||
"".join(stmt),
|
||||
f"{self.vals}",
|
||||
)
|
||||
|
||||
stmt = [
|
||||
f"SELECT hex(t1), t2, t3 FROM test LIMIT 1 OFFSET {i};"
|
||||
for i in range(self.vals)
|
||||
]
|
||||
|
||||
expected = [f"{zero_blob}|{t2_val}|{t3_val}" for _ in range(self.vals)]
|
||||
sqlite.run_test(
|
||||
"Check Values correctly inserted in Sqlite",
|
||||
"".join(stmt),
|
||||
"\n".join(expected),
|
||||
)
|
||||
|
||||
def run(self, limbo: TestLimboShell):
|
||||
limbo.execute_dot(f".open {self.db_path}")
|
||||
# TODO blobs are hard. Forget about blob updates for now
|
||||
# one_blob = ("0" * ((self.blob_size * 2) - 1)) + "1"
|
||||
# TODO For now update just on one row. To expand the tests in the future
|
||||
# use self.updates and do more than 1 update
|
||||
t2_update_val = "123"
|
||||
stmt = f"UPDATE test SET t2 = {t2_update_val} WHERE key = {0};"
|
||||
limbo.run_test(self.name, stmt, "")
|
||||
|
||||
def test_compat(self):
|
||||
print("Testing in SQLite\n")
|
||||
|
||||
with TestLimboShell(
|
||||
init_commands="",
|
||||
exec_name="sqlite3",
|
||||
flags=f"{self.db_path}",
|
||||
) as sqlite:
|
||||
sqlite.execute_dot(f".open {self.db_path}")
|
||||
zero_blob = "0" * self.blob_size * 2
|
||||
|
||||
t2_val = "1"
|
||||
t2_update_val = "123"
|
||||
t3_val = "2"
|
||||
stmt = []
|
||||
stmt.append("SELECT count(*) FROM test;")
|
||||
|
||||
sqlite.run_test(
|
||||
"Check all rows present in Sqlite",
|
||||
"".join(stmt),
|
||||
f"{self.vals}",
|
||||
)
|
||||
|
||||
stmt = [
|
||||
f"SELECT hex(t1), t2, t3 FROM test LIMIT 1 OFFSET {i};"
|
||||
for i in range(self.vals)
|
||||
]
|
||||
|
||||
expected = [
|
||||
f"{zero_blob}|{t2_val}|{t3_val}"
|
||||
if i != 0
|
||||
else f"{zero_blob}|{t2_update_val}|{t3_val}"
|
||||
for i in range(self.vals)
|
||||
]
|
||||
sqlite.run_test(
|
||||
"Check Values correctly updated in Sqlite",
|
||||
"".join(stmt),
|
||||
"\n".join(expected),
|
||||
)
|
||||
print()
|
||||
|
||||
|
||||
def cleanup(db_fullpath: str):
|
||||
wal_path = f"{db_fullpath}-wal"
|
||||
shm_path = f"{db_fullpath}-shm"
|
||||
paths = [db_fullpath, wal_path, shm_path]
|
||||
for path in paths:
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
|
||||
|
||||
def main():
|
||||
test = UpdateTest(name="Update 1 column", vals=1)
|
||||
db_path = test.db_path
|
||||
try:
|
||||
test.init_db()
|
||||
# Use with syntax to automatically close shell on error
|
||||
with TestLimboShell("") as limbo:
|
||||
test.run(limbo)
|
||||
|
||||
test.test_compat()
|
||||
|
||||
except Exception as e:
|
||||
print(f"Test FAILED: {e}")
|
||||
cleanup(db_path)
|
||||
exit(1)
|
||||
# delete db after every compat test so we we have fresh db for next test
|
||||
cleanup(db_path)
|
||||
print("All tests passed successfully.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -61,12 +61,12 @@ class InsertTest(BaseModel):
|
||||
lambda res: self.db_schema in res,
|
||||
"Tables created by previous Limbo test exist in db file",
|
||||
)
|
||||
# TODO Have some pydantic object be passed to this function with common fields
|
||||
# To extract the information necessary to query the db in sqlite
|
||||
# The object should contain Schema information and queries that should be run to
|
||||
# test in sqlite for compatibility sakes
|
||||
sqlite.run_test_fn(
|
||||
"SELECT count(*) FROM test;",
|
||||
lambda res: res == str(self.vals * 2),
|
||||
"Counting total rows inserted",
|
||||
)
|
||||
print()
|
||||
pass
|
||||
|
||||
|
||||
def validate_with_expected(result: str, expected: str):
|
||||
@@ -75,7 +75,7 @@ def validate_with_expected(result: str, expected: str):
|
||||
|
||||
# TODO no delete tests for now
|
||||
def blob_tests() -> list[InsertTest]:
|
||||
tests: list[dict] = []
|
||||
tests: list[InsertTest] = []
|
||||
|
||||
for vals in range(0, 1000, 100):
|
||||
tests.append(
|
||||
@@ -121,28 +121,6 @@ def blob_tests() -> list[InsertTest]:
|
||||
return tests
|
||||
|
||||
|
||||
def test_sqlite_compat(db_fullpath: str, schema: str):
|
||||
with TestLimboShell(
|
||||
init_commands="",
|
||||
exec_name="sqlite3",
|
||||
flags=f"{db_fullpath}",
|
||||
) as sqlite:
|
||||
sqlite.run_test_fn(
|
||||
".show",
|
||||
lambda res: f"filename: {db_fullpath}" in res,
|
||||
"Opened db file created with Limbo in sqlite3",
|
||||
)
|
||||
sqlite.run_test_fn(
|
||||
".schema",
|
||||
lambda res: schema in res,
|
||||
"Tables created by previous Limbo test exist in db file",
|
||||
)
|
||||
# TODO Have some pydantic object be passed to this function with common fields
|
||||
# To extract the information necessary to query the db in sqlite
|
||||
# The object should contain Schema information and queries that should be run to
|
||||
# test in sqlite for compatibility sakes
|
||||
|
||||
|
||||
def cleanup(db_fullpath: str):
|
||||
wal_path = f"{db_fullpath}-wal"
|
||||
shm_path = f"{db_fullpath}-shm"
|
||||
@@ -158,7 +136,7 @@ def main():
|
||||
db_path = test.db_path
|
||||
try:
|
||||
# Use with syntax to automatically close shell on error
|
||||
with TestLimboShell() as limbo:
|
||||
with TestLimboShell("") as limbo:
|
||||
limbo.execute_dot(f".open {db_path}")
|
||||
test.run(limbo)
|
||||
|
||||
@@ -10,9 +10,10 @@ dependencies = [
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
test-writes = "cli_tests.writes:main"
|
||||
test-write = "cli_tests.write:main"
|
||||
test-shell = "cli_tests.cli_test_cases:main"
|
||||
test-extensions = "cli_tests.extensions:main"
|
||||
test-update = "cli_tests.update:main"
|
||||
|
||||
[tool.uv]
|
||||
package = true
|
||||
|
||||
Reference in New Issue
Block a user