Skip to content

Commit

Permalink
tests: add basic integration testing
Browse files Browse the repository at this point in the history
This commit adds basic integration testing for the project. It
is pytest based and can run both locally or via `tmt` [0] which
will spin up a clean VM and run the tests inside.

[0] https://github.com/teemtee/tmt
  • Loading branch information
mvo5 committed Dec 6, 2023
1 parent 6d671b7 commit d25af5a
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 0 deletions.
1 change: 1 addition & 0 deletions .fmf/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
20 changes: 20 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,23 @@ jobs:
# don't check /etc/os-release sourcing, allow useless cats to live inside our codebase, and
# allow seemingly unreachable commands
SHELLCHECK_OPTS: -e SC1091 -e SC2002 -e SC2317

integration:
# TODO: run this also via tmt/testing-farm
name: "Integration"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup up python
uses: actions/setup-python@v4
- name: Install test dependencies
run: |
sudo apt install -y podman python3-pytest flake8
- name: Run tests
run: |
# podman needs (parts of) the environment but will break when
# XDG_RUNTIME_DIR is set.
# TODO: figure out what exactly podman needs
sudo -E XDG_RUNTIME_DIR= pytest-3 -s -vv
13 changes: 13 additions & 0 deletions plans/all.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
summary: Run all tests inside a VM environment
provision:
how: virtual
image: fedora:39
prepare:
how: install
package:
- podman
- pytest
- python3-flake8
execute:
how: tmt
script: pytest -s -vv
12 changes: 12 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Integration tests for osbuild-deploy-container
----------------------------------------------

This directory contans integration tests for osbuild-deploy-container.
They can be run in two ways:
1. On the local machine by just running `sudo pytest -s -v`
2. Via `tmt` [0] which will spin up a clean VM and run the tests inside:

tmt run -vvv


[0] https://github.com/teemtee/tmt
11 changes: 11 additions & 0 deletions test/test_flake8.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import os
import pathlib
import subprocess


def test_flake8():
p = pathlib.Path(__file__).parent
# TODO: use all static checks from osbuild instead
subprocess.check_call(
["flake8", "--ignore=E402", "--max-line-length=120",
os.fspath(p)])
67 changes: 67 additions & 0 deletions test/test_smoke.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import json
import os
import pathlib
import subprocess

import pytest

# local test utils
import testutil


@pytest.fixture(name="output_path")
def output_path_fixture(tmp_path):
output_path = tmp_path / "output"
output_path.mkdir(exist_ok=True)
return output_path


@pytest.fixture(name="config_json")
def config_json_fixture(output_path):
CFG = {
"blueprint": {
"customizations": {
"user": [
{
"name": "test",
"password": "password",
"groups": ["wheel"],
},
],
},
},
}
config_json_path = output_path / "config.json"
config_json_path.write_text(json.dumps(CFG), encoding="utf-8")
return config_json_path


@pytest.mark.skipif(os.getuid() != 0, reason="needs root")
@pytest.mark.skipif(not testutil.has_executable("podman"), reason="need podman")
def test_smoke(output_path, config_json):
# build local container
subprocess.check_call([
"podman", "build",
"-f", "Containerfile",
"-t", "osbuild-deploy-container-test",
])
cursor = testutil.journal_cursor()
# and run container to deploy an image into output/disk.qcow2
subprocess.check_call([
"podman", "run", "--rm",
"--privileged",
"--security-opt", "label=type:unconfined_t",
"-v", f"{output_path}:/output",
"osbuild-deploy-container-test",
"quay.io/centos-bootc/centos-bootc:stream9",
"--config", "/output/config.json",
])
# check that there are no denials
# TODO: actually check this once https://github.com/osbuild/images/pull/287
# is merged
journal_output = testutil.journal_after_cursor(cursor)
assert journal_output != ""
generated_img = pathlib.Path(output_path) / "qcow2/disk.qcow2"
assert generated_img.exists(), f"output file missing, dir content: {os.listdir(os.fspath(output_path))}"
# TODO: boot and do basic checks, see
# https://github.com/osbuild/osbuild-deploy-container/compare/main...mvo5:integration-test?expand=1
17 changes: 17 additions & 0 deletions test/testutil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import shutil
import subprocess


def journal_cursor():
output = subprocess.check_output(["journalctl", "-n0", "--show-cursor"], encoding="utf-8").strip()
cursor = output.split("\n")[-1]
return cursor.split("cursor: ")[-1]


def journal_after_cursor(cursor):
output = subprocess.check_output(["journalctl", f"--after-cursor={cursor}"])
return output


def has_executable(name):
return shutil.which(name) is not None

0 comments on commit d25af5a

Please sign in to comment.