introduce testing script

This commit is contained in:
Martin Sehnoutka 2019-07-08 15:47:37 +02:00 committed by Lars Karlitski
parent 9ea6150ee7
commit 824cba1c08
7 changed files with 189 additions and 0 deletions

1
test/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.qcow2

24
test/1-create-base.json Normal file
View file

@ -0,0 +1,24 @@
{
"name": "base",
"stages": [
{
"name": "io.weldr.dnf",
"systemResourcesFromEtc": ["/etc/pki"],
"options": {
"releasever": "30",
"repos": {
"fedora": {
"name": "Fedora",
"metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch",
"gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch"
}
},
"packages": [
"@Core",
"selinux-policy-targeted",
"grub2-pc"
]
}
}
]
}

View file

@ -0,0 +1,40 @@
{
"name": "base-qcow2",
"base": "1f663f817473ffa5b01241b17adbd71bc734962313f5d4eef230073c0ac5884e",
"stages": [
{
"name": "io.weldr.script",
"options": {
"script": "echo root | passwd --stdin root; echo 'SELINUX=disabled' > /etc/selinux/config;"
}
},
{
"name": "io.weldr.script",
"options": {
"script": "mkdir -p /var/web; echo 'hello, world!' > /var/web/index; echo -e \"[Unit]\\nDescription=Testing web server\\nAfter=network.target\\n\\n[Service]\\nType=simple\\nExecStart=python3 -m http.server 8888\\nWorkingDirectory=/var/web/\\n\\n[Install]\\nWantedBy=multi-user.target\" > /etc/systemd/system/web-server.service;"
}
},
{
"name": "io.weldr.systemd",
"options": {
"enabled_services": [
"NetworkManager",
"web-server"
],
"disabled_services": [
"firewalld"
]
}
},
{
"name": "io.weldr.grub2",
"systemResourcesFromEtc": [
"/etc/grub.d"
],
"options": {
"root_fs_uuid": "76a22bf4-f153-4541-b6c7-0332c0dfaeac",
"partition_table_id": "0xdeadbeef"
}
}
]
}

15
test/3-compose-qcow2.json Normal file
View file

@ -0,0 +1,15 @@
{
"name": "base-qcow2",
"base": "552b5555bdf64c5e19bf4ca8a709da37fb3046678643a8f8499297b6dd95c7e7",
"assembler": {
"name": "io.weldr.qcow2",
"systemResourcesFromEtc": [
"/etc/grub.d"
],
"options": {
"filename": "base.qcow2",
"root_fs_uuid": "76a22bf4-f153-4541-b6c7-0332c0dfaeac",
"partition_table_id": "0xdeadbeef"
}
}
}

8
test/Makefile Normal file
View file

@ -0,0 +1,8 @@
base:
$(OSBUILD) --input $(BASE_INPUT) --output $(BASE_OUTPUT) 1-create-base.json
web:
$(OSBUILD) --input $(BASE_OUTPUT) --output $(WEB_OUTPUT) 2-configure-web-server.json
qcow2:
$(OSBUILD) --input $(WEB_OUTPUT) --output $(QCOW2_OUTPUT) 3-compose-qcow2.json

95
test/run-tests.py Normal file
View file

@ -0,0 +1,95 @@
import contextlib
import logging
import os
import subprocess
import sys
import tempfile
import time
EXPECTED_TIME_TO_BOOT = 60 # seconds
RESET = "\033[0m"
BOLD = "\033[1m"
RED = "\033[31m"
OBJECTS = os.environ.get("OBJECTS", tempfile.mkdtemp(prefix="osbuild-"))
OUTPUT_DIR = os.environ.get("OUTPUT_DIR", tempfile.mkdtemp(prefix="osbuild-"))
OSBUILD = os.environ.get("OSBUILD", os.path.join(os.path.dirname(__file__), "..", "osbuild"))
IMAGE_PATH = os.environ.get("IMAGE_PATH", OUTPUT_DIR + "/base.qcow2")
logging.basicConfig(level=logging.getLevelName(os.environ.get("TESTS_LOGLEVEL", "INFO")))
def run_osbuild(pipeline: str, check=True):
cmd = [OSBUILD, "--objects", OBJECTS, "-o", OUTPUT_DIR, pipeline]
logging.info(f"Running osbuild: {cmd}")
osbuild = subprocess.run(cmd, capture_output=True)
if osbuild.returncode != 0:
logging.error(f"{RED}osbuild failed!{RESET}")
print(f"{BOLD}STDERR{RESET}")
print(osbuild.stderr.decode())
print(f"{BOLD}STDOUT{RESET}")
print(osbuild.stdout.decode())
if check:
sys.exit(1)
return osbuild.returncode
def rel_path(fname: str) -> str:
return os.path.join(os.path.dirname(__file__), fname)
def build_web_server_image():
run_osbuild(rel_path("1-create-base.json"))
r = run_osbuild(rel_path("2-configure-web-server.json"), check=False)
# TODO: remove this workaround once the grub2 stage works on the first try :-)
if r != 0:
run_osbuild(rel_path("2-configure-web-server.json"))
run_osbuild(rel_path("3-compose-qcow2.json"))
def uname() -> str:
uname = subprocess.run(["uname"], capture_output=True)
return uname.stdout.decode("utf-8").strip()
@contextlib.contextmanager
def boot_image(path: str):
acceleration = ["-accel", "kvm:hvf:tcg"]
network = ["-net", "nic,model=rtl8139", "-net", "user,hostfwd=tcp::8888-:8888"]
cmd = ["qemu-system-x86_64", "-nographic", "-m", "1024", "-snapshot"] + acceleration + [path] + network
logging.info(f"Booting image: {cmd}")
vm = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try:
time.sleep(EXPECTED_TIME_TO_BOOT)
yield None
finally:
vm.kill()
def test_web_server():
cmd = ["curl", "-s", "http://127.0.0.1:8888/index"]
logging.info(f"Running curl: {cmd}")
curl = subprocess.run(cmd, capture_output=True)
logging.info(f"Curl returned: code={curl.returncode}, stdout={curl.stdout.decode()}, stderr={curl.stderr.decode()}")
assert curl.returncode == 0
assert curl.stdout.decode("utf-8").strip() == "hello, world!"
if __name__ == '__main__':
if uname() == "Darwin":
logging.info("Running on macOS. Skipping image build.")
else:
logging.info("Building image")
build_web_server_image()
logging.info("Running tests")
tests = [test_web_server]
with boot_image(IMAGE_PATH):
for test in tests:
try:
test()
print(f"{RESET}{BOLD}{test.__name__}: Success{RESET}")
except AssertionError as e:
print(f"{RESET}{BOLD}{test.__name__}: {RESET}{RED}Fail{RESET}")
print(e)

6
test/variables Normal file
View file

@ -0,0 +1,6 @@
export OSBUILD=../osbuild
export BASE_INPUT=/osbuild/workdir
export BASE_OUTPUT=/osbuild/base-tree
export WEB_OUTPUT=/osbuild/web-tree
export QCOW2_OUTPUT=/osbuild/output
export IMAGE_PATH=/osbuild/output/base.qcow2