package models import "testing" func TestJobStateStr(t *testing.T) { tests := []struct { name string state int want string }{ { name: "PEND", state: JOBSTAT["PEND"], want: "PEND", }, { name: "PSUSP (PEND+PSUSP)", state: JOBSTAT["PEND"] | JOBSTAT["PSUSP"], want: "PSUSP", }, { name: "RUN", state: JOBSTAT["RUN"], want: "RUN", }, { name: "USUSP (RUN+USUSP)", state: JOBSTAT["RUN"] | JOBSTAT["USUSP"], want: "USUSP", }, { name: "SSUSP (RUN+SSUSP)", state: JOBSTAT["RUN"] | JOBSTAT["SSUSP"], want: "SSUSP", }, { name: "RUNKWN (RUN+RUNKWN — lost contact with remote cluster)", state: JOBSTAT["RUN"] | JOBSTAT["RUNKWN"], want: "RUNKWN", }, { name: "EXIT", state: JOBSTAT["EXIT"], want: "EXIT", }, { name: "DONE", state: JOBSTAT["DONE"], want: "DONE", }, { name: "UNKNOWN (0x10000 — worker lost contact with controller)", state: JOBSTAT["UNKNOWN"], want: "UNKWN", }, { name: "zero state returns ERR", state: 0, want: "ERR", }, { name: "TRANSIENT (0x400 — job uncertain after failover)", state: 0x400, want: "TRANSIENT", }, { name: "TRANSIENT with other bits set", state: 0x400 | 0x01, // TRANSIENT + PEND want: "TRANSIENT", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := JobStateStr(tt.state) if got != tt.want { t.Errorf("JobStateStr(0x%X) = %q, want %q", tt.state, got, tt.want) } }) } } func TestJobStatMapValues(t *testing.T) { // Verify bitmask values match C JOB_STAT_* defines in src/include/xce/types.h. expected := map[string]int{ "PEND": 0x01, "RUN": 0x02, "EXIT": 0x04, "DONE": 0x08, "PSUSP": 0x10, "USUSP": 0x20, "SSUSP": 0x40, "PDONE": 0x80, "PERR": 0x100, "WAIT": 0x200, "TRANSIENT": 0x400, "RUNKWN": 0x8000, "UNKNOWN": 0x10000, } for key, want := range expected { got, ok := JOBSTAT[key] if !ok { t.Errorf("JOBSTAT[%q] missing", key) continue } if got != want { t.Errorf("JOBSTAT[%q] = 0x%X, want 0x%X", key, got, want) } } }