run-cts: add "log" arg to log test results to file
Bug: dawn:1123
Change-Id: Id9ad62dde8f7988cb66e39ca0d543c23d0fad341
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/65781
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/dawn_node/tools/src/cmd/run-cts/main.go b/src/dawn_node/tools/src/cmd/run-cts/main.go
index 872f5cf..d0dd681 100644
--- a/src/dawn_node/tools/src/cmd/run-cts/main.go
+++ b/src/dawn_node/tools/src/cmd/run-cts/main.go
@@ -67,7 +67,7 @@
}
}
- var dawnNode, cts, node, npx string
+ var dawnNode, cts, node, npx, logFilename string
var verbose, build bool
var numRunners int
flag.StringVar(&dawnNode, "dawn-node", "", "path to dawn.node module")
@@ -78,6 +78,7 @@
flag.BoolVar(&build, "build", true, "attempt to build the CTS before running")
flag.BoolVar(&colors, "colors", colors, "enable / disable colors")
flag.IntVar(&numRunners, "j", runtime.NumCPU(), "number of concurrent runners")
+ flag.StringVar(&logFilename, "log", "", "path to log file of tests run and result")
flag.Parse()
if colors {
@@ -140,6 +141,15 @@
require('./src/common/runtime/cmdline.ts');`,
}
+ if logFilename != "" {
+ writer, err := os.Create(logFilename)
+ if err != nil {
+ return fmt.Errorf("failed to open log '%v': %w", logFilename, err)
+ }
+ defer writer.Close()
+ r.log = newLogger(writer)
+ }
+
if build {
// Attempt to build the CTS (instead of using the `setup-ts-in-node` transpiler)
if npx != "" {
@@ -163,12 +173,41 @@
return r.run()
}
+type logger struct {
+ writer io.Writer
+ idx int
+ resultByIndex map[int]result
+}
+
+// newLogger creates a new logger instance.
+func newLogger(writer io.Writer) logger {
+ return logger{writer, 0, map[int]result{}}
+}
+
+// logResult writes the test results to the log file in sequential order.
+// logResult should be called whenever a new test result becomes available.
+func (l *logger) logResults(res result) {
+ if l.writer == nil {
+ return
+ }
+ l.resultByIndex[res.index] = res
+ for {
+ logRes, ok := l.resultByIndex[l.idx]
+ if !ok {
+ break
+ }
+ fmt.Fprintf(l.writer, "%v [%v]\n", logRes.testcase, logRes.status)
+ l.idx++
+ }
+}
+
type runner struct {
numRunners int
verbose bool
node, npx, dawnNode, cts string
evalScript string
testcases []string
+ log logger
}
// buildCTS calls `npx grunt run:build-out-node` in the CTS directory to compile
@@ -265,9 +304,12 @@
// we're not printing endless progress bars.
progressUpdateRate = time.Second
}
+
for res := range results {
- name := res.testcase
+ r.log.logResults(res)
+
numByStatus[res.status] = numByStatus[res.status] + 1
+ name := res.testcase
if r.verbose || (res.status != pass && res.status != skip) {
fmt.Printf("%v - %v: %v\n", name, res.status, res.message)
updateProgress()
@@ -308,6 +350,7 @@
// result holds the information about a completed test
type result struct {
+ index int
testcase string
status status
message string
@@ -341,15 +384,15 @@
msg := string(out)
switch {
case errors.Is(err, context.DeadlineExceeded):
- return result{testcase: testcase, status: timeout, message: msg}
+ return result{index: idx, testcase: testcase, status: timeout, message: msg}
case strings.Contains(msg, "[fail]"):
- return result{testcase: testcase, status: fail, message: msg}
+ return result{index: idx, testcase: testcase, status: fail, message: msg}
case strings.Contains(msg, "[skip]"):
- return result{testcase: testcase, status: skip, message: msg}
+ return result{index: idx, testcase: testcase, status: skip, message: msg}
case strings.Contains(msg, "[pass]"), err == nil:
- return result{testcase: testcase, status: pass, message: msg}
+ return result{index: idx, testcase: testcase, status: pass, message: msg}
}
- return result{testcase: testcase, status: fail, message: fmt.Sprint(msg, err), error: err}
+ return result{index: idx, testcase: testcase, status: fail, message: fmt.Sprint(msg, err), error: err}
}
// filterTestcases returns in with empty strings removed