⌑ MarginNook

MARGINNOOK / DEVELOPER PREVIEW

JUnit failure extraction

Extract failed cases, error events and traces from a JUnit report.

Developer preview. Hosted API is not live yet. Explore fixed synthetic samples; anonymous uploads, hosted execution and payments remain closed.

Inputs and results

Input: JUnit XML. Returns: Case and event counts, separate traces and source references.

HTTP business ID report.failures maps to MCP test_failures.

Arguments

{
  "max_cases": 10,
  "offset": 0
}

max_cases is 1–100 (default 10). Case identities and reruns are not deduplicated. Error cases are a subset of failed cases; multiple events remain distinct. DTD/entities and unsupported nesting are rejected.

Reproducible sample

JUnit failures

Fixed synthetic sample · generated by the local processing core · no upload or live API call.

1. Upload input

{
  "format": "junit_xml",
  "content": "<testsuite name=\"checkout\"><testcase classname=\"Cart\" name=\"total\"><failure message=\"Expected 19.75\" type=\"AssertionError\">actual: 19.00</failure></testcase><testcase classname=\"Cart\" name=\"empty\"/></testsuite>"
}

2. Submit a job

{
  "tool": "report.failures",
  "resource_id": "<private-resource-handle>",
  "arguments": {
    "max_cases": 10,
    "offset": 0
  }
}

3. Operation output

This is the operation output inside result.output, not a complete job envelope.

{
  "operation": "report.failures",
  "scope": {
    "input": "single-junit-document",
    "counting": "actual-case-and-event-elements",
    "deduplicated": false
  },
  "source_refs": [
    "input:xml"
  ],
  "counts": {
    "cases": 2,
    "failed_cases": 1,
    "error_cases": 0,
    "skipped_cases": 0,
    "passed_cases": 1,
    "failure_events": 1,
    "error_events": 0
  },
  "duplicate_case_identities": 0,
  "notice": "failed_cases includes cases with failure or error events; error_cases is a subset. Duplicate identities and reruns are counted separately.",
  "offset": 0,
  "next_offset": null,
  "total_items": 1,
  "omitted_items": 0,
  "incomplete": false,
  "source_read_required": false,
  "oversized_item_refs": [],
  "cases": [
    {
      "case_id": "suite-0001/case-00001",
      "suite": "checkout",
      "classname": "Cart",
      "name": "total",
      "events": [
        {
          "kind": "failure",
          "message": "Expected 19.75",
          "type": "AssertionError",
          "trace": "actual: 19.00"
        }
      ]
    }
  ]
}

Fields, bounds and evidence for this operation

Result fields and evidence

scope declares what was processed. incomplete, next_offset, omitted_items and source_read_required describe the bounded page. The core result is at most 128 KiB; whole items are omitted instead of clipped. A download is the complete returned page, not an unlimited result.

source_refs point back to the uploaded input; the HTTP job supplies source_resource_id and result_resource. cases contain case_id, suite, classname, name and separate events with kind/message/type/trace. counts comes from actual case and event elements.

Use GET /v1/resources/<private-resource-handle> for stored original/result bytes, or MCP read_evidence(resource_id, offset=0, length=4000). Never publish real handles. Resource-family expiry and management deletion apply to all derived evidence.

Errors and recovery

Quote checks arguments and metadata, not parsing. Preserve input and job ID on failure. Retry keyed submission with the original key; do not repeat uncertain uploads automatically. Invalid input needs correction; quota and platform capacity use distinct machine codes. Successfully extracting failing tests is a completed tool job.

HTTP contract · MCP · Limits · Switch samples