summaryrefslogtreecommitdiffstats
path: root/tests
Commit message (Collapse)AuthorAgeFilesLines
* tests: fix lxc lifecycle suite hang and tighten download-skip predicateHEADmasterBruce Ashfield5 days1-5/+62
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two diagnostics-quality fixes to test_lxc_runtime.py uncovered by running the full suite after lxc-networking landed in the lxc profile: 1. test_start used `exit $rc` after the lxc-start invocation to propagate the exit code through run_cmd's marker harness. With lxc-networking now installed, lxc-start succeeds (rc=0) and the `exit 0` terminates the guest's interactive login shell, which triggers getty respawn. Every subsequent lifecycle test then times out waiting for its marker because the new getty is sitting at the login prompt with no auto-login. Wrap the cleanup in `( exit $LXC_RC )` so only a subshell exits; the outer login shell stays alive for the next test. While here, pre-flight checks for lxc-net.service and the lxcbr0 link surface in the failure message — the "ABORTING" path that bit us during bring-up gave no hint which precondition was missing. 2. test_create_alpine_via_download treated any non-zero lxc-create rc as "network unreachable" and skipped. That swallowed a stale "Container already exists" left over from an interrupted previous run (or from manual poking), silently turning a real test-harness bug into a green skip. Pre-clean with `lxc-destroy --force` (best-effort, ignores rc), then match a list of known network-error markers explicitly. Any other failure is a real bug and fails the test with the full lxc-create output instead of hiding behind pytest.skip. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: use CONTAINER_PROFILE and surface runqemu errors in lxc fixtureBruce Ashfield5 days1-9/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two correctness improvements to the lxc runtime test fixture. 1. Switch the build from CONTAINER_IMAGE_HOST_EXTRA_INSTALL = "lxc" to CONTAINER_PROFILE = "lxc". The original fixture set CONTAINER_IMAGE_HOST_EXTRA_INSTALL to force lxc into the rootfs without depending on a profile fragment, because at the time no lxc profile existed. Now that container-host-lxc.conf is in tree, the test should exercise the same path real users take — which is the entire point of a runtime test. Using the profile also pulls in lxc-networking and lxc-templates automatically (via packagegroup-lxc), where the original "just install lxc" approach silently left a half-broken LXC the test couldn't usefully verify. 2. Capture the runqemu output to a file and surface it in the pexpect.EOF failure message. pexpect's default 100-character "before" buffer truncates runqemu's actual error to the trailing fragment, which is rarely enough to diagnose the failure. Boot failures during fixture setup now print the last 60 lines of the runqemu log into the pytest failure message and leave the full log at /tmp/test_lxc_runtime-runqemu.log for follow-up. When the lxc image still wasn't booting cleanly, this is what made the "lxc-net.service could not be found" / bridge-missing root cause visible without re-instrumenting the fixture. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add lxc runtime tests with download-template regressionmaster-nextBruce Ashfield6 days2-0/+291
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The "lxc was tested" claim during the recent runtime testing sweep was actually transitive — incus runs against LXC libraries under the hood, so incus passing was treated as evidence that LXC itself worked. That inference was wrong: incus uses its own go bindings into liblxc rather than the lxc-* command-line tools, and the breakage Ferry Toth reported on 2026-06-13 sat entirely in templates/lxc-download.in (a script invoked by lxc-create, never reached through incus). The bug would not have been caught by any existing test in the layer. Add tests/test_lxc_runtime.py to close the gap. The suite boots container-image-host with CONTAINER_IMAGE_HOST_EXTRA_INSTALL=lxc, then runs three groups of checks against the live guest: TestLxcInstalled — sanity that lxc-create, lxc-start and lxc --version work at all. Catches packaging and PATH-level regressions. TestLxcDownloadTemplate — explicit regression for the templates-actually-create-DOWNLOAD_TEMP-directory.patch failure mode. Runs `lxc-create --template download` and asserts the broken early-mktemp error string ("mktemp: failed to create file via template '-d…") does not appear in the output. We deliberately do not require the download itself to succeed — the bug fires before any HTTP request, so the test stays meaningful on air-gapped CI where the actual fetch would fail for unrelated reasons. TestLxcContainerLifecycle (@pytest.mark.network) — full end-to-end: create from images.linuxcontainers.org, start, attach, stop, destroy. Marked @network so offline runners deselect it cleanly. The regression test above is the primary guard; this is depth. Also register the lxc marker in pytest.ini so collection doesn't warn. The test conventions (pexpect-driven runqemu boot, marker-delimited command runner, TERM=dumb to suppress shell integration escape sequences) match test_incus_runtime.py and test_xen_runtime.py so the three suites read consistently. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add requirements.txtTim Orling8 days1-0/+3
| | | | | | | Add requirements.txt to allow versions to be pinned. Signed-off-by: Tim Orling <tim.orling@konsulko.com> Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add containerd and CRI-O recipe and runtime testsBruce Ashfield8 days1-0/+358
| | | | | | | | | | | | | | | | | | | | | | | 35 tests across three tiers: Tier 1 (static): containerd recipe checks (virtual/containerd provider, systemd service, CNI networking, ctr/shim install), profile config, packagegroup, nerdctl and cri-tools recipe existence, CRI-O recipe checks (seccomp requirement, systemd service, CNI/conmon/runtime deps). Tier 2 (build): containerd, nerdctl, and container-image-host with containerd profile build verification. Tier 3 (boot): containerd service status, ctr/nerdctl availability and version, namespace listing, runtime availability, CNI plugins, nerdctl pull/run/images cycle with busybox. The boot tests build container-image-host with CONTAINER_PROFILE=containerd automatically. CRI-O boot tests are not included — CRI-O requires a kubelet to drive it, so runtime testing is covered by k3s tests when k3s is configured to use CRI-O as its CRI. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add libvirt recipe and runtime testsBruce Ashfield8 days1-0/+468
| | | | | | | | | | | | | | | | | | | | | | | 46 tests across three tiers: Tier 1 (static, no build): Recipe structure, PACKAGECONFIG options, hook_support.py python3 compatibility (text mode, raw string regex, syntax validation), service files, patch files, kvm-image-minimal recipe checks. Tier 2 (build): libvirt and kvm-image-minimal build verification. Tier 3 (boot): libvirtd service status, virtlockd socket, virsh connectivity via monolithic daemon socket, capabilities, nodeinfo, domain listing, default network, hook script installation and permissions, qemu user and libvirt group existence. The boot tests use the explicit monolithic daemon socket path (qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock) because libvirt v12 defaults to modular daemons (virtqemud) but the kvm-image-minimal recipe runs the monolithic libvirtd. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: remove redundant DISTRO_FEATURES appends from build fixturesBruce Ashfield8 days3-3/+2
| | | | | | | | | | | | | | | | | The -R conf files used by test build fixtures appended DISTRO_FEATURES values that are already provided by meta-virt-host.conf (virtualization, vcontainer, systemd). BitBake tracks append operations in task hashes, so a duplicate append changes the hash and invalidates sstate for every recipe that depends on DISTRO_FEATURES — causing full rebuilds even when the image was just built. Only append features genuinely needed by the test profile and not already present in the base config: - k3s: append only "k3s" (virtualization already in base) - xen: append only "xen vxn" (virtualization systemd vcontainer in base) - incus: no append needed (CONTAINER_PROFILE alone is sufficient) Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* k3s: fix pause image reference for containerd v2Bruce Ashfield8 days1-3/+8
| | | | | | | | | | | | | | | | | | K3s's default pause image reference "rancher/mirrored-pause:3.6" is a short name that containerd v1 auto-expanded to the fully qualified "docker.io/rancher/mirrored-pause:3.6". The k3s v1.36 uprev moved to containerd v2, which uses a new CRI plugin (io.containerd.cri.v1) with a pinned_images config instead of the old sandbox_image. Containerd v2 no longer auto-expands short names when looking up pinned images, causing every pod sandbox creation to fail with "image not found" even though the image is present in the containerd image store under its fully qualified name. Pass --pause-image docker.io/rancher/mirrored-pause:3.6 in both the server and agent systemd service files to use the fully qualified reference that containerd v2 can resolve. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: make k3s, incus, and xen tests self-containedBruce Ashfield8 days3-49/+159
| | | | | | | | | | | | | | | | | | | These boot tests previously required manual local.conf changes to set CONTAINER_PROFILE, DISTRO_FEATURES, and other variables before the image could be built and tested. This meant complete test coverage required editing local.conf between runs. Add build fixtures that use bitbake -R with a temporary conf file to inject the required variables automatically: - k3s: builds container-image-host with CONTAINER_PROFILE=k3s-host - incus: builds container-image-host with CONTAINER_PROFILE=incus - xen: builds xen-image-minimal with xen/vxn DISTRO_FEATURES Each test module now builds its own image before booting, using the same run_bitbake + extra_vars pattern established in test_container_cross_install.py. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: fix image ID parsing and 9p assertion patternsBruce Ashfield8 days2-22/+25
| | | | | | | | | | | | | | test_vdkr_registry.py: Docker's images output changed from separate REPOSITORY TAG IMAGE_ID columns to combined IMAGE ID DISK_USAGE columns. The parser grabbed the disk usage (8.45MB) as the image ID. Handle both old and new formats. test_container_registry_script.py: The secure registry tests checked for literal 'virtfs' and 'cashare' strings in vrunner.sh, but the 9p share setup was refactored to use hv_build_9p_opts(). Update assertions to match the current abstraction. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: parametrize boot tests over container profiles for full coverageBruce Ashfield8 days2-209/+227
| | | | | | | | | | | | | | | | | | | | | | | | | | The boot tests (TestBundledContainersBoot, TestCustomServiceFileBoot) previously depended on whatever CONTAINER_PROFILE was in local.conf, skipping docker checks when podman was configured and vice versa. Getting complete coverage required manually editing local.conf and running the tests twice. Add --container-profiles pytest option (default: docker,podman) and a profiled_session fixture that builds container-image-host with each profile via a temporary bitbake -R conf file, boots it, and runs all checks. Both docker and podman get a full build-boot-verify cycle in a single test run with no local.conf changes. Also fix: - run_bitbake() gains extra_vars parameter for bitbake -R overrides - Strip OSC 3008 shell integration escape sequences from run_command output (BusyBox shell emits these, corrupting file paths used in subsequent commands) - Use known file paths for service file content checks instead of extracting paths from ls output (avoids escape sequence corruption) - Add test_bundle_class_unpack_enabled to catch do_unpack[noexec] regression Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: fix container-cross-install bitbake invocation and busybox compatBruce Ashfield8 days2-20/+34
| | | | | | | | | | | | | | | | | | | | | | | | Three issues in test_container_cross_install.py: - run_bitbake() called bitbake directly, requiring the OE build environment to be pre-sourced. test_multilayer_oci.py wraps bitbake in 'bash -c source oe-init-build-env && bitbake' which is self- contained. Adopt the same pattern so tests work from any shell. - test_vdkr_initramfs_create and test_vpdmn_initramfs_create built the initramfs recipes in the main config, but these recipes require the vruntime multiconfig distro. Use mc:vruntime-x86-64: prefix. - test_systemd_services_directory_exists used 'head -5' which BusyBox does not support (requires 'head -n 5'). The container-image-host image uses BusyBox when built without coreutils. Also fix conftest.py VdkrRunner and VpdmnRunner ensure_memres() to default no_registry=True, so pulled images use short names (alpine:latest) rather than registry-prefixed names from the baked-in VDKR_DEFAULT_REGISTRY config. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* vcontainer: add BBMASK for parse savings and suppress layer warningsBruce Ashfield2026-05-101-4/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | The initial vcontainer distro had no BBMASK at all, making it effectively poky with fewer DISTRO_FEATURES. Every multiconfig parsed the entire recipe universe even though container image builds only need a small subset. With 4+ multiconfigs, the parse overhead is significant. Add vcontainer-bbmask.inc as a lighter alternative to vruntime's aggressive BBMASK. It masks the same categories irrelevant to any container/VM build (graphics, multimedia, desktop, virtualization platforms, orchestration tools, meta-python, meta-filesystems, meta-webserver) but keeps the OCI tooling that vruntime blocks: umoci, container-registry, image recipes, sloci, oci-image-tools. Masking entire layers (meta-python, meta-filesystems, meta-webserver) produces BBFILE_PATTERN warnings because the layers are registered in bblayers.conf (shared with the main build) but have zero recipes after masking. BitBake provides BBFILE_PATTERN_IGNORE_EMPTY_<collection> to suppress this, but checks it on self.data (the base datastore), not per-multiconfig datastores. Setting it in the distro config has no effect. Move the suppression to meta-virt-host.conf which is included by the main build's local.conf and therefore visible to the base datastore. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* container-registry: add multi-arch OCI push support and testsBruce Ashfield2026-05-101-0/+493
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The registry push script (container-registry-index.bb) treated all OCI directories as single-arch, calling 'skopeo copy oci:<dir>' which fails with "more than one image in oci, choose an image" when the directory contains a multi-arch image index. The original push implementation predated multi-arch OCI support and only handled the single-manifest case. Detect multi-arch OCI Image Index directories (both flat and nested layouts) in the direct-path push mode and use 'skopeo copy --all' to push the entire manifest list to the registry in one operation. This preserves the multi-platform structure so that clients pulling from the registry automatically get the correct architecture. Also strip the '-multiarch' suffix from directory names when deriving the registry image name, so container-base-multiarch-multiarch-oci pushes as 'container-base' rather than 'container-base-multiarch'. Add build-profiles.md documentation for the vcontainer distro, container multiconfigs, and multi-arch container build workflow. Add test_vcontainer_distro.py with 54 tests across three tiers: - Tier 1: Static file assertions (vruntime-base.inc, vcontainer.conf, multiconfigs, bbclass defaults, recipe structure) - Tier 2: Cross-file consistency (shared base, distro-MC alignment, bbclass-to-multiconfig file matching) - Tier 3: Build output verification (OCI index structure, platform entries, blob integrity, manifest validation) Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add vcontainer --config / VDKR_CONFIG auth plumbing testsTim Orling2026-04-291-0/+642
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add a new pytest module (tests/test_vcontainer_auth_config.py) covering the registry-auth-config feature introduced in the previous commit. Split into two tiers: TestAuthConfigStaticPlumbing (40 static/shell-level assertions): - vrunner.sh: AUTH_CONFIG picks up VDKR_CONFIG/VPDMN_CONFIG; --config parsing; validate_auth_config and setup_auth_share definitions; every validator reject rule (symlink / non-regular / unreadable / missing / <2B / >1MiB / mode whitelist 400|600|200 / non-owner WARN); 0700 staging dir and 0400 staged file; readonly=on on the 9p share; dedicated ${TOOL_NAME}_auth tag. Critically also asserts that AUTH_CONFIG, VDKR_CONFIG and VPDMN_CONFIG never appear in KERNEL_APPEND - only the ${CMDLINE_PREFIX}_auth=1 flag does. - vcontainer-common.sh: env-var init, --config parsing, AUTH_CONFIG forwarding via --config to vrunner, and show_usage documentation. - vcontainer-init-common.sh: RUNTIME_AUTH default, cmdline parsing, mount_auth_share/unmount_auth_share presence, dedicated per-runtime ${VCONTAINER_RUNTIME_NAME}_auth tag, and the ro,nosuid,nodev,noexec mount options. - vdkr-init.sh: install_auth_config present, writes to /root/.docker/config.json with 0600 and 0700 parent, mount + unmount pairing, precedence NOTE logged, and ordering after install_registry_ca so --config wins over --registry-user/-pass. - vpdmn-init.sh: writes to /run/containers/0/auth.json with matching modes, exports REGISTRY_AUTH_FILE, mount/unmount pairing, and ordering after verify_podman. - README.md: --config section exists and documents both env vars and both runtime target paths. TestAuthConfigValidator (13 functional cases): - Extracts validate_auth_config() from vrunner.sh with a brace-matching parser, sources it in a bash subshell with a stubbed log() helper, and drives it with real files: accepts modes 0600 / 0400, accepts the 2-byte minimum "{}", rejects missing / symlink / directory / empty / 1-byte / >1 MiB / 0644 (world-readable) / 0640 / 0700 (owner-exec) / 0000 (unreadable, skipped when running as root). Path resolution is resilient: VCONTAINER_FILES_DIR env override first, otherwise repo-relative to the test file, falling back to the /opt/bruce/poky path used elsewhere in the suite. No tests need QEMU, a registry, or network. All 53 tests complete in ~0.1s. Add tests/__pycache__ to .gitignore. AI-Generated: Claude Cowork Opus 4.7 Signed-off-by: Tim Orling <tim.orling@konsulko.com> Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* test_vdkr_registry: fix test_image_requires_subcommandTim Orling2026-04-281-1/+5
| | | | | | | | | vdkr.run() merges stderr into stdout (see conftest.py), so the error message ends up in result.stdout even though the script writes it to stderr (>&2). Signed-off-by: Tim Orling <tim.orling@konsulko.com> Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: fix FD inheritance in test harness for all vdkr/vpdmn commandsBruce Ashfield2026-04-223-17/+38
| | | | | | | | | | | | | | | | | | Change VdkrRunner.run() and VpdmnRunner.run() to use Popen with start_new_session=True, stdin=DEVNULL, and file-based stdout instead of subprocess.run(capture_output=True). This prevents daemon background processes from inheriting pipe FDs, which causes communicate() to hang in CI/test harness environments (e.g., buildbot). The fix applies to all commands, not just memres start, because any vdkr command can auto-start the daemon (auto-daemon is enabled by default). Also fix test_volume_mount_requires_memres to check both stdout and stderr for the error message, since stderr is now merged into stdout by the Popen approach. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: fix memres start hanging in subprocess.runBruce Ashfield2026-04-221-2/+58
| | | | | | | | | | | | | | | | | | | | | | memres start spawns background processes (QEMU VM, idle watchdog) that persist after the vrunner script exits. When invoked via subprocess.run(capture_output=True), these background processes inherit the pipe file descriptors, preventing communicate() from returning until all pipe holders exit — which can be 30+ minutes (the idle timeout). Fix by using Popen with: - stdin=subprocess.DEVNULL (no inherited stdin pipe) - file-based stdout (no pipe FDs to inherit) - start_new_session=True (new process group, so wait() only waits for the parent script, not the background children) This matches the behavior when running from a shell, where the daemon processes are fully detached from the caller's FD table. Applied to both VdkrRunner and VpdmnRunner memres_start methods. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add @pytest.mark.memres to daemon-dependent testsBruce Ashfield2026-04-222-0/+16
| | | | | | | | | | | | | | | | | | | | | | Test classes that depend on vmemres (daemon mode) were not marked, causing them to run even when filtered with '-m "not memres"'. This caused timeout failures on CI/buildbot environments where KVM may not be available and daemon startup exceeds the test timeout. Mark the following classes with @pytest.mark.memres in both test_vdkr.py and test_vpdmn.py: - TestMemresBasic - TestPortForwarding (vdkr only) - TestContainerLifecycle - TestVolumeMounts - TestSystem - TestVstorage - TestRun - TestAutoStartDaemon (vdkr only) - TestDynamicPortForwarding (vdkr only) - TestPortForwardRegistry (vdkr only) Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* incus: add runtime test suiteBruce Ashfield2026-04-092-0/+158
| | | | | | | | | | | | pexpect-based tests covering: - Daemon startup via systemd - incus-admin group creation - incus admin init --minimal - Alpine container launch, exec, stop, delete Run: pytest tests/test_incus_runtime.py -v --machine qemux86-64 Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: update k3s multi-node to use kernel cmdline role setupBruce Ashfield2026-04-071-53/+31
| | | | | | | | | | | | | | | | | | Update the multi-node test fixture to use kernel cmdline parameters (k3s.role, k3s.node-ip, k3s.node-name) instead of manual IP configuration and k3s restart. The k3s-role-setup.service handles networking and role switching automatically on boot. - Pass kernel_append to K3sRunner for k3s.role and k3s.node-ip - Remove manual ip-addr-add and k3s stop/restart from fixture - Use k3s-get-token helper to extract join token on server - Agent starts k3s agent manually with extracted token (token not known at boot time) - Remove _QEMU_ARCH_CONFIG dict (moved to run-qemu-vm.sh script) All 10 tests pass: 5 single-node + 5 multi-node. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests, k3s: update test suite and README for multi-nodeBruce Ashfield2026-04-071-100/+30
| | | | | | | | | | | | | | | | | test_k3s_runtime.py: - Use run-qemu-vm.sh script for multi-node QEMU launches instead of inline command building (shared infrastructure with manual testing) - Resolve script path to absolute for pexpect compatibility - Accept >= 1 Ready node in single-node test (persistent rootfs state) README.md: - Complete rewrite with current build profile workflow - Document single-node quick start and multi-node cluster setup - Document kernel cmdline parameters for role-based boot - Document k3s-get-token helper, packages, and useful commands - Add automated testing instructions Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: fix k3s multi-node test suiteBruce Ashfield2026-04-061-8/+62
| | | | | | | | | | | | | | | | | | | | | | | Fix several issues discovered during multi-node testing: - Find native QEMU binary from build sysroots-components instead of relying on PATH (qemu-system-native is not in OE build env PATH) - Set LD_LIBRARY_PATH for native QEMU shared library dependencies (libSDL2, etc. from native sysroots) - Add if=virtio to drive parameter so root device appears as /dev/vda - Add CNI bin dirs to PATH when starting k3s manually (systemd service has the PATH fix but manual launch does not) - Wipe server TLS/cred/db state and kubeconfig before restarting with cluster IPs to avoid stale certificate errors (cert only valid for DHCP IP, not 192.168.50.1) - Add --tls-san for cluster IP to server start - Wipe agent k3s state to avoid "not authorized" from stale tokens - Remove server-only config.yaml on agent (disable-cloud-controller flag crashes the agent) - Set unique --node-name on agent to prevent hostname collision when both VMs boot from the same image Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add k3s runtime test suiteBruce Ashfield2026-04-061-0/+731
| | | | | | | | | | | | | | | | | | | | | | | | | | | Add test_k3s_runtime.py with 10 tests for k3s single-node and multi-node verification: Single-node (5 tests): - Boot, verify k3s binary and service unit - Start k3s server, wait for node Ready - Verify 1 node in Ready state - Deploy a busybox pod, verify Running - Delete pod, verify cleanup Multi-node (5 tests): - Boot 2 VMs via QEMU socket networking - Verify inter-VM ping on socket network - Start k3s server on VM1, join agent on VM2 - Verify 2 nodes Ready - Deploy 2-replica deployment, verify scheduling Uses architecture-aware QEMU configuration (x86-64 and arm64 supported). Multi-node tests launch QEMU directly (not runqemu) to support two concurrent VMs. kubectl commands use KUBECONFIG instead of embedded 'k3s kubectl' which is not available in the Yocto build. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* vruntime, vrunner, conftest: fix multiconfig and batch import issuesBruce Ashfield2026-04-061-0/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | vruntime.conf: - Reset all VIRTUAL-RUNTIME_container_* variables to prevent CONTAINER_PROFILE selections from leaking into vruntime multiconfigs (e.g., podman profile pulling netavark into vruntime builds) - Disable ptest for glib-2.0 — its -ptest RDEPENDS chain (python3-dbusmock -> python3-pygobject -> cairo -> fontconfig) pulls the entire graphics stack which is masked in vruntime - OE-core commit 159148f4de2 replaced DISTRO_FEATURES_BACKFILL_CONSIDERED with DISTRO_FEATURES_OPTED_OUT. The old variable no longer has any effect, which meant ptest, gobject-introspection-data, wayland, and other features were no longer being blocked in vruntime builds. This caused glib-2.0's ptest RDEPENDS to pull in the cairo → fontconfig → freetype graphics stack, which is masked by the vruntime BBMASK. - Set PREFERRED_PROVIDER_virtual/runc with strong assignment to ensure the unified runc recipe is used vrunner.sh: - Fix batch import exit code handling: wrap import chain in subshell and make the images listing best-effort. The previous '&& podman images' caused false failures when podman images couldn't initialize its network backend. Using 'exit' was also wrong as the command runs inside PID 1 init's eval — exit kills init causing kernel panic. vpdmn-rootfs-image.bb: - Switch from netavark to CNI networking — netavark's dependency chain (nmap -> libpcap -> bluez5 -> python3-pygobject -> cairo) cannot be built under the vruntime BBMASK environment - Add nsswitch.conf override (files-only backend) to prevent libnss_systemd segfaults — the vruntime VM uses busybox init with no systemd running, but libnss_systemd.so is pulled in as a dependency and segfaults on NSS resolution vdkr-rootfs-image.bb: - Document skopeo requirement for batch import conftest.py: - Add --k3s-timeout option and k3s/multinode markers for upcoming K3s test suite Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* xen: add runtime boot tests for hypervisor, guest bundling, vxn and containerdBruce Ashfield2026-02-263-1/+502
| | | | | | | | | | | | | | | | | | New test_xen_runtime.py boots xen-image-minimal via runqemu and verifies: - Xen hypervisor running (xl list, dmesg, Dom0 memory cap) - Bundled guest autostart (alpine visible in xl list) - vxn standalone (vxn run --rm alpine echo hello) - containerd/vctr integration (ctr pull + vctr run) Uses pexpect-based XenRunner with module-scoped fixture (boot once, run all tests). TERM=dumb set after login to suppress terminal UI from ctr/vxn progress bars. Free memory check skips vxn/vctr tests gracefully when insufficient Xen memory available. Also registers 'boot' marker in conftest.py and documents build prerequisites, test options and skip behavior in README.md. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* xen: add configuration tests and update documentationBruce Ashfield2026-02-261-8/+121
| | | | | | | | | | | | | Add TestXenImageMinimalX86Config test class verifying: - QB_CPU_KVM host passthrough for Xen CPUID filtering - QB_MEM_VALUE override (not QB_MEM which can't override bbclass) - dom0_mem in both QB_XEN_CMDLINE_EXTRA and WKS syslinux config - vgabios SAVANNAH_GNU_MIRROR usage Update Alpine recipe tests for per-arch checksums (name=${ALPINE_ARCH}) and S variable. Add qemux86-64 build and boot section to README-xen.md. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* xen: document guest import system and add testsBruce Ashfield2026-02-261-0/+361
| | | | | | | | | | | | Add 3rd-party guest import section to README-xen.md covering import types, kernel modes, Alpine example, and how to add custom import handlers. Add test_xen_guest_bundle.py with 46 pytest tests covering bbclass structure, import handlers, kernel modes, license warning, Alpine recipe, and README content. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* container-registry: add tests and documentation for secure registryBruce Ashfield2026-02-092-0/+951
| | | | | | | | | | | | | | | | | | | | | | | | Add comprehensive test coverage and documentation for the secure registry infrastructure. Tests added: TestRegistryAuthentication - auth modes (none, home, authfile, credsfile, env, creds, token) for push and import TestSecureRegistryTLSOnly - TLS-only mode using running registry TestSecureRegistryWithAuth - isolated TLS+auth instance on port 5001 TestDockerRegistryConfig - static analysis of bbclass/recipe logic TestContainerCrossInstallSecure - auto IMAGE_INSTALL verification TestVcontainerSecureRegistry - script pattern verification for virtio-9p CA transport, daemon _9p=1, shared folder reads README.md: Document authentication modes (none, home, authfile, credsfile, env), secure registry setup, PKI generation, target integration, and CI/CD examples. conftest.py: Add --secure-registry pytest option and skip_secure fixture for tests requiring openssl/htpasswd. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* container-cross-install: add tests and documentation for custom service filesBruce Ashfield2026-02-092-1/+199
| | | | | | | | | | | | | | | | | | | | | | | | | | Add pytest tests to verify CONTAINER_SERVICE_FILE varflag support: TestCustomServiceFileSupport (unit tests, no build required): - test_bbclass_has_service_file_support - test_bundle_class_has_service_file_support - test_service_file_map_syntax - test_install_custom_service_function TestCustomServiceFileBoot (boot tests, require built image): - test_systemd_services_directory_exists - test_container_services_present - test_container_service_enabled - test_custom_service_content - test_podman_quadlet_directory Documentation updates: - docs/container-bundling.md: Add "Custom Service Files" section with variable format, usage examples for both BUNDLED_CONTAINERS and container-bundle packages, and example .service/.container files - tests/README.md: Add test class entries to structure diagram and "What the Tests Check" table Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* vcontainer: add multi-arch OCI supportBruce Ashfield2026-02-093-7/+777
| | | | | | | | | | | | | | | | | | | | | Add functions to detect and handle multi-architecture OCI Image Index format with automatic platform selection during import. Also add oci-multiarch.bbclass for build-time multi-arch OCI creation. Runtime support (vcontainer-common.sh): - is_oci_image_index() - detect multi-arch OCI images - get_oci_platforms() - list available platforms - select_platform_manifest() - select manifest for target architecture - extract_platform_oci() - extract single platform to new OCI dir - normalize_arch_to_oci/from_oci() - architecture name mapping - Update vimport to auto-select platform from multi-arch images Build-time support (oci-multiarch.bbclass): - Create OCI Image Index from multiconfig builds - Collect images from vruntime-aarch64, vruntime-x86-64 - Combine blobs and create unified manifest list Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* image-oci: add layer caching for multi-layer OCI buildsBruce Ashfield2026-02-091-0/+466
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add layer caching to speed up multi-layer OCI image rebuilds. When enabled, pre-installed package layers are cached to disk and restored on subsequent builds, avoiding repeated package installation. New variables: - OCI_LAYER_CACHE: Enable/disable caching (default "1") - OCI_LAYER_CACHE_DIR: Cache location (default ${TOPDIR}/oci-layer-cache/${MACHINE}) Cache key is computed from: - Layer name and type - Sorted package list - Package versions from PKGDATA_DIR - MACHINE and TUNE_PKGARCH Cache automatically invalidates when: - Package versions change - Layer definition changes - Architecture changes Benefits: - First build: ~10-30s per layer (cache miss, packages installed) - Subsequent builds: ~1s per layer (cache hit, files copied) - Shared across recipes with identical layer definitions Build log shows cache status: NOTE: OCI Cache HIT: Layer 'base' (be88c180f651416b) NOTE: OCI: Pre-installed packages for 3 layers (cache: 3 hits, 0 misses) Also adds comprehensive pytest suite for multi-layer OCI functionality including tests for 1/2/3 layer modes and cache behavior. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add container registry pytest testsBruce Ashfield2026-02-093-0/+1096
| | | | | | | | | Add pytest tests for registry functionality: - test_vdkr_registry.py: vconfig registry, image commands, CLI override - test_container_registry_script.py: start/stop/push/import/list/tags - conftest.py: --registry-url, --registry-script options Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: increase stop command timeouts to 30 secondsBruce Ashfield2026-02-091-10/+10
| | | | | | | | | Docker stop has a default 10-second grace period before SIGKILL, so test timeouts of 10 seconds were insufficient. Increase all stop timeouts to 30 seconds to account for the grace period plus command overhead. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add --network=host backward compatibility testBruce Ashfield2026-02-092-4/+67
| | | | | | | | | | | | Add test_network_host_backward_compat to verify that explicit --network=host still works with the new bridge networking default. Uses busybox httpd with configurable port since static port forwards now map host_port -> host_port on VM (for bridge networking's Docker -p handling). Also update test docstrings to reflect bridge networking as the new default and add port 8082 to TEST_PORTS for orphan cleanup. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* vcontainer: fix ps -q to suppress port forward displayBruce Ashfield2026-02-091-4/+4
| | | | | | | | When using `ps -q` or `ps --quiet`, only container IDs should be output. The port forward registry display was being included, which broke cleanup code that expected just container IDs. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add cleanup for orphan QEMU and stale test stateBruce Ashfield2026-02-091-0/+98
| | | | | | | | | | | | | Add session-scoped autouse fixture that at session start: 1. Kills any QEMU processes holding ports used by tests (8080, 8081, 8888, etc.) - handles orphans from manual testing or crashed runs 2. Cleans up corrupt test state directories (docker-state.img with "needs journal recovery") to ensure tests start fresh This ensures tests don't fail due to leftover state from previous runs or manual testing. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add bridge networking testBruce Ashfield2026-02-091-2/+70
| | | | | | | | | | | | | | Add test_multiple_containers_same_internal_port() to verify the key benefit of bridge networking: multiple containers can listen on the same internal port with different host port mappings. The test runs two nginx containers both listening on port 80 internally, mapped to host ports 8080 and 8081, and verifies both are accessible. Also update TestPortForwarding docstring to reflect the change from host networking to bridge networking. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add tests for auto-start and dynamic port forwardingBruce Ashfield2026-02-092-0/+250
| | | | | | | | | | | | | | | | | | | | | | | Add test coverage for new vmemres features: TestAutoStartDaemon: - test_auto_start_on_first_command: Verify daemon auto-starts - test_no_daemon_flag: Verify --no-daemon uses ephemeral mode - test_vconfig_auto_daemon: Test auto-daemon config setting - test_vconfig_idle_timeout: Test idle-timeout config setting TestDynamicPortForwarding: - test_dynamic_port_forward_run: Run -d -p adds forward dynamically - test_port_forward_cleanup_on_stop: Forwards removed on stop - test_port_forward_cleanup_on_rm: Forwards removed on rm - test_multiple_dynamic_port_forwards: Multiple containers work TestPortForwardRegistry: - test_port_forward_cleared_on_memres_stop: Registry cleared Also add ensure_busybox() helper to both VdkrRunner and VpdmnRunner. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: fix has_image false positive from substring matchBruce Ashfield2026-02-091-6/+20
| | | | | | | | | | | | Change has_image() to use 'image inspect' instead of substring search in 'images' output. The substring approach caused false positives when images like 'nginx:alpine' were present - searching for 'alpine' would match and skip pulling 'alpine:latest'. This fixes TestSaveLoad::test_save_and_load which failed after the port forwarding test introduced nginx:alpine. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* docs: fix dead references to vdkr-native and obsolete test classesBruce Ashfield2026-02-091-4/+1
| | | | | | | | | Update references to reflect the current architecture: - Change vdkr-native/vpdmn-native to vcontainer-native in comments - Remove TestContainerCrossTools and TestContainerCrossInitramfs from README - Fix build command: vdkr-native → vcontainer-tarball Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* vcontainer: default to --network=host for container runBruce Ashfield2026-02-091-5/+5
| | | | | | | | | | | | | | | | | | Docker bridge networking is intentionally disabled in vdkr (dockerd runs with --bridge=none --iptables=false). Rather than requiring users to explicitly add --network=host to every container run command, make it the default. This simplifies port forwarding workflows: vdkr memres start -p 8080:80 vdkr run -d --rm nginx:alpine # Just works, no --network=host needed Users can still override with --network=none if they explicitly want no networking. Updates help text and examples to reflect the new default. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add port forwarding test for vdkrBruce Ashfield2026-02-092-6/+84
| | | | | | | | | | | | Add TestPortForwarding class with test_port_forward_nginx that: - Starts memres with port forwarding (-p 8080:80) - Runs nginx with --network=host - Verifies accessibility from host via curl Also adds port_forwards parameter to memres_start() in both VdkrRunner and VpdmnRunner helper classes. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
* tests: add pytest framework for vdkr and vpdmnBruce Ashfield2026-02-097-0/+3658
Add pytest-based test suite for testing vdkr and vpdmn CLI tools. Tests use a separate state directory (~/.vdkr-test/) to avoid interfering with production images. Test files: - conftest.py: Pytest fixtures for VdkrRunner and VpdmnRunner - test_vdkr.py: Docker CLI tests (images, vimport, vrun, volumes, etc.) - test_vpdmn.py: Podman CLI tests (mirrors vdkr test coverage) - memres-test.sh: Helper script for running tests with memres - pytest.ini: Pytest configuration and markers Test categories: - Basic operations: images, info, version - Import/export: vimport, load, save - Container execution: vrun, run, exec - Storage management: system df, vstorage - Memory resident mode: memres/vmemres start/stop/status Running tests: pytest tests/test_vdkr.py -v --vdkr-dir /tmp/vcontainer-standalone pytest tests/test_vpdmn.py -v --vdkr-dir /tmp/vcontainer-standalone Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>