diff --git a/Earthfile b/Earthfile index be5d54fe..dc161330 100644 --- a/Earthfile +++ b/Earthfile @@ -215,10 +215,17 @@ mocks: SAVE ARTIFACT $mockfile AS LOCAL $mockfile END +unit-test-parser: + FROM +deps + COPY scripts/unit-test-parser/main.go . + RUN go build -o testparser main.go + SAVE ARTIFACT testparser + # unit-test runs unit tests (and some integration tests). unit-test: FROM +code RUN apk add --no-cache --update podman fuse-overlayfs + COPY +unit-test-parser/testparser . COPY not-a-unit-test.sh . ARG testname # when specified, only run specific unit-test, otherwise run all. diff --git a/not-a-unit-test.sh b/not-a-unit-test.sh index 22948dec..c3a4a1f7 100755 --- a/not-a-unit-test.sh +++ b/not-a-unit-test.sh @@ -75,4 +75,4 @@ if [ -n "$testname" ] then testarg="-run $testname" fi -go test -timeout 20m $testarg $pkgname +go test -timeout 20m -json $testarg $pkgname | ./testparser diff --git a/scripts/unit-test-parser/main.go b/scripts/unit-test-parser/main.go new file mode 100644 index 00000000..526fe3b1 --- /dev/null +++ b/scripts/unit-test-parser/main.go @@ -0,0 +1,71 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "log" + "os" + "sort" + "text/tabwriter" + "time" +) + +type TestEvent struct { + Time time.Time // encodes as an RFC3339-format string + Action string + Package string + Test string + Elapsed float64 // seconds + Output string +} + +func main() { + eventsWithElapsedTimes := []TestEvent{} + scanner := bufio.NewScanner(os.Stdin) + passed := true + for scanner.Scan() { + var event TestEvent + l := scanner.Text() + if err := json.Unmarshal([]byte(l), &event); err != nil { + log.Println(err) + os.Exit(1) + } + fmt.Printf("%s", event.Output) + if event.Elapsed > 0 { + eventsWithElapsedTimes = append(eventsWithElapsedTimes, event) + } + if event.Action == "fail" { + passed = false + } + } + + if err := scanner.Err(); err != nil { + log.Println(err) + os.Exit(1) + } + + sort.Slice(eventsWithElapsedTimes, func(i, j int) bool { + return eventsWithElapsedTimes[i].Elapsed < eventsWithElapsedTimes[j].Elapsed + }) + + fmt.Printf("\n--- Test Duration Summary ---\n") + + var buf bytes.Buffer + w := tabwriter.NewWriter(&buf, 0, 0, 2, ' ', 0) + fmt.Fprintf(w, "Package\tTest\tAction\tElapsed (seconds)\n") + for _, event := range eventsWithElapsedTimes { + if event.Test != "" { + fmt.Fprintf(w, "%s\t%s\t%s\t%v\n", event.Package, event.Test, event.Action, event.Elapsed) + } + } + w.Flush() + fmt.Printf("%s", buf.String()) + + if !passed { + fmt.Printf("test(s) failed\n") + os.Exit(1) + } + fmt.Printf("test(s) passed\n") +}