Skip to content

Instantly share code, notes, and snippets.

@jmchilton
Created February 27, 2026 15:12
Show Gist options
  • Select an option

  • Save jmchilton/9795414e766bd44d120b385491e10d77 to your computer and use it in GitHub Desktop.

Select an option

Save jmchilton/9795414e766bd44d120b385491e10d77 to your computer and use it in GitHub Desktop.

Fix CWL Docker-Only Tests (Category 4)

Problem

Two conformance tests require Docker container execution:

  1. test_conformance_v1_0_dockeroutputdir — Tool docker-output-dir.cwl uses dockerOutputDirectory: /other, runs touch /other/thing. Without Docker, /other doesn't exist.
  2. test_conformance_v1_0_docker_entrypoint — Tool docker-run-cmd.cwl with bash:4.4.12 image. Command is -c 'echo moo' > cow relying on Docker ENTRYPOINT (bash). Without Docker, -c is "command not found".

Root Cause

Galaxy's CWL conformance tests run without Docker enabled. Key code path:

  1. CwlToolSource.parse_requirements() (cwl.py:304-323) extracts docker_identifier but discards dockerOutputDirectory
  2. JobProxy._ensure_cwl_job_initialized() (parser.py:377-397) creates cwltool RuntimeContext with use_container=False
  3. Without a container, commands run on the host directly — no /other mount, no entrypoint

Fix — Two Parts

Part 1: Test Infrastructure — Enable Docker for These Tests

Need a way to run specific conformance tests with docker_enabled: true.

Option A: Set GALAXY_TEST_JOB_CONFIG_FILE pointing to a Docker-enabled config. May not work for API-style conformance tests.

Option B: Integration test class with handle_galaxy_config_kwds override. More reliable.

Either way, create a job config like:

runners:
  local:
    load: galaxy.jobs.runners.local:LocalJobRunner
    workers: 1
execution:
  default: local_docker
  environments:
    local_docker:
      runner: local
      docker_enabled: true
    local_upload:
      runner: local
tools:
  - id: upload1
    environment: local_upload

Tests must skip if Docker is not available (CI may not have it).

Part 2: dockerOutputDirectory Support

Galaxy needs to map dockerOutputDirectory into the container volume/workdir.

a) Parse dockerOutputDirectory from CWL DockerRequirement:

  • lib/galaxy/tool_util/cwl/parser.py — Add docker_output_directory() to CommandLineToolProxy (next to docker_identifier() at line 338)
  • lib/galaxy/tool_util/parser/cwl.py — Add parse_docker_output_directory() to CwlToolSource
  • lib/galaxy/tool_util/deps/requirements.py — Extend ContainerDescription with optional docker_output_directory field

b) Container command generation:

  • lib/galaxy/tool_util/deps/container_classes.py — In DockerContainer.containerize_command(): when tool has docker_output_directory, add -v <working_directory>:<docker_output_directory>:rw and set -w <docker_output_directory>

Part 3: Entrypoint Test

Likely works once Docker is enabled with no code changes:

  • CwlTool.may_use_container_entry_point = True passes raw command to container
  • docker run bash:4.4.12 -c 'echo moo > cow' uses image's ENTRYPOINT (bash)
  • Galaxy's build_docker_run_command does NOT set --entrypoint, so Docker default is used

Verify first before writing code.

Part 4: Flip Tests from Red to Green

  • scripts/cwl_conformance_to_test_cases.py — Remove these from RED_TESTS["v1.0"]
  • Regenerate: make update-cwl-conformance-tests

Testing

# With Docker-enabled config
GALAXY_TEST_JOB_CONFIG_FILE=test/integration/cwl_docker_job_conf.yml \
  .venv/bin/pytest -xvs lib/galaxy_test/api/cwl/test_cwl_conformance_v1_0.py \
  -k "dockeroutputdir or docker_entrypoint"

Unresolved Questions

  1. Does GALAXY_TEST_JOB_CONFIG_FILE work for API-style conformance tests, or does it need integration test class with handle_galaxy_config_kwds?
  2. For entrypoint test: does Galaxy's build_docker_run_command pass the raw command correctly when may_use_container_entry_point=True? The command goes through commands_builder.build() which may add cd working; prefix and stdout capture — could that break the Docker entrypoint invocation?
  3. Should dockerOutputDirectory volume mount go in DockerContainer.containerize_command() or higher in _find_container()/_expand_volume_str()?
  4. Is Docker reliably available in CI? If not, tests stay red in CI and only pass locally.
  5. Does collect_outputs work correctly post-container? cwltool collects with use_container=False looking in host outdir (working dir). Volume mount means Docker writes to host working dir — glob thing should find it there. But needs verification.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment