Repository navigation
test(integration-tests): run report scenarios on SQLite, MySQL and D1 across ports - #421
Conversation
…oss the ports The FR-044 report scenarios ran on Postgres in every port and on SQLite in TypeScript only. They now also run where a port's runtime has the engine: - Persistence report-* scenarios: TypeScript on SQLite, MySQL 8.4 and D1's local runtime (Miniflare, `meta migrate --dialect d1`); C# (EF Core, Pomelo) and Kotlin (Exposed) on SQLite and MySQL; Java (OMDB) on MySQL. - api-contract report/ sub-corpus: TypeScript on SQLite, MySQL and D1; C# on SQLite and MySQL, against the real views. - Cube lane: a second live file runs the MySQL path against a real MySQL 8.4 holding the report views buildReportViews lowers, comparing each report's Cube query with SELECT * from its view. Each engine executes an artifact TypeScript produced (canonical/schema.sqlite.sql from meta migrate, canonical/schema.mysql.sql from the adopter tables plus buildReportViews, and report/ equivalents), held equal to its generator by a test. Postgres expectations are unchanged; engine spelling is mapped on the actual side, and report-relative-date gains a per-engine seed (seed-data-engine). Stated limitations, recorded in docs/CONFORMANCE.md and docs/features/reporting.md: Java's OMDB has no SQLite driver and Python's runtime ships only a Postgres driver; the Java/Kotlin/Python api-contract report lane serves rows behind the repository seam, so no engine reaches it. Also removes two stray tmp-* test output directories that were committed under codegen-ts/test and made the workspace typecheck fail, and gives the MySQL test files' afterAll hook a real timeout.
…nd MySQL lanes; key the D1 binding per server The SQLite and D1 lanes split a script on every ';', so a seed value holding one would break there and pass on MySQL. All three lanes now use the end-of-line splitter from sql-script.ts. The D1 api-contract server hands its binding to the generated db module through a per-server global key instead of one shared name.
…port lanes Folds duplicated engine names, corpus paths and schema-reading helpers in the SQLite, MySQL and D1 report lanes into one definition per language. No behaviour change.
|
Notes for the reviewer. Gate runs: 1 no-mistakes run (review fix round 1, then test and document gates answered with local evidence). Cube MySQL: this takes the smaller option. A second live file runs Cube against a real MySQL 8.4 holding the report views Stated limitations (documented in Port defects: none found. The C# SQLite/MySQL lanes use a view-only test Also in this PR: two stray Local evidence on the final head (all green): TypeScript |
…pora (#423) * test(reporting): cover more FR-044 features in the canonical test model and every port Adds 12 reports to the canonical fitness model (and a Session entity) and grows the api-contract report corpus to four entities and nine reports, so the report corpora exercise vocabulary they did not before: multi-hop and self-referencing dimensions, day/quarter/year/hour/date time grains, min/max/avg/count-distinct over more column types, negative and decimal measure defaults over an empty table, measure filters on the remaining operators, segment and report filters combining like/in/or/ne, a two-hop @spine, and a TPH base as @from. - persistence-conformance: 10 new report query scenarios, all five ports - api-contract-conformance/report: 6 new scenarios (22 in all), all five ports - cube-model goldens and the live Cube lane cover the new reports - committed derived artifacts regenerated with the repo's own tools - test-harness fixes only: date and uuid operand coercion in the Java and C# runners, `like` and uuid in the seam lanes' in-memory report repositories, and the SQLite convergence test's known inet residue - removes a stray generated temp directory committed in #420, which turned the ts build + typecheck gate red on main No product port defect was found, so no CHANGELOG entry. * test(reporting): run the new report scenarios on SQLite, MySQL and D1 and the MySQL Cube lane The engine lanes added in #421 now run all 19 report scenarios. The MySQL adopter tables gain the nodes, sessions, measurements, auths and all_types tables, the api-contract MySQL schema gains the disputed/category/sku columns, and the MySQL Cube lane covers all 21 served reports. A naive timestamp keeps its wall clock without a zone suffix on the SQLite and D1 wire form; two scenarios no longer depend on engine-specific NULL ordering or on a Postgres-only clock expression. * test(integration-tests-kotlin): coerce a date filter operand on SQLite and read min/max timestamps there The Kotlin SQLite lane spells a DATE column's SQL type as TEXT, so the string operand of a date filter reached Exposed uncoerced; key the coercion on the column type as well. The report-time-min-max seed now spells its timestamps in the form the SQLite driver's date_string_format parses (fixture seed only; expect blocks unchanged).
Intent
Before 1.1.0-rc.3, close three reporting test gaps ("Yeah do 1, 2, 3"): 1. Databases other than Postgres outside TypeScript: Java, Kotlin, C# and Python never run the report scenarios on SQLite (or MySQL); only TypeScript does. 2. MySQL: no persistence or api-contract report scenarios run on MySQL in any port; only TypeScript's own @spine/@default view value tests read MySQL views, and the Cube MySQL output is golden-compared, never executed. 3. D1: no run against a real Cloudflare D1 (or its local runtime); it is covered only as SQLite. Context: report SQL is produced by TypeScript only (migrate creates the views on Postgres, SQLite and D1; MySQL view bodies come from buildReportViews per docs/recipes/mysql.md). The other ports read the views TypeScript produced and byte-match report-shapes.json. A parallel task (mo-1-1-0-report-coverage) is adding ~10 persistence and ~6 api-contract report scenarios; rebase onto it if it lands first so the new lanes run every scenario.
What Changed
QueryScenarioSqlite*runners and tests), and on MySQL in TypeScript, Java, Kotlin and C# (new MySQL schema, report views,MySqlContainer/MySqlDatabaseandquery-scenario-mysql.ts,api-contract-report-mysql-server.ts).query-scenario-d1.ts,d1-kysely.ts) that runs the report scenarios against the local D1 runtime, and a live Cube lane for the MySQL model (cube-model-mysql.live.ts,cube-live-support.ts), with the MySQL and SQLite report and canonical schema artifacts added underfixtures/.tmp-*codegen-ts test output directories that were committed by mistake, and update the reporting, Cube export, MySQL recipe and conformance docs to match the new lanes.Risk Assessment
✅ Low: The fix round fixes all three selected findings correctly and adds no new defects; it only touches test infrastructure, and the Python and Java engine scope-down was accepted earlier as a documented limitation.
Testing
Baseline ts-fast/ts-unit already green. Drove the new report-scenario lanes live: SQLite and D1 (miniflare local workerd) and MySQL (Docker) all pass, plus engine-wire and schema-artifact-engines. Full server bun suite did not finish within the time limit (no failures seen in partial output). The C#, Java and Kotlin lanes that the review fixes touched were not run here, so their MySQL changes are unverified live.
Evidence: full server bun test log (partial, timed out)
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 4 issues found → auto-fixed ✅
docs/features/reporting.md:644- The intent requires closing gap 1: "Java, Kotlin, C# and Python never run the report scenarios on SQLite (or MySQL); only TypeScript does." The change closes it for C# and Kotlin on both engines and for Java on MySQL only. Python gets no non-Postgres lane at all, and Java gets no SQLite lane. Both are written up as 'stated limitations, not gaps' (reporting.md:643-644:| Java (OMDB) | ✓ | not run: OMDB has no SQLite driver |and| Python | ✓ | not run: the runtime ships a Postgres driver only (pg8000) | not run: same |, plus the matching CONFORMANCE.md row). The reasoning holds up in the source: Python's ObjectManager hardcodes%splaceholders and ships only PostgresDriver, and OMDB has no SQLite driver. Still, this is scoping down a named requirement. Ask the user whether to accept this narrower scope. The alternative is a minimal Python driver (stdlib sqlite3 and/or PyMySQL behind the DB-API seam) and a Java SQLite lane (GenericSQLDriver plus sqlite-jdbc). Either one extends the runtime surface, so the remedy needs the user's authorization.server/java/integration-tests-kotlin/src/test/kotlin/com/metaobjects/integration/kotlin/QueryScenarioRunner.kt:154-dropMysqlSchemarunsSHOW FULL TABLES, setsFOREIGN_KEY_CHECKS = 0, and drops every view and table in the connected database. WithMETAOBJECTS_TEST_MYSQL_URLset (documented in MySqlContainer.kt), the Kotlin lane wipes every table and view in that database, including ones it did not create. The repo states the opposite rule in report-views-mysql.test.ts: drop 'Only the views and tables THIS file creates, by name: METAOBJECTS_TEST_MYSQL_URL may point at a shared database'. The Java and TS runners in this same change follow that rule: they parseCREATE VIEW/TABLEnames from the schema artifact and drop only those. Fix: drop only the names incanonical/schema.mysql.sql, views first, then tables in reverse order, as Java'sdropSchemadoes.server/csharp/MetaObjects.IntegrationTests/QueryScenarioMySqlTests.cs:23- Each C# MySQL theory case starts its own mysql:8.4 Testcontainers container: 9 persistence report cases here plus 16 api-contract cases (ApiContractReportConformanceTest.cs:56), so about 25 MySQL cold starts per run. CI has no shared MySQL sidecar, unlike Postgres (METAOBJECTS_TEST_PG_URL). The TS, Java and Kotlin MySQL lanes each start one server per file. MySqlDatabase already has a mode that creates a fresh, uniquely named database per scenario on an existing server. Fix: start one container in an xUnit class/collection fixture and give each scenario its own database through that mode. This removes several minutes of container startup per lane run.server/csharp/MetaObjects.IntegrationTests/Runner/MySqlDatabase.cs:39- C# parsesMETAOBJECTS_TEST_MYSQL_URLas an ADO.NET connection string. TypeScript reads the same variable asmysql://user:pass@host:port/db, and Java/Kotlin read it asjdbc:mysql://host:port/db. integration-test.sh runs every port in one environment, so setting the variable for one port makes another fail at startup. For example, MySqlConnectionStringBuilder rejects amysql://URL. Fix: accept themysql://URL form in C# (convert it to a MySqlConnectionStringBuilder), or use a C#-specific variable name.🔧 Fix applied.
✅ Re-checked - no issues remain.
cd server/typescript && bun test) did not complete within 1500s; result unknown beyond no failures in partial output. Re-run with a longer timeout to confirm.scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchainscd server/typescript/packages/integration-tests && bun test test/query-sqlite.test.ts test/query-d1.test.ts test/engine-wire.test.ts test/schema-artifact-engines.test.ts test/api-contract-report-sqlite.test.ts -> 72 pass, 0 failcd server/typescript/packages/integration-tests && bun test test/query-mysql.test.ts test/api-contract-report-mysql.test.ts test/report-views-mysql.test.ts -> 44 pass, 0 fail (Docker testcontainers MySQL)cd server/typescript && bun test (full server suite, regression) -> killed by 1500s timeout, log at ~/.no-mistakes/evidence/01M4KX1RW3QCXBNS3DKW7Z2AVM/full-server-bun-test.log; no '(fail)' lines before cutoff, but run not completeddocs/features/reporting.md:644- Python and Java SQLite/MySQL scope: confirm narrower scope is accepted. Python runs report scenarios on Postgres only; Java has no SQLite lane. Docs call these stated limitations. The user accepted this in review; confirm it stands for the release.✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.