diff --git a/tests/distros/Containerfile.arch b/tests/distros/Containerfile.arch index 6e1fd0e..6b6366f 100644 --- a/tests/distros/Containerfile.arch +++ b/tests/distros/Containerfile.arch @@ -1,4 +1,4 @@ FROM docker.io/archlinux/archlinux:latest RUN pacman --noconfirm -Syu --needed aria2 openssl python-lz4 python-protobuf \ - && pacman --noconfirm -Scc + && yes | pacman -Scc diff --git a/tests/distros/Containerfile.arch-wine b/tests/distros/Containerfile.arch-wine new file mode 100644 index 0000000..a6d512d --- /dev/null +++ b/tests/distros/Containerfile.arch-wine @@ -0,0 +1,49 @@ +FROM docker.io/archlinux/archlinux:latest + +RUN pacman --noconfirm -Syu --needed aria2 xorg-server-xvfb \ + && yes | pacman -Scc + +# Yep, we're installing Windows msys2 packages directly on top of Arch + +ARG KEYRING_VERSION=1~20221024-1 +ARG KEYRING_SHA256=e90fb4413f6056dbc8b2df9eac670924aa2851151bc97569e7df12c928acc209 + +RUN aria2c https://mirror.msys2.org/msys/x86_64/msys2-keyring-${KEYRING_VERSION}-any.pkg.tar.zst \ + --checksum SHA-256=${KEYRING_SHA256} \ + && pacman --noconfirm -U msys2-keyring-${KEYRING_VERSION}-any.pkg.tar.zst \ + && rm msys2-keyring-${KEYRING_VERSION}-any.pkg.tar.zst + +COPY wine/pacman.additional.conf /tmp/ +RUN cat /tmp/pacman.additional.conf >> /etc/pacman.conf \ + && pacman-key --init \ + && pacman-key --populate \ + && rm /tmp/pacman.additional.conf + +RUN pacman --noconfirm -Sy \ + mingw-w64-x86_64-aria2 \ + mingw-w64-x86_64-ca-certificates \ + mingw-w64-x86_64-openssl \ + mingw-w64-x86_64-python \ + mingw-w64-x86_64-python-lz4 \ + mingw-w64-x86_64-python-protobuf \ + mingw-w64-x86_64-zlib \ + wine \ + wine-mono \ + && yes | pacman -Scc + +# Since binfmt_misc can't work in an unprivileged container, all post-install +# .exe executions failed, including the ones for setting up the trusted CA +# certificates. Run the post install script using the Linux version of p11-kit +# so we don't have to create a wine prefix (see below). +RUN cat /var/lib/pacman/local/mingw-w64-x86_64-ca-certificates-*/install \ + | sed 's,[^ ]*/\([^ ]\+\).exe,\1,g; $a post_install' \ + | bash -s + +COPY --chmod=755 wine/python3.sh /usr/local/bin/python3 + +# We don't precreate a wine prefix because openssl fails to gather entropy when +# using a persisted wine prefix for some reason. It doesn't seem to actually be +# caused by the lack of entropy. + +ENTRYPOINT ["xvfb-run"] +CMD ["bash"] diff --git a/tests/distros/wine/pacman.additional.conf b/tests/distros/wine/pacman.additional.conf new file mode 100644 index 0000000..1d4ff77 --- /dev/null +++ b/tests/distros/wine/pacman.additional.conf @@ -0,0 +1,6 @@ +[multilib] +Include = /etc/pacman.d/mirrorlist + +[mingw64] +SigLevel = Required DatabaseOptional +Server = https://mirror.msys2.org/mingw/$repo/ diff --git a/tests/distros/wine/python3.sh b/tests/distros/wine/python3.sh new file mode 100644 index 0000000..fcdaf3a --- /dev/null +++ b/tests/distros/wine/python3.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exec wine /mingw64/bin/python.exe "${@}" diff --git a/tests/tests_containerized.py b/tests/tests_containerized.py index 7a4c2ae..bbe0152 100755 --- a/tests/tests_containerized.py +++ b/tests/tests_containerized.py @@ -7,6 +7,7 @@ import queue import subprocess import sys import threading +import time def build_cmd(image_name, tag, container_file, rebuild=False): @@ -30,7 +31,7 @@ def test_cmd(image_name, tag, extra_args=[], default_args=True, network=False): full_image = f'{image_name}:{tag}' project_dir = os.path.realpath(os.path.join(sys.path[0], '..')) - network_args = ['--network', 'none'] if network else [] + network_args = [] if network else ['--network', 'none'] test_args = extra_args.copy() if default_args: test_args.append('--delete-on-success') @@ -109,6 +110,8 @@ class Job: self.stderr_thread.start() self.completion_thread.start() + self.start_time = time.perf_counter_ns() + def kill(self): self.process.kill() @@ -118,11 +121,14 @@ class Job: self.stderr_thread.join() self.completion_thread.join() + self.elapsed_time = time.perf_counter_ns() - self.start_time + return self.process.returncode def run_jobs(name_to_cmd, max_jobs): results = {n: None for n in name_to_cmd} + durations = {n: 'n/a' for n in name_to_cmd} job_queue = collections.deque(name_to_cmd.items()) jobs = {} completion_queue = queue.Queue() @@ -139,6 +145,7 @@ def run_jobs(name_to_cmd, max_jobs): name = completion_queue.get() job = jobs.pop(name) results[name] = job.wait() + durations[name] = f'{job.elapsed_time / 1_000_000_000:.1f}s' except: for _, job in jobs.items(): job.kill() @@ -151,10 +158,13 @@ def run_jobs(name_to_cmd, max_jobs): if name_to_cmd: max_name_len = max(len(n) for n in name_to_cmd) + max_dur_len = max(len(durations[n]) for n in name_to_cmd) print('Results:') + for name, status in sorted(results.items()): - print(f'- {name:<{max_name_len}}: ', end='') + print(f'- {name:<{max_name_len}} | ' + f'Elapsed: {durations[name]:<{max_dur_len}} | ', end='') if status is None: failed += 1