hurl-test
The whole pipeline lives in Dagger: the module compiles the Go applicationunder test from its source (via the languages/go module — no Dockerfile
involved), runs the static binary in a pinned Alpine service, then runs a
hurl (https://hurl.dev) suite from a tests directory against it. Nothing
app-specific is hardcoded — base URLs, credentials, ports and the package
to build are all supplied by the caller.
Two operations mirror the trivy/droast gate-vs-artifact split: Test fails
the call on any red test; TestArtifact never fails and exports junit.xml,
an HTML report, the console output and a `failures` counter the pipeline
reads to decide the gate.
Naming deviation: in this module Test() IS the business operation (it runs
the test suite), so the conventional module self-check is named Version().
Installation
dagger install dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3Entrypoint
Return Type
HurlTest ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
func (m *MyModule) Example() *dagger.HurlTest {
return dag.
Hurltest()
}@function
def example() -> dagger.HurlTest:
return (
dag.hurl_test()
)@func()
example(): HurlTest {
return dag
.hurlTest()
}Types
HurlTest 🔗
hurlVersion() 🔗
Tag of the ghcr.io/orange-opensource/hurl image
Return Type
String ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
hurl-versionfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Hurltest().
Hurlversion(ctx)
}@function
async def example() -> str:
return await (
dag.hurl_test()
.hurlversion()
)@func()
async example(): Promise<string> {
return dag
.hurlTest()
.hurlVersion()
}goVersion() 🔗
Golang image tag used to compile the app under test
Return Type
String ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
go-versionfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Hurltest().
Goversion(ctx)
}@function
async def example() -> str:
return await (
dag.hurl_test()
.goversion()
)@func()
async example(): Promise<string> {
return dag
.hurlTest()
.goVersion()
}jobs() 🔗
Parallel workers for hurl –jobs (0 => hurl default: one per core)
Return Type
Integer ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
jobsfunc (m *MyModule) Example(ctx context.Context) int {
return dag.
Hurltest().
Jobs(ctx)
}@function
async def example() -> int:
return await (
dag.hurl_test()
.jobs()
)@func()
async example(): Promise<number> {
return dag
.hurlTest()
.jobs()
}appHostname() 🔗
Hostname the app service is bound under (tests reach http://:)
Return Type
String ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
app-hostnamefunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Hurltest().
Apphostname(ctx)
}@function
async def example() -> str:
return await (
dag.hurl_test()
.apphostname()
)@func()
async example(): Promise<string> {
return dag
.hurlTest()
.appHostname()
}appPorts() 🔗
Ports exposed on the app service — every port the tests reach must be listed
Return Type
[Integer ! ] ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
app-portsfunc (m *MyModule) Example(ctx context.Context) []int {
return dag.
Hurltest().
Appports(ctx)
}@function
async def example() -> List[int]:
return await (
dag.hurl_test()
.appports()
)@func()
async example(): Promise<number[]> {
return dag
.hurlTest()
.appPorts()
}appEnv() 🔗
Environment variables for the app container
Return Type
[HurlTestVariable ! ] ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
app-envfunc (m *MyModule) Example() []*dagger.HurlTestVariable {
return dag.
Hurltest().
Appenv()
}@function
def example() -> List[dagger.HurlTestVariable]:
return (
dag.hurl_test()
.appenv()
)@func()
example(): HurlTestVariable[] {
return dag
.hurlTest()
.appEnv()
}appSecrets() 🔗
Secret environment variables for the app container
Return Type
[HurlTestSecretVariable ! ] ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
app-secretsfunc (m *MyModule) Example() []*dagger.HurlTestSecretVariable {
return dag.
Hurltest().
Appsecrets()
}@function
def example() -> List[dagger.HurlTestSecretVariable]:
return (
dag.hurl_test()
.appsecrets()
)@func()
example(): HurlTestSecretVariable[] {
return dag
.hurlTest()
.appSecrets()
}variables() 🔗
hurl variables, passed as –variable key=value (visible in logs)
Return Type
[HurlTestVariable ! ] ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
variablesfunc (m *MyModule) Example() []*dagger.HurlTestVariable {
return dag.
Hurltest().
Variables()
}@function
def example() -> List[dagger.HurlTestVariable]:
return (
dag.hurl_test()
.variables()
)@func()
example(): HurlTestVariable[] {
return dag
.hurlTest()
.variables()
}secrets() 🔗
Secret hurl variables, injected as HURL_ env vars (never in argv)
Return Type
[HurlTestSecretVariable ! ] ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
secretsfunc (m *MyModule) Example() []*dagger.HurlTestSecretVariable {
return dag.
Hurltest().
Secrets()
}@function
def example() -> List[dagger.HurlTestSecretVariable]:
return (
dag.hurl_test()
.secrets()
)@func()
example(): HurlTestSecretVariable[] {
return dag
.hurlTest()
.secrets()
}appService() 🔗
AppService exposes the application built from source as a standalone
service, for interactive debugging: dagger call ... app-service up.
Return Type
Service !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Application source: the Go module root |
| buildPath | String | "." | Go package to build, relative to source (e.g. “./cmd/api-mock”) |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
app-service --source DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory) *dagger.Service {
return dag.
Hurltest().
Appservice(source)
}@function
def example(source: dagger.Directory) -> dagger.Service:
return (
dag.hurl_test()
.appservice(source)
)@func()
example(source: Directory): Service {
return dag
.hurlTest()
.appService(source)
}test() 🔗
Test compiles the app from source, runs the hurl suite against it and returns hurl’s console output. The call fails on any red test (hurl’s non-zero exit propagates), making it the blocking form for CI gates that do not need report files.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Application source: the Go module root |
| tests | Directory ! | - | Directory containing the hurl test files |
| buildPath | String | "." | Go package to build, relative to source (e.g. “./cmd/api-mock”) |
| glob | String | "*.hurl" | Glob selecting test files inside tests |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
test --source DIR_PATH --tests DIR_PATHfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory, tests *dagger.Directory) string {
return dag.
Hurltest().
Test(ctx, source, tests)
}@function
async def example(source: dagger.Directory, tests: dagger.Directory) -> str:
return await (
dag.hurl_test()
.test(source, tests)
)@func()
async example(source: Directory, tests: Directory): Promise<string> {
return dag
.hurlTest()
.test(source, tests)
}testArtifact() 🔗
TestArtifact runs the hurl suite once and never fails on test failures. It returns a directory holding:
junit.xml - JUnit report, one <testcase> per .hurl file
(a bare <testsuites/> if hurl aborted early)
html/ - hurl HTML report
report.txt - full console output
failures - failed+errored file count, "0" = green (the CI gate)
exitcode - raw hurl exit code (0 ok, 1 option, 2 parse, 3 runtime, 4 asserts)
This mirrors trivy’s ScanFsArtifact and droast’s LintArtifact: reports are
always exportable and the pipeline decides the gate by reading failures.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Application source: the Go module root |
| tests | Directory ! | - | Directory containing the hurl test files |
| buildPath | String | "." | Go package to build, relative to source (e.g. “./cmd/api-mock”) |
| glob | String | "*.hurl" | Glob selecting test files inside tests |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
test-artifact --source DIR_PATH --tests DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory, tests *dagger.Directory) *dagger.Directory {
return dag.
Hurltest().
Testartifact(source, tests)
}@function
def example(source: dagger.Directory, tests: dagger.Directory) -> dagger.Directory:
return (
dag.hurl_test()
.testartifact(source, tests)
)@func()
example(source: Directory, tests: Directory): Directory {
return dag
.hurlTest()
.testArtifact(source, tests)
}testRemote() 🔗
TestRemote runs the hurl suite against a remote host and returns hurl’s console output. The call fails on any red test.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| tests | Directory ! | - | Directory containing the hurl test files |
| glob | String | "*.hurl" | Glob selecting test files inside tests |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
test-remote --tests DIR_PATHfunc (m *MyModule) Example(ctx context.Context, tests *dagger.Directory) string {
return dag.
Hurltest().
Testremote(ctx, tests)
}@function
async def example(tests: dagger.Directory) -> str:
return await (
dag.hurl_test()
.testremote(tests)
)@func()
async example(tests: Directory): Promise<string> {
return dag
.hurlTest()
.testRemote(tests)
}testRemoteArtifact() 🔗
TestRemoteArtifact runs the hurl suite against a remote host and never fails on test failures. Same artifact contract as TestArtifact.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| tests | Directory ! | - | Directory containing the hurl test files |
| glob | String | "*.hurl" | Glob selecting test files inside tests |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
test-remote-artifact --tests DIR_PATHfunc (m *MyModule) Example(tests *dagger.Directory) *dagger.Directory {
return dag.
Hurltest().
Testremoteartifact(tests)
}@function
def example(tests: dagger.Directory) -> dagger.Directory:
return (
dag.hurl_test()
.testremoteartifact(tests)
)@func()
example(tests: Directory): Directory {
return dag
.hurlTest()
.testRemoteArtifact(tests)
}version() 🔗
Version prints the pinned hurl version (module self-check).
Return Type
String ! Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
versionfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Hurltest().
Version(ctx)
}@function
async def example() -> str:
return await (
dag.hurl_test()
.version()
)@func()
async example(): Promise<string> {
return dag
.hurlTest()
.version()
}withAppEnv() 🔗
WithAppEnv adds an environment variable to the app container.
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| key | String ! | - | No description provided |
| value | String ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-app-env --key string --value stringfunc (m *MyModule) Example(key string, value string) *dagger.HurlTest {
return dag.
Hurltest().
Withappenv(key, value)
}@function
def example(key: str, value: str) -> dagger.HurlTest:
return (
dag.hurl_test()
.withappenv(key, value)
)@func()
example(key: string, value: string): HurlTest {
return dag
.hurlTest()
.withAppEnv(key, value)
}withAppHostname() 🔗
WithAppHostname overrides the service-binding hostname (default “app”). Test variables must use the same name, e.g. base=http://app:3000/api/v1.
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| hostname | String ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-app-hostname --hostname stringfunc (m *MyModule) Example(hostname string) *dagger.HurlTest {
return dag.
Hurltest().
Withapphostname(hostname)
}@function
def example(hostname: str) -> dagger.HurlTest:
return (
dag.hurl_test()
.withapphostname(hostname)
)@func()
example(hostname: string): HurlTest {
return dag
.hurlTest()
.withAppHostname(hostname)
}withAppPort() 🔗
WithAppPort exposes a port on the app service. Dagger only routes exposed ports through service bindings, so every port the tests reach must be added here — there is no Dockerfile EXPOSE to inherit from.
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| port | Integer ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-app-port --port integerfunc (m *MyModule) Example(port int) *dagger.HurlTest {
return dag.
Hurltest().
Withappport(port)
}@function
def example(port: int) -> dagger.HurlTest:
return (
dag.hurl_test()
.withappport(port)
)@func()
example(port: number): HurlTest {
return dag
.hurlTest()
.withAppPort(port)
}withAppSecret() 🔗
WithAppSecret adds a secret environment variable to the app container.
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| key | String ! | - | No description provided |
| value | Secret ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-app-secret --key string --value env:MYSECRETfunc (m *MyModule) Example(key string, value *dagger.Secret) *dagger.HurlTest {
return dag.
Hurltest().
Withappsecret(key, value)
}@function
def example(key: str, value: dagger.Secret) -> dagger.HurlTest:
return (
dag.hurl_test()
.withappsecret(key, value)
)@func()
example(key: string, value: Secret): HurlTest {
return dag
.hurlTest()
.withAppSecret(key, value)
}withGoVersion() 🔗
WithGoVersion overrides the golang image tag used to compile the app.
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| version | String ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-go-version --version stringfunc (m *MyModule) Example(version string) *dagger.HurlTest {
return dag.
Hurltest().
Withgoversion(version)
}@function
def example(version: str) -> dagger.HurlTest:
return (
dag.hurl_test()
.withgoversion(version)
)@func()
example(version: string): HurlTest {
return dag
.hurlTest()
.withGoVersion(version)
}withHurlVersion() 🔗
WithHurlVersion overrides the hurl runner image tag.
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| version | String ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-hurl-version --version stringfunc (m *MyModule) Example(version string) *dagger.HurlTest {
return dag.
Hurltest().
Withhurlversion(version)
}@function
def example(version: str) -> dagger.HurlTest:
return (
dag.hurl_test()
.withhurlversion(version)
)@func()
example(version: string): HurlTest {
return dag
.hurlTest()
.withHurlVersion(version)
}withJobs() 🔗
WithJobs sets the number of parallel hurl workers (1 = sequential, for suites whose files mutate shared server state).
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| jobs | Integer ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-jobs --jobs integerfunc (m *MyModule) Example(jobs int) *dagger.HurlTest {
return dag.
Hurltest().
Withjobs(jobs)
}@function
def example(jobs: int) -> dagger.HurlTest:
return (
dag.hurl_test()
.withjobs(jobs)
)@func()
example(jobs: number): HurlTest {
return dag
.hurlTest()
.withJobs(jobs)
}withSecretVariable() 🔗
WithSecretVariable adds a hurl variable injected as a HURL_
environment variable (hurl reads HURL_name as variable name), so the
value never appears in argv or in Dagger logs.
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| key | String ! | - | No description provided |
| value | Secret ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-secret-variable --key string --value env:MYSECRETfunc (m *MyModule) Example(key string, value *dagger.Secret) *dagger.HurlTest {
return dag.
Hurltest().
Withsecretvariable(key, value)
}@function
def example(key: str, value: dagger.Secret) -> dagger.HurlTest:
return (
dag.hurl_test()
.withsecretvariable(key, value)
)@func()
example(key: string, value: Secret): HurlTest {
return dag
.hurlTest()
.withSecretVariable(key, value)
}withVariable() 🔗
WithVariable adds a hurl variable, passed as --variable key=value.
The value is visible in logs — use WithSecretVariable for sensitive ones.
Return Type
HurlTest !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| key | String ! | - | No description provided |
| value | String ! | - | No description provided |
Example
dagger -m dev.azure.com/dordogne/DAGGER-TEMPLATES/_git/DAGGER-TEMPLATES/testing/hurl@0427c8cc75c3e4bf24f1c1a9ab3aedbdcbb4c2c3 call \
with-variable --key string --value stringfunc (m *MyModule) Example(key string, value string) *dagger.HurlTest {
return dag.
Hurltest().
Withvariable(key, value)
}@function
def example(key: str, value: str) -> dagger.HurlTest:
return (
dag.hurl_test()
.withvariable(key, value)
)@func()
example(key: string, value: string): HurlTest {
return dag
.hurlTest()
.withVariable(key, value)
}HurlTestVariable 🔗
Variable is a non-sensitive key/value pair (hurl variable or app env var).
key() 🔗
Return Type
String ! Example
Function HurlTestVariable.key is not accessible from the hurl-test moduleFunction HurlTestVariable.key is not accessible from the hurl-test moduleFunction HurlTestVariable.key is not accessible from the hurl-test moduleFunction HurlTestVariable.key is not accessible from the hurl-test modulevalue() 🔗
Return Type
String ! Example
Function HurlTestVariable.value is not accessible from the hurl-test moduleFunction HurlTestVariable.value is not accessible from the hurl-test moduleFunction HurlTestVariable.value is not accessible from the hurl-test moduleFunction HurlTestVariable.value is not accessible from the hurl-test moduleHurlTestSecretVariable 🔗
SecretVariable is a sensitive key/value pair carried as a Dagger secret.
key() 🔗
Return Type
String ! Example
Function HurlTestSecretVariable.key is not accessible from the hurl-test moduleFunction HurlTestSecretVariable.key is not accessible from the hurl-test moduleFunction HurlTestSecretVariable.key is not accessible from the hurl-test moduleFunction HurlTestSecretVariable.key is not accessible from the hurl-test modulevalue() 🔗
Return Type
Secret ! Example
Function HurlTestSecretVariable.value is not accessible from the hurl-test moduleFunction HurlTestSecretVariable.value is not accessible from the hurl-test moduleFunction HurlTestSecretVariable.value is not accessible from the hurl-test moduleFunction HurlTestSecretVariable.value is not accessible from the hurl-test module