diff --git a/code/rewrite.go b/code/rewrite.go index fcf53cf..e5d2e66 100644 --- a/code/rewrite.go +++ b/code/rewrite.go @@ -112,7 +112,15 @@ func ToComments(wdst io.Writer, rsrc io.Reader) ([]*Failpoint, error) { ws = strings.Split(l, "i")[0] n := strings.Split(strings.Split(l, "__fp_")[1], ".")[0] - t := strings.Split(strings.Split(l, ".(")[1], ")")[0] + // The generated header is written as a single line, but gofmt splits + // it across several, which leaves the type assertion on a later line + // than the one matched above. + typeParts := strings.SplitN(l, ".(", 2) + if len(typeParts) < 2 { + return fps, fmt.Errorf("gofail: failpoint %q header is missing its type assertion, "+ + "the generated code may have been reformatted: %q", n, strings.TrimRight(l, "\n")) + } + t := strings.Split(typeParts[1], ")")[0] dst.WriteString(ws + pfx + " var " + n + " " + t + "\n") if !strings.Contains(l, "; goto __nomock") { // not single liner diff --git a/code/rewrite_test.go b/code/rewrite_test.go index 07dc685..37eefc5 100644 --- a/code/rewrite_test.go +++ b/code/rewrite_test.go @@ -124,3 +124,34 @@ func TestToComment(t *testing.T) { require.Equalf(t, len(fps), ex.wfps, "%d: got %d failpoints but expected %d", i, len(fps), ex.wfps) } } + +// gofmt splits the single-line header the generator writes across several +// lines, which leaves the type assertion on a later line than the "if". The +// header match still fires on the "if" line, so the type lookup has to cope +// with not finding one. +func TestToCommentReformattedHeader(t *testing.T) { + reformatted := `package mypkg + +import "fmt" + +func Serve() { + if vSlowDown, __fpErr := __fp_SlowDown.Acquire(); __fpErr == nil { + _, __fpTypeOK := vSlowDown.(struct{}) + if !__fpTypeOK { + goto __badTypeSlowDown + } + goto __nomockSlowDown + __badTypeSlowDown: + __fp_SlowDown.BadType(vSlowDown, "struct{}") + __nomockSlowDown: + } + fmt.Println("serving") +} +` + + dst := bytes.NewBuffer(make([]byte, 0, 1024)) + _, err := ToComments(dst, strings.NewReader(reformatted)) + + require.Error(t, err, "expected an error rather than a panic") + require.Contains(t, err.Error(), "missing its type assertion") +}