{
  "part": 3,
  "title": "Folder-based report drive + target_state.txt",
  "reset": "standard",
  "steps": [
    { "id": "3.1", "title": "Confirm the report-drive config",
      "actions": [
        { "do": "config_get", "path": "target.report.targetDrive.label", "store_as": "RLABEL" },
        { "do": "config_get", "path": "target.report.targetDrive.mountPoint", "store_as": "RMOUNT" }
      ],
      "assertions": [
        { "type": "regex_present", "var": "RLABEL", "pattern": "^$", "message": "target.report.targetDrive.label is empty" },
        { "type": "regex_present", "var": "RMOUNT", "pattern": "^/storage/testing/report$", "message": "target.report.targetDrive.mountPoint points at the folder" }
      ]
    },
    { "id": "3.2", "title": "Run a full source-target trip and inspect the report drive", "depends_on": ["3.1"],
      "actions": [
        { "do": "zfs_snapshot", "dataset": "{SRC}/ds1@part3" },
        { "do": "run_sneakernet", "servername": "test-source", "verbosity": 2, "log": "part3_source", "expect_exit": 0 },
        { "do": "run_sneakernet", "servername": "test-target", "verbosity": 2, "log": "part3_target", "expect_exit": 0,
          "capture": { "name": "TGT_LOG" } },
        { "do": "read_file", "path": "{REPORT}/target_state.txt", "store_as": "STATE_TEXT" }
      ],
      "assertions": [
        { "type": "regex_present", "var": "TGT_LOG", "pattern": "sendTargetState: Created target state file at /storage/testing/report/target_state\\.txt \\(\\d+ snapshots?\\)", "message": "log confirms target_state.txt was created with a snapshot count" },
        { "type": "file_nonempty", "path": "{REPORT}/target_state.txt", "message": "target_state.txt is not empty (the exact bug that was fixed)" },
        { "type": "regex_present", "var": "STATE_TEXT", "pattern": "^#", "message": "target_state.txt opens with a #-prefixed header" },
        { "type": "regex_present", "var": "STATE_TEXT", "pattern": "storage/testing/dst/ds1\\@", "message": "target_state.txt lists a real snapshot after the header" }
      ]
    },
    { "id": "3.3", "title": "Confirm it fails safely, not silently", "depends_on": ["3.1"],
      "_comment": "The OVERVIEW block is written into the report drive's timestamped report FILE by cleanup()/sendReport(), never printed to the process's own console/log output - so it cannot be checked against OUT33 (run_sneakernet's captured stdout+stderr). {REPORT} is emptied first (3.2 already left its own report file there) so read_file_matching's exactly-one-match requirement finds only this step's own report.",
      "config": { "mutations": [ { "op": "set", "path": "target.poolname", "value": "storage/testing/doesnotexist" } ] },
      "actions": [
        { "do": "empty_dir", "path": "{REPORT}" },
        { "do": "write_file", "path": "{TRANSPORT}/serial.txt", "content": "1" },
        { "do": "run_sneakernet", "servername": "test-target", "verbosity": 1, "log": "part3_3", "expect_exit": "any",
          "capture": { "name": "OUT33" } },
        { "do": "read_file_matching", "dir": "{REPORT}", "pattern": "_sneakernet_report_\\d+\\.txt$",
          "capture": { "name": "REPORT33" } }
      ],
      "assertions": [
        { "type": "regex_present", "var": "OUT33", "pattern": "(?i)could not read the snapshot inventory", "message": "log explicitly says it could not read the inventory" },
        { "type": "regex_present", "var": "OUT33", "pattern": "Is the pool imported\\?", "message": "log asks the diagnostic question" },
        { "type": "regex_present", "var": "REPORT33", "pattern": "(?is)=== OVERVIEW ===.*could not read the snapshot inventory", "message": "the same message appears inside the OVERVIEW block of the actual report file, not just the log" }
      ]
    }
  ]
}
