aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-05-13 17:51:56 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-05-13 20:37:26 +0200
commit3d789641a384b4356a5a9e7c65ca94eda68915b3 (patch)
treed0f73efce60789d0dd3199df91230499d3380bc3 /pkg
parentb3fe7470a482f2a877cbe43f46636153031b20e3 (diff)
pkg/report: add Report.SkipPos
SkipPos is what pkg/instance needs, but also will be needed for ParseAll.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/instance/instance.go7
-rw-r--r--pkg/report/fuzz.go35
-rw-r--r--pkg/report/report.go11
-rw-r--r--pkg/report/report_test.go31
4 files changed, 58 insertions, 26 deletions
diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go
index d88838576..39de02017 100644
--- a/pkg/instance/instance.go
+++ b/pkg/instance/instance.go
@@ -6,7 +6,6 @@
package instance
import (
- "bytes"
"encoding/json"
"fmt"
"net"
@@ -245,11 +244,7 @@ func (inst *inst) test() error {
rep := inst.reporter.Parse(testErr.Output)
if rep != nil && rep.Type == report.UnexpectedReboot {
// Avoid detecting any boot crash as "unexpected kernel reboot".
- output := testErr.Output[rep.EndPos:]
- if pos := bytes.IndexByte(testErr.Output[rep.StartPos:], '\n'); pos != -1 {
- output = testErr.Output[rep.StartPos+pos:]
- }
- rep = inst.reporter.Parse(output)
+ rep = inst.reporter.Parse(testErr.Output[rep.SkipPos:])
}
if rep == nil {
rep = &report.Report{
diff --git a/pkg/report/fuzz.go b/pkg/report/fuzz.go
index 82b42849f..02f02c4db 100644
--- a/pkg/report/fuzz.go
+++ b/pkg/report/fuzz.go
@@ -11,7 +11,7 @@ import (
func Fuzz(data []byte) int {
res := 0
- for _, reporter := range fuzzReporters {
+ for os, reporter := range fuzzReporters {
typ := reporter.(*reporterWrapper).typ
containsCrash := reporter.ContainsCrash(data)
rep := reporter.Parse(data)
@@ -32,18 +32,41 @@ func Fuzz(data []byte) int {
if len(rep.Output) == 0 {
panic(fmt.Sprintf("%v: len(Output) == 0", typ))
}
+ switch os {
+ case "openbsd", "netbsd", "fuchsia":
+ // openbsd/netbsd has Start/End/SkipPos set incorrectly due to messing with /r/n.
+ // fuchsia because it symbolizes before parsing.
+ continue
+ }
if rep.StartPos != 0 && rep.EndPos != 0 && rep.StartPos >= rep.EndPos {
- panic(fmt.Sprintf("%v: StartPos=%v >= EndPos=%v", typ, rep.StartPos, rep.EndPos))
+ panic(fmt.Sprintf("%v: bad StartPos\nStartPos=%v >= EndPos=%v",
+ typ, rep.StartPos, rep.EndPos))
}
if rep.EndPos > len(rep.Output) {
- panic(fmt.Sprintf("%v: EndPos=%v > len(Output)=%v", typ, rep.EndPos, len(rep.Output)))
+ panic(fmt.Sprintf("%v: bad EndPos\nEndPos=%v > len(Output)=%v",
+ typ, rep.EndPos, len(rep.Output)))
+ }
+ if rep.SkipPos <= rep.StartPos || rep.SkipPos > rep.EndPos {
+ panic(fmt.Sprintf("%v: bad SkipPos\nSkipPos=%v: StartPos=%v EndPos=%v",
+ typ, rep.SkipPos, rep.StartPos, rep.EndPos))
+ }
+ // If we parse from StartPos, we must find the same report.
+ rep1 := reporter.Parse(data[rep.StartPos:])
+ if rep1 == nil || rep1.Title != rep.Title || rep1.StartPos != 0 {
+ title, startPos := "", -1
+ if rep1 != nil {
+ title, startPos = rep1.Title, rep1.StartPos
+ }
+ panic(fmt.Sprintf("%v: did not find the same reports at StartPos\n"+
+ "StartPos=%v/%v\nTitle0=%q\nTitle1=%q",
+ typ, rep.StartPos, startPos, rep.Title, title))
}
}
return res
}
-var fuzzReporters = func() []Reporter {
- var reporters []Reporter
+var fuzzReporters = func() map[string]Reporter {
+ reporters := make(map[string]Reporter)
for os := range ctors {
if os == "windows" {
continue
@@ -59,7 +82,7 @@ var fuzzReporters = func() []Reporter {
if _, ok := reporter.(*stub); ok {
continue
}
- reporters = append(reporters, reporter)
+ reporters[os] = reporter
}
return reporters
}()
diff --git a/pkg/report/report.go b/pkg/report/report.go
index 673407f92..e6d13b930 100644
--- a/pkg/report/report.go
+++ b/pkg/report/report.go
@@ -42,6 +42,8 @@ type Report struct {
// StartPos/EndPos denote region of output with oops message(s).
StartPos int
EndPos int
+ // SkipPos is position in output where parsing for the next report should start.
+ SkipPos int
// Suppressed indicates whether the report should not be reported to user.
Suppressed bool
// Corrupted indicates whether the report is truncated of corrupted in some other way.
@@ -184,6 +186,15 @@ func (wrap *reporterWrapper) Parse(output []byte) *Report {
if pos := bytes.Index(rep.Report, []byte(VMDiagnosisStart)); pos != -1 {
rep.Report = rep.Report[:pos]
}
+ rep.SkipPos = len(output)
+ if pos := bytes.IndexByte(output[rep.StartPos:], '\n'); pos != -1 {
+ rep.SkipPos = rep.StartPos + pos
+ }
+ if rep.EndPos < rep.SkipPos {
+ // This generally should not happen.
+ // But openbsd does some hacks with /r/n which may lead to off-by-one EndPos.
+ rep.EndPos = rep.SkipPos
+ }
return rep
}
diff --git a/pkg/report/report_test.go b/pkg/report/report_test.go
index aebcb45f8..39cd0deb6 100644
--- a/pkg/report/report_test.go
+++ b/pkg/report/report_test.go
@@ -186,22 +186,10 @@ func testParseImpl(t *testing.T, reporter Reporter, test *ParseTest) {
if rep == nil {
return
}
- checkReport(t, rep, test)
- if rep.StartPos != 0 {
- // If we parse from StartPos, we must find the same report.
- rep1 := reporter.Parse(test.Log[rep.StartPos:])
- if rep1 == nil || rep1.Title != rep.Title {
- t.Fatalf("did not find the same report from rep.StartPos=%v", rep.StartPos)
- }
- // If we parse from EndPos, we must not find the same report.
- rep2 := reporter.Parse(test.Log[rep.EndPos:])
- if rep2 != nil && rep2.Title == rep.Title {
- t.Fatalf("found the same report after rep.EndPos=%v", rep.EndPos)
- }
- }
+ checkReport(t, reporter, rep, test)
}
-func checkReport(t *testing.T, rep *Report, test *ParseTest) {
+func checkReport(t *testing.T, reporter Reporter, rep *Report, test *ParseTest) {
if test.HasReport && !bytes.Equal(rep.Report, test.Report) {
t.Fatalf("extracted wrong report:\n%s\nwant:\n%s", rep.Report, test.Report)
}
@@ -214,6 +202,9 @@ func checkReport(t *testing.T, rep *Report, test *ParseTest) {
if rep.EndPos > len(rep.Output) {
t.Fatalf("EndPos=%v > len(Output)=%v", rep.EndPos, len(rep.Output))
}
+ if rep.SkipPos <= rep.StartPos || rep.SkipPos > rep.EndPos {
+ t.Fatalf("bad SkipPos=%v: StartPos=%v EndPos=%v", rep.SkipPos, rep.StartPos, rep.EndPos)
+ }
if test.StartLine != "" {
if test.EndLine == "" {
test.EndLine = test.StartLine
@@ -226,6 +217,18 @@ func checkReport(t *testing.T, rep *Report, test *ParseTest) {
string(test.Log[rep.StartPos:rep.EndPos]))
}
}
+ if rep.StartPos != 0 {
+ // If we parse from StartPos, we must find the same report.
+ rep1 := reporter.Parse(test.Log[rep.StartPos:])
+ if rep1 == nil || rep1.Title != rep.Title || rep1.StartPos != 0 {
+ t.Fatalf("did not find the same report from rep.StartPos=%v", rep.StartPos)
+ }
+ // If we parse from EndPos, we must not find the same report.
+ rep2 := reporter.Parse(test.Log[rep.EndPos:])
+ if rep2 != nil && rep2.Title == rep.Title {
+ t.Fatalf("found the same report after rep.EndPos=%v", rep.EndPos)
+ }
+ }
}
func updateReportTest(t *testing.T, test *ParseTest, title string, corrupted, suppressed bool,