package collector import "testing" // Fixture shape matches Broadcom's published storcli2 system-schema.json // ("show all" -> Controllers[0].Response Data.System Overview[].Ctrl). func TestParseStorcli2ControllerIndices(t *testing.T) { raw := []byte(`{ "Controllers": [ { "Command Status": {"Status": "Success"}, "Response Data": { "Number of Controllers": 2, "System Overview": [ {"Ctrl": 0, "Product Name": "SAS3808-iMR", "Personality": "RAID", "Status": "Optimal", "PD(s)": 2, "VD(s)": 0}, {"Ctrl": 1, "Product Name": "SAS3808-iMR", "Personality": "RAID", "Status": "Optimal", "PD(s)": 4, "VD(s)": 1} ] } } ] }`) got := parseStorcli2ControllerIndices(raw) if len(got) != 2 || got[0] != 0 || got[1] != 1 { t.Fatalf("indices=%v want [0 1]", got) } } func TestParseStorcli2ControllerIndicesEmptyOrMalformed(t *testing.T) { if got := parseStorcli2ControllerIndices([]byte("not json")); got != nil { t.Fatalf("malformed input should return nil, got %v", got) } if got := parseStorcli2ControllerIndices([]byte(`{"Controllers":[]}`)); got != nil { t.Fatalf("no controllers should return nil, got %v", got) } } // TestCollectStorcli2DrivesEndToEnd exercises the full path this bug fix // targets: storcli64 sees the Tri-Mode controller but no drives (real // support-bundle behavior for SAS3808-iMR), storcli2 is the tool that // actually finds them. func TestCollectStorcli2DrivesEndToEnd(t *testing.T) { orig := raidToolQuery t.Cleanup(func() { raidToolQuery = orig }) raidToolQuery = func(name string, args ...string) ([]byte, error) { switch name { case "storcli2": if len(args) > 0 && args[0] == "show" { return []byte(`{"Controllers":[{"Response Data":{"System Overview":[{"Ctrl":0,"Product Name":"SAS3808-iMR"}]}}]}`), nil } // per-controller drive listing: /c0/eall/sall show all J return []byte(`{ "Controllers": [ { "Response Data": { "Drive Information": [ {"EID:Slt": "252:0", "State": "Onln", "Size": "1.746 TB", "Intf": "NVMe", "Med": "SSD", "Model": "SAMSUNG MZQL21T9HCJR", "SN": "S6EYNE0T123456"}, {"EID:Slt": "252:1", "State": "UGood", "Size": "1.746 TB", "Intf": "NVMe", "Med": "SSD", "Model": "SAMSUNG MZQL21T9HCJR", "SN": "S6EYNE0T654321"} ] } } ] }`), nil } return nil, nil } drives := collectStorcli2Drives() if len(drives) != 2 { t.Fatalf("drives=%d want 2 (%#v)", len(drives), drives) } if drives[0].SerialNumber == nil || *drives[0].SerialNumber != "S6EYNE0T123456" { t.Fatalf("drives[0]=%#v want serial S6EYNE0T123456", drives[0]) } } // TestParseStorcliDrivesJSONPerSlotKeys regression-tests against a live // SAS3808-iMR "storcli64 /call/eall/sall show all J" dump: "Response Data" // has no "Drive Information" array at all, only per-slot keys like // "Drive /c0/e69/s0" (plus a paired "... - Detailed Information" key that // must be skipped). The previous parser, which only looked for "Drive // Information", silently returned zero drives against this real output. func TestParseStorcliDrivesJSONPerSlotKeys(t *testing.T) { raw := []byte(`{ "Controllers": [ { "Command Status": {"Status": "Success"}, "Response Data": { "Drive /c0/e69/s0": [ {"EID:Slt": "69:0", "DID": 0, "State": "JBOD", "DG": "-", "Size": "447.130 GB", "Intf": "SATA", "Med": "SSD", "Model": "SAMSUNG MZ7L3480HCHQ-00B7C", "Sp": "U", "Type": "-"} ], "Drive /c0/e69/s0 - Detailed Information": { "Drive /c0/e69/s0 State": {"Shield Counter": 0} } } } ] }`) drives := parseStorcliDrivesJSON(raw) if len(drives) != 1 { t.Fatalf("drives=%d want 1 (%#v)", len(drives), drives) } if drives[0].Model == nil || *drives[0].Model != "SAMSUNG MZ7L3480HCHQ-00B7C" { t.Fatalf("drives[0]=%#v want model SAMSUNG MZ7L3480HCHQ-00B7C", drives[0]) } if drives[0].Slot == nil || *drives[0].Slot != "69:0" { t.Fatalf("drives[0].Slot=%v want 69:0", drives[0].Slot) } }