diff options
| author | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-01-01 17:15:29 +0000 |
|---|---|---|
| committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-02-09 03:32:52 +0000 |
| commit | 1165c61f5ab8ada644c7def03e991890c4d380ca (patch) | |
| tree | 1cd1c1d58039afad5a1d24b5c10d8030237e2d7c /tests/README.md | |
| parent | c32e1081c81ba27f0d5a21a1885601f04d329d21 (diff) | |
| download | meta-virtualization-1165c61f5ab8ada644c7def03e991890c4d380ca.tar.gz | |
tests: add pytest framework for vdkr and vpdmn
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>
Diffstat (limited to 'tests/README.md')
| -rw-r--r-- | tests/README.md | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000..6a02678b --- /dev/null +++ b/tests/README.md | |||
| @@ -0,0 +1,569 @@ | |||
| 1 | # Tests for vdkr, vpdmn and container-cross-install | ||
| 2 | |||
| 3 | Pytest-based test suite for: | ||
| 4 | - **vdkr**: Docker CLI for cross-architecture emulation | ||
| 5 | - **vpdmn**: Podman CLI for cross-architecture emulation | ||
| 6 | - **container-cross-install**: Yocto container bundling system | ||
| 7 | |||
| 8 | ## Requirements | ||
| 9 | |||
| 10 | ```bash | ||
| 11 | pip install pytest pytest-timeout pexpect | ||
| 12 | ``` | ||
| 13 | |||
| 14 | - `pytest` - Test framework | ||
| 15 | - `pytest-timeout` - Test timeout handling | ||
| 16 | - `pexpect` - Required for boot tests (QEMU console interaction) | ||
| 17 | |||
| 18 | --- | ||
| 19 | |||
| 20 | ## vdkr Tests | ||
| 21 | |||
| 22 | ### Prerequisites | ||
| 23 | |||
| 24 | Before running vdkr tests, you must build the standalone tarball: | ||
| 25 | |||
| 26 | ```bash | ||
| 27 | # 1. Set up your Yocto build environment | ||
| 28 | cd /opt/bruce/poky | ||
| 29 | source oe-init-build-env | ||
| 30 | |||
| 31 | # 2. Ensure multiconfig is enabled in conf/local.conf: | ||
| 32 | # BBMULTICONFIG = "vruntime-aarch64 vruntime-x86-64" | ||
| 33 | |||
| 34 | # 3. Build the standalone SDK tarball (includes blobs + QEMU) | ||
| 35 | MACHINE=qemux86-64 bitbake vcontainer-tarball | ||
| 36 | # Output: tmp/deploy/sdk/vcontainer-standalone-x86_64.sh | ||
| 37 | |||
| 38 | # 4. Extract the tarball (self-extracting installer) | ||
| 39 | /opt/bruce/poky/build/tmp/deploy/sdk/vcontainer-standalone-x86_64.sh -d /tmp/vcontainer -y | ||
| 40 | |||
| 41 | # 5. Set up the environment | ||
| 42 | cd /tmp/vcontainer | ||
| 43 | source init-env.sh | ||
| 44 | ``` | ||
| 45 | |||
| 46 | ### Running vdkr Tests | ||
| 47 | |||
| 48 | Tests use a separate state directory (`~/.vdkr-test/`) to avoid interfering with your production images in `~/.vdkr/`. | ||
| 49 | |||
| 50 | ```bash | ||
| 51 | # Run all vdkr tests | ||
| 52 | cd /opt/bruce/poky/meta-virtualization | ||
| 53 | pytest tests/test_vdkr.py -v --vdkr-dir /tmp/vcontainer | ||
| 54 | |||
| 55 | # Run with memres pre-started (much faster - starts once, reuses for all tests) | ||
| 56 | ./tests/memres-test.sh start --vdkr-dir /tmp/vcontainer | ||
| 57 | pytest tests/test_vdkr.py -v --vdkr-dir /tmp/vcontainer --skip-destructive | ||
| 58 | ./tests/memres-test.sh stop --vdkr-dir /tmp/vcontainer | ||
| 59 | |||
| 60 | # Run only fast tests (skip network/slow tests) | ||
| 61 | pytest tests/test_vdkr.py -v -m "not slow and not network" --vdkr-dir /tmp/vcontainer | ||
| 62 | |||
| 63 | # Run specific test class | ||
| 64 | pytest tests/test_vdkr.py::TestMemresBasic -v --vdkr-dir /tmp/vcontainer | ||
| 65 | |||
| 66 | # Run with an OCI image for import tests | ||
| 67 | pytest tests/test_vdkr.py -v --vdkr-dir /tmp/vcontainer \ | ||
| 68 | --oci-image /opt/bruce/poky/build/tmp/deploy/images/qemux86-64/my-container-oci | ||
| 69 | ``` | ||
| 70 | |||
| 71 | ### vdkr Test Options | ||
| 72 | |||
| 73 | | Option | Description | | ||
| 74 | |--------|-------------| | ||
| 75 | | `--vdkr-dir PATH` | Path to extracted vdkr standalone directory (required) | | ||
| 76 | | `--arch ARCH` | Target architecture: x86_64 or aarch64 (default: x86_64) | | ||
| 77 | | `--skip-destructive` | Skip tests that stop memres or clean state (use when memres is pre-started) | | ||
| 78 | | `--oci-image PATH` | Path to OCI image directory for import tests | | ||
| 79 | |||
| 80 | ### Testing ARM64 Architecture | ||
| 81 | |||
| 82 | When testing ARM64 containers (e.g., after building with `MACHINE=qemuarm64`): | ||
| 83 | |||
| 84 | ```bash | ||
| 85 | # Run tests for aarch64 | ||
| 86 | pytest tests/test_vdkr.py tests/test_vpdmn.py -v \ | ||
| 87 | --vdkr-dir /tmp/vcontainer \ | ||
| 88 | --arch aarch64 \ | ||
| 89 | --oci-image /opt/bruce/poky/build/tmp/deploy/images/qemuarm64/container-app-base-latest-oci | ||
| 90 | ``` | ||
| 91 | |||
| 92 | **Important**: The `--arch` flag must match the OCI image architecture. An arm64 OCI image | ||
| 93 | requires `--arch aarch64`, and an x86_64 OCI image requires `--arch x86_64` (the default). | ||
| 94 | |||
| 95 | --- | ||
| 96 | |||
| 97 | ## vpdmn Tests | ||
| 98 | |||
| 99 | vpdmn tests mirror the vdkr tests but for Podman. They use a separate state directory (`~/.vpdmn-test/`). | ||
| 100 | |||
| 101 | ### Running vpdmn Tests | ||
| 102 | |||
| 103 | ```bash | ||
| 104 | # Run all vpdmn tests | ||
| 105 | cd /opt/bruce/poky/meta-virtualization | ||
| 106 | pytest tests/test_vpdmn.py -v --vdkr-dir /tmp/vcontainer | ||
| 107 | |||
| 108 | # Run with memres pre-started (much faster) | ||
| 109 | ./tests/memres-test.sh start --vdkr-dir /tmp/vcontainer --tool vpdmn | ||
| 110 | pytest tests/test_vpdmn.py -v --vdkr-dir /tmp/vcontainer --skip-destructive | ||
| 111 | ./tests/memres-test.sh stop --vdkr-dir /tmp/vcontainer --tool vpdmn | ||
| 112 | |||
| 113 | # Run only fast tests (skip network/slow tests) | ||
| 114 | pytest tests/test_vpdmn.py -v -m "not slow and not network" --vdkr-dir /tmp/vcontainer | ||
| 115 | |||
| 116 | # Run specific test class | ||
| 117 | pytest tests/test_vpdmn.py::TestVrun -v --vdkr-dir /tmp/vcontainer | ||
| 118 | ``` | ||
| 119 | |||
| 120 | ### Running Both vdkr and vpdmn Tests | ||
| 121 | |||
| 122 | ```bash | ||
| 123 | # Run all tests for both tools | ||
| 124 | pytest tests/test_vdkr.py tests/test_vpdmn.py -v --vdkr-dir /tmp/vcontainer | ||
| 125 | |||
| 126 | # Skip slow and network tests | ||
| 127 | pytest tests/test_vdkr.py tests/test_vpdmn.py -v -m "not slow and not network" --vdkr-dir /tmp/vcontainer | ||
| 128 | ``` | ||
| 129 | |||
| 130 | --- | ||
| 131 | |||
| 132 | ## container-cross-install Tests | ||
| 133 | |||
| 134 | ### Prerequisites | ||
| 135 | |||
| 136 | container-cross-install tests require a fully configured Yocto build environment: | ||
| 137 | |||
| 138 | ```bash | ||
| 139 | # 1. Set up your Yocto build environment | ||
| 140 | cd /opt/bruce/poky | ||
| 141 | source oe-init-build-env | ||
| 142 | |||
| 143 | # 2. Ensure required layers are present: | ||
| 144 | # - meta-virtualization | ||
| 145 | # - meta-oe (openembedded-core) | ||
| 146 | |||
| 147 | # 3. Enable multiconfig in conf/local.conf: | ||
| 148 | BBMULTICONFIG = "vruntime-aarch64 vruntime-x86-64" | ||
| 149 | |||
| 150 | # 4. (Optional) Build vdkr/vpdmn blobs via multiconfig if testing container bundling: | ||
| 151 | # These are built automatically via mcdepends when building images that | ||
| 152 | # inherit container-cross-install or container-bundle. | ||
| 153 | ``` | ||
| 154 | |||
| 155 | ### What the Tests Check | ||
| 156 | |||
| 157 | | Test Class | What It Tests | Build Required | | ||
| 158 | |------------|---------------|----------------| | ||
| 159 | | `TestContainerCrossTools` | container-cross-tools-native | `bitbake container-cross-tools-native` | | ||
| 160 | | `TestContainerCrossClass` | bbclass file syntax | None (file check only) | | ||
| 161 | | `TestOCIImageBuild` | OCI image generation | `bitbake container-app-base` (if available) | | ||
| 162 | | `TestBundledContainers` | End-to-end bundling | Full image build with `BUNDLED_CONTAINERS` | | ||
| 163 | | `TestVdkrRecipes` | vdkr recipe builds | `bitbake vdkr-native` | | ||
| 164 | | `TestMulticonfig` | Multiconfig setup | `BBMULTICONFIG` configured | | ||
| 165 | | `TestBundledContainersBoot` | **Boot image and verify containers** | Full image with Docker/Podman | | ||
| 166 | |||
| 167 | ### Boot Tests (TestBundledContainersBoot) | ||
| 168 | |||
| 169 | Boot tests actually start the built image in QEMU and verify bundled containers are visible and runnable. This is the ultimate verification that container-cross-install worked correctly. | ||
| 170 | |||
| 171 | #### Build Prerequisites | ||
| 172 | |||
| 173 | Before running boot tests, you need a built image with bundled containers: | ||
| 174 | |||
| 175 | ```bash | ||
| 176 | cd /opt/bruce/poky | ||
| 177 | source oe-init-build-env | ||
| 178 | |||
| 179 | # Option 1: Package-based bundling (recommended) | ||
| 180 | # Ensure example-container-bundle is in IMAGE_INSTALL (already configured in local.conf): | ||
| 181 | # IMAGE_INSTALL:append:pn-container-image-host = " example-container-bundle" | ||
| 182 | |||
| 183 | # Build the image (includes container bundling via vrunner/QEMU) | ||
| 184 | bitbake container-image-host | ||
| 185 | |||
| 186 | # Option 2: Legacy BUNDLED_CONTAINERS variable | ||
| 187 | # Add to local.conf: | ||
| 188 | # BUNDLED_CONTAINERS = "container-base-latest-oci:podman" | ||
| 189 | # Then rebuild: | ||
| 190 | # bitbake container-image-host -C rootfs | ||
| 191 | ``` | ||
| 192 | |||
| 193 | #### Additional Requirements | ||
| 194 | |||
| 195 | ```bash | ||
| 196 | pip install pexpect | ||
| 197 | ``` | ||
| 198 | |||
| 199 | #### What Boot Tests Verify | ||
| 200 | |||
| 201 | 1. **System boots** - Image boots successfully and reaches login prompt | ||
| 202 | 2. **Docker images visible** - If Docker containers bundled, `docker images` shows them | ||
| 203 | 3. **Podman images visible** - If Podman containers bundled, `podman images` shows them | ||
| 204 | 4. **Docker run works** - Can actually run a bundled Docker container | ||
| 205 | 5. **Podman run works** - Can actually run a bundled Podman container | ||
| 206 | |||
| 207 | #### Running Boot Tests | ||
| 208 | |||
| 209 | ```bash | ||
| 210 | cd /opt/bruce/poky/meta-virtualization | ||
| 211 | |||
| 212 | # Run boot tests (requires built image with bundled containers) | ||
| 213 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v | ||
| 214 | |||
| 215 | # Run with custom image | ||
| 216 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v \ | ||
| 217 | --image container-image-host | ||
| 218 | |||
| 219 | # Disable KVM (slower, but works in VMs) | ||
| 220 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v --no-kvm | ||
| 221 | |||
| 222 | # Longer boot timeout (default: 120s) | ||
| 223 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v --boot-timeout 180 | ||
| 224 | ``` | ||
| 225 | |||
| 226 | #### Boot Test Options | ||
| 227 | |||
| 228 | | Option | Default | Description | | ||
| 229 | |--------|---------|-------------| | ||
| 230 | | `--image NAME` | container-image-host | Image name to boot | | ||
| 231 | | `--image-fstype TYPE` | ext4 | Filesystem type (ext4, wic, etc.) | | ||
| 232 | | `--boot-timeout SECS` | 120 | Timeout for boot to complete | | ||
| 233 | | `--no-kvm` | (KVM enabled) | Disable KVM acceleration | | ||
| 234 | |||
| 235 | #### Container Detection | ||
| 236 | |||
| 237 | Boot tests automatically detect bundled containers using two methods: | ||
| 238 | |||
| 239 | 1. **Direct detection (preferred)**: Reads container storage in the rootfs | ||
| 240 | - Docker: `/var/lib/docker/image/overlay2/repositories.json` | ||
| 241 | - Podman: `/var/lib/containers/storage/vfs-images/images.json` | ||
| 242 | |||
| 243 | 2. **Legacy fallback**: Parses `BUNDLED_CONTAINERS` variable from `local.conf` | ||
| 244 | |||
| 245 | #### Test Skipping Behavior | ||
| 246 | |||
| 247 | Tests skip when no containers are detected: | ||
| 248 | |||
| 249 | - **No Docker containers** → Docker tests skip: | ||
| 250 | `"No Docker containers in bundle packages or BUNDLED_CONTAINERS"` | ||
| 251 | |||
| 252 | - **No Podman containers** → Podman tests skip: | ||
| 253 | `"No Podman containers in bundle packages or BUNDLED_CONTAINERS"` | ||
| 254 | |||
| 255 | - **No containers at all** → All container tests skip: | ||
| 256 | `"No container bundles found (no containers in rootfs storage and no BUNDLED_CONTAINERS in local.conf)"` | ||
| 257 | |||
| 258 | - **Bundle package installed but no containers** → Skip with rebuild hint: | ||
| 259 | `"Bundle packages installed but no containers detected in storage (image may need rebuild)"` | ||
| 260 | |||
| 261 | ### Freshness Checking | ||
| 262 | |||
| 263 | Boot tests can detect when your rootfs is stale (older than source files) and warn or fail: | ||
| 264 | |||
| 265 | ```bash | ||
| 266 | # Warn if rootfs older than OCI containers or bbclass (default: just warns) | ||
| 267 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v | ||
| 268 | |||
| 269 | # Fail if rootfs is stale (CI mode) | ||
| 270 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v --fail-stale | ||
| 271 | |||
| 272 | # Adjust max age before warning (default: 24 hours) | ||
| 273 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v --max-age 48 | ||
| 274 | ``` | ||
| 275 | |||
| 276 | #### Freshness Check Options | ||
| 277 | |||
| 278 | | Option | Default | Description | | ||
| 279 | |--------|---------|-------------| | ||
| 280 | | `--fail-stale` | false | Fail (not just warn) if rootfs is stale | | ||
| 281 | | `--max-age HOURS` | 24 | Max rootfs age in hours before warning | | ||
| 282 | |||
| 283 | #### What Gets Checked | ||
| 284 | |||
| 285 | The freshness check compares the rootfs mtime against: | ||
| 286 | 1. **OCI container directories** - Any container in `BUNDLED_CONTAINERS` | ||
| 287 | 2. **container-cross-install.bbclass** - The class that bundles containers | ||
| 288 | |||
| 289 | If any source is newer than the rootfs, you'll see: | ||
| 290 | |||
| 291 | ``` | ||
| 292 | WARNING: Rootfs may be stale! | ||
| 293 | Rootfs: 2025-12-27 10:30:00 | ||
| 294 | Newer sources found: | ||
| 295 | - container-app-base-latest-oci: 2025-12-28 14:22:33 | ||
| 296 | Consider rebuilding: bitbake container-image-host -C rootfs | ||
| 297 | ``` | ||
| 298 | |||
| 299 | #### Fresh Test Workflow | ||
| 300 | |||
| 301 | To ensure you're testing the latest functionality: | ||
| 302 | |||
| 303 | ```bash | ||
| 304 | # 1. Rebuild containers (if changed) | ||
| 305 | bitbake container-base container-app-base | ||
| 306 | |||
| 307 | # 2. Rebuild image rootfs | ||
| 308 | bitbake container-image-host -C rootfs | ||
| 309 | |||
| 310 | # 3. Run boot tests with stale check | ||
| 311 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v --fail-stale | ||
| 312 | ``` | ||
| 313 | |||
| 314 | ### Running container-cross-install Tests | ||
| 315 | |||
| 316 | ```bash | ||
| 317 | cd /opt/bruce/poky/meta-virtualization | ||
| 318 | |||
| 319 | # Run all container-cross-install tests (many are slow) | ||
| 320 | pytest tests/test_container_cross_install.py -v | ||
| 321 | |||
| 322 | # Run only fast tests (file checks, no building) | ||
| 323 | pytest tests/test_container_cross_install.py -v -m "not slow" | ||
| 324 | |||
| 325 | # Run with custom build directory | ||
| 326 | pytest tests/test_container_cross_install.py -v --build-dir /path/to/build | ||
| 327 | |||
| 328 | # Run specific test | ||
| 329 | pytest tests/test_container_cross_install.py::TestContainerCrossClass -v | ||
| 330 | ``` | ||
| 331 | |||
| 332 | ### container-cross-install Test Options | ||
| 333 | |||
| 334 | | Option | Description | | ||
| 335 | |--------|-------------| | ||
| 336 | | `--poky-dir PATH` | Path to poky directory (default: /opt/bruce/poky) | | ||
| 337 | | `--build-dir PATH` | Path to build directory (default: $POKY_DIR/build) | | ||
| 338 | | `--machine MACHINE` | Target machine (default: qemux86-64) | | ||
| 339 | | `--image NAME` | Image to boot for boot tests (default: container-image-host) | | ||
| 340 | | `--image-fstype TYPE` | Filesystem type (default: ext4) | | ||
| 341 | | `--boot-timeout SECS` | Boot timeout in seconds (default: 120) | | ||
| 342 | | `--no-kvm` | Disable KVM acceleration for boot tests | | ||
| 343 | | `--fail-stale` | Fail if rootfs is older than source files | | ||
| 344 | | `--max-age HOURS` | Max rootfs age before warning (default: 24) | | ||
| 345 | |||
| 346 | --- | ||
| 347 | |||
| 348 | ## Capturing Test Output | ||
| 349 | |||
| 350 | Test output is automatically captured to files for debugging: | ||
| 351 | |||
| 352 | | File | Contents | | ||
| 353 | |------|----------| | ||
| 354 | | `/tmp/pytest-vcontainer.log` | Python logging (DEBUG level) | | ||
| 355 | | `/tmp/pytest-results.xml` | JUnit XML results (for CI) | | ||
| 356 | |||
| 357 | To capture full stdout/stderr (including test failures and assertions): | ||
| 358 | |||
| 359 | ```bash | ||
| 360 | # Capture everything to a log file | ||
| 361 | pytest tests/test_vpdmn.py --vdkr-dir /tmp/vcontainer 2>&1 | tee /tmp/pytest-output.log | ||
| 362 | |||
| 363 | # Then share the log file for debugging | ||
| 364 | cat /tmp/pytest-output.log | ||
| 365 | ``` | ||
| 366 | |||
| 367 | --- | ||
| 368 | |||
| 369 | ## Test Markers | ||
| 370 | |||
| 371 | | Marker | Description | | ||
| 372 | |--------|-------------| | ||
| 373 | | `slow` | Tests that take a long time (building recipes, images) | | ||
| 374 | | `memres` | Tests requiring vdkr memory resident mode | | ||
| 375 | | `network` | Tests requiring network access (docker pull, etc.) | | ||
| 376 | | `boot` | Tests that boot a QEMU image (requires built image) | | ||
| 377 | |||
| 378 | ### Filtering by Marker | ||
| 379 | |||
| 380 | ```bash | ||
| 381 | # Skip slow tests | ||
| 382 | pytest tests/ -m "not slow" | ||
| 383 | |||
| 384 | # Run only network tests | ||
| 385 | pytest tests/ -m network | ||
| 386 | |||
| 387 | # Combine markers | ||
| 388 | pytest tests/ -m "not slow and not network" | ||
| 389 | ``` | ||
| 390 | |||
| 391 | --- | ||
| 392 | |||
| 393 | ## Environment Variables | ||
| 394 | |||
| 395 | | Variable | Description | | ||
| 396 | |----------|-------------| | ||
| 397 | | `VDKR_STANDALONE_DIR` | Default path to vdkr standalone directory | | ||
| 398 | | `VDKR_ARCH` | Default architecture (x86_64 or aarch64) | | ||
| 399 | | `TEST_OCI_IMAGE` | Default OCI image for import tests | | ||
| 400 | | `POKY_DIR` | Path to poky directory | | ||
| 401 | | `BUILD_DIR` | Path to build directory | | ||
| 402 | | `MACHINE` | Target machine for Yocto builds | | ||
| 403 | |||
| 404 | --- | ||
| 405 | |||
| 406 | ## Test Structure | ||
| 407 | |||
| 408 | ``` | ||
| 409 | tests/ | ||
| 410 | ├── conftest.py # Fixtures and configuration | ||
| 411 | ├── pytest.ini # Pytest settings | ||
| 412 | ├── memres-test.sh # Helper to start/stop memres for tests | ||
| 413 | ├── test_vdkr.py # vdkr (Docker) CLI tests | ||
| 414 | │ ├── TestMemresBasic # memres start/stop/status | ||
| 415 | │ ├── TestImages # images, pull, rmi | ||
| 416 | │ ├── TestVimport # OCI import | ||
| 417 | │ ├── TestSaveLoad # save/load images | ||
| 418 | │ ├── TestVrun # container execution | ||
| 419 | │ ├── TestInspect # inspect command | ||
| 420 | │ ├── TestHistory # history command | ||
| 421 | │ ├── TestClean # clean command | ||
| 422 | │ ├── TestFallbackMode # non-memres operation | ||
| 423 | │ ├── TestContainerLifecycle # ps, stop, rm | ||
| 424 | │ └── TestVolumeMounts # volume mount tests | ||
| 425 | ├── test_vpdmn.py # vpdmn (Podman) CLI tests | ||
| 426 | │ ├── TestMemresBasic # memres start/stop/status | ||
| 427 | │ ├── TestImages # images, pull, rmi | ||
| 428 | │ ├── TestVimport # OCI import | ||
| 429 | │ ├── TestSaveLoad # save/load images | ||
| 430 | │ ├── TestVrun # container execution | ||
| 431 | │ ├── TestRun # run with entrypoint override | ||
| 432 | │ ├── TestInspect # inspect command | ||
| 433 | │ ├── TestHistory # history command | ||
| 434 | │ ├── TestClean # clean command | ||
| 435 | │ ├── TestFallbackMode # non-memres operation | ||
| 436 | │ ├── TestContainerLifecycle # ps, stop, rm | ||
| 437 | │ └── TestVolumeMounts # volume mount tests | ||
| 438 | ├── test_container_cross_install.py # Yocto integration tests | ||
| 439 | │ ├── TestContainerCrossInitramfs # blob building | ||
| 440 | │ ├── TestContainerCrossTools # tools-native | ||
| 441 | │ ├── TestContainerCrossClass # bbclass syntax | ||
| 442 | │ ├── TestOCIImageBuild # OCI generation | ||
| 443 | │ ├── TestBundledContainers # end-to-end bundling | ||
| 444 | │ ├── TestVdkrRecipes # vdkr builds | ||
| 445 | │ ├── TestMulticonfig # multiconfig setup | ||
| 446 | │ └── TestBundledContainersBoot # boot and verify containers | ||
| 447 | └── README.md # This file | ||
| 448 | ``` | ||
| 449 | |||
| 450 | --- | ||
| 451 | |||
| 452 | ## Quick Reference | ||
| 453 | |||
| 454 | ### Full vdkr + vpdmn test run (recommended) | ||
| 455 | |||
| 456 | ```bash | ||
| 457 | # 1. Build the unified standalone SDK (includes both vdkr and vpdmn) | ||
| 458 | cd /opt/bruce/poky | ||
| 459 | source oe-init-build-env | ||
| 460 | MACHINE=qemux86-64 bitbake vcontainer-tarball | ||
| 461 | |||
| 462 | # 2. Extract the tarball (self-extracting installer) | ||
| 463 | /opt/bruce/poky/build/tmp/deploy/sdk/vcontainer-standalone-x86_64.sh -d /tmp/vcontainer -y | ||
| 464 | |||
| 465 | # 3. Run fast tests for both tools (skips network and slow tests) | ||
| 466 | cd /opt/bruce/poky/meta-virtualization | ||
| 467 | pytest tests/test_vdkr.py tests/test_vpdmn.py -v --vdkr-dir /tmp/vcontainer -m "not network and not slow" | ||
| 468 | |||
| 469 | # 4. Run ALL tests for both tools (includes network tests like pull) | ||
| 470 | pytest tests/test_vdkr.py tests/test_vpdmn.py -v --vdkr-dir /tmp/vcontainer | ||
| 471 | ``` | ||
| 472 | |||
| 473 | ### vdkr only test run | ||
| 474 | |||
| 475 | ```bash | ||
| 476 | # Build SDK (includes both vdkr and vpdmn) | ||
| 477 | MACHINE=qemux86-64 bitbake vcontainer-tarball | ||
| 478 | |||
| 479 | # Extract | ||
| 480 | /opt/bruce/poky/build/tmp/deploy/sdk/vcontainer-standalone-x86_64.sh -d /tmp/vcontainer -y | ||
| 481 | |||
| 482 | # Run vdkr tests only | ||
| 483 | pytest tests/test_vdkr.py -v --vdkr-dir /tmp/vcontainer | ||
| 484 | ``` | ||
| 485 | |||
| 486 | ### With OCI image import test | ||
| 487 | |||
| 488 | ```bash | ||
| 489 | # Run tests including OCI import (requires a built OCI image) | ||
| 490 | pytest tests/test_vdkr.py -v --vdkr-dir /tmp/vcontainer \ | ||
| 491 | --oci-image /opt/bruce/poky/build/tmp/deploy/images/qemux86-64/container-app-base-latest-oci | ||
| 492 | ``` | ||
| 493 | |||
| 494 | ### Faster repeated runs (memres mode) | ||
| 495 | |||
| 496 | ```bash | ||
| 497 | # Start memres once (keeps QEMU VM running) | ||
| 498 | ./tests/memres-test.sh start --vdkr-dir /tmp/vcontainer | ||
| 499 | |||
| 500 | # Run tests multiple times (~1s per command vs ~30s cold boot) | ||
| 501 | pytest tests/test_vdkr.py -v --vdkr-dir /tmp/vcontainer --skip-destructive | ||
| 502 | |||
| 503 | # Stop memres when done | ||
| 504 | ./tests/memres-test.sh stop --vdkr-dir /tmp/vcontainer | ||
| 505 | ``` | ||
| 506 | |||
| 507 | ### Minimal container-cross-install test run | ||
| 508 | |||
| 509 | ```bash | ||
| 510 | # Just check files exist (no building) | ||
| 511 | cd /opt/bruce/poky/meta-virtualization | ||
| 512 | pytest tests/test_container_cross_install.py::TestContainerCrossClass -v | ||
| 513 | ``` | ||
| 514 | |||
| 515 | ### Boot test (verify bundled containers) | ||
| 516 | |||
| 517 | ```bash | ||
| 518 | # 1. Ensure image is built with BUNDLED_CONTAINERS in local.conf: | ||
| 519 | # BUNDLED_CONTAINERS = "container-base-latest-oci:docker container-app-base-latest-oci:docker" | ||
| 520 | |||
| 521 | # 2. Build the image | ||
| 522 | cd /opt/bruce/poky && source oe-init-build-env | ||
| 523 | bitbake container-image-host | ||
| 524 | |||
| 525 | # 3. Run boot tests | ||
| 526 | cd /opt/bruce/poky/meta-virtualization | ||
| 527 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v | ||
| 528 | |||
| 529 | # 4. Run with freshness check (CI mode) | ||
| 530 | pytest tests/test_container_cross_install.py::TestBundledContainersBoot -v --fail-stale | ||
| 531 | ``` | ||
| 532 | |||
| 533 | --- | ||
| 534 | |||
| 535 | ## Adding New Tests | ||
| 536 | |||
| 537 | ### vdkr tests | ||
| 538 | |||
| 539 | Use the `vdkr` or `memres_session` fixture: | ||
| 540 | |||
| 541 | ```python | ||
| 542 | def test_my_command(memres_session): | ||
| 543 | vdkr = memres_session | ||
| 544 | result = vdkr.run("my-command", "arg1", "arg2") | ||
| 545 | assert result.returncode == 0 | ||
| 546 | assert "expected" in result.stdout | ||
| 547 | ``` | ||
| 548 | |||
| 549 | ### vpdmn tests | ||
| 550 | |||
| 551 | Use the `vpdmn` or `vpdmn_memres_session` fixture: | ||
| 552 | |||
| 553 | ```python | ||
| 554 | def test_my_podman_command(vpdmn_memres_session): | ||
| 555 | vpdmn = vpdmn_memres_session | ||
| 556 | result = vpdmn.run("my-command", "arg1", "arg2") | ||
| 557 | assert result.returncode == 0 | ||
| 558 | assert "expected" in result.stdout | ||
| 559 | ``` | ||
| 560 | |||
| 561 | ### container-cross-install tests | ||
| 562 | |||
| 563 | Use `run_bitbake()` helper: | ||
| 564 | |||
| 565 | ```python | ||
| 566 | def test_my_recipe(build_dir): | ||
| 567 | result = run_bitbake(build_dir, "my-recipe") | ||
| 568 | assert result.returncode == 0 | ||
| 569 | ``` | ||
