tests/lib: Add a new unittest type to simplify launching test programs

We were reusing the same logic everywhere, while we can just reuse an
unique class to base our tests on that avoids having to copy-and-paste
code for no good reason
This commit is contained in:
Marco Trevisan (Treviño)
2025-02-05 00:58:29 +01:00
parent 4bcd99de43
commit 00ebf4e1eb
11 changed files with 234 additions and 407 deletions

View File

@@ -22,7 +22,6 @@
"""Integration tests for glib-genmarshal utility."""
import collections
import os
import shutil
import subprocess
@@ -32,16 +31,14 @@ from textwrap import dedent
import unittest
import taptestrunner
import testprogramrunner
# Disable line length warnings as wrapping the C code templates would be hard
# flake8: noqa: E501
Result = collections.namedtuple("Result", ("info", "out", "err", "subs"))
class TestGenmarshal(unittest.TestCase):
class TestGenmarshal(testprogramrunner.TestProgramRunner):
"""Integration test for running glib-genmarshal.
This can be run when installed or uninstalled. When uninstalled, it
@@ -54,58 +51,15 @@ class TestGenmarshal(unittest.TestCase):
convert this test to just check command line behaviour.
"""
# Track the cwd, we want to back out to that to clean up our tempdir
cwd = ""
def setUp(self):
self.timeout_seconds = 10 # seconds per test
self.tmpdir = tempfile.TemporaryDirectory()
self.cwd = os.getcwd()
os.chdir(self.tmpdir.name)
print("tmpdir:", self.tmpdir.name)
if "G_TEST_BUILDDIR" in os.environ:
self.__genmarshal = os.path.join(
os.environ["G_TEST_BUILDDIR"], "..", "glib-genmarshal"
)
else:
self.__genmarshal = shutil.which("glib-genmarshal")
print("genmarshal:", self.__genmarshal)
def tearDown(self):
os.chdir(self.cwd)
self.tmpdir.cleanup()
PROGRAM_NAME = "glib-genmarshal"
PROGRAM_TYPE = testprogramrunner.ProgramType.INTERPRETED
def runGenmarshal(self, *args):
argv = [self.__genmarshal]
# shebang lines are not supported on native
# Windows consoles
if os.name == "nt":
argv.insert(0, sys.executable)
argv.extend(args)
print("Running:", argv)
env = os.environ.copy()
env["LC_ALL"] = "C.UTF-8"
env["G_DEBUG"] = "fatal-warnings"
print("Environment:", env)
# We want to ensure consistent line endings...
info = subprocess.run(
argv,
timeout=self.timeout_seconds,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
universal_newlines=True,
)
info.check_returncode()
out = info.stdout.strip()
err = info.stderr.strip()
return self.runTestProgram(args)
def _getSubs(self):
# Known substitutions for standard boilerplate
subs = {
return {
"standard_top_comment": "This file is generated by glib-genmarshal, do not modify "
"it. This code is licensed under the same license as the "
"containing project. Note that it links to GLib, so must "

View File

@@ -20,19 +20,13 @@
"""Integration tests for gobject-query utility."""
import collections
import os
import shutil
import subprocess
import unittest
import taptestrunner
import testprogramrunner
Result = collections.namedtuple("Result", ("info", "out", "err"))
class TestGobjectQuery(unittest.TestCase):
class TestGobjectQuery(testprogramrunner.TestProgramRunner):
"""Integration test for running gobject-query.
This can be run when installed or uninstalled. When uninstalled, it
@@ -42,44 +36,10 @@ class TestGobjectQuery(unittest.TestCase):
handling of command line arguments, and its exit statuses.
"""
def setUp(self):
self.timeout_seconds = 10 # seconds per test
if "G_TEST_BUILDDIR" in os.environ:
self.__gobject_query = os.path.join(
os.environ["G_TEST_BUILDDIR"], "..", "gobject-query"
)
else:
self.__gobject_query = shutil.which("gobject-query")
print("gobject-query:", self.__gobject_query)
PROGRAM_NAME = "gobject-query"
def runGobjectQuery(self, *args):
argv = [self.__gobject_query]
argv.extend(args)
print("Running:", argv)
env = os.environ.copy()
env["LC_ALL"] = "C.UTF-8"
env["G_DEBUG"] = "fatal-warnings"
print("Environment:", env)
# We want to ensure consistent line endings...
info = subprocess.run(
argv,
timeout=self.timeout_seconds,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
text=True,
encoding="utf-8",
)
info.check_returncode()
out = info.stdout.strip()
err = info.stderr.strip()
result = Result(info, out, err)
print("Output:", result.out)
return result
return self.runTestProgram(args)
def test_help(self):
"""Test the --help argument."""

View File

@@ -161,12 +161,17 @@ if cc.get_id() != 'msvc'
endif
python_tests = {
'genmarshal.py' : {},
'genmarshal.py' : {
'env': {'_G_TEST_PROGRAM_RUNNER_PATH': fs.parent(glib_genmarshal.full_path())},
},
'gobject-query.py' : {
'depends' : gobject_query,
'env': {'_G_TEST_PROGRAM_RUNNER_PATH': fs.parent(gobject_query.full_path())},
'can_fail' : host_system == 'windows',
},
'mkenums.py' : {},
'mkenums.py' : {
'env': {'_G_TEST_PROGRAM_RUNNER_PATH': fs.parent(glib_mkenums.full_path())},
},
}
test_env = environment()
@@ -238,13 +243,18 @@ foreach test_name, extra_args : python_tests
suite += 'failing'
endif
local_test_env = python_test_env
foreach var, value : extra_args.get('env', {})
local_test_env.set(var, value)
endforeach
test(
test_name,
python,
protocol : extra_args.get('protocol', test_protocol),
depends: depends,
args: ['-B', files(test_name)],
env: python_test_env,
env: local_test_env,
suite: suite,
)

View File

@@ -22,22 +22,16 @@
"""Integration tests for glib-mkenums utility."""
import collections
import os
import shutil
import subprocess
import sys
import tempfile
import textwrap
import unittest
import taptestrunner
import testprogramrunner
Result = collections.namedtuple("Result", ("info", "out", "err", "subs"))
class TestMkenums(unittest.TestCase):
class TestMkenums(testprogramrunner.TestProgramRunner):
"""Integration test for running glib-mkenums.
This can be run when installed or uninstalled. When uninstalled, it
@@ -50,27 +44,14 @@ class TestMkenums(unittest.TestCase):
convert this test to just check command line behaviour.
"""
# Track the cwd, we want to back out to that to clean up our tempdir
cwd = ""
PROGRAM_NAME = "glib-mkenums"
PROGRAM_TYPE = testprogramrunner.ProgramType.INTERPRETED
rspfile = False
def setUp(self):
self.timeout_seconds = 10 # seconds per test
self.tmpdir = tempfile.TemporaryDirectory()
self.cwd = os.getcwd()
os.chdir(self.tmpdir.name)
print("tmpdir:", self.tmpdir.name)
if "G_TEST_BUILDDIR" in os.environ:
self.__mkenums = os.path.join(
os.environ["G_TEST_BUILDDIR"], "..", "glib-mkenums"
)
else:
self.__mkenums = shutil.which("glib-mkenums")
print("rspfile: {}, mkenums:".format(self.rspfile), self.__mkenums)
def tearDown(self):
os.chdir(self.cwd)
self.tmpdir.cleanup()
super().setUp()
print("rspfile: {}".format(self.rspfile))
def _write_rspfile(self, argv):
import shlex
@@ -85,39 +66,17 @@ class TestMkenums(unittest.TestCase):
return f.name
def runMkenums(self, *args):
argv = list(args)
if self.rspfile:
rspfile = self._write_rspfile(args)
args = ["@" + rspfile]
argv = [self.__mkenums]
argv = ["@" + rspfile]
# shebang lines are not supported on native
# Windows consoles
if os.name == "nt":
argv.insert(0, sys.executable)
argv.extend(args)
print("Running:", argv)
env = os.environ.copy()
env["LC_ALL"] = "C.UTF-8"
env["G_DEBUG"] = "fatal-warnings"
print("Environment:", env)
# We want to ensure consistent line endings...
info = subprocess.run(
argv,
timeout=self.timeout_seconds,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
universal_newlines=True,
)
info.check_returncode()
out = info.stdout.strip()
err = info.stderr.strip()
return self.runTestProgram(argv)
def _getSubs(self):
# Known substitutions for standard boilerplate
subs = {
return {
"standard_top_comment": "This file is generated by glib-mkenums, do not modify "
"it. This code is licensed under the same license as the "
"containing project. Note that it links to GLib, so must "
@@ -125,11 +84,6 @@ class TestMkenums(unittest.TestCase):
"standard_bottom_comment": "Generated data ends here",
}
result = Result(info, out, err, subs)
print("Output:", result.out)
return result
def runMkenumsWithTemplate(self, template_contents, *args):
with tempfile.NamedTemporaryFile(
dir=self.tmpdir.name, suffix=".template", delete=False