Repository navigation
Reports and CI
boot-log-diff writes its normal output to the terminal and, on request, two report files at the same time:
| Option | Writes | For |
|---|---|---|
--junit FILE |
JUnit XML | GitLab, Jenkins, GitHub Actions, test management tools |
--html FILE |
one self-contained HTML page | test records, repair tickets, e-mail |
--json |
JSON on stdout (instead of text) | your own scripts and databases |
The exit status stays the same: 0 no deviations, 1 deviations, 2
error.
A single file without scripts or external resources: open it anywhere, attach it to a ticket, archive it with the test record. It follows the light or dark mode of the viewer and fits a phone screen.
A board without deviations gets a short page:

One test case per check, so the test system shows what failed, not just "boot check failed":
| classname | test cases |
|---|---|
boot-log-diff.facts |
one per fact (model, dram, …, plus your --facts) |
boot-log-diff.lines |
log lines: fails when lines are missing or new; the hunks are in the failure text |
boot-log-diff.faults |
one per known fault rule; fails with the title as message and the diagnosis and lines as text |
For the example logs that is 30 test cases, 5 failed:
<testcase classname="boot-log-diff.faults" name="eth-phy">
<failure message="Ethernet PHY not found" type="error">The MAC cannot talk to the PHY over MDIO. Check the PHY supply and its reset line, the reference clock (25/50 MHz), the MDIO/MDC solder joints and the PHY address strapping.
dut line 50: [ 1.313120] fec 30be0000.ethernet eth0: Unable to connect to phy</failure>
</testcase>Because every rule is a test case, the CI history shows how often each fault occurred over time.
boot-check:
script:
- boot-log-diff golden.log dut.log --junit boot.xml --html boot.html
artifacts:
when: always
reports:
junit: boot.xml
paths: [boot.html]The failed checks show in the merge request and on the pipeline's Tests
tab. when: always keeps the reports when the job fails.
stage('Boot check') {
steps {
sh 'boot-log-diff golden.log dut.log --junit boot.xml --html boot.html || true'
}
post {
always {
junit 'boot.xml'
archiveArtifacts artifacts: 'boot.html'
}
}
}With || true the junit step decides: failed test cases mark the build
unstable instead of failed. Leave it out if a deviation must fail the build.
- name: Boot check
run: boot-log-diff golden.log dut.log --junit boot.xml --html boot.html
- uses: actions/upload-artifact@v7
if: always()
with:
name: boot-check
path: |
boot.xml
boot.htmlTo see the test cases in the job summary, add a JUnit report action from the
Marketplace that reads boot.xml.
A sequencer only needs the exit status; keep the HTML page per serial number:
boot-log-diff golden.log "logs/$SERIAL.log" --html "reports/$SERIAL.html"
case $? in
0) echo PASS ;;
1) echo FAIL ;;
*) echo "ERROR: check the station setup" ;;
esacfrom pathlib import Path
from boot_log_diff import compare
from boot_log_diff.report import render_html
def test_board_boots_like_golden(boot_log, tmp_path): # boot_log: your fixture
golden = Path("golden.log").read_text()
result = compare(golden, boot_log)
(tmp_path / "boot.html").write_text(render_html(result, "golden.log", "dut"))
faults = [f.rule.title for f in result.faults]
assert not result.has_deviations, (faults, result.summary())result.facts, result.hunks, result.faults and result.moved hold the
details; render_junit and render_json are next to render_html.
boot-log-diff · MIT licensed · the example logs are from a fictitious board (Acme EPC-8M).
