Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/nox-heavy-rundeck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
# Copyright (c) 2026, Alexei Znamensky <russoz@gmail.com>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

# Integration tests for the targets with the `heavy/rundeck` alias
name: nox-heavy-rundeck
'on':
workflow_dispatch:

permissions:
contents: read

jobs:
ansible-test:
uses: ansible-community/antsibull-nox/.github/workflows/reusable-nox-matrix.yml@main
with:
include-tags: heavy-rundeck
1 change: 1 addition & 0 deletions .github/workflows/nox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ jobs:
upload-codecov-schedule: true
allow-coverage-cd-override: true
max-ansible-core: "2.18"
exclude-tags: remote, no-gha, heavy
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
5 changes: 4 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,16 @@ If you replace `-Re` with `-e`, then the virtual environments will be re-created
### Heavy integration tests

Some integration test targets are not part of the regular `azp/posix/N` or `azp/generic/1` CI targets because they are too slow or need too many resources to run in CI.
Those that can run without credentials or special hardware are also tagged with the `heavy` alias, and should be run every once in a while:
Those that can run without credentials or special hardware are tagged with a `heavy/<backend>` alias instead, and should be run every once in a while.
Targets that need the same backend service share the same alias, for example `heavy/rundeck`.
Each alias has its own session in `antsibull-nox.toml`, and all of them can be run with:

```.bash
nox -Re ansible-test-integration-heavy
```

Additional options for `ansible-test` can be passed after `--`.
Each backend also has its own GitHub workflow, `nox-heavy-<backend>`, that must be triggered manually.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also try to have a single workflow, where you have to select from a dropdown which backend to use. That would avoid having to add more of these files in the future. I can work on that in a follow-up.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original idea was to have the heavy tests running periodically, on a more sparse schedule. How would the single-workflow model work for this? Would it have an "all" option or something like that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can have multiple schedule triggers (https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#schedule). I was hoping that you could provide different variables per schedule entry, but I'm not sure whether that's possible (need to dig deeper). If it's possible, we could do it with that.


## Run basic sanity, unit or integration tests locally (with ansible-test)

Expand Down
19 changes: 19 additions & 0 deletions antsibull-nox.toml
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,22 @@ remote = [
]

##################################################################################################

# Heavy integration tests:
# Targets that are too slow or resource-hungry for regular CI, but that can run without credentials or special hardware.
# Each one has a `heavy/<backend>` alias; targets sharing a backend run in the same session.
# The session of each backend is tagged `heavy-<backend>`, and only runs in the nox-heavy-<backend> workflow,
# which must be triggered manually.

[[sessions.ansible_test_integration.groups]]
session_name = "ansible-test-integration-heavy"
description = "Meta session for running all heavy integration test sessions."
tags = ["heavy"]

[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "devel"
target = [ "heavy/rundeck/" ]
docker = "ubuntu"
tags = ["heavy-rundeck"]

##################################################################################################
Comment thread
russoz marked this conversation as resolved.
Resolved
23 changes: 2 additions & 21 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,34 +57,15 @@ def ansible_output(session: nox.Session) -> None:
session.run("antsibull-docs", "ansible-output", *args, *session.posargs)


# Integration tests for targets that do not have the regular `azp/...` targets because they are too slow or
# resource-hungry for regular CI, but that can still run without credentials or special hardware.
# These targets are tagged with the `heavy` alias. This session is not registered for CI.
antsibull_nox.add_ansible_test_session(
name="ansible-test-integration-heavy",
description="Run integration tests for the non-CI targets tagged as heavy",
ansible_test_params=[
"integration",
"-v",
"--docker",
"ubuntu",
"--display-traceback",
"error",
"heavy/",
],
extra_deps_files=["tests/integration/requirements.yml"],
ansible_core_version="devel",
default=False,
)


@nox.session(name="update-azp-config", python=False)
def update_azp_config(session: nox.Session) -> None:
command = [
"antsibull-nox",
"update-azp-config",
"--min-ansible-core",
"2.19",
"--exclude-tags",
"heavy",
"--extra-session",
'{"group": "Sanity", "title": "Extra sanity tests", "session": "extra-sanity-tests"}',
]
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/targets/rundeck/aliases
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later

destructive
heavy
heavy/rundeck
skip/macos
skip/freebsd
38 changes: 36 additions & 2 deletions tests/sanity/extra/aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,62 @@
from __future__ import annotations

import glob
import os
import sys

import yaml

try:
import tomllib
except ImportError:
import tomli as tomllib
Comment thread
russoz marked this conversation as resolved.
Resolved


def get_heavy_targets():
Comment thread
russoz marked this conversation as resolved.
Resolved
"""Return the heavy/<backend> targets that have sessions in antsibull-nox.toml, and whether errors were found."""
with open("antsibull-nox.toml", "rb") as f:
config = tomllib.load(f)

targets = set()
has_errors = False
for group in config["sessions"]["ansible_test_integration"]["groups"]:
for session in [group] + group.get("sessions", []):
tags = set(group.get("tags", [])) | set(session.get("tags", []))
target = session.get("target", [])
for value in [target] if isinstance(target, str) else target:
if not value.startswith("heavy/"):
continue
target_name = value.rstrip("/")
backend = target_name.split("/", 1)[1]
if f"heavy-{backend}" not in tags:
print(f'antsibull-nox.toml: session for "{target_name}" has no tag "heavy-{backend}"')
has_errors = True
workflow = f".github/workflows/nox-heavy-{backend}.yml"
if not os.path.exists(workflow):
print(f'{workflow}: workflow for "{target_name}" not found')
has_errors = True
targets.add(target_name)
return targets, has_errors


def main():
Comment thread
felixfontein marked this conversation as resolved.
Resolved
"""Main entry point."""
with open(".azure-pipelines/azure-pipelines.yml", "rb") as f:
azp = yaml.safe_load(f)

allowed_targets = {"azp/generic/1", "heavy"}
allowed_targets = {"azp/generic/1"}
for stage in azp["stages"]:
if stage["stage"].startswith(("sanity", "unit", "Summary")):
continue
for job in stage["jobs"]:
for param in job["parameters"]["targets"]:
group = param["test"].rsplit("-", 1)[-1]
allowed_targets.add(f"azp/posix/{group}")
heavy_targets, has_errors = get_heavy_targets()
allowed_targets.update(heavy_targets)

paths = glob.glob("tests/integration/targets/*/aliases")

has_errors = False
for path in paths:
targets = []
skip = False
Expand Down
Loading