Live integration tests¶
The live suite runs the same F# tests against a real DataHub on .NET, Node.js, and Python. Every request is read-only. Unit tests and packaged documentation samples use controlled responses; passing those does not prove that a deployed DataHub's package storage and redirect configuration work.
Run the suite¶
Set these environment variables before running a build target:
| Variable | Purpose |
|---|---|
DATAHUB_TEST_URL |
DataHub root, such as https://gitdev.nfdi4plants.org. |
DATAHUB_TEST_TOKEN |
Personal access token permitted to read the selected project and packages. |
DATAHUB_TEST_PROJECT |
Positive numeric project ID for repository, issue, merge request, package-list, and validation reads. |
DATAHUB_TEST_REQUIRED |
Set to true to fail if URL, authentication, or project configuration is missing. The integration workflow always sets this. |
DATAHUB_TEST_ANONYMOUS |
Set to true explicitly to exercise public resources without authentication. Overrides the token locally; the workflow does not enable it. |
DATAHUB_TEST_ROCRATE_PROJECT |
Optional positive project ID whose isa_arc_json/0.0.1/arc-ro-crate-metadata.json export must be downloadable. Can differ from the general test project. |
DATAHUB_TEST_FIXTURE |
Optional dataplant-dev to require the canonical fixture described below. Leave unset for other projects. |
With no local configuration the suite skips. Invalid explicit configuration
fails, and required mode cannot silently pass with zero tests. The RO-Crate
cases run only when their project is configured; they check parsed JSON for
@context and a nonempty @graph whose entries have @id. These are structural
checks, not full RO-Crate semantic validation. A missing export, denied access, HTML
login page, or download error fails the test.
$env:DATAHUB_TEST_URL = "https://gitdev.nfdi4plants.org"
$env:DATAHUB_TEST_ANONYMOUS = "true"
$env:DATAHUB_TEST_PROJECT = "38"
$env:DATAHUB_TEST_ROCRATE_PROJECT = "38"
$env:DATAHUB_TEST_REQUIRED = "true"
.\build.cmd RunIntegrationTestsAll
Use ./build.sh on Linux/macOS. Individual targets are
RunIntegrationTestsDotNet, RunIntegrationTestsJavaScript, and
RunIntegrationTestsPython. Python needs uv sync and Python 3.12 or later.
For a download-only smoke test, omit DATAHUB_TEST_PROJECT and
DATAHUB_TEST_REQUIRED; instance listing and the configured download cases run.
GitHub Actions setup¶
The separate integration workflow
runs weekly and on demand, outside pull-request CI. All three jobs use the
integration_tests GitHub Environment. Store DATAHUB_TEST_TOKEN as an
environment secret and the URL/project/RO-Crate/fixture settings as environment
variables. The workflow sets required mode itself. A token secret's existence
does not prove its validity; an authenticated run checks that.
If GitHub reports disabled_inactivity, an administrator must re-enable the
workflow in Actions, or run gh workflow enable integration.yml, then dispatch
it. See GitHub's workflow enablement documentation.
Check the case counts and selected configuration as well as the green badge.
Issue/merge-request detail cases require at least one corresponding resource;
validation detail cases require populated cqc results. Empty fixtures do not
exercise those paths.
Make Git dev reproduce package redirects¶
A direct 200 package response tests downloading but cannot catch the original
HTTPX 302 failure. Prepare a stable ARC export in a fixture project, enable
its package registry, and ensure its file is stored in external object storage.
The package coordinates must be:
GET /api/v4/projects/<id>/packages/generic/isa_arc_json/0.0.1/arc-ro-crate-metadata.json
For GitLab's consolidated object-storage configuration, configure the packages
bucket and use proxy_download = false for packages so clients retrieve files
from the storage service. Existing local package files must be migrated or the
fixture republished into object storage. The exact configuration depends on the
GitLab version/deployment; use its matching object storage documentation
and package storage migration instructions.
The observed direct 200 alone does not identify whether the current dev
server uses local storage or proxies an object store.
Check the first response with redirects disabled: it must be a redirect with
a Location pointing to a different origin, and that destination must be
reachable from GitHub runners with a valid TLS certificate. For a public
fixture, this probe prints only the status and destination origin, keeping
signed URL query parameters out of logs:
import os
from urllib.parse import urljoin, urlsplit
import httpx
base = os.environ["DATAHUB_TEST_URL"].rstrip("/")
project = int(os.environ["DATAHUB_TEST_ROCRATE_PROJECT"])
url = f"{base}/api/v4/projects/{project}/packages/generic/isa_arc_json/0.0.1/arc-ro-crate-metadata.json"
response = httpx.get(url, follow_redirects=False, timeout=30)
assert response.status_code in (301, 302, 303, 307, 308)
target = urlsplit(urljoin(url, response.headers["location"]))
source = urlsplit(url)
def origin(parts):
return parts.scheme, parts.hostname, parts.port or (443 if parts.scheme == "https" else 80)
assert origin(target) != origin(source)
print(response.status_code, target.scheme, target.hostname, target.port)
Set DATAHUB_TEST_ROCRATE_PROJECT in the GitHub environment and run all three
integration jobs after establishing that redirect. Successful downloads prove
the deployed redirect path works. They do not prove that credentials were
removed: an object store can ignore and accept leaked GitLab headers.
To prove non-forwarding against Git dev, the receiving storage endpoint or a
controlled redirect receiver must record presence only, or reject requests
containing PRIVATE-TOKEN, JOB-TOKEN, or Authorization. Correlate a test
request with that observation. Never record token values or signed URL query
strings. The local transport regression tests provide deterministic header
assertions; the shared live download suite cannot see the remote receiver's
headers. Testing each authentication mode live also requires valid PAT,
OAuth, and GitLab job credentials; the GitHub suite currently uses a PAT.
The live JavaScript suite runs in Node. Browser coverage additionally needs appropriate CORS behavior and browser tests; Node success does not establish browser redirect support.
RunTestsBrowser installs the packed npm artifact and runs native fetch in
Chromium and Firefox, each with native ES modules, Vite development, and Vite
production. Its local authenticated package fixture requires a valid dummy
OAuth bearer token before issuing a redirect; missing and incorrect tokens
must return 401 without reaching storage. Same-origin destinations require
the token, while cross-origin destinations and later return hops reject all
GitLab credential headers. Successful cases verify exact UTF-8 RO-Crate content
through both download APIs and files saved by the documented browser helper.
These tests establish supported bearer-authenticated browser downloads against
controlled servers; they do not validate deployed DataHub credentials or CORS.
The separate browser cases for PRIVATE-TOKEN and JOB-TOKEN still require
redirects to be blocked, as described in RO-Crate downloads.
Optional canonical content fixture¶
DATAHUB_TEST_FIXTURE=dataplant-dev requires the public
integration_tests/test_1 project on https://gitdev.nfdi4plants.org, named
Test_1, with protected default branch main. Its README.md must contain
Hello DataHubClient!; issue IID 1 must be open, titled Test_Issue_1, described
as This is an issue for DataHubClient integration tests!, and labeled
integration_tests. Point DATAHUB_TEST_PROJECT at that project's actual ID.
A missing or different project now fails instead of silently passing the
fixture cases. These content assertions are independent of the RO-Crate
fixture, which can use another project.
Audit on 2026-10-14¶
- The last recorded integration run
was on September 28, with 19 tests executed and passed on each target at
commit
4826e22c25101b6a545aeeb732fa4ae2eb92cb81. These included only package listing, not package downloads. - GitHub reported the workflow as
disabled_inactivity; no October 5 or October 12 runs were listed. Re-enabling it is still an administrator action. - The GitHub environment contained the dev URL, project ID
38, and a token secret. Secret contents are unavailable through GitHub's read API, so this audit could not validate the stored token. - Anonymous reads identified project
38asschneider.kev/test, withmainandcqcbranches, no issues or merge requests, and the standard RO-Crate package. The canonical fixture path returned404anonymously. - The previous suite selected canonical fixture tests by hostname, then silently skipped their assertions for a different project. Those cases could appear as passed without checking fixture content. Fixture selection is now explicit and a mismatch fails.
- The dev RO-Crate returned direct
200, with 12 graph entities. This fixture can exercise download parsing now, but needs an actual cross-origin storage redirect to reproduce the production failure. - The updated suite passed anonymously on all three targets against dev project 38 (17 cases per target, including both downloads). The empty issue and merge-request lists still leave their detail paths unexercised. Download-only runs also passed on all targets against production project 1040 (three cases each), whose export redirects to object storage. These runs do not validate the GitHub token or the optional canonical fixture.
- No remote workflow, token, project, package, or storage configuration was changed during the audit.