mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 01:03:07 +00:00
vmtest.vm: add --{build,insert}-test-kmod options
When running tests manually with vmtest.vm, it's tedious to set up the test kernel module. Make vmtest.vm.run_in_vm() handle it and add command line options. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
2857739f59
commit
033510afb8
13
setup.py
13
setup.py
@ -200,21 +200,14 @@ class test(Command):
|
|||||||
return make_check_success and test.result.wasSuccessful()
|
return make_check_success and test.result.wasSuccessful()
|
||||||
|
|
||||||
def _run_vm(self, kernel):
|
def _run_vm(self, kernel):
|
||||||
from vmtest.kmod import build_kmod
|
|
||||||
import vmtest.vm
|
import vmtest.vm
|
||||||
|
|
||||||
logger.info("running tests in VM on Linux %s", kernel.release)
|
logger.info("running tests in VM on Linux %s", kernel.release)
|
||||||
|
|
||||||
try:
|
|
||||||
kmod = build_kmod(Path(self.vmtest_dir), kernel)
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
command = rf"""
|
command = rf"""
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
export PYTHON={shlex.quote(sys.executable)}
|
export PYTHON={shlex.quote(sys.executable)}
|
||||||
export DRGN_TEST_KMOD={shlex.quote(str(kmod))}
|
|
||||||
if [ -e /proc/vmcore ]; then
|
if [ -e /proc/vmcore ]; then
|
||||||
"$PYTHON" -Bm unittest discover -t . -s tests/linux_kernel/vmcore {"-v" if self.verbose else ""}
|
"$PYTHON" -Bm unittest discover -t . -s tests/linux_kernel/vmcore {"-v" if self.verbose else ""}
|
||||||
else
|
else
|
||||||
@ -228,7 +221,11 @@ fi
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
returncode = vmtest.vm.run_in_vm(
|
returncode = vmtest.vm.run_in_vm(
|
||||||
command, kernel, Path("/"), Path(self.vmtest_dir)
|
command,
|
||||||
|
kernel,
|
||||||
|
Path("/"),
|
||||||
|
Path(self.vmtest_dir),
|
||||||
|
test_kmod=vmtest.vm.TestKmodMode.BUILD,
|
||||||
)
|
)
|
||||||
except vmtest.vm.LostVMError:
|
except vmtest.vm.LostVMError:
|
||||||
logger.exception("error on Linux %s", kernel.release)
|
logger.exception("error on Linux %s", kernel.release)
|
||||||
|
@ -24,9 +24,8 @@ from vmtest.download import (
|
|||||||
DownloadKernel,
|
DownloadKernel,
|
||||||
download_in_thread,
|
download_in_thread,
|
||||||
)
|
)
|
||||||
from vmtest.kmod import build_kmod
|
|
||||||
from vmtest.rootfsbuild import build_drgn_in_rootfs
|
from vmtest.rootfsbuild import build_drgn_in_rootfs
|
||||||
from vmtest.vm import LostVMError, run_in_vm
|
from vmtest.vm import LostVMError, TestKmodMode, run_in_vm
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -296,7 +295,6 @@ chroot "$1" sh -c 'cd /mnt && pytest -v --ignore=tests/linux_kernel'
|
|||||||
for kernel in downloads:
|
for kernel in downloads:
|
||||||
if not isinstance(kernel, Kernel):
|
if not isinstance(kernel, Kernel):
|
||||||
continue
|
continue
|
||||||
kmod = build_kmod(args.directory, kernel)
|
|
||||||
|
|
||||||
# Skip excessively slow tests when emulating.
|
# Skip excessively slow tests when emulating.
|
||||||
if kernel.arch is HOST_ARCHITECTURE:
|
if kernel.arch is HOST_ARCHITECTURE:
|
||||||
@ -317,7 +315,6 @@ chroot "$1" sh -c 'cd /mnt && pytest -v --ignore=tests/linux_kernel'
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
export PYTHON={shlex.quote(sys.executable)}
|
export PYTHON={shlex.quote(sys.executable)}
|
||||||
export DRGN_TEST_KMOD={shlex.quote(str(kmod))}
|
|
||||||
export DRGN_RUN_LINUX_KERNEL_TESTS=1
|
export DRGN_RUN_LINUX_KERNEL_TESTS=1
|
||||||
if [ -e /proc/vmcore ]; then
|
if [ -e /proc/vmcore ]; then
|
||||||
"$PYTHON" -Bm pytest -v tests/linux_kernel/vmcore
|
"$PYTHON" -Bm pytest -v tests/linux_kernel/vmcore
|
||||||
@ -333,6 +330,7 @@ fi
|
|||||||
kernel,
|
kernel,
|
||||||
args.directory / kernel.arch.name / "rootfs",
|
args.directory / kernel.arch.name / "rootfs",
|
||||||
args.directory,
|
args.directory,
|
||||||
|
test_kmod=TestKmodMode.BUILD,
|
||||||
)
|
)
|
||||||
except LostVMError as e:
|
except LostVMError as e:
|
||||||
print("error:", e, file=sys.stderr)
|
print("error:", e, file=sys.stderr)
|
||||||
|
53
vmtest/vm.py
53
vmtest/vm.py
@ -1,6 +1,7 @@
|
|||||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
import enum
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
@ -20,6 +21,7 @@ from vmtest.download import (
|
|||||||
download,
|
download,
|
||||||
download_kernel_argparse_type,
|
download_kernel_argparse_type,
|
||||||
)
|
)
|
||||||
|
from vmtest.kmod import build_kmod
|
||||||
|
|
||||||
# Script run as init in the virtual machine.
|
# Script run as init in the virtual machine.
|
||||||
_INIT_TEMPLATE = r"""#!/bin/sh
|
_INIT_TEMPLATE = r"""#!/bin/sh
|
||||||
@ -138,6 +140,7 @@ if [ -z "$vport" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
cd {cwd}
|
cd {cwd}
|
||||||
|
{test_kmod}
|
||||||
set +e
|
set +e
|
||||||
setsid -c sh -c {command}
|
setsid -c sh -c {command}
|
||||||
rc=$?
|
rc=$?
|
||||||
@ -192,12 +195,23 @@ def _build_onoatimehack(dir: Path) -> Path:
|
|||||||
return onoatimehack_so
|
return onoatimehack_so
|
||||||
|
|
||||||
|
|
||||||
|
class TestKmodMode(enum.Enum):
|
||||||
|
NONE = 0
|
||||||
|
BUILD = 1
|
||||||
|
INSERT = 2
|
||||||
|
|
||||||
|
|
||||||
class LostVMError(Exception):
|
class LostVMError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def run_in_vm(
|
def run_in_vm(
|
||||||
command: str, kernel: Kernel, root_dir: Optional[Path], build_dir: Path
|
command: str,
|
||||||
|
kernel: Kernel,
|
||||||
|
root_dir: Optional[Path],
|
||||||
|
build_dir: Path,
|
||||||
|
*,
|
||||||
|
test_kmod: TestKmodMode = TestKmodMode.NONE,
|
||||||
) -> int:
|
) -> int:
|
||||||
if root_dir is None:
|
if root_dir is None:
|
||||||
if kernel.arch is HOST_ARCHITECTURE:
|
if kernel.arch is HOST_ARCHITECTURE:
|
||||||
@ -205,6 +219,14 @@ def run_in_vm(
|
|||||||
else:
|
else:
|
||||||
root_dir = build_dir / kernel.arch.name / "rootfs"
|
root_dir = build_dir / kernel.arch.name / "rootfs"
|
||||||
|
|
||||||
|
if test_kmod == TestKmodMode.NONE:
|
||||||
|
test_kmod_command = ""
|
||||||
|
else:
|
||||||
|
kmod = build_kmod(build_dir, kernel)
|
||||||
|
test_kmod_command = f"export DRGN_TEST_KMOD={shlex.quote(str(kmod))}"
|
||||||
|
if test_kmod == TestKmodMode.INSERT:
|
||||||
|
test_kmod_command += '\ninsmod "$DRGN_TEST_KMOD"'
|
||||||
|
|
||||||
qemu_exe = "qemu-system-" + kernel.arch.name
|
qemu_exe = "qemu-system-" + kernel.arch.name
|
||||||
match = re.search(
|
match = re.search(
|
||||||
r"QEMU emulator version ([0-9]+(?:\.[0-9]+)*)",
|
r"QEMU emulator version ([0-9]+(?:\.[0-9]+)*)",
|
||||||
@ -278,6 +300,7 @@ def run_in_vm(
|
|||||||
),
|
),
|
||||||
command=shlex.quote(command),
|
command=shlex.quote(command),
|
||||||
kdump_needs_nosmp="" if kvm_args else "export KDUMP_NEEDS_NOSMP=1",
|
kdump_needs_nosmp="" if kvm_args else "export KDUMP_NEEDS_NOSMP=1",
|
||||||
|
test_kmod=test_kmod_command,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
init_path.chmod(0o755)
|
init_path.chmod(0o755)
|
||||||
@ -403,6 +426,22 @@ if __name__ == "__main__":
|
|||||||
type=Path,
|
type=Path,
|
||||||
help="directory to use as root directory in VM (default: / for the host architecture, $directory/$arch/rootfs otherwise)",
|
help="directory to use as root directory in VM (default: / for the host architecture, $directory/$arch/rootfs otherwise)",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--build-test-kmod",
|
||||||
|
dest="test_kmod",
|
||||||
|
action="store_const",
|
||||||
|
const=TestKmodMode.BUILD,
|
||||||
|
default=argparse.SUPPRESS,
|
||||||
|
help="build the drgn test kernel module and define the DRGN_TEST_KMOD environment variable in the VM",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--insert-test-kmod",
|
||||||
|
dest="test_kmod",
|
||||||
|
action="store_const",
|
||||||
|
const=TestKmodMode.INSERT,
|
||||||
|
default=argparse.SUPPRESS,
|
||||||
|
help="insert the drgn test kernel module. Implies --build-test-kmod",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"command",
|
"command",
|
||||||
type=str,
|
type=str,
|
||||||
@ -420,6 +459,8 @@ if __name__ == "__main__":
|
|||||||
kernel = next(download(args.directory, [args.kernel])) # type: ignore[assignment]
|
kernel = next(download(args.directory, [args.kernel])) # type: ignore[assignment]
|
||||||
if not hasattr(args, "root_directory"):
|
if not hasattr(args, "root_directory"):
|
||||||
args.root_directory = None
|
args.root_directory = None
|
||||||
|
if not hasattr(args, "test_kmod"):
|
||||||
|
args.test_kmod = TestKmodMode.NONE
|
||||||
|
|
||||||
try:
|
try:
|
||||||
command = (
|
command = (
|
||||||
@ -427,7 +468,15 @@ if __name__ == "__main__":
|
|||||||
if args.command
|
if args.command
|
||||||
else "sh -i"
|
else "sh -i"
|
||||||
)
|
)
|
||||||
sys.exit(run_in_vm(command, kernel, args.root_directory, args.directory))
|
sys.exit(
|
||||||
|
run_in_vm(
|
||||||
|
command,
|
||||||
|
kernel,
|
||||||
|
args.root_directory,
|
||||||
|
args.directory,
|
||||||
|
test_kmod=args.test_kmod,
|
||||||
|
)
|
||||||
|
)
|
||||||
except LostVMError as e:
|
except LostVMError as e:
|
||||||
print("error:", e, file=sys.stderr)
|
print("error:", e, file=sys.stderr)
|
||||||
sys.exit(args.lost_status)
|
sys.exit(args.lost_status)
|
||||||
|
Loading…
Reference in New Issue
Block a user