47 Commits
Author SHA1 Message Date
Igor Opaniuk b7fdbaecd2 tests: add cli argument parsing tests
With qdl_parse_args() in cli.c it is now unit testable. Cover the
option-to-struct mapping for valid inputs: the defaults, storage and
backend selection, --dry-run/--create-digests pinning the SIM backend
(and a later --backend being ignored), the skipblock mode, the flag
and value options, and that --help/--version report "done" while
too-few positional arguments report a usage error.

Invalid storage/backend/skipblock values errx() out of the process
and so are
left to the integration tests.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-10-01 10:54:22 +02:00
Igor Opaniuk a45bf832cd tests: add read and patch XML loader unit tests
patch_load_xml() and read_op_load() turn XML into firehose op lists
and had no direct coverage. Add a cmocka suite (linking util.c for
the real attribute accessors and stubbing the device/ux layers) that
checks a valid entry produces the expected op, that an unrecognized
child tag is skipped, and - locking in the recently fixed error
propagation - that a malformed entry or a missing file makes the
loader return an error instead of reporting success.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-10-01 10:53:46 +02:00
Igor Opaniuk ee3d93fc22 ux: route remaining diagnostics through shared logging
USB warnings, Sahara ramdump failures, fatal CLI and archive errors,
and packet hex dumps bypass the ux helpers, so they never get a
--debug timestamp and leave gaps in the protocol timeline.

Route them through shared logging via new warn and die helpers that
keep the program-name prefix, errno text, and exit status. Output
without --debug is unchanged and hex dumps stay visible in both modes.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-10-01 10:21:20 +02:00
Igor Opaniuk 65711e63a1 ux: own the program name used in diagnostics
The error prefix comes from __progname, a BSD-ism that glibc and the
Apple libc export but Windows lacks, so qdl.c and every unit test that
links util.c define their own copy. The nbdkit plugin links neither.

Keep the name in ux.c with a "qdl" default and set it through
ux_set_progname(): from argv[0] in main() and from the plugin's load
hook. Move print_version() into qdl.c, its only caller, so util.c and
the tests no longer need the symbol.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-10-01 10:21:20 +02:00
Ali Erdinc Koroglu c882582b81 Add missing stdint.h include
Include <stdint.h> to provide the definition of uintptr_t and fix
the GCC build failure

Signed-off-by: Ali Erdinc Koroglu <ali.koroglu@oss.qualcomm.com>
2026-09-24 16:20:43 +03:00
Igor Opaniuk b70ec6cf47 tests: add input type detection tests
Cover detect_type(): the command verbs (read/write/erase/flash/
sha256), an argument that is neither a verb nor an existing file, the
recognized XML roots (patches, data with program/read/ufs children,
contents), a well-formed document with an unrecognized root or child
resolving to QDL_FILE_UNKNOWN, and malformed XML being rejected.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 14:34:28 +02:00
Igor Opaniuk 92bbcd941f tests: cover decode_backend and qdl_split_specifier
Extend the util test suite with the two parsers just moved out of
qdl.c: backend-name decoding (auto/usb/qud, NULL defaulting to auto,
and an unknown name) and specifier splitting (plain filename,
file::selector, and the malformed empty / double-"::" / empty-part
forms).

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 14:34:28 +02:00
Igor Opaniuk fd57e01041 tests: add util helper unit tests
Cover the pure helpers in util.c that had no test: the storage
address parser (partition, partition/sector, sector+length, and the
bare-name / partition-name GPT forms, plus the rejected forms), the
storage-type encode/decode round-trip, and the XML attribute
accessors - including that a present-but-empty attribute yields NULL
without raising an error, which several load paths rely on.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 14:34:28 +02:00
Igor Opaniuk 25c484f5f7 tests: add programmer archive decoder unit tests
The archive decoder parses an untrusted blob with hand-rolled bounds
checks, and the audit found real holes there - unvalidated image ids
and entry names among them. Those hardened paths could previously only
be exercised by handing qdl a corrupt archive on the command line.
With the decoder extracted into its own module, craft newc archives in
memory and pin the contract: a valid archive maps its images, and a
truncated header, an out-of-range or zero image id and an unterminated
name are each rejected without touching the image table.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 14:34:28 +02:00
Igor Opaniuk 5e668830d4 tests: add ufs provisioning loader tests
The loader's failure handling is exactly what the context refactor
changed, and nothing exercised it before - the module globals made
the loader untestable, so its error paths could only be reached with
a malformed provisioning XML in a real flashing session. Pin the new
contract while it is fresh: a malformed document must leave the
context empty rather than half-populated, cleanup must be safe to
repeat, and under ASAN the error paths must leak nothing.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 13:50:06 +02:00
Igor Opaniuk e74af1d13c tests: add Firehose response parser unit tests
The response parsers make protocol decisions - ACK versus NAK versus
log, rawmode entry, payload size negotiation - and mistakes there only
surface on real devices. In particular, a configure NAK is the
payload-size negotiation handshake rather than a failure: treating it
as an error makes the configure exchange loop forever, a lesson that
took a bricked flashing session on hardware to learn. Pin the parser
contract in unit tests so it cannot regress silently again.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 10:41:37 +02:00
Igor Opaniuk 84e8e387e5 tests: compare partition digests case-insensitively
The verify step extracts the device digest with a case-insensitive
grep but compares it case-sensitively against the local sha256sum
output. The firehose response carries uppercase hex while sha256sum
prints lowercase, so the comparison only worked as long as the
extraction happened to pick a lowercase rendering of the digest from
qdl's output. With QDL_HIL_DEBUG enabled the first match in the
output is the device's raw uppercase digest, and the step failed on
identical values - caught by the first debug-enabled CI run.

Lowercase both sides before comparing.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 09:32:07 +02:00
Igor Opaniuk c5e29f11df tests: add QDL_HIL_DEBUG to run qdl with debug logging
A failing HIL step reports qdl's normal output, which is often not
enough to diagnose a device-side problem after the fact - and the
failure may not reproduce once the board state changes, so enabling
debug logging for a rerun loses the moment.

Add a QDL_HIL_DEBUG environment knob that puts --debug on every qdl
invocation in both suites. Rigs set it in their board configuration;
the full protocol log then lands in the meson testlog for every run,
so a failure ships its own post-mortem and green runs provide a
known-good log to diff against. The flag is placed before subcommand
verbs, which is safe for flag-type options - only value-taking
options confuse the verb dispatcher.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 09:32:07 +02:00
Igor Opaniuk cac2198e58 tests: add hil-vip suite for VIP flashing on secured boards
The hil suite exercises plain flashing; secured boards additionally
support Validated Image Programming, where the device verifies the
flashed data stream against signed digest tables - the feature that
regressed unnoticed on Windows in v2.7. Add a dedicated hil-vip
suite: list and chipinfo reuse the existing steps, and a
sign-and-flash step signs a copy of the firehose programmer, has qdl
generate the VIP digest tables, wraps them with mbn-tool, signs them,
and flashes the build with --vip-table-path.

Signing follows the signimages.sh recipe from the qcom-sec-tools
repository (image ids DEVICE-PROGRAMMER and VIP, signing key index 0)
and requires QDL_HIL_SECTOOLS, QDL_HIL_SECPROFILE and QDL_HIL_SECKEYS
on top of the usual configuration; without them the suite skips, so
rigs without signing material stay green. Only the programmer and the
digest tables are signed - VIP validates the data stream, so the
individual images need no signatures for this test.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 09:32:07 +02:00
Igor Opaniuk fda91d7c0e tests: pass the serial after the chipinfo verb
qdl's verb dispatcher scans argv for a known verb but stops at the
first argument without a leading dash. With a serial configured the
chipinfo step ran 'qdl -S <serial> chipinfo': the scan stops at the
serial value, never sees the verb, and falls through to the flash
parser, which rejects the command line with a usage message. The
suite's Linux runs never caught this because they run without
QDL_HIL_SERIAL.

Pass the serial after the verb, where the chipinfo subcommand parses
-S itself. The dispatcher's inability to step over value-taking
options deserves a fix in qdl proper; this keeps the suite working
against released binaries either way.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 09:32:07 +02:00
Igor Opaniuk b3b3a2e633 tests: make the list step honor QDL_HIL_SERIAL
The list step passes as soon as any EDL device enumerates. On a rig
with several boards attached to one host - the setup QDL_HIL_SERIAL
exists for - another board sitting in EDL mode satisfies the check
and masks the selected board never appearing; the suite then proceeds
and fails later, in a less obvious place.

When QDL_HIL_SERIAL is set, require the qdl list output to contain
that serial before declaring the device present, and name the serial
in the timeout diagnostic.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 09:32:07 +02:00
Igor Opaniuk 38881a66e1 tests: add enter-EDL hook for unattended HIL runs
The HIL suite assumes a human has already put the board into EDL mode
before the suite starts, which rules out unattended execution on a CI
runner.

Add an optional QDL_HIL_ENTER_EDL_CMD environment hook, run in the
suite's first step (after all skip gating, so runs without a
configured board still skip cleanly). The environment supplies
whatever mechanism the rig uses - 'adb reboot edl' on a booted board,
a USB relay toggle, or a lab power controller - keeping the suite
board-agnostic. The command only needs to trigger the mode switch:
the flash steps already wait for the device, and the list step now
polls for enumeration for up to QDL_HIL_SETTLE seconds (default 30),
since a power-cycled board takes several seconds to come back as an
EDL device. The suite's final reset step boots the board back into
its OS, where the next run's hook can reach it again.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 09:32:07 +02:00
Igor Opaniuk 93dec5529c tests: anchor HIL fail-fast reset to the suite's first step
The abort sentinel that implements fail-fast across the serialized HIL
steps is cleared at the start of flash_full, which was the suite's
first step when the mechanism was introduced. The list and chipinfo
steps have since been added with higher priorities, so they run before
flash_full - and a failure in either sets the sentinel only for
flash_full to wipe it (it is also exempted from the fail-fast check)
and carry on flashing a board that just failed a sanity step.

Introduce a FIRST_STEP anchor: the sentinel reset runs there and
nowhere else, and no step is exempt from the fail-fast check - the
first step clears the sentinel before checking, so a set sentinel
always means a failure in this run. Keep FIRST_STEP in sync with the
priorities in tests/meson.build.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-08-25 09:32:07 +02:00
Bjorn Andersson 1c11a0734e tests: cover Sahara archive creation
Exercise create-sahara-archive through the built qdl binary. Cover
programmer maps, Sahara XML, contents.xml, archive inputs, and invalid
arguments.

Verify that contents.xml storage selectors select distinct programmer
payloads and that an unselected multi-variant contents.xml is rejected.

Parse the generated archive in the test itself so coverage does not
depend on an external cpio implementation.

Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
2026-08-18 21:01:27 +00:00
Bjorn Andersson d1fdb7efc5 contents: load selected programmer images
Consumers that only need Sahara programmer images must not also construct
the Firehose operations used for flashing. Add a dedicated loading path
that resolves exactly one contents.xml storage/flavor combination and
returns its programmer images.

Pass the resolved selection through programmer discovery and Sahara XML
payload resolution. This prevents a valid selector from being accepted
while silently selecting a different programmer variant.

Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
2026-08-18 21:01:27 +00:00
Igor Opaniuk fd0e86d542 tests: warn and skip overly-long paths in rmtree
rmtree() concatenates the directory path and entry name into a
PATH_MAX buffer without checking for truncation, which -Wformat-
truncation flags on the Windows build where PATH_MAX is 260. A
truncated path would also make the cleanup delete the wrong file in
principle.

Check the snprintf() result and skip entries that do not fit; using
the return value also satisfies the warning. A skipped entry means
the parent rmdir() fails with ENOTEMPTY and the workdir lingers, so
report the skip on stderr instead of hiding it - the message names
the entry, making a leftover workdir traceable to its cause.

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-07-21 14:57:42 +02:00
Igor Opaniuk 4ef8df7db2 tests: extend HIL test suite
Extend the hardware-in-the-loop suite with self-contained steps that
fit the existing round-trip model:

- list devices: enumerate the attached EDL device with the list verb
  and require a vid:pid line in the output, covering device discovery
  over real USB.

- chipinfo via Sahara: read the chip identity (serial number, HW ID
  and OEM PK hash) with the chipinfo verb. The step runs before the
  programmer upload because chip identity is only available while the
  device still speaks Sahara; the verb switches the device back to
  image-transfer mode on exit, so the subsequent flash still gets its
  Sahara HELLO. SKIPs when a programmer is already running.

- create-zip and flash: package a build from a contents.xml with the
  create-zip verb, then flash the produced zip, covering the zip
  writer and the zip flashing path end to end. Gated on
  QDL_HIL_CONTENTS.

- flash sparse build: flash a bundle that uses Android sparse images,
  covering the sparse decoding path against real storage. Gated on
  QDL_HIL_SPARSE.

- NAK on bad partition: a read of a nonexistent physical partition
  must fail, verifying that a device NAK is reported as an error
  instead of silently succeeding.

- sha256 by partition name: digest a partition addressed by its GPT
  name rather than by partition and sector numbers, covering GPT name
  resolution against the device.

- write chunked: rewrite the partition image with an overridden
  --out-chunk-size=16384, covering the chunked transfer path.

- verify write integrity: compare the device-computed partition
  digest against a local sha256 of the previously read-back and
  rewritten image, proving the read/write round trip is bit-exact.

- reset board: switch the final step to the new reset verb, covering
  the explicit device-reset path instead of relying on the implicit
  reset after a dummy 1-sector read.

The two gated steps SKIP when their environment variable is unset,
and every step SKIPs without hardware, so a plain meson test stays
green.

Example invocation against an attached EDL device:

  D=<path_to_build>
  QDL_HIL_BUILD=$D QDL_HIL_CONTENTS=$D/contents.xml \
    QDL_HIL_STORAGE=ufs meson test -C build --suite=hil

   1/18 hil - qdl:HIL list devices             OK          0.05s
   2/18 hil - qdl:HIL chipinfo via Sahara      OK          0.4s
   3/18 hil - qdl:HIL flash whole build        OK         29.03s
   4/18 hil - qdl:HIL create-zip and flash     OK         79.62s
   5/18 hil - qdl:HIL flash sparse build       SKIP        0.02s
  ...
  18/18 hil - qdl:HIL reset board              OK          3.68s

  Ok:                17
  Fail:              0
  Skipped:           1

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-07-16 17:15:34 -05:00
Dmitry Baryshkov f8ab6dc81a Merge pull request #263 from quic-bjorande/for-linux-msm/flashmap-multi-layout
For linux msm/flashmap multi layout
2026-06-27 12:16:18 +03:00
Igor Opaniuk 29cf915799 Merge pull request #269 from igoropaniuk/ramdump/create-output-dir 2026-06-27 09:05:19 +02:00
Bjorn Andersson e01b33b214 flashmap: support selecting layouts
Flashmap packages can contain more than one layout, but qdl previously
rejected anything other than a single layout. Add flashmap-specific
specifier parsing so callers can select a layout by name while
preserving the existing storage-only selector form.

The supported forms are now:

  qdl flash flashmap.json::layout-name

  qdl flash flashmap.json::layout-name/storage1,storage2

  qdl flash flashmap.json::storage1,storage2

When a multi-layout flashmap is used without a layout selector, report
the valid layout names instead of failing with the old single-layout
limitation. Extend the cmocka flashmap tests to cover required layout
selection, layout-only selection, and layout plus storage filtering.

Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
2026-06-27 00:04:10 +00:00