Skip to content

Commit

Permalink
[squashme] split out separate docs for scripts, address feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
benesch committed Jan 1, 2025
1 parent 1a5df32 commit 8bd1f1e
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 84 deletions.
5 changes: 4 additions & 1 deletion site/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ nav:
- "Mutual exclusion and rate-limiting": docs/configuration/test-groups.md
- "Environment variables": docs/configuration/env-vars.md
- "Extra arguments": docs/configuration/extra-args.md
- docs/configuration/setup-scripts.md
- "Scripts":
- "Overview": docs/scripts/index.md
- docs/scripts/setup.md
- docs/scripts/pre-timeout.md
- Machine-readable output:
- "About output formats": docs/machine-readable/index.md
- "JUnit support": docs/machine-readable/junit.md
Expand Down
112 changes: 112 additions & 0 deletions site/src/docs/scripts/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
icon: material/script-text
---

# Scripts

<!-- md:version 0.9.59 -->

Nextest supports running _scripts_ when certain events occur during a test run. Scripts can be scoped to particular tests via [filtersets](../filtersets/index.md).

Nextest currently recognizes two types of scripts:

* [_Setup scripts_](setup.md), which execute at the start of a test run.
* [_Pre-timeout scripts_](pre-timeout.md), which execute before nextest terminates a test that has exceeded its timeout.

Scripts are configured in two parts: _defining scripts_, and _setting up rules_ for when they should be executed.

## Defining scripts

Scripts are defined using the top-level `script.<type>` configuration.

For example, to define a setup script named "my-script", which runs `my-script.sh`:

```toml title="Setup script definition in <code>.config/nextest.toml</code>"
[script.setup.my-script]
command = 'my-script.sh'
# Additional options...
```

See [_Defining setup scripts_](setup.md#defining-setup-scripts) for the additional options available for configuring setup scripts.

To instead define a pre-timeout script named "my-script", which runs `my-script.sh`:

```toml title="Pre-timeout script definition in <code>.config/nextest.toml</code>"
[script.pre-timeout.my-script]
command = 'my-script.sh'
# Additional options...
```

See [_Defining pre-timeout scripts_](pre-timeout.md#defining-pre-timeout-scripts) for the additional options available for configuring pre-timeout scripts.

### Command specification

All script types support the `command` option, which specifies how to invoke the script. Commands can either be specified using Unix shell rules, or as a list of arguments. In the following example, `script1` and `script2` are equivalent.

```toml
[script.<type>.script1]
command = 'script.sh -c "Hello, world!"'

[script.<type>.script2]
command = ['script.sh', '-c', 'Hello, world!']
```

### Namespacing

Script names must be unique across all script types.

This means that you cannot use the same name for a setup script and a pre-timeout script:

```toml title="Pre-timeout script definition in <code>.config/nextest.toml</code>"
[script.setup.my-script]
command = 'setup.sh'

# Reusing the `my-script` name for a pre-timeout script is NOT permitted.
[script.pre-timeout.my-script]
command = 'pre-timeout.sh'
```

## Setting up rules

In configuration, you can create rules for when to use scripts on a per-profile basis. This is done via the `profile.<profile-name>.scripts` array. For example, you can configure a setup script that generates a database if tests from the `db-tests` package, or any packages that depend on it, are run.

```toml title="Basic rules"
[[profile.default.scripts]]
filter = 'rdeps(db-tests)'
setup = 'db-generate'
```

(This example uses the `rdeps` [filterset](../filtersets/index.md) predicate.)

Scripts can also filter based on platform, using the rules listed in [_Specifying platforms_](../configuration/specifying-platforms.md):

```toml title="Platform-specific rules"
[[profile.default.scripts]]
platform = { host = "cfg(unix)" }
setup = 'script1'
```

A set of scripts can also be specified. All scripts in the set will be executed.

```toml title="Multiple setup scripts"
[[profile.default.scripts]]
filter = 'test(/^script_tests::/)'
setup = ['script1', 'script2']
```

Executing pre-timeout scripts follows the same pattern. For example, you can configure a pre-timeout script for every test that contains `slow` in its name.

```toml title="Basic pre-timeout rules"
[[profile.default.scripts]]
filter = 'test(slow)'
pre-timeout = 'capture-backtrace'
```

A single rule can specify any number of setup scripts and any number of pre-timeout scripts.

```toml title="Combination rules"
[[profile.default.scripts]]
filter = 'test(slow)'
setup = ['setup-1', 'setup-2']
pre-timeout = ['pre-timeout-1', 'pre-timeout-2']
```
52 changes: 52 additions & 0 deletions site/src/docs/scripts/pre-timeout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
icon: material/timer-sand-empty
status: experimental
---

<!-- md:version TODO -->

# Pre-timeout scripts

!!! experimental "Experimental: This feature is not yet stable"

- **Enable with:** Add `experimental = ["setup-scripts"]` to `.config/nextest.toml`
- **Tracking issue:** [#978](https://github.com/nextest-rs/nextest/issues/978)


Nextest runs *pre-timeout scripts* before terminating a test that has exceeded
its timeout.

## Defining pre-timeout scripts

Pre-timeout scripts are defined using the top-level `script.pre-timeout` configuration. For example, to define a script named "my-script", which runs `my-script.sh`:

```toml title="Script definition in <code>.config/nextest.toml</code>"
[script.pre-timeout.my-script]
command = 'my-script.sh'
```

Pre-timeout scripts can have the following configuration options attached to them:

- TODO

### Example

```toml title="Advanced script definition"
[script.pre-timeout.db-generate]
command = 'cargo run -p db-generate'
# TODO options
```

## Script execution

A given pre-timeout script _S_ is executed when the current profile has at least one rule where the `platform` predicates match the current execution environment, the script _S_ is listed in `pre-timeout`, and a test matching the `filter` has reached its configured timeout.

Pre-timeout scripts are executed serially, in the order they are defined (_not_ the order they're specified in the rules). If any pre-timeout script exits with a non-zero exit code, an error is logged but the test run continues.

Nextest sets the following environment variables when executing a pre-timeout script:

* **`NEXTEST_PRE_TIMEOUT_TEST_PID`**: the ID of the process running the test.
* **`NEXTEST_PRE_TIMEOUT_TEST_NAME`**: the name of the running test.
* **`NEXTEST_PRE_TIMEOUT_TEST_PACKAGE_NAME`**: the name of the package in which the test is located.
* **`NEXTEST_PRE_TIMEOUT_TEST_BINARY_NAME`**: the name of the test binary, if known.
* **`NEXTEST_PRE_TIMEOUT_TEST_BINARY_KIND`**: the kind of the test binary, if known.
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,37 @@ icon: material/ray-start-arrow
status: experimental
---

# Scripts

<!-- md:version 0.9.59 -->

!!! experimental "Experimental: Setup scripts are not yet stable"
# Setup scripts

- **Enable with:** Add `experimental = ["setup-scripts"]` to `.config/nextest.toml`
- **Tracking issue:** [#978](https://github.com/nextest-rs/nextest/issues/978)
!!! experimental "Experimental: This feature is not yet stable"

!!! experimental "Experimental: Pre-timeout scripts are not yet stable"

- **Enable with:** Add `experimental = ["pre-timeout-scripts"]` to `.config/nextest.toml`
- **Enable with:** Add `experimental = ["setup-scripts"]` to `.config/nextest.toml`
- **Tracking issue:** [#978](https://github.com/nextest-rs/nextest/issues/978)

Nextest supports running _scripts_ when certain events occur during a test run. Scripts can be scoped to particular tests via [filtersets](../filtersets/index.md).
Nextest runs *setup scripts* before tests are run.

Nextest currently recognizes two types of scripts:
## Defining setup scripts

* _Setup scripts_, which are executed at the start of a test run.
* _Pre-timeout scripts_, which are executed before nextest begins terminating a test that has exceeded its timeout.

Scripts are configured in two parts: _defining scripts_, and _setting up rules_ for when they should be executed.

## Defining scripts

Scripts are defined using the top-level `script` configuration. For example, to define a script named "my-script", which runs `my-script.sh`:
Setup scripts are defined using the top-level `script.setup` configuration. For example, to define a script named "my-script", which runs `my-script.sh`:

```toml title="Script definition in <code>.config/nextest.toml</code>"
[script.my-script]
[script.setup.my-script]
command = 'my-script.sh'
```

Commands can either be specified using Unix shell rules, or as a list of arguments. In the following example, `script1` and `script2` are equivalent.

```toml
[script.script1]
[script.setup.script1]
command = 'script.sh -c "Hello, world!"'

[script.script2]
[script.setup.script2]
command = ['script.sh', '-c', 'Hello, world!']
```

Scripts can have the following configuration options attached to them:
Setup scripts can have the following configuration options attached to them:

- **`slow-timeout`**: Mark a script [as slow](../features/slow-tests.md) or [terminate it](../features/slow-tests.md#terminating-tests-after-a-timeout), using the same configuration as for tests. By default, scripts are not marked as slow or terminated (this is different from the slow timeout for tests).
- **`leak-timeout`**: Mark scripts [leaky](../features/leaky-tests.md) after a timeout, using the same configuration as for tests. By default, the leak timeout is 100ms.
Expand All @@ -55,68 +43,21 @@ Scripts can have the following configuration options attached to them:
### Example

```toml title="Advanced script definition"
[script.db-generate]
[script.setup.db-generate]
command = 'cargo run -p db-generate'
slow-timeout = { period = "60s", terminate-after = 2 }
leak-timeout = "1s"
capture-stdout = true
capture-stderr = false
```

## Setting up rules

In configuration, you can create rules for when to use scripts on a per-profile basis. This is done via the `profile.<profile-name>.scripts` array. For example, you can configure a setup script that generates a database if tests from the `db-tests` package, or any packages that depend on it, are run.

```toml title="Basic rules"
[[profile.default.scripts]]
filter = 'rdeps(db-tests)'
setup = 'db-generate'
```

(This example uses the `rdeps` [filterset](../filtersets/index.md) predicate.)

Scripts can also filter based on platform, using the rules listed in [_Specifying platforms_](../configuration/specifying-platforms.md):

```toml title="Platform-specific rules"
[[profile.default.scripts]]
platform = { host = "cfg(unix)" }
setup = 'script1'
```

A set of scripts can also be specified. All scripts in the set will be executed.

```toml title="Multiple setup scripts"
[[profile.default.scripts]]
filter = 'test(/^script_tests::/)'
setup = ['script1', 'script2']
```

Executing pre-timeout scripts follows the same pattern. For example, you can configure a pre-timeout script for every test that contains `slow` in its name.

```toml title="Basic pre-timeout rules"
[[profile.default.scripts]]
filter = 'test(slow)'
pre-timeout = 'capture-backtrace'
```

A single rule can specify any number of setup scripts and any number of pre-timeout scripts.

```toml title="Combination rules"
[[profile.default.scripts]]
filter = 'test(slow)'
setup = ['setup-1', 'setup-2']
pre-timeout = ['pre-timeout-1', 'pre-timeout-2']
```

## Script execution

### Setup scripts

A given setup script _S_ is only executed if the current profile has at least one rule where the `filter` and `platform` predicates match the current execution environment, and the setup script _S_ is listed in `setup`.

Setup scripts are executed serially, in the order they are defined (_not_ the order they're specified in the rules). If any setup script exits with a non-zero exit code, the entire test run is terminated.

#### Environment variables
### Environment variables

Setup scripts can define environment variables that will be exposed to tests that match the script. This is done by writing to the `$NEXTEST_ENV` environment variable from within the script.

Expand Down Expand Up @@ -154,18 +95,6 @@ fn my_env_test() {
}
```

### Pre-timeout scripts

A given pre-timeout script _S_ is executed when the current profile has at least one rule where the `platform` predicates match the current execution environment, the script _S_ is listed in `pre-timeout`, and a test matching the `filter` has reached its configured timeout.

Pre-timeout scripts are executed serially, in the order they are defined (_not_ the order they're specified in the rules). If any pre-timeout script exits with a non-zero exit code, an error is logged but the test run continues.

Nextest sets the following environment variables when executing a pre-timeout script:

* **`NEXTEST_PRE_TIMEOUT_TEST_PID`**: the ID of the process running the test.
* **`NEXTEST_PRE_TIMEOUT_TEST_NAME`**: the name of the running test.
* **`NEXTEST_PRE_TIMEOUT_TEST_BINARY`**: the name of the binary running the test.

## Setup scripts in JUnit output

<!-- md:version 0.9.86 -->
Expand Down

0 comments on commit 8bd1f1e

Please sign in to comment.