Component pipeline
gtool test runs a microservice's component tests against an isolated, disposable
environment:
- Mocks — every service in
third-party.mocksis started and seeded (Mock services). - App — when
app-config.docker-imageis set, the application under test is started as a container (Application under test). - Tests — the Karate launcher runs the features in
test-config.features-path. - Report — the Karate HTML report is written to
test-config.reports-path. - Cleanup — the app and the mocks are stopped in reverse order.
Cleanup always runs: on success, on a failed phase and on Ctrl-C or SIGTERM. It uses a fresh context, so a cancelled run still tears everything down.
The command exits non-zero when a phase fails or any test fails, so it can gate a CI job directly.
The Karate launcher
Tests run in the gtool/test-launcher-back:latest image, built from
test-launcher/
with make test-launcher-image (see Installation);
it is not published to a registry. For each run gtool:
- mounts
features-pathread-only andreports-pathread-write into the container; - runs it on the host network, so features reach the app and the mocks on
localhost:<port>; - passes
TAGSfromtest-config.tags, andPUBSUB_EMULATOR_HOSTwhen thepubsubmock is configured; - passes this run's values:
GTOOL_APP_URL,GTOOL_APP_PORT,GTOOL_APP_HOST_PORT, oneGTOOL_<SERVICE>_<PORT_KEY>per port key of every enabled mock, defaults included (GTOOL_POSTGRESQL_PORT,GTOOL_KAFKA_DOCKER_PORT,GTOOL_COUCHBASE_ADMIN_PORT, ...), andGTOOL_<SERVICE>_{USER,USERNAME,PASSWORD,DATABASE}when set inmock-config; features use* url appUrlinstead of a hardcoded port; - runs the launcher as your host user, so the reports belong to you (a final
chownis only a safety net); - reads the real scenario counts from
karate-summary-json.txt; a run with zero scenarios is a failure.
test-config.features-path is required: without it gtool test fails instead
of testing nothing.
Every gtool test run scopes its containers with a run ID (GTOOL_RUN_ID, or a
generated one), so concurrent runs on one host never tear each other down. See
Dynamic ports and concurrent runs.
Running only the tests
Keep the environment up while you write features, and rerun only Karate:
This flow spans separate invocations, so it needs explicit ports: port: auto
and host-port: auto only work in single-invocation pipelines (gtool test,
gtool stress) and are rejected here. Without GTOOL_RUN_ID, services and
app act only on containers of no run; --all-runs widens them to every run.
gtool test karate uses the same launcher and environment as gtool test: it reads
test-config and the ports of the configuration file (a file is required) and
prints the path of the HTML report. It accepts:
| Flag | Purpose |
|---|---|
--tags |
Karate tags filter (overrides test-config.tags) |
--features |
features path (overrides test-config.features-path) |
--reports |
reports path (overrides test-config.reports-path) |
--image |
override the launcher image |
--stable |
fixed-contract runner, see below |
--urls-to-block |
with --stable; accepted for compatibility, ignored by the gtool launcher |
--no-open |
with --stable; do not open the HTML report |
Stable mode
gtool test --stable runs the pipeline with a fixed contract: the postgresql, pubsub and mountebank mocks on official public
images seeded from test/component/mocks-data, the app binaries declared in
build-config.yml launched as native processes, then Karate.
The same building blocks are available on their own: gtool services up --stable,
gtool app start --native and gtool test karate --stable. The latter always uses
test/component/features and test/component/reports (cleared before the run),
points Pub/Sub helpers at the stable emulator and opens the HTML report on an
interactive terminal (not with CI or NO_COLOR).
Networking
The app container runs on the Docker bridge network while the mocks publish their
ports on the host. gtool maps host.docker.internal to the host gateway on the app
container, so point the app at host.docker.internal:<mock port> on Linux and
Docker Desktop alike.
Linux firewalls
If the host firewall drops traffic from the Docker bridge (ufw with its default
policy, for example), the app cannot reach the mocks. Allow it with
sudo ufw allow in on docker0.