introduce testing script
This commit is contained in:
parent
9ea6150ee7
commit
824cba1c08
7 changed files with 189 additions and 0 deletions
1
test/.gitignore
vendored
Normal file
1
test/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
*.qcow2
|
||||
24
test/1-create-base.json
Normal file
24
test/1-create-base.json
Normal 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"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
40
test/2-configure-web-server.json
Normal file
40
test/2-configure-web-server.json
Normal 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
15
test/3-compose-qcow2.json
Normal 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
8
test/Makefile
Normal 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
95
test/run-tests.py
Normal 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
6
test/variables
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue