feat(bbmri-miabis): add MIABIS-on-FHIR + BBMRI.de mixed-node E2E test#4
feat(bbmri-miabis): add MIABIS-on-FHIR + BBMRI.de mixed-node E2E test#4a-tuerk wants to merge 5 commits intosamply:mainfrom
Conversation
Adds a new `bbmri-miabis/` integration test folder that validates the
MIABIS CQL flavour (focus PR #341) alongside a standard BBMRI.de node.
Stack:
- focus-miabis (CQL_FLAVOUR=miabis, localbuild) + blaze-miabis + MIABIS test bundle
- focus-bbmri (localbuild with rustyspot 0.2.x compat fix) + blaze-bbmri + BBMRI.de test bundle
- spot (rustyspot:latest 0.2.2) fans queries out to both nodes via Beam
Test script (test.sh):
- Uses rustyspot 0.2.x two-step API: POST /beam (submit) + GET /beam/{id} (SSE)
- 8 scenarios: 5 mixed-node patient counts + 3 diagnosis scenarios
- All 8 pass (verified 2026-03-20)
Note: both focus instances use localbuild because rustyspot 0.2.x changed
the Beam task body format (raw Operation JSON instead of base64-wrapped
Language struct); the compat fix falls back to parsing raw Operation JSON
when base64 decode fails.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the old 5-scenario single-node description with the current 8-scenario mixed-node (MIABIS-on-FHIR + BBMRI.de) setup, including both test bundles, the tester service, and the rustyspot 0.2.x note. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
timakro
left a comment
There was a problem hiding this comment.
Thanks for the PR. I hadn't had the chance to test it yet but the approach looks good. I have one comment that needs to be addressed.
bbmri-miabis/test.sh
Outdated
| query_str=$(printf '%s' "${ast_obj}" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))") | ||
| # Step 1: submit the query | ||
| curl -sf -m 10 \ | ||
| -X POST "${SPOT_URL}/beam" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d "{\"query\":${query_str},\"id\":\"${id}\"}" \ |
There was a problem hiding this comment.
Spot expects a double base64-encoded request, which is admittedly a bit confusing. See this example request:
{"id":"e015565c-af71-4567-900e-4aee16de8a21","query":"eyJsYW5nIjoiYXN0IiwicGF5bG9hZCI6ImV5SmhjM1FpT25zaWIzQmxjbUZ1WkNJNklrOVNJaXdpWTJocGJHUnlaVzRpT2x0ZGZTd2lhV1FpT2lJNE56YzJZelZoWkMxa05Ua3lMVFExWVRBdFlqZ3hNUzA1WWpZME5UazBNVGsyWmpFaWZRPT0ifQ=="}
The query field is base64-encoded, and if you decode that you get another JSON object with a payload field which contains the base64-encoded (again) AST.
Encode your request like that and you can remove the special request handling you added to Focus.
Also better use jq and base64 instead of python.
There was a problem hiding this comment.
Ah, the python thing was in my understanding to format the json object as an escaped json string (hence my comment below). I missed the double b64, hence, support your suggestion of jq (which can do b64 encoding internally, if I recall correctly. So no need to use the external base64 command)
TKussel
left a comment
There was a problem hiding this comment.
Thank you for branching out the integration tests of the original Focus PR to Headlights. While I can't comment on Headlight's conventions, I found mainly "taste" things regarding the docker compose setup.
Spot expects query=base64({"lang":"ast","payload":base64(AST)}).
The previous approach (Python JSON-string escaping) sent a raw JSON
object through the Spot→Beam path, which focus could not decode.
Switch to jq + base64 (no python dependency). Also replace the
grep+sed pipeline with sed -n for SSE line filtering, and use
bracket notation for test-data-loader entrypoints.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The inner payload for Spot must decode to {"ast":{...},"id":"..."} as
expected by focus parse_blaze_query_payload_ast, not bare AST JSON.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use http://spot:8055 (Docker DNS) in test.sh instead of localhost - Remove network_mode: host from tester (not needed with Docker DNS) - Consolidate local actual declaration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Thank you both for the detailed reviews! Here's a summary of what was addressed:
All 8 scenarios pass with the updated encoding. |
Summary
bbmri-miabis/with a compose stack running a two-node federation:one MIABIS-on-FHIR focus node (
CQL_FLAVOUR=miabis) and one BBMRI.de focus nodetest-bundle.json,test-bundle-bbmri.json)and a
testerservice running 8 bash scenariosWhat is tested
Mixed-node scenarios (totals across both sites):
storage_temperature = temperatureRoom→ 2storage_temperature = temperatureLN→ 3sample_kind = blood-plasma→ 2sample_kind = whole-blood→ 2Diagnosis scenarios (BBMRI.de node unaffected by MIABIS workarounds):
diagnosis = C34→ 1 (MIABIS only)diagnosis = C50→ 1 (BBMRI.de only)diagnosis = C61→ 1 (BBMRI.de only)Dependency
Requires samply/focus#342 (
Flavour::Miabis,CQL_FLAVOURenv var).Once that PR merges and a new focus image is published, the localbuild
tags will be replaced with the real tag.