Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split spread tests #252

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 3 additions & 1 deletion .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ concurrency:

jobs:
test:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
strategy:
matrix:
test-scenario: [short, long]
Expand Down Expand Up @@ -57,6 +57,8 @@ jobs:
name: ubuntu-image-coverage-${{ matrix.test-scenario }}
path: .coverage/coverage-*.out
retention-days: 1
if-no-files-found: error
include-hidden-files: true

mkfs-conf:
runs-on: ubuntu-latest
Expand Down
38 changes: 28 additions & 10 deletions .github/workflows/spread-test.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Run a spread test of the generated snap
name: Tests

on: [pull_request]

jobs:
snap-builds:
runs-on: ubuntu-22.04
snap-build:
runs-on: ubuntu-24.04
# Only build the snap for pull requests, it's not needed on release branches
# or on master since we have launchpad build recipes which do this already
if: ${{ github.event_name == 'pull_request' }}
Expand All @@ -20,18 +20,35 @@ jobs:
with:
name: snap
path: "*.snap"
if-no-files-found: error

spread:
name: Build a ${{ matrix.series }} image on ${{ matrix.group }} (${{ matrix.systems }})
runs-on: [self-hosted, ubuntu-image]
needs: snap-builds
needs: snap-build
strategy:
fail-fast: false
matrix:
include:
- group: ubuntu-arm
systems: 'ubuntu-20.04-arm-64 ubuntu-22.04-arm-64 ubuntu-24.04-arm-64'
- group: ubuntu
systems: 'ubuntu-18.04-64 ubuntu-20.04-64 ubuntu-22.04-64 ubuntu-23.10-64 ubuntu-24.04-64'
- group: ubuntu-devel
series: oracular
systems: 'ubuntu-24.04-64'
- group: ubuntu-latest
series: noble
systems: 'ubuntu-24.04-64'
- group: ubuntu-old
series: noble
systems: 'ubuntu-20.04-64 ubuntu-22.04-64'
- group: ubuntu-arm-devel
series: oracular
systems: 'ubuntu-24.04-arm-64'
- group: ubuntu-arm-latest
series: noble
systems: 'ubuntu-24.04-arm-64'
- group: ubuntu-arm-old
series: noble
systems: 'ubuntu-20.04-arm-64 ubuntu-22.04-arm-64'

steps:
- name: Cleanup job workspace
id: cleanup-job-workspace
Expand Down Expand Up @@ -97,6 +114,7 @@ jobs:

BACKEND=google
SPREAD=spread
SERIES=${{ matrix.series }}

if [[ "${{ matrix.systems }}" =~ -arm- ]]; then
BACKEND=google-arm
Expand Down Expand Up @@ -127,7 +145,7 @@ jobs:
spread -discard -reuse-pid="$(echo "$r" | grep -o -E '[0-9]+')";
done

- name: analyze spread test results
- name: Analyze spread test results
if: always()
run: |
if [ -f spread.log ]; then
Expand Down Expand Up @@ -158,7 +176,7 @@ jobs:
touch "$FAILED_TESTS_FILE"
fi

- name: save spread test results to cache
- name: Save spread test results to cache
if: always()
uses: actions/cache/save@v4
with:
Expand Down
24 changes: 7 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This document covers the following topics:

## Setting up

Ubuntu 20.04 LTS or later is recommended for ubuntu-image development.
Ubuntu 22.04 LTS or later is recommended for ubuntu-image development.
Usually, the [latest LTS](https://releases.ubuntu.com/) would be the best choice.

Go 1.21 [(or later)](https://snapcraft.io/go) is required to build ubuntu-image.
Expand Down Expand Up @@ -75,7 +75,7 @@ mkdir -p ~/.spread/qemu
cd ~/.spread/qemu
```

Run the following to build a 64-bit Ubuntu 16.04 LTS (or later):
Run the following to build a 64-bit Ubuntu 22.04 LTS (or later):
```
autopkgtest-buildvm-ubuntu-cloud -r <release-short-name>
mv autopkgtest-<release-short-name>-amd64.img ubuntu-<release-version>-64.img
Expand All @@ -84,13 +84,7 @@ mv autopkgtest-<release-short-name>-amd64.img ubuntu-<release-version>-64.img
For the correct values of `<release-short-name>` and `<release-version>`, see the official list of [Ubuntu releases](https://wiki.ubuntu.com/Releases).

* `<release-short-name>` is the first word in the release's full name,
e.g. for "Bionic Beaver" it is `bionic`.

If you are running Ubuntu 16.04 LTS, use `adt-buildvm-ubuntu-cloud` instead of `autopkgtest-buildvm-ubuntu-cloud` (the latter replaced the former in 18.04):
```
adt-buildvm-ubuntu-cloud -r xenial
mv adt-<release-name>-amd64-cloud.img ubuntu-<release-version>-64.img
```
e.g. for "Noble Numbat" it is `noble`.

#### Downloading Spread VM images

Expand All @@ -101,26 +95,22 @@ Alternatively, instead of building the QEMU images manually, you can download un

#### Running Spread with QEMU

Finally, you can run the Spread tests for Ubuntu 20.04 LTS 64-bit with:
Finally, you can run the Spread tests for Ubuntu 22.04 LTS 64-bit with:
```
spread -v qemu:ubuntu-20.04-64
spread -v qemu:ubuntu-22.04-64
```

* To run for a different system, replace `ubuntu-20.04-64` with a different system name, which should be a basename of the [built](#building-spread-vm-images) or [downloaded](#downloading-spread-vm-images) Ubuntu image file.
* To run for a different system, replace `ubuntu-22.04-64` with a different system name, which should be a basename of the [built](#building-spread-vm-images) or [downloaded](#downloading-spread-vm-images) Ubuntu image file.

For quick reuse, run:
```
spread -reuse qemu:ubuntu-20.04-64
spread -reuse qemu:ubuntu-22.04-64
```

It prints how to reuse the systems. Run `export REUSE_PROJECT=1` in your environment, too.

* Spread tests can be exercised on Ubuntu Core 20 and higher but need UEFI. UEFI support with a QEMU backend for Spread requires a BIOS from the [OVMF](https://wiki.ubuntu.com/UEFI/OVMF) package, which can be installed with `sudo apt install ovmf`.

> [!NOTE]
> For series older than 20.04 a snap build (built on a 20.04 or onward) of the tool must be available in the current directory.
> The tool cannot be built on 18.04 or older.


### Maintaining test helpers

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The future versions of this tool will be more generalized, allowing users to bui

### Requirements

* Ubuntu 20.04 (Focal Fossa) or newer (recommended: Ubuntu 22.04 (Jammy Jellyfish))
* Ubuntu 20.04 (Focal Fossa) or newer (recommended: Ubuntu 24.04 (Noble Numbat))

* Ability to install snaps ([SnapStore: ubuntu-image](https://snapcraft.io/ubuntu-image))

Expand Down
12 changes: 6 additions & 6 deletions internal/imagedefinition/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The following specification defines what is supported in the YAML:
revision: <int> (optional)
# The architecture of the image to create.
architecture: amd64 | armhf | arm64 | s390x | ppc64el | riscv64
# The Ubuntu codename to use as apt sources. Example: jammy
# The Ubuntu codename to use as apt sources. Example: noble
series: <string>
# The classification for this image.
class: cloud | installer | preinstalled
Expand Down Expand Up @@ -408,13 +408,13 @@ series
======

This mandatory field specifies the Ubuntu release name as it should appear in
apt sources. For example, to produce an image for the 20.04 release, this
should be "focal". Example values include:
apt sources. For example, to produce an image for the 24.04 release, this
should be "noble". Example values include:

* bionic
* noble
* oracular
* focal
* jammy
* kinetic

Please consult the `Releases <https://wiki.ubuntu.com/Releases>`_ page for
currently valid release names, but bear in mind that release names must be
Expand All @@ -425,7 +425,7 @@ For example:

.. code:: yaml

series: jammy
series: noble


class
Expand Down
61 changes: 31 additions & 30 deletions internal/statemachine/classic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,7 @@ func TestStateMachine_FailedPopulateClassicRootfsContents(t *testing.T) {

// TestSateMachine_customizeSourcesList tests functionality of the customizeSourcesList state function
func TestSateMachine_customizeSourcesList(t *testing.T) {
series := getHostSuite()
testCases := []struct {
name string
deb822Format bool
Expand All @@ -2414,10 +2415,10 @@ func TestSateMachine_customizeSourcesList(t *testing.T) {
deb822Format: false,
existingSourcesList: "deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted",
customization: &imagedefinition.Customization{},
expectedSourcesList: `# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
expectedSourcesList: fmt.Sprintf(`# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://archive.ubuntu.com/ubuntu/ jammy main restricted universe
`,
deb http://archive.ubuntu.com/ubuntu/ %s main restricted universe
`, series),
},
{
name: "set less components sources.list",
Expand All @@ -2426,10 +2427,10 @@ deb http://archive.ubuntu.com/ubuntu/ jammy main restricted universe
customization: &imagedefinition.Customization{
Components: []string{"main"},
},
expectedSourcesList: `# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
expectedSourcesList: fmt.Sprintf(`# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://archive.ubuntu.com/ubuntu/ jammy main
`,
deb http://archive.ubuntu.com/ubuntu/ %s main
`, series),
},
{
name: "set components and pocket sources.list",
Expand All @@ -2439,11 +2440,11 @@ deb http://archive.ubuntu.com/ubuntu/ jammy main
Components: []string{"main"},
Pocket: "security",
},
expectedSourcesList: `# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
expectedSourcesList: fmt.Sprintf(`# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://archive.ubuntu.com/ubuntu/ jammy main
deb http://security.ubuntu.com/ubuntu/ jammy-security main
`,
deb http://archive.ubuntu.com/ubuntu/ %[1]s main
deb http://security.ubuntu.com/ubuntu/ %[1]s-security main
`, series),
},
{
name: "fail to write sources.list",
Expand All @@ -2470,15 +2471,15 @@ deb http://security.ubuntu.com/ubuntu/ jammy-security main
name: "set default ubuntu.sources and commented sources.list",
deb822Format: true,
existingSourcesList: "deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted",
existingDeb822SourcesList: `Types: deb
existingDeb822SourcesList: fmt.Sprintf(`Types: deb
URIs: http://archive.ubuntu.com/
Suites: jammy
Suites: %s
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
`,
`, series),
customization: &imagedefinition.Customization{},
expectedSourcesList: imagedefinition.LegacySourcesListComment,
expectedDeb822SourcesList: `## Ubuntu distribution repository
expectedDeb822SourcesList: fmt.Sprintf(`## Ubuntu distribution repository
##
## The following settings can be adjusted to configure which packages to use from Ubuntu.
## Mirror your choices (except for URIs and Suites) in the security section below to
Expand Down Expand Up @@ -2508,38 +2509,38 @@ Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
## See the sources.list(5) manual page for further settings.
Types: deb
URIs: http://archive.ubuntu.com/ubuntu/
Suites: jammy
Suites: %[1]s
Components: main restricted
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

## Ubuntu security updates. Aside from URIs and Suites,
## this should mirror your choices in the previous section.
Types: deb
URIs: http://security.ubuntu.com/ubuntu/
Suites: jammy-security
Suites: %[1]s-security
Components: main restricted
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

`,
`, series),
},
{
name: "fail to write ubuntu.sources and commented sources.list",
deb822Format: true,
existingSourcesList: "deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted",
existingDeb822SourcesList: `Types: deb
existingDeb822SourcesList: fmt.Sprintf(`Types: deb
URIs: http://archive.ubuntu.com/
Suites: jammy
Suites: %s
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
`,
`, series),
customization: &imagedefinition.Customization{},
expectedSourcesList: "deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted",
expectedDeb822SourcesList: `Types: deb
expectedDeb822SourcesList: fmt.Sprintf(`Types: deb
URIs: http://archive.ubuntu.com/
Suites: jammy
Suites: %s
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
`,
`, series),
expectedErr: "unable to open ubuntu.sources file",
mockFuncs: func() func() {
mock := testhelper.NewOSMock(
Expand All @@ -2556,20 +2557,20 @@ Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
name: "fail to create sources.list.d",
deb822Format: true,
existingSourcesList: "deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted",
existingDeb822SourcesList: `Types: deb
existingDeb822SourcesList: fmt.Sprintf(`Types: deb
URIs: http://archive.ubuntu.com/
Suites: jammy
Suites: %s
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
`,
`, series),
customization: &imagedefinition.Customization{},
expectedSourcesList: "deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted",
expectedDeb822SourcesList: `Types: deb
expectedDeb822SourcesList: fmt.Sprintf(`Types: deb
URIs: http://archive.ubuntu.com/
Suites: jammy
Suites: %s
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
`,
`, series),
expectedErr: "Error /etc/apt/sources.list.d directory",
mockFuncs: func() func() {
mock := testhelper.NewOSMock(
Expand All @@ -2595,7 +2596,7 @@ Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
stateMachine.parent = &stateMachine
stateMachine.ImageDef = imagedefinition.ImageDefinition{
Architecture: getHostArch(),
Series: getHostSuite(),
Series: series,
Rootfs: &imagedefinition.Rootfs{
SourcesListDeb822: helper.BoolPtr(tc.deb822Format),
},
Expand Down
2 changes: 1 addition & 1 deletion internal/statemachine/state_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ func (s *StateMachine) displayStates() {
// partial state machine run
func (stateMachine *StateMachine) writeMetadata(metadataFile string) error {
jsonfilePath := filepath.Join(stateMachine.stateMachineFlags.WorkDir, metadataFile)
jsonfile, err := os.OpenFile(jsonfilePath, os.O_CREATE|os.O_WRONLY, 0644)
jsonfile, err := os.OpenFile(jsonfilePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil && !os.IsExist(err) {
return fmt.Errorf("error opening JSON metadata file for writing: %s", jsonfilePath)
}
Expand Down
Loading
Loading