blob: 0190f0468fd2e87f2288adb8484b557b92b90eeb [file] [log] [blame]
package pstore
import (
"fmt"
"testing"
"testing/fstest"
"time"
)
func TestParseHeader(t *testing.T) {
var cases = []struct {
input string
expectedOut *pstoreDmesgHeader
}{
{"Panic#2 Part30", &pstoreDmesgHeader{"Panic", 2, 30}},
{"Oops#1 Part5", &pstoreDmesgHeader{"Oops", 1, 5}},
// Random kernel output that is similar, but definitely not a dump header
{"<4>[2501503.489317] Oops: 0010 [#1] SMP NOPTI", nil},
}
for i, c := range cases {
t.Run(fmt.Sprintf("Test#%d", i+1), func(t *testing.T) {
out, err := parseDmesgHeader(c.input)
switch {
case err != nil && c.expectedOut != nil:
t.Errorf("Failed parsing %q: %v", c.input, err)
case err == nil && c.expectedOut == nil:
t.Errorf("Successfully parsed %q, expected error", c.input)
case err != nil && c.expectedOut == nil:
case err == nil && c.expectedOut != nil:
if out.Part != c.expectedOut.Part {
t.Errorf("Expected part to be %d, got %d", c.expectedOut.Part, out.Part)
}
if out.Counter != c.expectedOut.Counter {
t.Errorf("Expected counter to be %d, got %d", c.expectedOut.Counter, out.Counter)
}
if out.Reason != c.expectedOut.Reason {
t.Errorf("Expected reason to be %q, got %q", c.expectedOut.Reason, out.Reason)
}
}
})
}
}
func TestGetKmsgDumps(t *testing.T) {
testTime1 := time.Date(2022, 06, 13, 1, 2, 3, 4, time.UTC)
testTime2 := time.Date(2020, 06, 13, 1, 2, 3, 4, time.UTC)
testTime3 := time.Date(2010, 06, 13, 1, 2, 3, 4, time.UTC)
cases := []struct {
name string
inputFS fstest.MapFS
expectErr bool
expectedDumps []KmsgDump
}{
{"EmptyPstore", map[string]*fstest.MapFile{}, false, []KmsgDump{}},
{"SingleDumpSingleFile", map[string]*fstest.MapFile{
"dmesg-efi-165467917816002": {ModTime: testTime1, Data: []byte("Panic#2 Part1\ntest1\ntest2")},
"yolo-efi-165467917816002": {ModTime: testTime1, Data: []byte("something totally unrelated")},
}, false, []KmsgDump{{
Reason: "Panic",
OccurredAt: testTime1,
Counter: 2,
Lines: []string{
"test1",
"test2",
},
}}},
{"SingleDumpMultipleFiles", map[string]*fstest.MapFile{
"dmesg-efi-165467917816002": {ModTime: testTime1, Data: []byte("Panic#2 Part1\ntest2\ntest3")},
"dmesg-efi-165467917817002": {ModTime: testTime2, Data: []byte("Panic#2 Part2\ntest1")},
}, false, []KmsgDump{{
Reason: "Panic",
OccurredAt: testTime1,
Counter: 2,
Lines: []string{
"test1",
"test2",
"test3",
},
}}},
{"MultipleDumpsMultipleFiles", map[string]*fstest.MapFile{
"dmesg-efi-165467917816002": {ModTime: testTime1, Data: []byte("Panic#2 Part1\ntest2\ntest3")},
"dmesg-efi-165467917817002": {ModTime: testTime2, Data: []byte("Panic#2 Part2\ntest1")},
"dmesg-efi-265467917816002": {ModTime: testTime3, Data: []byte("Oops#1 Part1\noops3")},
"dmesg-efi-265467917817002": {ModTime: testTime2, Data: []byte("Oops#1 Part2\noops1\noops2")},
}, false, []KmsgDump{{
Reason: "Panic",
OccurredAt: testTime1,
Counter: 2,
Lines: []string{
"test1",
"test2",
"test3",
},
}, {
Reason: "Oops",
OccurredAt: testTime3,
Counter: 1,
Lines: []string{
"oops1",
"oops2",
"oops3",
},
}}},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
dumps, err := getKmsgDumpsFromFS(c.inputFS)
switch {
case err == nil && c.expectErr:
t.Error("Expected error, but got none")
return
case err != nil && !c.expectErr:
t.Errorf("Got unexpected error: %v", err)
return
case err != nil && c.expectErr:
// Got expected error
return
case err == nil && !c.expectErr:
if len(dumps) != len(c.expectedDumps) {
t.Fatalf("Expected %d dumps, got %d", len(c.expectedDumps), len(dumps))
}
for i, dump := range dumps {
if dump.OccurredAt != c.expectedDumps[i].OccurredAt {
t.Errorf("Dump %d expected to have occurred at %v, got %v", i, c.expectedDumps[i].OccurredAt, dump.OccurredAt)
}
if dump.Reason != c.expectedDumps[i].Reason {
t.Errorf("Expected reason in dump %d to be %v, got %v", i, c.expectedDumps[i].Reason, dump.Reason)
}
if dump.Counter != c.expectedDumps[i].Counter {
t.Errorf("Expected counter in dump %d to be %d, got %d", i, c.expectedDumps[i].Counter, dump.Counter)
}
if len(dump.Lines) != len(c.expectedDumps[i].Lines) {
t.Errorf("Expected number of lines in dump %d to be %d, got %d", i, len(c.expectedDumps[i].Lines), len(dump.Lines))
}
for j := range dump.Lines {
if dump.Lines[j] != c.expectedDumps[i].Lines[j] {
t.Errorf("Expected line %d in dump %d to be %q, got %q", i, j, c.expectedDumps[i].Lines[j], dump.Lines[j])
}
}
}
}
})
}
}