Conversation
The find_gitlab_ci_file() function only searches parent directories and ~/u/ for the GitLab CI file. When running from the U-Boot root directory, or when $USRC is set to point to the source tree, the file is not found, so 'um ci -p help' shows empty board and job lists. Add the current directory as the first candidate path, and also check $USRC/.gitlab-ci.yml when the environment variable is set. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Some boards need extra environment variables like BL31 or TEE to point to firmware binaries. There is currently no way to pass these through the command line. Add a repeatable -e/--env KEY=VALUE flag to the build and pytest subcommands. For pytest, the variables are passed to both the build step and the test execution. Example: um py -B qemu_arm64 -b -e BL31=/path/bl31.bin test_fw_handoff Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When testing boards like qemu_arm64 with firmware handoff, the test framework needs TEST_PY_ID to select the right configuration, and PYTHONPATH must include the hooks directory so the boardenv file (u_boot_boardenv_<board>_<id>.py) is found. Add an --id flag that overrides the auto-detected TEST_PY_ID from .gitlab-ci.yml, passes --id to test.py and adds test/hooks/py/travis-ci/ to PYTHONPATH. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When running pytest, skipped tests are silent by default, giving no indication of why a test was skipped. This makes it hard to know whether a skip is expected or indicates a misconfiguration. Add a --why-skip flag that passes -rs to pytest so the reason for each skipped test is shown in the summary. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The gdb_monitor() function puts the parent terminal in raw mode so that all keystrokes (arrows, backspace, etc.) pass through to gdb. Raw mode disables ISIG, so Ctrl-C no longer generates SIGINT on the parent side, and the \x03 byte is just forwarded through the pty to gdb where it is echoed but not acted on. Intercept \x03 bytes on stdin and send SIGINT directly to gdb's process group. The byte is stripped from the forwarded data so it does not also reach gdb via the pty. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The RE_LEAK_DETAIL regex matches any line with whitespace and two hex-ish tokens. This false-matches on rsvmem dumps, GPT partition tables, cryptographic hashes, and host info lines that happen to have the same shape. As a result, tests like rsvmem, files_api_norun and cmd_host report hundreds of kilobytes of phantom leaks even though u-boot's own 'Leak:' line shows zero or near-zero allocs. Require the caller field to match the function:line format (\S+:\d+, e.g. sandbox_mmc_probe:194) which is distinctive to real leak entries emitted by u-boot's allocator and does not appear in the false-matching lines. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The --pollute verify-alone step uses -k with just the target test name, which does substring matching and picks up other tests containing that name. Worse, it uses /tmp/b/<board>-pollute as the build dir but only populates it when -b is passed, so without -b the tests fail with a FileNotFoundError on the u-boot binary rather than a genuine pollution signal. Include both the user's test_spec and the gitlab TEST_PY_TEST_SPEC in the -k expression for both pollute_run() and collect_tests(), wrapping each clause in parentheses and joining with 'and'. Always run buildman incrementally (fast for no-op) so the pollute build is current whether or not -b is passed. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The --pollute bisect algorithm assumes a single polluter test, so it cannot diagnose failures that need two or more prior tests to trigger. When the verify step returns PASS, the user is told the result is inconclusive with no further help. Add a --pollute-algo option with two new algorithms alongside bisect: - linear: grow the suffix from the target one test at a time and stop at the minimal window that reproduces the failure - ddmin: delta debugging to find a 1-minimal subset of tests that together cause the pollution, suitable for multi-test interactions The existing binary search is refactored into pollute_bisect() and remains the default. On an inconclusive bisect result the hint now points the user at --pollute-algo linear. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The setup command has no way to install the ldr tool used on Analog Devices boards. The U-Boot Docker image builds it from source with meson inside a Python venv and exposes it via prefixed symlinks, but local users have no equivalent and have to follow the Docker recipe by hand. Add an adi-ldr component that clones adsp-ldr v1.0.2 to ~/dev/adi-adsp-ldr, builds it with meson inside a venv and creates the arm-linux-gnueabi-ldr and aarch64-linux-ldr symlinks needed to match $(CROSS_COMPILE) on supported platforms. Each step is skipped when its output is already present, so reruns are cheap, and -f forces a rebuild. Output is captured to ~/dev/adi-adsp-ldr/build.log in the same style as qemu-build. Update the README accordingly. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The ci subcommand sets WORLD, SUITES, PYTEST and SJG_LAB pipeline variables but has no control over the sage-lab stage, so the only way to skip or target it is to edit the GitLab pipeline manually. Add a -S/--sage [NAME] option that mirrors --sjg: bare -S enables all sage-lab jobs, an explicit value selects a specific job (e.g. 'Raspberry Pi 4 (rpi_arm64)'), and 'help' lists the available choices. Job names are discovered by parsing the included .gitlab-ci-sage-lab.yml for top-level dictionary entries with a variables section, so the list stays in sync with the lab definition. SAGE_LAB is added to the default ci_vars and to -a/--all, and a [skip-sage] tag is emitted in merge-request descriptions when the stage is skipped. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two related cc subcommand bugs around mount handling: First, 'cc -u <name>' removes the LXC device but the next 'cc' run re-adds it from get_essential_mounts(), so unmounts do not stick across restarts. Track explicitly-removed mounts in a per-container skip file at ~/.claude/cc/<name>/skipped-mounts. add_all_mounts() now consults this list, and an explicit 'cc -m' re-mount clears the entry. Second, 'cc -m' prints "Mounted ..." even when the lxc command fails (e.g. when the host source path does not exist), giving the illusion of success while the device is never created. add_mount() now validates that the source path exists, checks the lxc return code, returns a bool, and the CLI handler reports failure with a non-zero exit. Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
The pytest subcommand ANDs the user-supplied -t spec with the gitlab TEST_PY_TEST_SPEC for the board. For boards like qemu_arm64_spl with TEST_PY_TEST_SPEC="test_passage", running 'uman py -t help' produces '-k help and (test_passage)', which selects nothing. Use the gitlab spec only as a fallback when the user does not supply -t, so 'uman py -t help' simply runs '-k help'. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When 'lxc start' fails (e.g. a missing mount source path), cc keeps going and falls into wait_for_user(), which loops forever running 'lxc exec' and never reports the underlying problem. Make ensure_running() return whether the container is actually running and abort the cc subcommand with an error if it is not. Also give wait_for_user() a timeout so it cannot hang the run if 'lxc exec' keeps failing. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the t subcommand cannot resolve a partial name like 'efi' to a
known suite, it scans all tests for any whose name contains the
search term and returns one spec per matching suite. The pattern it
builds, '{suite}_test_{search}*', assumes the matching tests start
with that exact prefix. Real tests like 'bootstd_test_bootflow_efi'
and tests in suites whose name itself contains 'efi' (e.g.
efi_unicoll_test_a) do not match the constructed prefix, so 'um t -b
-B sandbox efi' reports 'No tests found matching' for every suite
that should have matched.
Return the actual matching (suite, test_name) tuples from the scan
so each matching test runs as its own ut command, with its real
name, instead of relying on a constructed glob.
Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The progress line and final 'Results:' line always show all three of 'passed', 'failed' and 'skipped' even when the latter two are zero, which adds visual noise to the common all-passing case. Drop the failed and skipped fields when their count is zero. The progress line now also clears to end of line so it does not leave trailing characters when transitioning to a shorter form. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Progress class uses has_emit_result() to pick its counting strategy at construction. When that returns False (older U-Boot tree without 'emit_result' in cmd_ut.c), Progress counts every Test: line as a pass, while parse_results() at the end still counts only Result: lines. The two disagree when the framework emits Result: lines despite the static check thinking it does not, leaving live output like '24 passed' followed by 'Results: 2 passed'. Make Progress prefer Result: lines as soon as it sees one, dropping any Test:-line counts gathered before. The Test: fallback still covers very old trees that emit no Result: lines at all. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The UTF_DM constant in cmdtest.py is 0x80, which is actually UTF_OTHER_FDT (BIT(7)) in include/test/test.h UTF_DM is BIT(6) = 0x40. As a result, predict_test_count() misclassifies some tests: real UTF_DM tests are not double-counted on flat tree under --full, and tests that happen to set UTF_OTHER_FDT are double-counted incorrectly. Set UTF_DM to 0x40 and add BIT() comments next to each constant so the link to U-Boot's header is obvious. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Working on uman itself usually means inspecting build output under /tmp/b, so the -o/--output flag is reached for almost every cc invocation in this tree. For unrelated projects the mount has no purpose and is just noise. Default -o on when uman_pkg/__init__.py is present in the project source. The new is_uman_project() check is also defeated cleanly by -O, which calls remove_mount() and adds 'tmpb' to the per-container skip list, so an explicit removal sticks across runs. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There is no convenient way to authorise the container to ssh into another host. Doing it by hand means picking the right user, running ssh-keygen inside the container, copying the public key out, then appending it on the remote side. Add a --ssh [USER@]HOST option to the cc subcommand. It generates an ed25519 keypair under /home/ubuntu/.ssh in the named container if one is missing, then runs ssh-copy-id from inside the container so the remote authorised_keys is updated. When USER is omitted the current host user name is used. The ssh-copy-id call runs without output capture, so the destination password prompt is interactive. The container has its own resolver and may not see the user's local hostnames or /etc/hosts entries, so the host name is resolved on the host side and an /etc/hosts entry is added inside the container if the destination is not already a literal IP address. Plain 'ssh HOST' from inside the container would otherwise pick up the ubuntu default user. Add a matching 'Host'/'User' block to /home/ubuntu/.ssh/config so the right user is selected automatically. Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On upstream U-Boot, running 'um py -B sandbox bootstd' aborts during
pytest collection with:
test/py/img/vbe.py:14: in <module>
from u_boot_pylib import tools
E ModuleNotFoundError: No module named 'u_boot_pylib'
The u_boot_pylib module lives at <uboot>/tools/u_boot_pylib but
nothing puts <uboot>/tools on sys.path, so any test module that
imports it fails to load. Custom CI trees work because they set
PYTHONPATH elsewhere; upstream does not.
Always include <uboot>/tools in PYTHONPATH when it exists. The
--id hooks directory, when used, is layered in front so its
modules still take precedence.
Co-developed-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Subcommands section at the top of the README is missing the build and test entries, even though both are first-class commands with two-letter aliases (b and t). Readers scanning the table get the wrong impression of what uman covers. Add them, and while here sort the whole list alphabetically so the order stays predictable as new commands are added. Also broaden the setup description: it now installs apt packages, toolchains, the adi-ldr tool and aliases, and deploys to remote hosts, so the "firmware blobs (OpenSBI, TF-A, etc.)" wording is too narrow. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
setup adi-ldrcomponent to clone and build the Analog Devicesldrtool with meson in a venv, plus prefixed symlinkstprogress to Result: lines onceseen, omit zero counts from summaries, return partial-match names
from resolve, tighten leak-detail regex, --pollute filters and new
pollution search algorithms
cc) fixes: --ssh key setup, auto-mount /tmp/b when inthe uman tree, detect lxc start failures, persist unmounts and
detect mount failures
py) improvements: add tools/ to PYTHONPATH, --id option,let user test spec override the gitlab default, --why-skip flag
forwarded to gdb in monitor loop, UTF_DM constant fix, README
Subcommands list updated and sorted
Test plan
python3 -m pytest uman_pkg/ftest.py -vpython3 -m pylint uman_pkg/um setup adi-ldr -nandum t -ron sandbox