tools: merge generate-test-case{,s} scripts

The fact that we have two scripts and one captures output of the other
makes it hard to use in scenarios where the test case generation often
fails. This output capturing results in subtle bugs like described in
issue: https://github.com/osbuild/osbuild-composer/issues/769

This patch merge these two scripts and use class to organize it
instead of files.
This commit is contained in:
Martin Sehnoutka 2020-06-14 14:48:22 +02:00 committed by Tom Gundersen
parent 4da9c3389b
commit 7be8cefab9
2 changed files with 61 additions and 86 deletions

View file

@ -1,82 +0,0 @@
#!/usr/bin/python3
import argparse
import subprocess
import json
import os
import sys
import tempfile
'''
This script generates a json test case. It accepts a test_case_request as input through standard input.
{
"boot": {
"type": "qemu"
},
"compose-request": {
"distro": "fedora-30",
"arch": "x86_64",
"image-type": "qcow2",
"filename": "disk.qcow2",
"blueprint": {}
}
}
It then outputs a json test case as standard output.
'''
def get_subprocess_stdout(*args, **kwargs):
sp = subprocess.run(*args, **kwargs, stdout=subprocess.PIPE)
if sp.returncode != 0:
sys.stderr.write(sp.stdout)
sys.exit(1)
return sp.stdout
def run_osbuild(manifest, store, output):
with tempfile.TemporaryFile(dir="/tmp", prefix="osbuild-test-case-generator-", suffix=".log") as log:
try:
subprocess.run(["osbuild",
"--store", store,
"--output-directory", output,
"-"],
stdout=log,
stderr=subprocess.STDOUT,
check=True,
encoding="utf-8",
input=json.dumps(manifest))
except:
print(log.read())
def main(test_case, no_image_info, store):
compose_request = json.dumps(test_case["compose-request"])
pipeline_command = ["go", "run", "./cmd/osbuild-pipeline", "-"]
test_case["manifest"] = json.loads(get_subprocess_stdout(pipeline_command, input=compose_request, encoding="utf-8"))
pipeline_command = ["go", "run", "./cmd/osbuild-pipeline", "-rpmmd", "-"]
test_case["rpmmd"] = json.loads(get_subprocess_stdout(pipeline_command, input=compose_request, encoding="utf-8"))
if no_image_info == False:
with tempfile.TemporaryDirectory(dir=store, prefix="test-case-output-") as output:
run_osbuild(test_case["manifest"], store, output)
image_file = os.path.join(output, test_case["compose-request"]["filename"])
image_info = get_subprocess_stdout(["tools/image-info", image_file], encoding="utf-8")
test_case["image-info"] = json.loads(image_info)
return test_case
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Generate test cases")
parser.add_argument("store", metavar="DIRECTORY", type=os.path.abspath, help="path to the osbuild store")
parser.add_argument("--no-image-info", action='store_true', help="skip image info (re)generation")
args = parser.parse_args()
test_case_request = json.load(sys.stdin)
test_case = main(test_case_request, args.no_image_info, args.store)
sys.stdout.write(json.dumps(test_case))
sys.exit()

View file

@ -5,6 +5,7 @@ import subprocess
import json
import os
import sys
import tempfile
def get_subprocess_stdout(*args, **kwargs):
sp = subprocess.run(*args, **kwargs, stdout=subprocess.PIPE)
@ -14,6 +15,64 @@ def get_subprocess_stdout(*args, **kwargs):
return sp.stdout
def run_osbuild(manifest, store, output):
with tempfile.TemporaryFile(dir="/tmp", prefix="osbuild-test-case-generator-", suffix=".log") as log:
try:
subprocess.run(["osbuild",
"--store", store,
"--output-directory", output,
"-"],
stdout=log,
stderr=subprocess.STDOUT,
check=True,
encoding="utf-8",
input=json.dumps(manifest))
except:
print(log.read())
class TestCaseGenerator:
'''
This class generates a json test case. It accepts a test_case_request as input to the constructor:
{
"boot": {
"type": "qemu"
},
"compose-request": {
"distro": "fedora-30",
"arch": "x86_64",
"image-type": "qcow2",
"filename": "disk.qcow2",
"blueprint": {}
}
}
It then outputs a json test case from the get_test_case() method.
'''
def __init__(self, test_case_request):
self.test_case = test_case_request
def get_test_case(self, no_image_info, store):
compose_request = json.dumps(self.test_case["compose-request"])
pipeline_command = ["go", "run", "./cmd/osbuild-pipeline", "-"]
self.test_case["manifest"] = json.loads(get_subprocess_stdout(pipeline_command, input=compose_request, encoding="utf-8"))
pipeline_command = ["go", "run", "./cmd/osbuild-pipeline", "-rpmmd", "-"]
self.test_case["rpmmd"] = json.loads(get_subprocess_stdout(pipeline_command, input=compose_request, encoding="utf-8"))
if no_image_info == False:
with tempfile.TemporaryDirectory(dir=store, prefix="test-case-output-") as output:
run_osbuild(self.test_case["manifest"], store, output)
image_file = os.path.join(output, self.test_case["compose-request"]["filename"])
image_info = get_subprocess_stdout(["tools/image-info", image_file], encoding="utf-8")
self.test_case["image-info"] = json.loads(image_info)
return self.test_case
def main(distro, arch, image_types, keep_image_info, store, output):
with open("tools/test-case-generators/format-request-map.json") as format_request_json:
format_request_dict = json.load(format_request_json)
@ -26,10 +85,8 @@ def main(distro, arch, image_types, keep_image_info, store, output):
test_case_request["compose-request"]["distro"] = distro
test_case_request["compose-request"]["arch"] = arch
test_case_request["compose-request"]["repositories"] = repos_dict[distro][arch]
args = ["tools/test-case-generators/generate-test-case", store]
if keep_image_info:
args += ["--no-image-info"]
test_case = json.loads(get_subprocess_stdout(args, input=json.dumps(test_case_request), encoding="utf-8"))
generator = TestCaseGenerator(test_case_request)
test_case = generator.get_test_case(keep_image_info, store)
name = distro.replace("-", "_") + "-" + arch + "-" + output_format.replace("-", "_") + "-boot.json"
file_name = output + "/" + name
if keep_image_info: