Skip to content

Commit

Permalink
ovirt-img: command testing
Browse files Browse the repository at this point in the history
Add the required testing infrastructure to test
ovirt-img command with a local setup.

Engine configuration needs to be set in a configuration
file, and then the tests will read this configuration
and run normally through tox.

Fixes: oVirt#124
Signed-off-by: Albert Esteve <[email protected]>
  • Loading branch information
aesteve-rh committed Aug 24, 2022
1 parent ed6e07c commit 8e84a59
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 3 deletions.
22 changes: 22 additions & 0 deletions test/client/client_tests.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Example configuration for client tests.
# Adapt these settings to your local engine setup and then run:
# tox -e client
# This configuration can be copied to a different location and used as
# CLIENT_TEST_CONF=/path/to/test.conf tox -e client

# Common parameters must be all kept, and are used by all tests
common:
engine_url: https://engine.com
username: admin@internal
password: password
cafile: /path/to/cert.pem

tests:
# Image upload and download test. Different formats are tested.
# Image and disk contents are compared.
upload-download:
# Set local storage domain names to test.
# At least one block and one file storage domain shall be tested.
storage-domains:
- nfs1
- scsi1
35 changes: 35 additions & 0 deletions test/client/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ovirt-imageio
# Copyright (C) 2022 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

import logging
import os
import yaml

import pytest


log = logging.getLogger("test")


@pytest.fixture
def config(tmpdir):
with open(os.environ['CLIENT_TEST_CONF'], encoding='utf-8') as fstream:
try:
conf = yaml.safe_load(fstream)
except yaml.YAMLError as exc:
log.error("Invalid YAML format: %s", exc)
raise

conf_file = os.path.join(tmpdir, 'ovirt-img.conf')
os.environ['XDG_CONFIG_HOME'] = str(tmpdir)
with open(conf_file, "w+", encoding="utf-8") as fstream:
fstream.write("[test]\n")
for k, v in conf["common"].items():
fstream.write(f"{k} = {v}\n")

yield conf
94 changes: 94 additions & 0 deletions test/client/upload_download_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# ovirt-imageio
# Copyright (C) 2022 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

import contextlib
import logging
import os
import uuid
import subprocess
import sys

import pytest
import ovirtsdk4 as sdk

from ovirt_imageio._internal import qemu_img


log = logging.getLogger("test")


class ClientError(Exception):
pass


def run_upload_disk(storage_domain, image, disk_id=None, log_level=None):
# Make sure it runs with the same tox environment executable
cmd = [sys.executable, './ovirt-img', 'upload-disk', '-c', 'test']
cmd.extend(['-s', storage_domain])
if log_level:
cmd.extend(['--log-level', log_level])
if disk_id:
cmd.extend(['--disk-id', disk_id])
cmd.append(image)
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as exc:
raise ClientError(f'Client Error: {exc}') from exc


def run_download_disk(disk_id, image, log_level=None):
# Make sure it runs with the same tox environment executable
cmd = [sys.executable, './ovirt-img', 'download-disk', '-c', 'test']
if log_level:
cmd.extend(['--log-level', log_level])
cmd.extend([disk_id, image])
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as exc:
raise ClientError(f'Client Error: {exc}') from exc


def remove_disk(conf, sd_name, disk_id):
connection = sdk.Connection(
url=f'{conf["engine_url"]}/ovirt-engine/api',
username=conf["username"],
password=conf["password"],
ca_file=conf["cafile"]
)
with contextlib.closing(connection):
sd_service = connection.system_service().storage_domains_service()
found_sd = sd_service.list(search=f'name={sd_name}')
if not found_sd:
raise RuntimeError(f"Couldn't find storage domain {sd_name}")

sd = found_sd[0]
sd_service = sd_service.storage_domain_service(sd.id)
sd_service.disks_service().disk_service(disk_id).remove()


@pytest.mark.parametrize("fmt", ["raw", "qcow2"])
def test_upload_download(config, tmpdir, fmt):
image = os.path.join(tmpdir, f'image.{fmt}')
qemu_img.create(image, fmt, size='10g')
test_config = config["tests"]["upload-download"]
for sd_name in test_config.get("storage-domains", []):
disk_id = str(uuid.uuid4())
try:
log.info("Upload %s image to SD %s", fmt, sd_name)
run_upload_disk(sd_name, image, disk_id)
down_img = os.path.join(tmpdir, f'downloaded.{fmt}')
log.info("Download image %s", disk_id)
run_download_disk(disk_id, down_img)
log.info("Comparing images")
qemu_img.compare(image, down_img)
except ClientError as exc:
log.error("%s", exc)
# Skip disk cleanup if client failed
return
finally:
remove_disk(config["common"], sd_name, disk_id)
17 changes: 14 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# and then run "tox" from this directory.

[tox]
envlist = flake8,test-{py36,py38,py39,py310},bench-{py36,py38,py39,py310}
envlist = flake8,test-{py36,py38,py39,py310},bench-{py36,py38,py39,py310},client
skip_missing_interpreters = True
whitelist_externals =
ip
Expand All @@ -25,8 +25,19 @@ commands_pre =
/usr/bin/python3 setup.py build_ext --build-lib .
python -c 'from test import testutil; print("ipv6 supported: %s" % testutil.ipv6_enabled())'
commands =
test: pytest -m 'not benchmark' --cov=ovirt_imageio --durations=10 {posargs}
bench: pytest -m 'benchmark' -vs {posargs}
test: pytest -m 'not benchmark' --ignore=test/client --cov=ovirt_imageio --durations=10 {posargs}
bench: pytest -m 'benchmark' -vs --ignore=test/client {posargs}

[testenv:client]
setenv =
CLIENT_TEST_CONF = {env:CLIENT_TEST_CONF:{toxinidir}/test/client/client_tests.conf}
deps =
pytest
pytest-timeout
pyyaml
ovirt-engine-sdk-python
commands =
pytest -vs --timeout 200 {posargs} test/client

[testenv:flake8]
sitepackages = False
Expand Down

0 comments on commit 8e84a59

Please sign in to comment.