ChargeLink Native

Test Workflow: Plan and Run Protocol Campaigns

This chapter explains how ChargeLink turns a protocol test inventory into an executed campaign with verdicts and evidence, and how to use it without guessing. It covers the three test surfaces and states clearly where a PASS comes from.

The three test surfaces

SurfaceCommand familyScopeVerdictsLicense
Protocol-first campaignschargelink testISO 15118-2 (797 case bindings from ISO 15118-4) and ISO 15118-20 (383 bindings from ISO 15118-21 and ISO/PAS 15118-23); selection by SUT role, charging mode, test area, payment mode, securitypass / fail from a live-SUT or validated-replay evidence manifest; inconclusive in dry-runnot required for planning
Licensed conformance packageschargelink conformance packagePackages for ISO 15118-20, ISO 15118-2 and DIN 70121 per role and for transport security; PICS/PIXIT → campaign → run → verdict report → customer reportinconclusive (dry-run) or blocked until live/replay evidence is attached; the run directory carries the traceable case listpackage entitlement
Deterministic simulationchargelink simSeeded paired EVSE/EVCC scenarios and TLS/PKI campaigns with transcript hashespass_internal_deterministic / expected_fault_path; replay verified by hashnot required
Protocol-first test workflow: discover, plan, capture, evidence manifest, run, verdict 1 · Discoverprotocol → areas → cases797 + 383 executable case bindingstest areas list · cases list 2 · Planrole, mode, area, PICS/PIXITcampaign_plan.jsontest plan · run (dry-run) 3 · Capture on the benchlive session with the SUTrun directory + manifest.jsonevse start (external session) 4 · Evidence manifestreviewed checks per caseartifact SHA-256, live_sessionprotocol_test_evidence.v1 5 · Run with evidence → 6 · Verdict and report pass only when stimulus, expected behaviour, timing, state and transport checks are all true verdicts.json · campaign_status.json · customer_report.json status: completed_pass / completed_fail / completed_inconclusive test run --evidence live --evidence-source … · test report Licensed package flow (same engine) activate → pics-pixit → campaign → execute → report PICS/PIXIT templates, entitlement proof, customer reports and traceability conformance package execute --evidence-mode dry-run Orange steps happen on the bench and are reviewed by an engineer; ChargeLink records the decision with the evidence.
The protocol-first workflow. Steps 3 and 4 happen on the bench; the verdict binds that evidence to the selected cases.

Where a PASS comes from. ChargeLink never emits a PASS verdict for a protocol test case from the inventory alone. A case passes only when an evidence manifest states that the stimulus was applied, the expected behaviour was observed, the timing policy was satisfied, the state transition and transport were valid, and nothing unexpected was observed; and the manifest must identify either a live system-under-test session or a validated replay capture with its SHA-256. The campaign engine evaluates the manifest and binds it to the case. This is the product's claim boundary: the verdict is traceable engineering evidence, not certification.

Procedures written for older command groups (scenario run, suite run, campaign report) must be rewritten with the commands on this page.

Before running anything

$CL   = 'C:\ChargeLink\0.5.0-rc2\pc1\bin\chargelink.exe'
$Data = 'C:\ChargeLinkData'
$Run = "$Data\tests\$(Get-Date -Format yyyyMMdd-HHmmss)"
New-Item -ItemType Directory -Force $Run | Out-Null

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json doctor
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json license status
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test protocols list

Why: the doctor catches missing roots before a long run; the license state decides whether packages are executable; the protocol list shows which inventories the installed release resolves (iso15118-2 → ISO 15118-4; iso15118-20 → ISO 15118-21 and ISO/PAS 15118-23). Standard selection is intentionally not exposed; you select the customer protocol.

Step 1 — discover areas and cases

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test areas list --protocol iso15118-20 --sut-role evse --charging-mode dc
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test cases list --protocol iso15118-20 --sut-role evse --charging-mode dc --test-area SessionSetup
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test cases list --protocol iso15118-2 --sut-role evcc --charging-mode ac --test-area ChargeParameterDiscovery

Each case carries case_id (for example TC21_SECC_SessionSetup_002), test_area, behavior_class, variant_class (positive/negative), execution_binding, execution_status (executable or blocked), the referenced requirement IDs, the timer IDs it depends on, and evidence_required: true. ISO 15118-20 EVSE DC resolves to 187 cases across 22 areas (Authorization 55, PowerDelivery 33, CertificateInstallation 30, SessionStop 20, ChargeLoop 19, V2GTP common and DC 16 each, ScheduleExchange 15, ServiceSelection 15, and so on).

Step 2 — create the plan

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test plan --protocol iso15118-20 --sut-role evse --charging-mode dc `
  --test-area SessionSetup --evidence dry-run --output "$Run\plan"

Result: status: plan_ready, the selected and executable case counts, and campaign_plan.json under the output directory. Optional selectors: --payment-mode, --security, --case-id <SOURCE_CASE_ID> for one case, --pics FILE/--pixit FILE to narrow applicability, --max-cases N.

Step 3 — dry-run the campaign

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test run --protocol iso15118-20 --sut-role evse --charging-mode dc `
  --test-area SessionSetup --evidence dry-run --max-cases 3 --output "$Run\dry"
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test status --output "$Run\dry"
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test report --output "$Run\dry"

A dry-run writes campaign_plan.json and campaign_status.json with campaign_status: planned. The status output lists, per case, the evidence_requirements (campaign.json, pics.json, pixit.json, stimulus_message.json, observed_message.json, timer_trace.json, protocol_state_trace.json, exi_trace.json, conformance_traceability.json, verdict.json), the PICS selector IDs and the PIXIT parameter IDs (PIXIT_NETWORK_INTERFACE, PIXIT_IPV6_LINK_LOCAL, PIXIT_V2G_TCP_PORT, PIXIT_SECURITY_MODE, PIXIT_RESPONSE_TIMEOUT_MS, ...). Use this to prepare the bench and the evidence collection.

Step 4 — capture evidence on the bench

Run the protocol session that exercises the case (for example the ISO 15118-20 EVSE listener with the vehicle under test) and keep the run directory. Then write an evidence manifest (schema chargelink.protocol_test_evidence.v1) that maps each case to the checks and the trace files with their SHA-256:

{
  "schema_version": "chargelink.protocol_test_evidence.v1",
  "customer_protocol": "iso15118-20",
  "sut_role": "evcc",
  "charging_mode": "dc",
  "test_area": "ChargeLoop",
  "source_kind": "live_sut",
  "capture_id": "bench3-2026-09-23-001",
  "live_session": {
    "session_id": "iso20-20260923-101500",
    "sut_endpoint": "[fe80::d7d2:c8b6:1aa6:af7e%2]:50118",
    "capture_started_at_utc": "2026-09-23T10:15:00Z",
    "capture_completed_at_utc": "2026-09-23T10:16:30Z",
    "transport": "ipv6-v2gtp-tcp-tls"
  },
  "cases": [
    {
      "case_id": "TC23_EVCC_ChargeLoop_003",
      "execution_binding": "chargelink_compliance::ats::execute_iso15118_23_remaining_dc_case::TC23_EVCC_ChargeLoop_003",
      "checks": {
        "stimulus_applied": true,
        "expected_behavior_observed": true,
        "timing_policy_satisfied": true,
        "state_transition_valid": true,
        "transport_valid": true,
        "unexpected_behavior_observed": false
      },
      "artifacts": [
        { "path": "traces/live-v2gtp-frames.jsonl", "kind": "protocol_trace", "sha256": "<64 hex>" }
      ]
    }
  ]
}

Rules: source_kind is live_sut (then live_session is required) or validated_replay (then a validation block with validated: true, the validator, the time and the source_capture_sha256 is required). Every case needs at least one artifact with a SHA-256; obtain hashes from the run's manifest.json or Get-FileHash. The execution_binding string comes from test cases list. Who fills in the checks: the engineer who reviewed the trace against the expected behaviour rule; ChargeLink records the decision with the evidence, it does not make it for you.

Step 5 — run with evidence and report

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test run --protocol iso15118-20 --sut-role evcc --charging-mode dc `
  --test-area ChargeLoop --case-id TC23_EVCC_ChargeLoop_003 `
  --evidence live --evidence-source "$Run\evidence_manifest.json" --output "$Run\live"
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test status --output "$Run\live"
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json test report --output "$Run\live"

Outputs: campaign_plan.json, campaign_status.json (completed_pass, completed_fail or completed_inconclusive), verdicts.json, customer_report.json, evidence\source_manifest.json, evidence\evidence_index.json and artifact_manifest.json with SHA-256 per file. A case is pass only when all five positive checks are true and unexpected_behavior_observed is false. Use test stop --output DIR to mark an interrupted campaign as stopped.

Licensed package flow

Packages wrap the same engine with a PICS/PIXIT generator, a campaign manifest, a runner and customer-facing reports, and they are gated by entitlements. The end-to-end command is execute; the individual steps are pics-pixit, campaign, run and report.

$Package = 'iso15118-2-evse'
$Role    = 'evse'
$Pics    = "$Run\pics.json"
$Pixit   = "$Run\pixit.json"

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json conformance packages list --protocol iso15118-2 --role evse
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json conformance package activate --package $Package --license "$Data\licenses\customer.cllic"
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json conformance package pics-pixit --package $Package --role $Role --pics $Pics --pixit $Pixit --executable-only
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json conformance package campaign  --package $Package --role $Role --pics $Pics --pixit $Pixit --executable-only --max-cases 10
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json conformance package execute   --package $Package --role $Role --pics $Pics --pixit $Pixit `
  --out "$Run\package-run" --evidence-mode dry-run --executable-only --max-cases 10
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json conformance package report --run-dir "$Run\package-run" --out "$Run\package-run\verdict_report.json"

Review the generated PICS (supports_dc, supports_ac, supports_eim, supports_pnc, supports_tls, supports_bpt, ...) and PIXIT (default_sdp_udp_port, default_v2gtp_tcp_port, external_evcc_bind_host, interface and address examples, tls_policy, evidence_mode_default) before executing; any change creates a different campaign. The package writes pics_pixit.json, campaign.json, run_report.json, verdict_report.json, signed_verdict_manifest.json, customer_report.json, customer_report.md, customer_report.html, support_bundle_manifest.json, package_protection_manifest.json, entitlement_evaluation.json and package_content_sha256_manifest.json. Evidence modes are dry-run, replay and live; the package runner reports inconclusive for dry-run and blocked for the others until live or replay evidence is bound, so use the package for planning, entitlement proof and traceability and the test flow for verdicts.

Package IDs, SKUs, case counts and entitlements are in the Test Package Catalog.

Interpreting results

OutcomeMeaningOperator action
passEvidence manifest satisfied all checks for the caseRetain the run directory, manifest and traces together
failA check was false or unexpected behaviour was observedInspect the trace and the SUT logs; do not edit the manifest to change the outcome
inconclusiveDry-run, or no evidence boundAttach evidence and rerun
blockedPrerequisite absent (entitlement, hardware, applicability)Correct the prerequisite; a blocked case is not a failure
not selectedPICS/PIXIT or selectors excluded the caseConfirm the exclusion reflects the SUT

Practical regression workflow

  1. Save doctor, version and license outputs with the run.
  2. test plan the area under test; review the PIXIT parameters it needs.
  3. Run one bench session; verify artifact integrity.
  4. Write the evidence manifest with reviewed checks and hashes.
  5. test run --evidence live; export the report.
  6. Archive plan, manifest, traces, report and environment inventory together; compare with the last accepted baseline.