From c014c913a5dd9288284ddae0ce6675f6708b9e4f Mon Sep 17 00:00:00 2001 From: Matthew Nibecker Date: Thu, 20 Jun 2024 12:05:34 -0700 Subject: [PATCH] Test Go Library Examples (#5095) Add markdown test to run go vet on go library examples. Fix existing go library examples. Closes #4703 --- docs/libraries/go.md | 18 ++++++++++-------- mdtest/mdtest.go | 5 +++++ mdtest/test.go | 36 ++++++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/docs/libraries/go.md b/docs/libraries/go.md index 3b9dbf55e9..f820074c34 100644 --- a/docs/libraries/go.md +++ b/docs/libraries/go.md @@ -39,7 +39,7 @@ go get github.com/brimdata/zed ### ZSON Reader Read ZSON from stdin, dereference field `s`, and print results: -``` +```mdtest-go-example package main import ( @@ -54,7 +54,8 @@ import ( func main() { zctx := zed.NewContext() - reader := zsonio.NewReader(os.Stdin, zctx) + reader := zsonio.NewReader(zctx, os.Stdin) + arena := zed.NewArena() for { val, err := reader.Read() if err != nil { @@ -63,9 +64,9 @@ func main() { if val == nil { return } - s := val.Deref("s") + s := val.Deref(arena, "s") if s == nil { - s = zctx.Missing() + s = zctx.Missing(arena).Ptr() } fmt.Println(zson.String(s)) } @@ -105,7 +106,7 @@ zed create -lake scratch Demo echo '{s:"hello, world"}{x:1}{s:"good bye"}' | zed load -lake scratch -use Demo - ``` Now replace `main.go` with this code: -``` +```mdtest-go-example package main import ( @@ -129,7 +130,7 @@ func main() { log.Fatalln(err) } ctx := context.TODO() - lake, err := api.OpenLake(ctx, uri.String()) + lake, err := api.OpenLake(ctx, nil, uri.String()) if err != nil { log.Fatalln(err) } @@ -139,6 +140,7 @@ func main() { } defer reader.Close() zctx := zed.NewContext() + arena := zed.NewArena() for { val, err := reader.Read() if err != nil { @@ -147,9 +149,9 @@ func main() { if val == nil { return } - s := val.Deref("s") + s := val.Deref(arena, "s") if s == nil { - s = zctx.Missing() + s = zctx.Missing(arena).Ptr() } fmt.Println(zson.String(s)) } diff --git a/mdtest/mdtest.go b/mdtest/mdtest.go index a6a9679138..c8dc842ceb 100644 --- a/mdtest/mdtest.go +++ b/mdtest/mdtest.go @@ -192,6 +192,11 @@ func parseMarkdown(source []byte) (map[string]string, []*Test, error) { Line: fcbLineNumber(commandFCB, source), }) commandFCB = nil + case "mdtest-go-example": + tests = append(tests, &Test{ + GoExample: fcbLines(fcb, source), + Line: fcbLineNumber(fcb, source), + }) } return ast.WalkContinue, nil }) diff --git a/mdtest/test.go b/mdtest/test.go index 07eb489b90..35e58b9ac6 100644 --- a/mdtest/test.go +++ b/mdtest/test.go @@ -3,7 +3,9 @@ package mdtest import ( "errors" "fmt" + "os" "os/exec" + "path/filepath" "strings" "github.com/pmezard/go-difflib/difflib" @@ -11,16 +13,20 @@ import ( // Test represents a single test in a Markdown file. type Test struct { - Command string - Dir string - Expected string - Fails bool - Head bool - Line int + Command string + Dir string + Expected string + Fails bool + Head bool + Line int + GoExample string } // Run runs the test, returning nil on success. func (t *Test) Run() error { + if t.GoExample != "" { + return t.vetGoExample() + } c := exec.Command("bash", "-e", "-o", "pipefail") c.Dir = t.Dir c.Stdin = strings.NewReader(t.Command) @@ -57,3 +63,21 @@ func (t *Test) Run() error { } return nil } + +func (t *Test) vetGoExample() error { + dir, err := os.MkdirTemp("", "") + if err != nil { + return err + } + defer os.RemoveAll(dir) + path := filepath.Join(dir, "main.go") + if err := os.WriteFile(path, []byte(t.GoExample), 0666); err != nil { + return err + } + _, err = exec.Command("go", "vet", path).Output() + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + return fmt.Errorf("could not vet go example: %s", string(exitErr.Stderr)) + } + return err +}