Supported Formats
UniTrack is polyglot: every upload’s format is auto-detected from its content, so you
push your tool’s native output and UniTrack maps it into one model. The three upload fields
(junit, jacoco, perf) are named for the common case but each accepts any format in
its category.
1. Test results (junit field)
| Format | Detected by | Notes |
|---|---|---|
JUnit / Surefire XML ( |
|
The JVM standard; also the conversion target many tools already emit. |
.NET TRX ( |
|
Visual Studio / |
xUnit.net XML ( |
|
xUnit.net v2 ( |
NUnit 3 XML ( |
|
|
CTRF JSON ( |
top-level |
Common Test Report Format — one schema with reporters for Jest, Playwright, pytest, PHPUnit, Go and more. |
Go |
NDJSON action events ( |
|
2. Coverage (jacoco field)
| Format | Detected by | Notes |
|---|---|---|
JaCoCo XML ( |
|
JVM. Line, branch, instruction, method counters. |
Cobertura XML ( |
|
Python (coverage.py), Go (gocover-cobertura), JS, .NET (Coverlet). |
LCOV ( |
|
JS/TS (Istanbul/nyc, c8), C/C++ (gcov), Rust, Swift. |
OpenCover XML ( |
|
.NET (Coverlet |
Go cover profile ( |
|
|
3. Performance / load tests (perf field)
| Format | Detected by | Notes |
|---|---|---|
JMeter JTL ( |
CSV header with |
Per-sample latency → real percentiles + error rate. |
k6 JSON summary ( |
k6 |
Pre-aggregated metrics. |
JMH JSON ( |
JSON array with |
JVM microbenchmarks ( |
Go |
|
The Go analog of JMH; |
Gatling ( |
tab-separated |
Per-request latency ( |
|
Adding a format is a small |
4. Multiple perf tests in one upload
A build often runs several perf suites (an API load test, a checkout scenario, a JMH
microbenchmark). Upload them together — each perf file becomes its own series, keyed
by a flag, so its trend and regression are tracked independently:
curl -F project=myapp -F commit=$SHA \
-F '[email protected]' -F 'perfFlag=api' \
-F '[email protected]' -F 'perfFlag=checkout' \
-F '[email protected]' -F 'perfFlag=micro' \
http://localhost:8080/api/v1/ingest
perfFlag is matched to each perf file by position. If you omit it, the filename stem is
used (api.jtl → api); a single perf file with no perfFlag keeps using the request
flag. The Load-tests page shows a flag filter to switch between series (like the coverage
module filter).
5. Perf regression detection
Each perf series (flag) is watched for a sustained level shift in p95 latency. When a
series steps to a worse level and stays there, the Load-tests page shows a p95 latency
regressed badge with the onset commit/date and the depth (a robust z-score vs the series'
own noise) — so a regression that hides inside normal run-to-run jitter is still caught,
and you can see when it started. Detection is classical and transparent (median/MAD
CUSUM onset); a lone spike or a series that has since recovered does not flag.
6. Large reports & memory
Parsing is bounded-memory, so a large report won’t exhaust the heap:
-
XML (JUnit/TRX/xUnit/NUnit, JaCoCo/Cobertura/OpenCover) is parsed with streaming StAX — one suite / package / module is held at a time, never the whole document tree.
-
JSON with an unbounded array (CTRF tests, JMH benchmarks) is streamed element by element; the k6 summary is pre-aggregated and small.
-
Perf logs (JMeter JTL, Gatling) stream line by line into a fixed-size histogram.
A hard decompressed-size guard (unitrack.ingest.max-report-bytes / max-perf-bytes)
backs this up: a pathological upload is rejected with a clear error rather than risking an
out-of-memory crash. See Ingestion.