Did you know? isotovideo is the tool at the heart of openQA. You can actually use it without the whole scheduler, and it’s easier than you think!

This is a job for isotovideo

openQA is a framework composed of several components. There’s the test API, the scheduler which executes jobs, the web UI which exposes the state of jobs and job group management in addition to the RESTful API and finally the workers of which you need at least one to run a test.

Here we’re going to look at using isotovideo via containers to do what a worker does without integrating with the whole framework, which has some exciting benefits.

Running tests from the example distri

The example distri is exactly what you’d think. A starting point for a new openQA test distribution. And you can try running tests with it via podman:

git clone https://github.com/os-autoinst/os-autoinst-distri-example
cd os-autoinst-distri-example
podman run --rm -it -v .:/tests:Z registry.opensuse.org/devel/openqa/containers/isotovideo:qemu-x86 casedir=./tests

You will notice how main.pm gets loaded and you can see test functions in the logs. What you get here is analoguous to an openQA worker running with qemu on x86. autoinst-log.txt is the file that would contain this output in that case.

Running openSUSE tests

An excellent example of openQA in production would be the openSUSE distribution which can of course be found at openqa.opensuse.org. And if you want to run those in a container, that, too, can be done easily:

git clone https://github.com/os-autoinst/os-autoinst-distri-opensuse
cd os-autoinst-distri-opensuse
podman run --pull=always --rm -it -v .:/opt/tests registry.opensuse.org/devel/openqa/containers-tw/isotovideo:qemu-x86-os-autoinst-distri-opensuse -d casedir=/opt/tests productdir=products/opensuse _exit_after_schedule=1

Note that we’ve used _exit_after_schedule here to specify that we only want to validate the tests to be run, which is actually used as a regular CI check as well to spot obvious issues early. Also the container includes the dependencies needed to run openSUSE tests.

Say we wanna go a step further and run actual tests. For that we will have to have the needles available and expose the pool directory by adding -v ./pool:/opt/pool -w /opt/pool.

Note: The openSUSE needles are quite big, and you probably don’t want to try and browse them in a graphical file manager. Chances are it will be very slow!

git clone --depth 1 https://github.com/os-autoinst/os-autoinst-needles-opensuse products/opensuse/needles
mkdir pool
podman run --pull=always --rm -it -v .:/opt/tests -v ./pool:/opt/pool -w /opt/pool registry.opensuse.org/devel/openqa/containers-tw/isotovideo:qemu-x86-os-autoinst-distri-opensuse -d casedir=/opt/tests productdir=products/opensuse

You shall run the test in my image

Taking a look at the pool directory, we find all of the assets from our test run. What we also find is the video.ogv and testresults/boot-*.png images with the stream and needles from the execution. And if you’ve looked at the log before No bootable devices won’t come as a surprise because it explains the needle match errors from before:

... [debug] post_fail_hook failed: no candidate needle with tag(s) 'root-console' matched

There’s no bootable image here, which means the test never reaches the boot loader or the login screen that is expected. Perhaps we can change that by providing ISO?

wget https://download.opensuse.org/tumbleweed/iso/openSUSE-Tumbleweed-NET-x86_64-Current.iso -O pool/tumbleweed.iso
podman run --pull=always --rm -it -v .:/opt/tests -v ./pool:/opt/pool -w /opt/pool registry.opensuse.org/devel/openqa/containers-tw/isotovideo:qemu-x86-os-autoinst-distri-opensuse -d casedir=/opt/tests productdir=products/opensuse ISO=tumbleweed.iso

Shame. Looks like this isn’t the prepared image that test was expecting and the test doesn’t make it passt the boot loader. 🤔️

Let’s instead provide a disk image via HDD_1:

wget https://download.opensuse.org/tumbleweed/appliances/openSUSE-Tumbleweed-JeOS.x86_64-kvm-and-xen.qcow2 -O pool/jeOS.qcow2
podman run --pull=always --rm -it -v .:/opt/tests -v ./pool:/opt/pool -w /opt/pool registry.opensuse.org/devel/openqa/containers-tw/isotovideo:qemu-x86-os-autoinst-distri-opensuse -d casedir=/opt/tests productdir=products/opensuse ISO=tumbleweed.iso HDD_1=jeOS.qcow2 DESKTOP=textmode

Looking at video.ogv again after the executation shows a successfully booting image and tests executing, and the log files look much nicer, too!

Individually scheduled test modules

Supposing you don’t always want to run everything, just like a job executed via the web UI, you can also specify what to run here e.g. via SCHEDULE=tests/boot/boot_to_desktop,tests/console/rust:

podman run --pull=always --rm -it -v .:/opt/tests -v ./pool:/opt/pool -w /opt/pool registry.opensuse.org/devel/openqa/containers-tw/isotovideo:qemu-x86-os-autoinst-distri-opensuse -d casedir=/opt/tests productdir=products/opensuse SCHEDULE=tests/boot/boot_to_desktop,tests/console/rust

And this way only the initial boot and the rust test are “scheduled” where of course that means the two modules are run as part of this invocation.

Integrating isotovideo with your own CI

As mentioned previously, this is actually being used and if you’re setting up a new test distribution you can get started very quickly with a simple workflow snippet:

---
name: isotovideo
# yamllint disable-line rule:truthy
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    name: Running tests via isotovideo
    steps:
    - uses: actions/checkout@v2
    - name: Create pool directory
      run: mkdir -p ./pool
    - name: qemu via podman
      run: podman run --rm -it -v .:/tests:Z -v ./pool:/opt/pool -w /opt/pool registry.opensuse.org/devel/openqa/containers/isotovideo:qemu-x86 qemu_no_kvm=1 casedir=./tests OPENQA_BASEDIR=/var/lib
    - uses: actions/upload-artifact@v2
        with:
          name: Test results
          path: pool
        if: always()

By saving this as e.g. .github/workflows/isotovideo.yml and adding it to your repo you will get test runs for directly pushed code changes as well as pull requests.

Note: If you just want to get things to work and don’t need heavy customization you can also use the ready-made isotovideo-action:

on: [push, pull_request]
jobs:
  isotovideo:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: kalikiana/isotovideo-action@main
      - uses: actions/upload-artifact@v2
        with:
          name: Test results
          path: .
        if: always()