Regres: add cmd/run_testlist
This uses regres' test runner, without all the Gerrit functionality.
A faster, less frustrating version of dEQP's --deqp-caselist-file.
Kudos to paulthomson@ who did all the work here.
Change-Id: I1de26e731b197af64aeb60c79da0b75fe13cb338
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/40529
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/tests/regres/cmd/run_testlist/main.go b/tests/regres/cmd/run_testlist/main.go
new file mode 100644
index 0000000..f489adb
--- /dev/null
+++ b/tests/regres/cmd/run_testlist/main.go
@@ -0,0 +1,108 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// run_testlist is a tool runs a dEQP test list, using multiple sand-boxed
+// processes.
+//
+// Unlike simply running deqp with its --deqp-caselist-file flag, run_testlist
+// uses multiple sand-boxed processes, which greatly reduces testing time, and
+// gracefully handles crashing processes.
+package main
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "runtime"
+ "sort"
+ "strings"
+ "time"
+
+ "../../cause"
+ "../../deqp"
+ "../../shell"
+ "../../testlist"
+)
+
+var (
+ deqpVkBinary = flag.String("deqp-vk", "deqp-vk", "path to the deqp-vk binary")
+ testList = flag.String("test-list", "vk-master-PASS.txt", "path to a test list file")
+ numThreads = flag.Int("num-threads", runtime.NumCPU(), "number of parallel test runner processes")
+ maxProcMemory = flag.Uint64("max-proc-mem", shell.MaxProcMemory, "maximum virtual memory per child process")
+ output = flag.String("output", "results.json", "path to an output JSON results file")
+)
+
+const testTimeout = time.Minute * 2
+
+func runTests() error {
+ tests, err := ioutil.ReadFile(*testList)
+ if err != nil {
+ return cause.Wrap(err, "Couldn't read '%s'", *testList)
+ }
+ group := testlist.Group{
+ Name: "",
+ File: "",
+ API: testlist.Vulkan,
+ }
+ for _, line := range strings.Split(string(tests), "\n") {
+ line = strings.TrimSpace(line)
+ if line != "" && !strings.HasPrefix(line, "#") {
+ group.Tests = append(group.Tests, line)
+ }
+ }
+ sort.Strings(group.Tests)
+
+ testLists := testlist.Lists{group}
+
+ shell.MaxProcMemory = *maxProcMemory
+
+ config := deqp.Config{
+ ExeEgl: "",
+ ExeGles2: "",
+ ExeGles3: "",
+ ExeVulkan: *deqpVkBinary,
+ Env: os.Environ(),
+ NumParallelTests: *numThreads,
+ TestLists: testLists,
+ TestTimeout: testTimeout,
+ }
+
+ res, err := config.Run()
+ if err != nil {
+ return err
+ }
+
+ err = res.Save(*output)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func main() {
+ if runtime.GOOS != "linux" {
+ log.Fatal("regres only currently runs on linux")
+ }
+
+ flag.ErrHelp = errors.New("regres is a tool to detect regressions between versions of SwiftShader")
+ flag.Parse()
+ if err := runTests(); err != nil {
+ _, _ = fmt.Fprintln(os.Stderr, err)
+ os.Exit(-1)
+ }
+}