tools: More CTS tooling improvements

• Add the included trybots in the CL description. All of these trybots are tested by the roll, but the final CQ-submit wouldn't necessarily test all of the variants before landing. This would mean that the 'cts export' could miss some results, as it takes the last PS with any results.
• Add --force flag to cts roll to force a roll. Useful for testing.
• Emit timing diagnostics for tests labelled 'Slow' instead of unhelpfully stating they pass.
• Enable the --cl and --ps flags for cts export
• Export with the most recent data to the top of the spreadsheet

Bug: dawn:1401
Change-Id: Id926367ab805bfb9f3032fce9cce7f00daf7a5d4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/88661
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/tools/src/cmd/cts/roll/roll_test.go b/tools/src/cmd/cts/roll/roll_test.go
new file mode 100644
index 0000000..b7ba054
--- /dev/null
+++ b/tools/src/cmd/cts/roll/roll_test.go
@@ -0,0 +1,75 @@
+// Copyright 2022 The Dawn Authors
+//
+// 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.
+
+package roll
+
+import (
+	"testing"
+
+	"dawn.googlesource.com/dawn/tools/src/buildbucket"
+	"dawn.googlesource.com/dawn/tools/src/cmd/cts/common"
+	"dawn.googlesource.com/dawn/tools/src/git"
+	"github.com/google/go-cmp/cmp"
+)
+
+func MustParseHash(s string) git.Hash {
+	hash, err := git.ParseHash("d5e605a556408eaeeda64fb9d33c3f596fd90b70")
+	if err != nil {
+		panic(err)
+	}
+	return hash
+}
+
+func TestRollCommitMessage(t *testing.T) {
+	r := roller{
+		cfg: common.Config{
+			Builders: map[string]buildbucket.Builder{
+				"Win":   {Project: "chromium", Bucket: "try", Builder: "win-dawn-rel"},
+				"Mac":   {Project: "dawn", Bucket: "try", Builder: "mac-dbg"},
+				"Linux": {Project: "chromium", Bucket: "try", Builder: "linux-dawn-rel"},
+			},
+		},
+	}
+	msg := r.rollCommitMessage(
+		"d5e605a556408eaeeda64fb9d33c3f596fd90b70",
+		"29275672eefe76986bd4baa7c29ed17b66616b1b",
+		[]git.CommitInfo{
+			{
+				Hash:    MustParseHash("d5e605a556408eaeeda64fb9d33c3f596fd90b70"),
+				Subject: "Added thing A",
+			},
+			{
+				Hash:    MustParseHash("29275672eefe76986bd4baa7c29ed17b66616b1b"),
+				Subject: "Tweaked thing B",
+			},
+		},
+		"I4aa059c6c183e622975b74dbdfdfe0b12341ae15",
+	)
+	expect := `Roll third_party/webgpu-cts/ d5e605a55..29275672e (2 commits)
+
+Update expectations and ts_sources
+
+https://chromium.googlesource.com/external/github.com/gpuweb/cts/+log/d5e605a55640..29275672eefe
+ - d5e605 Added thing A
+ - d5e605 Tweaked thing B
+
+Created with './tools/run cts roll'
+
+Cq-Include-Trybots: luci.chromium.try:linux-dawn-rel,win-dawn-rel;luci.dawn.try:mac-dbg
+Change-Id: I4aa059c6c183e622975b74dbdfdfe0b12341ae15
+`
+	if diff := cmp.Diff(msg, expect); diff != "" {
+		t.Errorf("rollCommitMessage: %v", diff)
+	}
+}