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 4, 2023
1 parent d3c4178 commit ff93ac1
Show file tree
Hide file tree
Showing 7 changed files with 143 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: |
# for some reason GH runners keep the environment with sudo
# but that breaks podman because XDG_RUNTIME_DIR then points
# to /run/user/1001
sudo 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
- python-flake8
execute:
how: tmt
script: pytest -s -vv
14 changes: 14 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
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 `pytest`
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-boot/fedora-tier-1:eln",
"--config", "/output/config.json",
])
# check that there are no denials
journal_output = testutil.journal_after_cursor(cursor)
assert journal_output != ""
# TODO: actually check this once https://github.com/osbuild/images/pull/287
# is merged
generated_img = pathlib.Path(output_path) / "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 ff93ac1

Please sign in to comment.