Skip to content

Tests

Tests #1878

Workflow file for this run

name: Tests
on:
pull_request:
paths:
- '.github/workflows/tests.yml'
- 'bin/**'
- 'tests/**'
schedule:
- cron: '38 6 * * *'
workflow_dispatch:
inputs:
ubuntu-releases:
description: List of Ubuntu releases to run the tests against. In JSON format, i.e. '["22.04", "24.04"]'.
type: string
default: '["20.04", "22.04", "24.04"]'
snap-tracks:
description: List of snap tracks to run the tests. In JSON format, i.e. '["latest/stable", "5.0/candidate"]'.
type: string
default: '["latest/edge"]'
self-hosted-runner:
type: boolean
description: Whether to use self-hosted runners to run the jobs.
default: false
tmate-debug:
description: Use tmate debugging session on integration test failure.
type: boolean
default: false
tmate-timeout:
description: Timeout in minutes to keep tmate debugging session.
type: number
default: 30
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.ubuntu-releases }}-${{ inputs.snap-tracks }}
# XXX: scheduled runs should not cancel manually triggered ones
cancel-in-progress: ${{ !contains(github.event_name, 'schedule')}}
defaults:
run:
# Make sure bash is always invoked with `-eo pipefail`
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
shell: bash
jobs:
code-tests:
name: Code
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# A non-shallow clone is needed for the Differential ShellCheck
fetch-depth: 0
- id: ShellCheck
name: Differential ShellCheck
uses: redhat-plumbers-in-action/differential-shellcheck@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
strict-check-on-push: true
if: github.event_name == 'pull_request'
- name: Upload artifact with ShellCheck defects in SARIF format
uses: actions/upload-artifact@v4
with:
name: Differential ShellCheck SARIF
path: ${{ steps.ShellCheck.outputs.sarif }}
if: github.event_name == 'pull_request'
system-tests:
name: ${{ matrix.test }} (${{ matrix.track }} - ${{ matrix.os }})
runs-on: ubuntu-${{ matrix.os }}
# avoid runaway test burning 6 hours of CI
timeout-minutes: 60
permissions:
# need that to manipulate caches
actions: write
strategy:
fail-fast: false
matrix:
os: ${{ fromJSON(inputs.ubuntu-releases || '["20.04", "22.04", "24.04"]') }}
track: ${{ fromJSON(inputs.snap-tracks || '["latest/edge", "5.21/edge", "5.0/edge", "4.0/edge"]') }}
test:
- cgroup
- cluster
- container
- container-copy
- conversion
- cpu-vm
- devlxd-container
- devlxd-vm
- docker
- efi-vars-editor-vm
- lxd-user
- interception
- network-bridge-firewall
- network-ovn ovn:deb
- network-ovn ovn:latest/edge
- network-routed
- pylxd
- snapd
- storage-buckets
- storage-disks-vm
- storage-vm btrfs
- storage-vm ceph
- storage-vm dir
- storage-vm lvm
- storage-vm lvm-thin
- storage-vm zfs
- storage-volumes-vm
- tpm-vm
- vm
- vm-migration
- vm-nesting
include:
- test: qemu-external-vm
track: "latest/edge"
os: 24.04
exclude:
# not compatible with 4.0/*
- test: container-copy
track: "4.0/candidate"
- test: conversion
track: "4.0/candidate"
- test: cpu-vm
track: "4.0/candidate"
- test: devlxd-vm
track: "4.0/candidate"
- test: efi-vars-editor-vm
track: "4.0/candidate"
- test: lxd-user
track: "4.0/candidate"
- test: network-bridge-firewall
track: "4.0/candidate"
os: 20.04
- test: network-ovn ovn:deb
track: "4.0/candidate"
- test: network-ovn ovn:latest/edge
track: "4.0/candidate"
- test: storage-buckets
track: "4.0/candidate"
- test: storage-disks-vm
track: "4.0/candidate"
- test: storage-vm btrfs
track: "4.0/candidate"
- test: storage-vm ceph
track: "4.0/candidate"
- test: storage-vm dir
track: "4.0/candidate"
- test: storage-vm lvm
track: "4.0/candidate"
- test: storage-vm lvm-thin
track: "4.0/candidate"
- test: storage-vm zfs
track: "4.0/candidate"
- test: storage-volumes-vm
track: "4.0/candidate"
- test: tpm-vm
track: "4.0/candidate"
- test: vm-migration
track: "4.0/candidate"
- test: container-copy
track: "4.0/edge"
- test: conversion
track: "4.0/edge"
- test: cpu-vm
track: "4.0/edge"
- test: devlxd-vm
track: "4.0/edge"
- test: efi-vars-editor-vm
track: "4.0/edge"
- test: lxd-user
track: "4.0/edge"
- test: network-bridge-firewall
track: "4.0/edge"
os: 20.04
- test: network-ovn ovn:deb
track: "4.0/edge"
- test: network-ovn ovn:latest/edge
track: "4.0/edge"
- test: storage-buckets
track: "4.0/edge"
- test: storage-disks-vm
track: "4.0/edge"
- test: storage-vm btrfs
track: "4.0/edge"
- test: storage-vm ceph
track: "4.0/edge"
- test: storage-vm dir
track: "4.0/edge"
- test: storage-vm lvm
track: "4.0/edge"
- test: storage-vm lvm-thin
track: "4.0/edge"
- test: storage-vm zfs
track: "4.0/edge"
- test: storage-volumes-vm
track: "4.0/edge"
- test: tpm-vm
track: "4.0/edge"
- test: vm-migration
track: "4.0/edge"
# not compatible with 5.0/*
- test: efi-vars-editor-vm
track: "5.0/candidate"
- test: efi-vars-editor-vm
track: "5.0/edge"
- test: network-ovn ovn:latest/edge
track: "5.0/candidate"
- test: network-ovn ovn:latest/edge
track: "5.0/edge"
- test: vm-migration
track: "5.0/candidate"
- test: vm-migration
track: "5.0/edge"
# skip track/os combinations that are too far appart
- os: 24.04
track: "4.0/candidate"
- os: 24.04
track: "4.0/edge"
- os: 24.04
track: "5.0/candidate"
- os: 24.04
track: "5.0/edge"
- os: 20.04
track: "5.0/candidate"
- os: 20.04
track: "5.0/edge"
- os: 20.04
track: "5.21/candidate"
- os: 20.04
track: "5.21/edge"
- os: 20.04
track: "latest/candidate"
- os: 20.04
track: "latest/edge"
steps:
- name: Performance tuning
uses: canonical/lxd/.github/actions/tune-disk-performance@main
- name: Reclaim disk space
if: ${{ matrix.test == 'conversion' || startsWith(matrix.test, 'storage-') || matrix.test == 'vm-nesting' }}
uses: canonical/lxd/.github/actions/reclaim-disk-space@main
- name: Disable Docker
uses: canonical/lxd/.github/actions/disable-docker@main
- name: "Disable br_netfilter"
run: |
set -eux
# XXX: br_netfilter causes subtle issues by subjecting internal
# bridge traffic to NAT/MASQUERADING and IP filtering. This
# modules is not normally loaded on stock Ubuntu installs but it
# is on GHA runners.
lsmod | grep -qw ^br_netfilter && sudo modprobe -r br_netfilter
- name: Checkout
uses: actions/checkout@v4
# needed for cache key
- name: Get Date
id: get-date
if: ${{ matrix.test == 'qemu-external-vm' }}
run: |
echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
shell: bash
# for simplicity, just use one cache directory
# and make it valid for one day
- uses: actions/cache/restore@v4
id: cache-restore
if: ${{ matrix.test == 'qemu-external-vm' }}
with:
path: /home/runner/work/cache
key: cache-${{ steps.get-date.outputs.date }}
- name: Setup MicroCeph
if: ${{ matrix.test == 'conversion' || matrix.test == 'storage-buckets' || matrix.test == 'storage-vm ceph' || matrix.test == 'storage-volumes-vm' }}
uses: canonical/lxd/.github/actions/setup-microceph@main
- name: CPU info
run: lscpu
- name: ${{ matrix.test }} (${{ matrix.track }})
run: |
set -eux
# XXX: prevent accidental usage of `images:` in CI test jobs.
# All tests should be done using officially supported images.
echo '127.0.0.1 images.lxd.canonical.com' | sudo tee /etc/hosts
TEST_SCRIPT="$(echo ${{ matrix.test }} | cut -d " " -f 1)"
EXTRA_ARGS="$(echo ${{ matrix.test }} | cut -d " " -f 2- --only-delimited)"
if [ "${TEST_SCRIPT}" = "cluster" ]; then
dst_track="${{ matrix.track }}"
src_track="$(echo "${dst_track}" | cut -d/ -f1)/stable"
EXTRA_ARGS="${EXTRA_ARGS:-3} ${src_track} ${{ matrix.track }}"
elif [ "${TEST_SCRIPT}" = "network-ovn" ]; then
if [ -n "${EXTRA_ARGS}" ]; then
# Strip the `ovn:` prefix
export OVN_SOURCE="${EXTRA_ARGS##ovn:}"
EXTRA_ARGS=""
fi
fi
sudo --preserve-env=GITHUB_ACTIONS,GITHUB_STEP_SUMMARY,TEST_IMG,OVN_SOURCE ./bin/local-run "tests/${TEST_SCRIPT}" ${{ matrix.track }} ${EXTRA_ARGS:-}
# always update cache as we have our own logic of
# cache invalidation and updates in addition to a date check
- name: Delete previous cache
if: ${{ steps.cache-restore.outputs.cache-hit }}
continue-on-error: true
run: |
gh cache delete "cache-${{ steps.get-date.outputs.date }}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/cache/save@v4
if: ${{ matrix.test == 'qemu-external-vm' }}
with:
path: /home/runner/work/cache
key: cache-${{ steps.get-date.outputs.date }}
- name: Tmate debugging session (self-hosted)
if: ${{ failure() && inputs.tmate-debug && inputs.self-hosted-runner }}
uses: canonical/action-tmate@main
timeout-minutes: ${{ fromJSON(inputs.tmate-timeout) }}
- name: Tmate debugging session (gh-hosted)
if: ${{ failure() && inputs.tmate-debug && !inputs.self-hosted-runner }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: ${{ fromJSON(inputs.tmate-timeout) }}