[tools][cts] Remove old CTS roller codepath

Removes the old CTS roller codepath and all related code that is now
unused. There may be a bit of dead code remaining, but this should
remove the vast majority of it.

Bug: 372730248
Change-Id: I1f87e8139b9104f90680ef7f043e4819bf037f12
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/219374
Commit-Queue: Brian Sheedy <bsheedy@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Auto-Submit: Brian Sheedy <bsheedy@google.com>
diff --git a/tools/src/cmd/cts/roll/roll.go b/tools/src/cmd/cts/roll/roll.go
index 8e4e66f..16e1b1a 100644
--- a/tools/src/cmd/cts/roll/roll.go
+++ b/tools/src/cmd/cts/roll/roll.go
@@ -121,6 +121,8 @@
 	flag.BoolVar(&c.flags.preserve, "preserve", false, "do not abandon existing rolls")
 	flag.BoolVar(&c.flags.sendToGardener, "send-to-gardener", false, "send the CL to the WebGPU gardener for review")
 	flag.BoolVar(&c.flags.verbose, "verbose", false, "emit additional logging")
+	// Deprecated.
+	// TODO(crbug.com/372730248): Remove this flag once the roller stops passing it in.
 	flag.BoolVar(&c.flags.useSimplifiedCodepath, "use-simplified-codepath", false, "use the simplified codepath that only looks at unexpected failures")
 	flag.StringVar(&c.flags.parentSwarmingRunID, "parent-swarming-run-id", "", "parent swarming run id. All triggered tasks will be children of this task and will be canceled if the parent is canceled.")
 	flag.IntVar(&c.flags.maxAttempts, "max-attempts", 3, "number of update attempts before giving up")
@@ -414,11 +416,7 @@
 
 		// Gather the build results
 		log.Println("gathering results...")
-		if r.flags.useSimplifiedCodepath {
-			psResultsByExecutionMode, err = common.CacheUnsuppressedFailingResults(ctx, r.cfg, ps, r.flags.cacheDir, r.client, builds)
-		} else {
-			psResultsByExecutionMode, err = common.CacheResults(ctx, r.cfg, ps, r.flags.cacheDir, r.client, builds)
-		}
+		psResultsByExecutionMode, err = common.CacheUnsuppressedFailingResults(ctx, r.cfg, ps, r.flags.cacheDir, r.client, builds)
 		if err != nil {
 			return err
 		}
@@ -431,26 +429,14 @@
 		// Rebuild the expectations with the accumulated results
 		log.Println("building new expectations...")
 		for _, exInfo := range exInfos {
-			if r.flags.useSimplifiedCodepath {
-				// TODO(crbug.com/372730248): Modify exInfo.expectations in place once
-				// the old code path is removed.
-				exInfo.newExpectations = exInfo.expectations.Clone()
-				err := exInfo.newExpectations.AddExpectationsForFailingResults(psResultsByExecutionMode[exInfo.executionMode], testlist, r.flags.verbose)
-				if err != nil {
-					return err
-				}
-				exInfo.expectations = exInfo.newExpectations
-			} else {
-				// Merge the new results into the accumulated results
-				log.Printf("merging results for %s ...\n", exInfo.executionMode)
-				exInfo.results = result.Merge(exInfo.results, psResultsByExecutionMode[exInfo.executionMode])
-
-				exInfo.newExpectations = exInfo.expectations.Clone()
-				_, err := exInfo.newExpectations.Update(exInfo.results, testlist, r.flags.verbose)
-				if err != nil {
-					return err
-				}
+			// TODO(crbug.com/372730248): Modify exInfo.expectations in place once
+			// the old code path is removed.
+			exInfo.newExpectations = exInfo.expectations.Clone()
+			err := exInfo.newExpectations.AddExpectationsForFailingResults(psResultsByExecutionMode[exInfo.executionMode], testlist, r.flags.verbose)
+			if err != nil {
+				return err
 			}
+			exInfo.expectations = exInfo.newExpectations
 		}
 
 		// Otherwise, push the updated expectations, and try again
diff --git a/tools/src/cmd/cts/update/expectations/expectations.go b/tools/src/cmd/cts/update/expectations/expectations.go
index 8d49094..b32a059 100644
--- a/tools/src/cmd/cts/update/expectations/expectations.go
+++ b/tools/src/cmd/cts/update/expectations/expectations.go
@@ -80,6 +80,8 @@
 	c.flags.results.RegisterFlags(cfg)
 	c.flags.auth.Register(flag.CommandLine, auth.DefaultAuthOptions())
 	flag.BoolVar(&c.flags.verbose, "verbose", false, "emit additional logging")
+	// Deprecated.
+	// TODO(crbug.com/372730248): Remove this flag once the roller stops passing it in.
 	flag.BoolVar(&c.flags.useSimplifiedCodepath, "use-simplified-codepath", false, "use the simplified codepath that only looks at unexpected failures")
 	flag.Var(&c.flags.expectations, "expectations", "path to CTS expectations file(s) to update")
 	return nil, nil
@@ -111,12 +113,7 @@
 
 	// Fetch the results
 	log.Println("fetching results...")
-	var resultsByExecutionMode result.ResultsByExecutionMode
-	if c.flags.useSimplifiedCodepath {
-		resultsByExecutionMode, err = c.flags.results.GetUnsuppressedFailingResults(ctx, cfg, auth)
-	} else {
-		resultsByExecutionMode, err = c.flags.results.GetResults(ctx, cfg, auth)
-	}
+	resultsByExecutionMode, err := c.flags.results.GetUnsuppressedFailingResults(ctx, cfg, auth)
 	if err != nil {
 		return err
 	}
@@ -154,14 +151,9 @@
 			name = "compat"
 		}
 
-		var diag expectations.Diagnostics
-		if c.flags.useSimplifiedCodepath {
-			err = ex.AddExpectationsForFailingResults(resultsByExecutionMode[name], testlist, c.flags.verbose)
-			// TODO(crbug.com/372730248): Report actual diagnostics.
-			diag = expectations.Diagnostics{}
-		} else {
-			diag, err = ex.Update(resultsByExecutionMode[name], testlist, c.flags.verbose)
-		}
+		err = ex.AddExpectationsForFailingResults(resultsByExecutionMode[name], testlist, c.flags.verbose)
+		// TODO(crbug.com/372730248): Report actual diagnostics.
+		diag := expectations.Diagnostics{}
 		if err != nil {
 			return err
 		}
diff --git a/tools/src/cts/expectations/update.go b/tools/src/cts/expectations/update.go
index fba9912..5a107d7 100644
--- a/tools/src/cts/expectations/update.go
+++ b/tools/src/cts/expectations/update.go
@@ -28,18 +28,18 @@
 package expectations
 
 import (
-	"errors"
 	"fmt"
-	"log"
-	"os"
 	"strings"
 	"time"
 
 	"dawn.googlesource.com/dawn/tools/src/container"
 	"dawn.googlesource.com/dawn/tools/src/cts/query"
 	"dawn.googlesource.com/dawn/tools/src/cts/result"
-	"dawn.googlesource.com/dawn/tools/src/progressbar"
-	"github.com/mattn/go-isatty"
+)
+
+const (
+	// Chunk comment for the AddExpectationsForFailingResults path.
+	ROLLER_AUTOGENERATED_FAILURES = "# ##ROLLER_AUTOGENERATED_FAILURES##"
 )
 
 // AddExpectationsForFailingResults adds new expectations for the provided
@@ -246,777 +246,3 @@
 	chunkToModify.Expectations.SortPrioritizeQuery()
 	return nil
 }
-
-// Update performs an incremental update on the expectations using the provided
-// results.
-//
-// Update will:
-//   - Remove any expectation lines that have a query where no results match.
-//   - Remove expectations lines that are in a chunk which is not annotated with
-//     'KEEP', and all test results have the status 'Pass'.
-//   - Remove chunks that have had all expectation lines removed.
-//   - Appends new chunks for flaky and failing tests which are not covered by
-//     existing expectation lines.
-//
-// Update returns a list of diagnostics for things that should be addressed.
-//
-// Note: Validate() should be called before attempting to update the
-// expectations. If Validate() returns errors, then Update() behaviour is
-// undefined.
-// TODO(crbug.com/371501714): Remove the Diagnostics return value since it is
-// no longer used with the removal of commenting on CLs.
-func (c *Content) Update(results result.List, testlist []query.Query, verbose bool) (Diagnostics, error) {
-	// Make a copy of the results. This code mutates the list.
-	results = append(result.List{}, results...)
-
-	// Replace statuses that the CTS runner doesn't recognize with 'Failure'
-	simplifyStatuses(results)
-
-	// Produce a list of tag sets.
-	// We reverse the declared order, as webgpu-cts/expectations.txt lists the
-	// most important first (OS, GPU, etc), and result.MinimalVariantTags will
-	// prioritize folding away the earlier tag-sets.
-	tagSets := make([]result.Tags, len(c.Tags.Sets))
-	for i, s := range c.Tags.Sets {
-		tagSets[len(tagSets)-i-1] = s.Tags
-	}
-
-	// Scan the full result list to obtain all the test variants
-	// (unique tag combinations).
-	variants := results.Variants()
-
-	if verbose {
-		fmt.Println("result variants:")
-		for i, tags := range variants {
-			fmt.Printf(" (%.2d) %v\n", i, tags.List())
-		}
-	}
-
-	// Add 'consumed' results for tests that were skipped.
-	// This ensures that skipped results are not included in reduced trees.
-	results = c.appendConsumedResultsForSkippedTests(results, testlist, variants)
-
-	var pb *progressbar.ProgressBar
-	if isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd()) {
-		pb = progressbar.New(os.Stdout, nil)
-		defer pb.Stop()
-	}
-
-	testQueryTree, _ := query.NewTree[struct{}]()
-	for _, query := range testlist {
-		testQueryTree.Add(query, struct{}{})
-	}
-
-	u := updater{
-		in:              *c,
-		out:             Content{},
-		resultQueryTree: buildResultQueryTree(results),
-		testQueryTree:   testQueryTree,
-		variants:        variants,
-		tagSets:         tagSets,
-		pb:              pb,
-	}
-
-	if err := u.preserveRetryOnFailures(); err != nil {
-		return nil, err
-	}
-
-	// Update those expectations!
-	if err := u.build(); err != nil {
-		return nil, fmt.Errorf("while updating expectations: %w", err)
-	}
-
-	*c = u.out
-	return u.diags, nil
-}
-
-// updater holds the state used for updating the expectations
-type updater struct {
-	in              Content         // the original expectations Content
-	out             Content         // newly built expectations Content
-	resultQueryTree resultQueryTree // the results query tree
-	testQueryTree   query.Tree[struct{}]
-	variants        []container.Set[string]
-	diags           []Diagnostic             // diagnostics raised during update
-	tagSets         []result.Tags            // reverse-ordered tag-sets of 'in'
-	pb              *progressbar.ProgressBar // Progress bar, may be nil
-}
-
-// Returns 'results' with additional 'consumed' results for tests that have
-// 'Skip' expectations. This fills in gaps for results, preventing tree
-// reductions from marking skipped results as failure, which could result in
-// expectation collisions.
-func (c *Content) appendConsumedResultsForSkippedTests(results result.List,
-	testlist []query.Query,
-	variants []container.Set[string]) result.List {
-	tree := query.Tree[struct{}]{}
-	for _, q := range testlist {
-		tree.Add(q, struct{}{})
-	}
-	// For each variant...
-	for _, variant := range variants {
-		resultsForVariant := container.NewSet[string]()
-		for _, result := range results.FilterByVariant(variant) {
-			resultsForVariant.Add(result.Query.String())
-		}
-
-		// For each expectation...
-		for _, c := range c.Chunks {
-			for _, ex := range c.Expectations {
-				// Does this expectation apply for variant?
-				if !variant.ContainsAll(ex.Tags) {
-					continue // Nope.
-				}
-
-				// Does the expectation contain a Skip status?
-				if !container.NewSet(ex.Status...).Contains(string(result.Skip)) {
-					continue // Nope.
-				}
-
-				// Gather all the tests that apply to the expectation
-				glob, _ := tree.Glob(query.Parse(ex.Query))
-				for _, qd := range glob {
-					// If we don't have a result for the test, then append a
-					// synthetic 'consumed' result.
-					if query := qd.Query.String(); !resultsForVariant.Contains(query) {
-						resultsForVariant.Add(query)
-						results = append(results, result.Result{
-							Query:  qd.Query,
-							Tags:   variant,
-							Status: consumed,
-						})
-					}
-				}
-			}
-		}
-	}
-	return results
-}
-
-// simplifyStatuses replaces all result statuses that are not one of
-// 'Pass', 'RetryOnFailure', 'Slow', 'Skip' with 'Failure', and also replaces
-// 'Skip' results with 'Pass'.
-func simplifyStatuses(results result.List) {
-	for i, r := range results {
-		switch r.Status {
-		case result.Pass, result.RetryOnFailure, result.Slow:
-			// keep
-		case result.Skip:
-			// Typically represents a .unimplemented() test
-			results[i].Status = result.Pass
-		default:
-			results[i].Status = result.Failure
-		}
-	}
-}
-
-const (
-	// Status used to mark results that have been already handled by an
-	// expectation.
-	consumed result.Status = "<<consumed>>"
-	// Chunk comment for new flakes
-	newFlakesComment = "# New flakes. Please triage - will be discarded/regenerated by the next roll:"
-	// Chunk comment for new failures
-	newFailuresComment = "# New failures. Please triage - will be discarded/regenerated by the next roll:"
-	// Chunk comment for expectations the roller is allowed to mutate
-	ROLLER_MUTABLE = "# ##ROLLER_MUTABLE##"
-	// Chunk comment for expectations the roller should discard and rewrite
-	ROLLER_DISCARD_AND_REWRITE = "# ##ROLLER_DISCARD_AND_REWRITE##"
-	// Chunk comment for the AddExpectationsForFailingResults path.
-	ROLLER_AUTOGENERATED_FAILURES = "# ##ROLLER_AUTOGENERATED_FAILURES##"
-)
-
-// resultQueryTree holds tree of queries to all results (no filtering by tag or
-// status). The resultQueryTree is used to glob all the results that match a
-// particular query.
-type resultQueryTree struct {
-	// All the results.
-	results result.List
-	// consumedAt is a list of line numbers for the i'th result in 'results'
-	// Initially all line numbers are 0. When a result is consumed the line
-	// number is set.
-	consumedAt []int
-	// Each tree node holds a list of indices to results.
-	tree query.Tree[[]int]
-}
-
-// buildResultQueryTree builds the queryTree from the list of results.
-func buildResultQueryTree(results result.List) resultQueryTree {
-	log.Println("building query tree...")
-
-	// Build a map of query to result indices
-	queryToIndices := map[query.Query][]int{}
-	for i, r := range results {
-		l := queryToIndices[r.Query]
-		l = append(l, i)
-		queryToIndices[r.Query] = l
-	}
-
-	// Construct the query tree to result indices
-	tree := query.Tree[[]int]{}
-	for query, indices := range queryToIndices {
-		if err := tree.Add(query, indices); err != nil {
-			// Unreachable: The only error we could get is duplicate data for
-			// the same query, which should be impossible.
-			panic(err)
-		}
-	}
-
-	consumedAt := make([]int, len(results))
-	return resultQueryTree{results, consumedAt, tree}
-}
-
-// glob returns the list of results matching the given tags under (or with) the
-// given query.
-func (qt *resultQueryTree) glob(q query.Query) (result.List, error) {
-	glob, err := qt.tree.Glob(q)
-	if err != nil {
-		return nil, fmt.Errorf("while gathering results for query '%v': %w", q, err)
-	}
-
-	out := result.List{}
-	for _, indices := range glob {
-		for _, idx := range indices.Data {
-			out = append(out, qt.results[idx])
-		}
-	}
-
-	return out, nil
-}
-
-// globTags returns the list of results matching the given tags under (or with)
-// the given query.
-func (qt *resultQueryTree) globTags(q query.Query, t result.Tags) (result.List, error) {
-	glob, err := qt.tree.Glob(q)
-	if err != nil {
-		return nil, err
-	}
-
-	out := result.List{}
-	for _, indices := range glob {
-		for _, idx := range indices.Data {
-			if r := qt.results[idx]; r.Tags.ContainsAll(t) {
-				out = append(out, r)
-			}
-		}
-	}
-	return out, nil
-}
-
-// markAsConsumed marks all the results matching the given tags
-// under (or with) the given query, as consumed.
-// line is used to record the line at which the results were consumed. If the
-// results were consumed as part of generating new expectations then line should
-// be 0.
-func (qt *resultQueryTree) markAsConsumed(q query.Query, t result.Tags, line int) {
-	if glob, err := qt.tree.Glob(q); err == nil {
-		for _, indices := range glob {
-			for _, idx := range indices.Data {
-				r := &qt.results[idx]
-				if r.Tags.ContainsAll(t) {
-					r.Status = consumed
-					qt.consumedAt[idx] = line
-				}
-			}
-		}
-	}
-}
-
-// preserveRetryOnFailures changes any results matching expectations with a
-// RetryOnFailure expectation to RetryOnFailure.
-func (u *updater) preserveRetryOnFailures() error {
-	// For each expectation...
-	for _, c := range u.in.Chunks {
-		for _, ex := range c.Expectations {
-			// Does the expectation contain a RetryOnFailure status?
-			if !container.NewSet(ex.Status...).Contains(string(result.RetryOnFailure)) {
-				continue // Nope.
-			}
-
-			q := query.Parse(ex.Query)
-
-			glob, err := u.resultQueryTree.tree.Glob(q)
-			if err != nil {
-				if errors.As(err, &query.ErrNoDataForQuery{}) {
-					// No results for this RetryOnFailure expectation.
-					// Flaky tests might have been removed from the CTS.
-					// These expectations will be automatically removed by updater.expectation()
-					continue
-				}
-				return err
-			}
-			for _, indices := range glob {
-				for _, idx := range indices.Data {
-					if u.resultQueryTree.results[idx].Tags.ContainsAll(ex.Tags) {
-						u.resultQueryTree.results[idx].Status = result.RetryOnFailure
-					}
-				}
-			}
-		}
-	}
-	return nil
-}
-
-type Progress struct {
-	totalExpectations  int
-	currentExpectation int
-}
-
-// build is the updater top-level function.
-// build first appends to u.out all chunks from 'u.in' with expectations updated
-// using the new results, and then appends any new expectations to u.out.
-func (u *updater) build() error {
-	progress := Progress{}
-
-	// Chunks are considered immutable by default, unless annotated as
-	// ROLLER_MUTABLE or ROLLER_DISCARD_AND_REWRITE.
-	mutableTokens := []string{
-		ROLLER_MUTABLE,
-		ROLLER_DISCARD_AND_REWRITE,
-	}
-
-	// Bin the chunks into those that contain any of the strings in
-	// mutableTokens in the comments and those that do not have these strings.
-	immutableChunks, mutableChunks := []Chunk{}, []Chunk{}
-	for _, chunk := range u.in.Chunks {
-		keep := true
-
-	comments:
-		for _, line := range chunk.Comments {
-			for _, token := range mutableTokens {
-				if strings.Contains(line, token) {
-					keep = false
-					break comments
-				}
-			}
-		}
-
-		if keep {
-			immutableChunks = append(immutableChunks, chunk)
-		} else {
-			mutableChunks = append(mutableChunks, chunk)
-		}
-
-		progress.totalExpectations += len(chunk.Expectations)
-	}
-
-	log.Println("updating expectation chunks...")
-
-	// Update all the existing chunks in two passes - those that are immutable
-	// then those that are mutable. We do this because the former can't be
-	// altered and may declare expectations that may collide with later
-	// expectations.
-	for _, group := range []struct {
-		chunks      []Chunk
-		isImmutable bool
-	}{
-		{immutableChunks, true},
-		{mutableChunks, false},
-	} {
-		for _, in := range group.chunks {
-			out := u.chunk(in, group.isImmutable, &progress)
-
-			// If all chunk had expectations, but now they've gone, remove the chunk
-			if len(in.Expectations) > 0 && len(out.Expectations) == 0 {
-				continue
-			}
-
-			u.out.Chunks = append(u.out.Chunks, out)
-		}
-	}
-
-	// Emit new expectations (flaky, failing)
-	if err := u.addNewExpectations(); err != nil {
-		return fmt.Errorf("failed to add new expectations: %w", err)
-	}
-
-	return nil
-}
-
-// chunk returns a new Chunk, based on 'in', with the expectations updated.
-// isImmutable is true if the chunk is labelled with 'KEEP' and can't be changed.
-func (u *updater) chunk(in Chunk, isImmutable bool, progress *Progress) Chunk {
-	if len(in.Expectations) == 0 {
-		return in // Just a comment / blank line
-	}
-
-	// Skip over ROLLER_DISCARD_AND_REWRITE chunks (untriaged failures/flakes).
-	// We'll just rebuild them at the end.
-	for _, line := range in.Comments {
-		if strings.HasPrefix(line, ROLLER_DISCARD_AND_REWRITE) {
-			return Chunk{}
-		}
-	}
-
-	// Build the new chunk's expectations
-	newExpectations := container.NewMap[string, Expectation]()
-	for _, exIn := range in.Expectations {
-		if u.pb != nil {
-			u.pb.Update(progressbar.Status{Total: progress.totalExpectations, Segments: []progressbar.Segment{
-				{Count: 1 + progress.currentExpectation},
-			}})
-			progress.currentExpectation++
-		}
-
-		u.addExpectations(newExpectations, exIn, isImmutable)
-	}
-
-	// Sort the expectations to keep things clean and tidy.
-	out := Chunk{Comments: in.Comments, Expectations: newExpectations.Values()}
-	out.Expectations.Sort()
-	return out
-}
-
-// expectation returns a new list of Expectations, based on the Expectation 'in',
-// using the new result data.
-func (u *updater) addExpectations(out container.Map[string, Expectation], in Expectation, isImmutable bool) {
-	q := query.Parse(in.Query)
-
-	// keyOf returns the map key for out
-	keyOf := func(e Expectation) string { return fmt.Sprint(e.Tags, e.Query, e.Status) }
-
-	// noResults is a helper for returning when the expectation has no test results.
-	noResults := func() {
-		if glob, err := u.testQueryTree.Glob(q); err == nil && len(glob) > 0 {
-			// At least one test is found with the query in the test list - likely a variant that is not being run.
-			if len(in.Tags) > 0 {
-				u.diag(Note, in.Line, "no results found for query '%v' with tags %v", in.Query, in.Tags)
-			} else {
-				u.diag(Note, in.Line, "no results found for query '%v'", in.Query)
-			}
-			// Preserve.
-			out.Add(keyOf(in), in)
-		} else {
-			// Remove the no-results expectation (do not add to out)
-			u.diag(Warning, in.Line, "no tests exist with query '%v' - removing", in.Query)
-		}
-	}
-
-	// Glob the results for the expectation's query + tag combination.
-	// Ensure that none of these are already consumed.
-	results, err := u.resultQueryTree.globTags(q, in.Tags)
-	// If we can't find any results for this query + tag combination, then bail.
-	switch {
-	case errors.As(err, &query.ErrNoDataForQuery{}):
-		noResults()
-		return
-	case err != nil:
-		u.diag(Error, in.Line, "%v", err)
-		return
-	case len(results) == 0:
-		noResults()
-		return
-	}
-
-	// Before returning, mark all the results as consumed.
-	// Note: this has to happen *after* we've generated the new expectations, as
-	// marking the results as 'consumed' will impact the logic of
-	// expectationsForRoot()
-	defer u.resultQueryTree.markAsConsumed(q, in.Tags, in.Line)
-
-	if isImmutable { // Expectation chunk was marked with 'KEEP'
-		// Add a diagnostic if all tests of the expectation were 'Pass'
-		if s := results.Statuses(); len(s) == 1 && s.One() == result.Pass {
-			u.diagAllPass(in.Line, results)
-		}
-		out.Add(keyOf(in), in)
-		return
-	}
-
-	// Rebuild the expectations for this query.
-	expectations, somePass, someConsumed := u.expectationsForRoot(q, in.Line, in.Bug, in.Comment)
-
-	// Add the new expectations to out
-	for _, expectation := range expectations {
-		out.Add(keyOf(expectation), expectation)
-	}
-
-	// Add a diagnostic if the expectation is filtered away
-	if !out.Contains(keyOf(in)) && len(expectations) == 0 {
-		switch {
-		case somePass && someConsumed:
-			u.diag(Note, in.Line, "expectation is partly covered by previous expectations and the remaining tests all pass")
-		case someConsumed:
-			u.diag(Note, in.Line, "expectation is fully covered by previous expectations")
-		case somePass:
-			u.diagAllPass(in.Line, results)
-		}
-	}
-
-}
-
-// addNewExpectations (potentially) appends to 'u.out' chunks for new flaky and
-// failing tests.
-func (u *updater) addNewExpectations() error {
-	// For each variant:
-	// • Build a query tree using the results filtered to the variant, and then
-	//   reduce the tree.
-	// • Take all the reduced-tree leaf nodes, and add these to 'roots'.
-	// Once we've collected all the roots, we'll use these to build the
-	// expectations across the reduced set of tags.
-	log.Println("determining new expectation roots...")
-	roots := query.Tree[bool]{}
-	for i, variant := range u.variants {
-		if u.pb != nil {
-			u.pb.Update(progressbar.Status{Total: len(u.variants), Segments: []progressbar.Segment{
-				{Count: 1 + i},
-			}})
-		}
-
-		// Build a tree from the results matching the given variant.
-		filtered := u.resultQueryTree.results.FilterByVariant(variant)
-		tree, err := filtered.StatusTree()
-		if err != nil {
-			return fmt.Errorf("while building tree for tags '%v': %w", variant, err)
-		}
-		// Reduce the tree.
-		tree.Reduce(treeReducer)
-		// Add all the reduced leaf nodes to 'roots'.
-		for _, qd := range tree.List() {
-			if qd.Data != result.Pass {
-				roots.Add(qd.Query, true)
-			}
-		}
-	}
-
-	// Build all the expectations for each of the roots.
-	log.Println("building new expectations...")
-	rootsList := roots.List()
-	expectations := []Expectation{}
-	for i, root := range rootsList {
-		if u.pb != nil {
-			u.pb.Update(progressbar.Status{Total: len(rootsList), Segments: []progressbar.Segment{
-				{Count: 1 + i},
-			}})
-		}
-		rootExpectations, _, _ := u.expectationsForRoot(
-			root.Query,            // Root query
-			0,                     // Line number
-			"crbug.com/dawn/0000", // Bug
-			"",                    // Comment
-		)
-		expectations = append(expectations, rootExpectations...)
-	}
-
-	// Bin the expectations by failure or flake.
-	flakes, failures := []Expectation{}, []Expectation{}
-	for _, r := range expectations {
-		if container.NewSet(r.Status...).Contains(string(result.RetryOnFailure)) {
-			flakes = append(flakes, r)
-		} else {
-			failures = append(failures, r)
-		}
-	}
-
-	// Create chunks for any flakes and failures, in that order.
-	for _, group := range []struct {
-		results Expectations
-		comment string
-	}{
-		{flakes, newFlakesComment},
-		{failures, newFailuresComment},
-	} {
-		if len(group.results) > 0 {
-			group.results.Sort()
-			u.out.Chunks = append(u.out.Chunks, Chunk{
-				Comments: []string{
-					"################################################################################",
-					group.comment,
-					ROLLER_DISCARD_AND_REWRITE,
-					"################################################################################",
-				},
-				Expectations: group.results,
-			})
-		}
-	}
-
-	return nil
-}
-
-// expectationsForRoot builds a list of expectations that cover the failing
-// tests for the results under root.
-// The returned list of expectations is optimized by reducing queries to the
-// most common root, and reducing tags to the smallest required set.
-func (u *updater) expectationsForRoot(
-	root query.Query, // The sub-tree query root
-	line int, // The originating line, when producing diagnostics
-	bug string, // The bug to apply to all returned expectations
-	comment string, // The comment to apply to all returned expectations
-) (
-	expectations []Expectation, // The output expectations
-	somePass bool, // Some of the results for the query had a Pass status
-	someConsumed bool, // The query was at least partly consumed by previous expectations
-) {
-	results, err := u.resultQueryTree.glob(root)
-	if err != nil {
-		u.diag(Error, line, "%v", err)
-		return nil, false, false
-	}
-
-	// Using the full list of unfiltered tests, generate the minimal set of
-	// variants (tags) that uniquely classify the results with differing status.
-	minimalVariants := u.
-		removeUnknownTags(results).
-		MinimalVariantTags(u.tagSets)
-
-	// For each minimized variant...
-	reduced := result.List{}
-	for _, variant := range minimalVariants {
-		// Build a query tree from this variant...
-		tree := result.StatusTree{}
-		filtered := results.FilterByTags(variant)
-		for _, r := range filtered {
-			// Note: variants may overlap, but overlaped queries will have
-			// identical statuses, so we can just ignore the error for Add().
-			tree.Add(r.Query, r.Status)
-		}
-
-		// ... and reduce the tree by collapsing sub-trees that have common
-		// statuses.
-		tree.ReduceUnder(root, treeReducer)
-
-		// Append the reduced tree nodes to the results list
-		for _, qs := range tree.List() {
-			reduced = append(reduced, result.Result{
-				Query:  qs.Query,
-				Tags:   variant,
-				Status: qs.Data,
-			})
-		}
-	}
-
-	// Filter out any results that passed or have already been consumed
-	filtered := result.List{}
-	for _, r := range reduced {
-		switch r.Status {
-		case result.Pass:
-			somePass = true
-		case consumed:
-			someConsumed = true
-		default:
-			filtered = append(filtered, r)
-		}
-	}
-
-	// Mark all the new expectation results as consumed.
-	for _, r := range filtered {
-		u.resultQueryTree.markAsConsumed(r.Query, r.Tags, 0)
-	}
-
-	// Transform the results to expectations.
-	expectations = u.resultsToExpectations(filtered, bug, comment)
-	return expectations, somePass, someConsumed
-}
-
-// resultsToExpectations returns a list of expectations from the given results.
-// Each expectation will have the same query, tags and status as the input
-// result, along with the specified bug and comment.
-//
-// If the result query target is a test without a wildcard, then the expectation
-// will have a wildcard automatically appended. This is to satisfy a requirement
-// of the expectation validator.
-func (u *updater) resultsToExpectations(results result.List, bug, comment string) []Expectation {
-	results.Sort()
-
-	out := make([]Expectation, 0, len(results))
-	addedExpectations := container.NewSet[string]()
-	for _, r := range results {
-		q := r.Query.String()
-		if r.Query.Target() == query.Tests && !r.Query.IsWildcard() {
-			// The expectation validator wants a trailing ':' for test queries
-			q += query.TargetDelimiter
-		}
-		e := Expectation{
-			Bug:     bug,
-			Tags:    u.in.Tags.RemoveLowerPriorityTags(r.Tags),
-			Query:   q,
-			Status:  []string{string(r.Status)},
-			Comment: comment,
-		}
-		key := e.AsExpectationFileString()
-		// We keep track of all expectations we've added so far to avoid cases where
-		// two distinct results create the same expectation due to
-		// RemoveLowerPriorityTags removing the distinguishing tags.
-		if !addedExpectations.Contains(key) {
-			out = append(out, e)
-			addedExpectations.Add(key)
-		}
-	}
-
-	return out
-}
-
-// removeUnknownTags returns a copy of the provided results with all tags not
-// found in the expectations list removed
-func (u *updater) removeUnknownTags(results result.List) result.List {
-	return results.TransformTags(func(t result.Tags) result.Tags {
-		filtered := result.NewTags()
-		for tag := range t {
-			if _, ok := u.in.Tags.ByName[tag]; ok {
-				filtered.Add(tag)
-			}
-		}
-		return filtered
-	})
-}
-
-// treeReducer is a function that can be used by StatusTree.Reduce() to reduce
-// tree nodes with the same status.
-// treeReducer will collapse trees nodes if any of the following are true:
-//   - All child nodes have the same status
-//   - More than 50% of the child nodes have a non-pass status, and none of the
-//     children are consumed.
-//   - There are more than 10 child nodes with a non-pass status, and none of the
-//     children are consumed.
-func treeReducer(statuses []result.Status) *result.Status {
-	counts := map[result.Status]int{}
-	for _, s := range statuses {
-		counts[s] = counts[s] + 1
-	}
-	if len(counts) == 1 {
-		return &statuses[0] // All the same status
-	}
-	if counts[consumed] > 0 {
-		return nil // Partially consumed trees cannot be merged
-	}
-	highestNonPassCount := 0
-	highestNonPassStatus := result.Failure
-	for s, n := range counts {
-		if s != result.Pass {
-			if percent := (100 * n) / len(statuses); percent > 50 {
-				// Over 50% of all the children are of non-pass status s.
-				return &s
-			}
-			if n > highestNonPassCount {
-				highestNonPassCount = n
-				highestNonPassStatus = s
-			}
-		}
-	}
-
-	if highestNonPassCount > 10 {
-		// Over 10 child node failed.
-		return &highestNonPassStatus
-	}
-
-	return nil
-}
-
-// diag appends a new diagnostic to u.diags with the given severity, line and
-// message.
-func (u *updater) diag(severity Severity, line int, msg string, args ...interface{}) {
-	u.diags = append(u.diags, Diagnostic{
-		Severity: severity,
-		Line:     line,
-		Message:  fmt.Sprintf(msg, args...),
-	})
-}
-
-// diagAllPass appends a new note diagnostic that all the tests now pass
-func (u *updater) diagAllPass(line int, results result.List) {
-	if c := len(results); c > 1 {
-		u.diag(Note, line, "all %d tests now pass", len(results))
-	} else {
-		u.diag(Note, line, "test now passes")
-	}
-}
diff --git a/tools/src/cts/expectations/update_test.go b/tools/src/cts/expectations/update_test.go
index a4c1273..ce172dc 100644
--- a/tools/src/cts/expectations/update_test.go
+++ b/tools/src/cts/expectations/update_test.go
@@ -28,933 +28,15 @@
 package expectations
 
 import (
-	"strings"
 	"testing"
 
-	"dawn.googlesource.com/dawn/tools/src/container"
 	"dawn.googlesource.com/dawn/tools/src/cts/query"
 	"dawn.googlesource.com/dawn/tools/src/cts/result"
-	"github.com/google/go-cmp/cmp"
 	"github.com/stretchr/testify/assert"
 )
 
 var Q = query.Parse
 
-func TestUpdate(t *testing.T) {
-	header := `# BEGIN TAG HEADER
-# OS
-# tags: [ os-a os-b os-c ]
-# GPU
-# tags: [ gpu-a gpu-b gpu-c ]
-# END TAG HEADER
-`
-	headerLines := strings.Count(header, "\n")
-
-	type Test struct {
-		name         string
-		expectations string
-		results      result.List
-		updated      string
-		diagnostics  Diagnostics
-		err          string
-	}
-	for _, test := range []Test{
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "empty results",
-			expectations: ``,
-			results:      result.List{},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "no results found",
-			expectations: `
-# ##ROLLER_MUTABLE##
-crbug.com/a/123 a:missing,test,result:* [ Failure ]
-crbug.com/a/123 [ tag ] another:missing,test,result:* [ Failure ]
-some:other,test:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("some:other,test:*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("some:other,test:*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Failure,
-				},
-			},
-			updated: `
-# ##ROLLER_MUTABLE##
-some:other,test:* [ Failure ]
-crbug.com/a/123 a:missing,test,result:* [ Failure ]
-crbug.com/a/123 [ tag ] another:missing,test,result:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Note,
-					Line:     headerLines + 3,
-					Message:  "no results found for query 'a:missing,test,result:*'",
-				},
-				{
-					Severity: Note,
-					Line:     headerLines + 4,
-					Message:  "no results found for query 'another:missing,test,result:*' with tags [tag]",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "no results found immutable",
-			expectations: `
-crbug.com/a/123 a:missing,test,result:* [ Failure ]
-
-some:other,test:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("some:other,test:*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("some:other,test:*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Failure,
-				},
-			},
-			updated: `
-crbug.com/a/123 a:missing,test,result:* [ Failure ]
-
-some:other,test:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Note,
-					Line:     headerLines + 2,
-					Message:  "no results found for query 'a:missing,test,result:*'",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "unknown test",
-			expectations: `
-# ##ROLLER_MUTABLE##
-crbug.com/a/123 an:unknown,test:* [ Failure ]
-crbug.com/a/123 [ tag ] another:unknown:test [ Failure ]
-
-some:other,test:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("some:other,test:*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("some:other,test:*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Failure,
-				},
-			},
-			updated: `
-some:other,test:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Warning,
-					Line:     headerLines + 3,
-					Message:  "no tests exist with query 'an:unknown,test:*' - removing",
-				},
-				{
-					Severity: Warning,
-					Line:     headerLines + 4,
-					Message:  "no tests exist with query 'another:unknown:test' - removing",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "unknown test found in immutable chunk",
-			expectations: `
-crbug.com/a/123 an:unknown,test:* [ Failure ]
-
-some:other,test:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("some:other,test:*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("some:other,test:*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Failure,
-				},
-			},
-			updated: `
-some:other,test:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Warning,
-					Line:     headerLines + 2,
-					Message:  "no tests exist with query 'an:unknown,test:*' - removing",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "simple expectation with tags",
-			expectations: `
-# ##ROLLER_MUTABLE##
-[ os-a ] a:b,c:* [ Failure ]
-[ gpu-b ] a:b,c:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("os-a", "os-c", "gpu-b"),
-					Status: result.Failure,
-				},
-			},
-			updated: `
-# ##ROLLER_MUTABLE##
-a:b,c:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Note,
-					Line:     headerLines + 4,
-					Message:  "expectation is fully covered by previous expectations",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "simple expectation with tags new flakes implicitly mutable",
-			expectations: `
-################################################################################
-# New flakes. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-[ os-a ] a:b,c:* [ RetryOnFailure ]
-[ gpu-b ] a:b,c:* [ RetryOnFailure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("os-a", "os-c", "gpu-b"),
-					Status: result.RetryOnFailure,
-				},
-			},
-			updated: `
-################################################################################
-# New flakes. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 a:* [ RetryOnFailure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "simple expectation with tags new failures implicitly mutable",
-			expectations: `
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-[ os-a ] a:b,c:* [ Failure ]
-[ gpu-b ] a:b,c:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("os-a", "os-c", "gpu-b"),
-					Status: result.Failure,
-				},
-			},
-			updated: `
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 a:* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "simple expectation with tags immutable",
-			expectations: `
-[ os-a ] a:b,c:* [ Failure ]
-[ gpu-b ] a:b,c:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("os-a", "os-c", "gpu-b"),
-					Status: result.Failure,
-				},
-			},
-			updated: `
-[ gpu-b ] a:b,c:* [ Failure ]
-[ os-a ] a:b,c:* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "expectation test now passes",
-			expectations: `
-# ##ROLLER_MUTABLE##
-crbug.com/a/123 [ gpu-a os-a ] a:b,c:* [ Failure ]
-crbug.com/a/123 [ gpu-b os-b ] a:b,c:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Abort,
-				},
-			},
-			updated: `
-# ##ROLLER_MUTABLE##
-crbug.com/a/123 [ os-b ] a:b,c:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Note,
-					Line:     headerLines + 4,
-					Message:  "expectation is fully covered by previous expectations",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "expectation case now passes",
-			expectations: `
-# ##ROLLER_MUTABLE##
-crbug.com/a/123 [ gpu-a os-a ] a:b,c:d:* [ Failure ]
-crbug.com/a/123 [ gpu-b os-b ] a:b,c:d:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:d:*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Abort,
-				},
-			},
-			updated: `
-# ##ROLLER_MUTABLE##
-crbug.com/a/123 [ os-b ] a:b,c:d:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Note,
-					Line:     headerLines + 4,
-					Message:  "expectation is fully covered by previous expectations",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "first expectation expands to cover later expectations - no diagnostics",
-			expectations: `
-crbug.com/a/123 [ gpu-a os-a ] a:b,c:d:* [ Failure ]
-crbug.com/a/123 [ gpu-c os-a ] a:b,c:d:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("gpu-a", "os-a"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("gpu-a", "os-b"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("gpu-b", "os-a"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("gpu-b", "os-b"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("gpu-c", "os-a"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("gpu-c", "os-b"),
-					Status: result.Pass,
-				},
-			},
-			updated: `
-crbug.com/a/123 [ gpu-a os-a ] a:b,c:d:* [ Failure ]
-crbug.com/a/123 [ gpu-c os-a ] a:b,c:d:* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "expectation case now passes immutable - single",
-			expectations: `
-crbug.com/a/123 [ gpu-a os-a ] a:b,c:d:* [ Failure ]
-crbug.com/a/123 [ gpu-b os-b ] a:b,c:d:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:e"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Abort,
-				},
-			},
-			updated: `
-crbug.com/a/123 [ gpu-a os-a ] a:b,c:d:* [ Failure ]
-crbug.com/a/123 [ gpu-b os-b ] a:b,c:d:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Note,
-					Line:     headerLines + 2,
-					Message:  "test now passes",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "expectation case now passes immutable - multiple",
-			expectations: `
-crbug.com/a/123 a:b,c:d:* [ Failure ]
-`,
-			results: result.List{
-				result.Result{Query: Q("a:b,c:d:a"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:d:b"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:d:c"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:d:d"), Status: result.Pass},
-			},
-			updated: `
-crbug.com/a/123 a:b,c:d:* [ Failure ]
-`,
-			diagnostics: Diagnostics{
-				{
-					Severity: Note,
-					Line:     headerLines + 2,
-					Message:  "all 4 tests now pass",
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "new test results",
-			expectations: `# A comment`,
-			results: result.List{
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_a:*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Abort,
-				},
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_a:*"),
-					Tags:   result.NewTags("os-a", "gpu-b"),
-					Status: result.Abort,
-				},
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_c:case=4;*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Crash,
-				},
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_c:case=4;*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Crash,
-				},
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_c:case=5;*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.RetryOnFailure,
-				},
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_b:case=5;*"),
-					Tags:   result.NewTags("os-b", "gpu-b"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_b:case=6;*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.Slow,
-				},
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_b:case=6;*"),
-					Tags:   result.NewTags("os-b", "gpu-a"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("suite:dir_a,dir_b:test_c:case=6;*"),
-					Tags:   result.NewTags("os-a", "gpu-a"),
-					Status: result.RetryOnFailure,
-				},
-			},
-			updated: `# A comment
-
-################################################################################
-# New flakes. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 [ gpu-a os-a ] suite:dir_a,dir_b:test_c:case=6;* [ RetryOnFailure ]
-crbug.com/dawn/0000 [ gpu-b os-b ] suite:dir_a,dir_b:test_c:case=5;* [ RetryOnFailure ]
-
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 [ gpu-a os-a ] suite:dir_a,dir_b:test_a:* [ Failure ]
-crbug.com/dawn/0000 [ gpu-a os-a ] suite:dir_a,dir_b:test_b:* [ Slow ]
-crbug.com/dawn/0000 [ gpu-a os-a ] suite:dir_a,dir_b:test_c:case=4;* [ Failure ]
-crbug.com/dawn/0000 [ gpu-b os-a ] suite:* [ Failure ]
-crbug.com/dawn/0000 [ gpu-b os-b ] suite:dir_a,dir_b:test_c:case=4;* [ Failure ]
-`,
-		},
-
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "root node overlap",
-			expectations: `# A comment`,
-			results: result.List{
-				// For variant ['os-a'], we have a root node 'a:b,c:d:*'.
-				result.Result{
-					Query:  Q("a:b,c:d:x,*"),
-					Tags:   result.NewTags("os-a"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:y,*"),
-					Tags:   result.NewTags("os-a"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:e:*"),
-					Tags:   result.NewTags("os-a"),
-					Status: result.Pass,
-				},
-				// For variant ['os-b'], we have a root node 'a:b,c:d:x,*'.
-				result.Result{
-					Query:  Q("a:b,c:d:x,*"),
-					Tags:   result.NewTags("os-b"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:d:y,*"),
-					Tags:   result.NewTags("os-b"),
-					Status: result.Pass,
-				},
-				result.Result{
-					Query:  Q("a:b,c:e:*"),
-					Tags:   result.NewTags("os-b"),
-					Status: result.Pass,
-				},
-			},
-			updated: `# A comment
-
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 [ os-a ] a:b,c:d:* [ Failure ]
-crbug.com/dawn/0000 [ os-b ] a:b,c:d:x,* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "filter unknown tags",
-			expectations: ``,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-a", "gpu-x"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-b", "gpu-x"),
-					Status: result.Crash,
-				},
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-x", "gpu-b"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-x", "gpu-a"),
-					Status: result.Crash,
-				},
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-c", "gpu-c"),
-					Status: result.Pass,
-				},
-			},
-			updated: `
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 [ gpu-a ] a:* [ Failure ]
-crbug.com/dawn/0000 [ gpu-b ] a:* [ Failure ]
-crbug.com/dawn/0000 [ os-a ] a:* [ Failure ]
-crbug.com/dawn/0000 [ os-b ] a:* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "prioritize tag sets",
-			expectations: ``,
-			results: result.List{
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-a", "os-c", "gpu-b"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("gpu-a", "os-b", "gpu-c"),
-					Status: result.Failure,
-				},
-				result.Result{
-					Query:  Q("a:b,c:*"),
-					Tags:   result.NewTags("os-c", "gpu-c"),
-					Status: result.Pass,
-				},
-			},
-			updated: `
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 [ gpu-b os-c ] a:* [ Failure ]
-crbug.com/dawn/0000 [ gpu-c os-b ] a:* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "merge when 50% or more children fail",
-			expectations: ``,
-			results: result.List{ // 4 pass, 6 fail (50%)
-				result.Result{Query: Q("a:b,c:0:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:1:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:2:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:3:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:4:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:5:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:6:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:7:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:8:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:9:*"), Status: result.Pass},
-			},
-			updated: `
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 a:* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "don't merge when 50% or fewer children fail",
-			expectations: ``,
-			results: result.List{ // 5 pass, 5 fail (50%)
-				result.Result{Query: Q("a:b,c:0:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:1:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:2:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:3:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:4:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:5:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:6:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:7:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:8:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:9:*"), Status: result.Pass},
-			},
-			updated: `
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 a:b,c:0:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:2:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:5:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:6:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:8:* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "merge when more than 10 children fail",
-			expectations: ``,
-			results: result.List{ // 19 pass, 11 fail (37%)
-				result.Result{Query: Q("a:b,c:00:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:01:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:02:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:03:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:04:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:05:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:06:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:07:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:08:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:09:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:10:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:11:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:12:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:13:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:14:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:15:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:16:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:17:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:18:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:19:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:20:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:21:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:22:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:23:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:24:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:25:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:26:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:27:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:28:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:29:*"), Status: result.Failure},
-			},
-			updated: `
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 a:* [ Failure ]
-`,
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name:         "don't merge when 10 or fewer children fail",
-			expectations: ``,
-			results: result.List{ // 20 pass, 10 fail (33%)
-				result.Result{Query: Q("a:b,c:00:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:01:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:02:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:03:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:04:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:05:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:06:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:07:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:08:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:09:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:10:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:11:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:12:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:13:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:14:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:15:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:16:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:17:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:18:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:19:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:20:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:21:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:22:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:23:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:24:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:25:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:26:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:27:*"), Status: result.Pass},
-				result.Result{Query: Q("a:b,c:28:*"), Status: result.Failure},
-				result.Result{Query: Q("a:b,c:29:*"), Status: result.Failure},
-			},
-			updated: `
-################################################################################
-# New failures. Please triage - will be discarded/regenerated by the next roll:
-# ##ROLLER_DISCARD_AND_REWRITE##
-################################################################################
-crbug.com/dawn/0000 a:b,c:00:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:05:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:08:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:13:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:15:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:20:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:23:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:26:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:28:* [ Failure ]
-crbug.com/dawn/0000 a:b,c:29:* [ Failure ]
-`,
-		},
-	} {
-		ex, err := Parse("expectations.txt", header+test.expectations)
-		if err != nil {
-			t.Fatalf("'%v': expectations.Parse():\n%v", test.name, err)
-		}
-
-		testList := container.NewMap[string, query.Query]()
-		for _, r := range test.results {
-			testList.Add(r.Query.String(), r.Query)
-		}
-		for _, s := range []string{
-			"a:missing,test,result:a=1,b=2",
-			"another:missing,test,result:cat=meow,dog=woof",
-		} {
-			testList.Add(s, query.Parse(s))
-		}
-
-		errMsg := ""
-		diagnostics, err := ex.Update(test.results, testList.Values() /* verbose */, false)
-		if err != nil {
-			errMsg = err.Error()
-		}
-		if diff := cmp.Diff(errMsg, test.err); diff != "" {
-			t.Errorf("'%v': expectations.Update() error:\n%v", test.name, diff)
-		}
-
-		if diff := cmp.Diff(diagnostics, test.diagnostics); diff != "" {
-			t.Errorf("'%v': diagnostics were not as expected:\n%v", test.name, diff)
-		}
-
-		if diff := cmp.Diff(
-			strings.Split(ex.String(), "\n"),
-			strings.Split(header+test.updated, "\n")); diff != "" {
-			t.Errorf("'%v': updated was not as expected:\n%v", test.name, diff)
-		}
-	}
-}
-
-func createGenericUpdater(t *testing.T) updater {
-	header := `
-# BEGIN TAG HEADER
-# OS
-# tags: [ linux win10 ]
-# GPU
-# tags: [ intel
-#         nvidia nvidia-0x2184 ]
-# Driver
-# tags: [ nvidia_ge_31.0.15.4601 nvidia_lt_31.0.15.4601
-#         nvidia_ge_535.183.01 nvidia_lt_535.183.01 ]
-# END TAG HEADER
-`
-	inContent, err := Parse("expectations.txt", header)
-	if err != nil {
-		t.Fatalf("Failed to parse expectations: %v", err)
-	}
-
-	u := updater{
-		in: inContent,
-	}
-	return u
-}
-
-// Tests basic result -> expectation conversion.
-func TestResultsToExpectationsBasic(t *testing.T) {
-	results := result.List{
-		{
-			Query:  query.Parse("webgpu:shader,execution,memory_layout:read_layout:"),
-			Tags:   result.NewTags("linux", "nvidia"),
-			Status: result.Failure,
-		},
-		{
-			Query:  query.Parse("webgpu:shader,execution,memory_model,barrier:"),
-			Tags:   result.NewTags("win10", "intel"),
-			Status: result.Failure,
-		},
-	}
-
-	expectedOutput := []Expectation{
-		{
-			Bug:     "crbug.com/1234",
-			Tags:    result.NewTags("linux", "nvidia"),
-			Query:   "webgpu:shader,execution,memory_layout:read_layout:",
-			Status:  []string{"Failure"},
-			Comment: "comment",
-		},
-		{
-			Bug:     "crbug.com/1234",
-			Tags:    result.NewTags("win10", "intel"),
-			Query:   "webgpu:shader,execution,memory_model,barrier",
-			Status:  []string{"Failure"},
-			Comment: "comment",
-		},
-	}
-
-	u := createGenericUpdater(t)
-	output := u.resultsToExpectations(results, "crbug.com/1234", "comment")
-	assert.Equal(t, output, expectedOutput)
-}
-
-// Tests behavior when two unique results end up creating the same expectation
-// due to lower priority tags being removed.
-func TestResultsToExpectationsOverlappingExpectations(t *testing.T) {
-	results := result.List{
-		{
-			Query:  query.Parse("webgpu:shader,execution,memory_layout:read_layout:"),
-			Tags:   result.NewTags("nvidia", "nvidia-0x2184", "nvidia_ge_31.0.15.4601", "nvidia_lt_535.183.01"),
-			Status: result.Failure,
-		},
-		{
-			Query:  query.Parse("webgpu:shader,execution,memory_layout:read_layout:"),
-			Tags:   result.NewTags("nvidia", "nvidia-0x2184", "nvidia_lt_31.0.15.4601", "nvidia_lt_535.183.01"),
-			Status: result.Failure,
-		},
-	}
-
-	expectedOutput := []Expectation{
-		{
-			Bug:     "crbug.com/1234",
-			Tags:    result.NewTags("nvidia-0x2184", "nvidia_lt_535.183.01"),
-			Query:   "webgpu:shader,execution,memory_layout:read_layout:",
-			Status:  []string{"Failure"},
-			Comment: "comment",
-		},
-	}
-
-	u := createGenericUpdater(t)
-	output := u.resultsToExpectations(results, "crbug.com/1234", "comment")
-	assert.Equal(t, output, expectedOutput)
-}
-
-// Tests behavior related to automatic inclusion of a trailing :.
-func TestResultsToExpectationsTrailingColon(t *testing.T) {
-	results := result.List{
-		// Should automatically have a : added since it's a test query.
-		{
-			Query:  query.Parse("webgpu:shader,execution,memory_layout:read_layout"),
-			Tags:   result.NewTags("linux", "nvidia"),
-			Status: result.Failure,
-		},
-		// Should not have a : added since it is a wildcard query.
-		{
-			Query:  query.Parse("webgpu:shader,execution,*"),
-			Tags:   result.NewTags("win10", "intel"),
-			Status: result.Failure,
-		},
-	}
-
-	expectedOutput := []Expectation{
-		{
-			Bug:     "crbug.com/1234",
-			Tags:    result.NewTags("win10", "intel"),
-			Query:   "webgpu:shader,execution,*",
-			Status:  []string{"Failure"},
-			Comment: "comment",
-		},
-		{
-			Bug:     "crbug.com/1234",
-			Tags:    result.NewTags("linux", "nvidia"),
-			Query:   "webgpu:shader,execution,memory_layout:read_layout:",
-			Status:  []string{"Failure"},
-			Comment: "comment",
-		},
-	}
-
-	u := createGenericUpdater(t)
-	output := u.resultsToExpectations(results, "crbug.com/1234", "comment")
-	assert.Equal(t, output, expectedOutput)
-}
-
 /*******************************************************************************
  * removeExpectationsForUnknownTests tests
  ******************************************************************************/
diff --git a/tools/src/cts/query/tree.go b/tools/src/cts/query/tree.go
index 91ac323..4288b6f 100644
--- a/tools/src/cts/query/tree.go
+++ b/tools/src/cts/query/tree.go
@@ -112,105 +112,6 @@
 	return nil
 }
 
-// Merger is a function used to merge the children nodes of a tree.
-// Merger is called with the Data of each child node. If the function returns a
-// non-nil Data pointer, then this is used as the merged result. If the function
-// returns nil, then the node will not be merged.
-type Merger[Data any] func([]Data) *Data
-
-// merge collapses tree nodes based on child node data, using the function f.
-// merge operates on the leaf nodes first, working its way towards the root of
-// the tree.
-// Returns the merged target data for this node, or nil if the node is not a
-// leaf and its children has non-uniform data.
-func (n *TreeNode[Data]) merge(f Merger[Data]) *Data {
-	// If the node is a leaf, then simply return the node's data.
-	if len(n.Children) == 0 {
-		return n.Data
-	}
-
-	// Build a map of child target to merged child data.
-	// A nil for the value indicates that one or more children could not merge.
-	mergedChildren := map[Target][]Data{}
-	for key, child := range n.Children {
-		// Call merge() on the child. Even if we cannot merge this node, we want
-		// to do this for all children so they can merge their sub-graphs.
-		childData := child.merge(f)
-
-		if childData == nil {
-			// If merge() returned nil, then the data could not be merged.
-			// Mark the entire target as unmergeable.
-			mergedChildren[key.Target] = nil
-			continue
-		}
-
-		// Fetch the merge list for this child's target.
-		list, found := mergedChildren[key.Target]
-		if !found {
-			// First child with the given target?
-			mergedChildren[key.Target] = []Data{*childData}
-			continue
-		}
-		if list != nil {
-			mergedChildren[key.Target] = append(list, *childData)
-		}
-	}
-
-	merge := func(in []Data) *Data {
-		switch len(in) {
-		case 0:
-			return nil // nothing to merge.
-		case 1:
-			return &in[0] // merge of a single item results in that item
-		default:
-			return f(in)
-		}
-	}
-
-	// Might it possible to merge this node?
-	maybeMergeable := true
-
-	// The merged data, per target
-	mergedTargets := map[Target]Data{}
-
-	// Attempt to merge each of the target's data
-	for target, list := range mergedChildren {
-		if list != nil { // nil == unmergeable target
-			if data := merge(list); data != nil {
-				// Merge success!
-				mergedTargets[target] = *data
-				continue
-			}
-		}
-		maybeMergeable = false // Merge of this node is not possible
-	}
-
-	// Remove all children that have been merged
-	for key := range n.Children {
-		if _, merged := mergedTargets[key.Target]; merged {
-			delete(n.Children, key)
-		}
-	}
-
-	// Add wildcards for merged targets
-	for target, data := range mergedTargets {
-		data := data // Don't take address of iterator
-		n.getOrCreateChild(TreeNodeChildKey{"*", target}).Data = &data
-	}
-
-	// If any of the targets are unmergeable, then we cannot merge the node itself.
-	if !maybeMergeable {
-		return nil
-	}
-
-	// All targets were merged. Attempt to merge each of the targets.
-	data := make([]Data, 0, len(mergedTargets))
-	for _, d := range mergedTargets {
-		data = append(data, d)
-	}
-	return merge(data)
-}
-
 // print writes a textual representation of this node and its children to w.
 // prefix is used as the line prefix for each node, which is appended with
 // whitespace for each child node.
@@ -280,23 +181,6 @@
 	return nil
 }
 
-// Split adds a new data to the tree, clearing any ancestor node's data.
-// Returns ErrDuplicateData if the tree already contains a data for the given node at query
-func (t *Tree[Data]) Split(q Query, d Data) error {
-	node := &t.TreeNode
-	q.Walk(func(q Query, t Target, n string) error {
-		delete(node.Children, TreeNodeChildKey{Name: "*", Target: t})
-		node.Data = nil
-		node = node.getOrCreateChild(TreeNodeChildKey{n, t})
-		return nil
-	})
-	if node.Data != nil {
-		return ErrDuplicateData{node.Query}
-	}
-	node.Data = &d
-	return nil
-}
-
 // GetOrCreate returns existing, or adds a new data to the tree.
 func (t *Tree[Data]) GetOrCreate(q Query, create func() Data) *Data {
 	node := &t.TreeNode
@@ -327,40 +211,6 @@
 	return node
 }
 
-// Reduce reduces the tree using the Merger function f.
-// If the Merger function returns a non-nil Data value, then this will be used
-// to replace the non-leaf node with a new leaf node holding the returned Data.
-// This process recurses up to the tree root.
-func (t *Tree[Data]) Reduce(f Merger[Data]) {
-	for _, root := range t.TreeNode.Children {
-		root.merge(f)
-	}
-}
-
-// ReduceUnder reduces the sub-tree under the given query using the Merger
-// function f.
-// If the Merger function returns a non-nil Data value, then this will be used
-// to replace the non-leaf node with a new leaf node holding the returned Data.
-// This process recurses up to the node pointed at by the query to.
-func (t *Tree[Data]) ReduceUnder(to Query, f Merger[Data]) error {
-	node := &t.TreeNode
-	return to.Walk(func(q Query, t Target, n string) error {
-		if n == "*" {
-			node.merge(f)
-			return nil
-		}
-		child, ok := node.Children[TreeNodeChildKey{n, t}]
-		if !ok {
-			return ErrNoDataForQuery{q}
-		}
-		node = child
-		if q == to {
-			node.merge(f)
-		}
-		return nil
-	})
-}
-
 // glob calls f for every node under the given query.
 func (t *Tree[Data]) glob(fq Query, f func(f *TreeNode[Data]) error) error {
 	node := &t.TreeNode
@@ -403,44 +253,6 @@
 	})
 }
 
-// Replace replaces the sub-tree matching the query 'what' with the Data 'with'
-func (t *Tree[Data]) Replace(what Query, with Data) error {
-	node := &t.TreeNode
-	return what.Walk(func(q Query, t Target, n string) error {
-		childKey := TreeNodeChildKey{n, t}
-		if q == what {
-			for key, child := range node.Children {
-				// Use Query.Contains() to handle matching of Cases
-				// (which are not split into tree nodes)
-				if q.Contains(child.Query) {
-					delete(node.Children, key)
-				}
-			}
-			node = node.getOrCreateChild(childKey)
-			node.Data = &with
-		} else {
-			child, ok := node.Children[childKey]
-			if !ok {
-				return ErrNoDataForQuery{q}
-			}
-			node = child
-		}
-		return nil
-	})
-}
-
-// List returns the tree nodes flattened as a list of QueryData
-func (t *Tree[Data]) List() []QueryData[Data] {
-	out := []QueryData[Data]{}
-	t.traverse(func(n *TreeNode[Data]) error {
-		if n.Data != nil {
-			out = append(out, QueryData[Data]{n.Query, *n.Data})
-		}
-		return nil
-	})
-	return out
-}
-
 // Glob returns a list of QueryData's for every node that is under the given
 // query, which holds data.
 // Glob handles wildcards as well as non-wildcard queries:
diff --git a/tools/src/cts/query/tree_test.go b/tools/src/cts/query/tree_test.go
index c2e9ce7..9ed14f5 100644
--- a/tools/src/cts/query/tree_test.go
+++ b/tools/src/cts/query/tree_test.go
@@ -4,9 +4,7 @@
 	"fmt"
 	"testing"
 
-	"dawn.googlesource.com/dawn/tools/src/container"
 	"dawn.googlesource.com/dawn/tools/src/cts/query"
-	"dawn.googlesource.com/dawn/tools/src/fileutils"
 	"github.com/google/go-cmp/cmp"
 )
 
@@ -350,635 +348,6 @@
 	}
 }
 
-func TestSplit(t *testing.T) {
-	type Tree = query.Tree[string]
-	type Node = query.TreeNode[string]
-	type QueryData = query.QueryData[string]
-	type Children = query.TreeNodeChildren[string]
-
-	type Test struct {
-		in   QueryData
-		pre  Tree
-		post Tree
-	}
-	for _, test := range []Test{
-		{ /////////////////////////////////////////////////////////////////////
-			in: QueryData{
-				Query: Q(`suite:*`),
-				Data:  pass,
-			},
-			post: Tree{
-				TreeNode: Node{
-					Children: Children{
-						query.TreeNodeChildKey{`suite`, query.Suite}: {
-							Query: Q(`suite`),
-							Children: Children{
-								query.TreeNodeChildKey{`*`, query.Files}: {
-									Query: Q(`suite:*`),
-									Data:  &pass,
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{ /////////////////////////////////////////////////////////////////////
-			in: QueryData{
-				Query: Q(`suite:a,b:*`),
-				Data:  pass,
-			},
-			pre: Tree{
-				TreeNode: Node{
-					Children: Children{
-						query.TreeNodeChildKey{`suite`, query.Suite}: {
-							Query: Q(`suite`),
-							Children: Children{
-								query.TreeNodeChildKey{`a`, query.Files}: {
-									Query: Q(`suite:a`),
-									Children: Children{
-										query.TreeNodeChildKey{`*`, query.Files}: {
-											Query: Q(`suite:a,*`),
-											Data:  &pass,
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-			post: Tree{
-				TreeNode: Node{
-					Children: Children{
-						query.TreeNodeChildKey{`suite`, query.Suite}: {
-							Query: Q(`suite`),
-							Children: Children{
-								query.TreeNodeChildKey{`a`, query.Files}: {
-									Query: Q(`suite:a`),
-									Children: Children{
-										query.TreeNodeChildKey{`b`, query.Files}: {
-											Query: Q(`suite:a,b`),
-											Children: Children{
-												query.TreeNodeChildKey{`*`, query.Tests}: {
-													Query: Q(`suite:a,b:*`),
-													Data:  &pass,
-												},
-											},
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{ /////////////////////////////////////////////////////////////////////
-			in: QueryData{
-				Query: Q(`suite:a:*`),
-				Data:  pass,
-			},
-			pre: Tree{
-				TreeNode: Node{
-					Children: Children{
-						query.TreeNodeChildKey{`suite`, query.Suite}: {
-							Query: Q(`suite`),
-							Children: Children{
-								query.TreeNodeChildKey{`a`, query.Files}: {
-									Query: Q(`suite:a`),
-									Children: Children{
-										query.TreeNodeChildKey{`b`, query.Files}: {
-											Query: Q(`suite:a,b`),
-											Children: Children{
-												query.TreeNodeChildKey{`*`, query.Files}: {
-													Query: Q(`suite:a,b,*`),
-													Data:  &pass,
-												},
-											},
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-			post: Tree{
-				TreeNode: Node{
-					Children: Children{
-						query.TreeNodeChildKey{`suite`, query.Suite}: {
-							Query: Q(`suite`),
-							Children: Children{
-								query.TreeNodeChildKey{`a`, query.Files}: {
-									Query: Q(`suite:a`),
-									Children: Children{
-										query.TreeNodeChildKey{`*`, query.Tests}: {
-											Query: Q(`suite:a:*`),
-											Data:  &pass,
-										},
-										query.TreeNodeChildKey{`b`, query.Files}: {
-											Query: Q(`suite:a,b`),
-											Children: Children{
-												query.TreeNodeChildKey{`*`, query.Files}: {
-													Query: Q(`suite:a,b,*`),
-													Data:  &pass,
-												},
-											},
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{ /////////////////////////////////////////////////////////////////////
-			in: QueryData{
-				Query: Q(`suite:a,b:c:*`),
-				Data:  pass,
-			},
-			pre: Tree{
-				TreeNode: Node{
-					Children: Children{
-						query.TreeNodeChildKey{`suite`, query.Suite}: {
-							Query: Q(`suite`),
-							Children: Children{
-								query.TreeNodeChildKey{`a`, query.Files}: {
-									Query: Q(`suite:a`),
-									Children: Children{
-										query.TreeNodeChildKey{`b`, query.Files}: {
-											Query: Q(`suite:a,b`),
-											Children: Children{
-												query.TreeNodeChildKey{`*`, query.Tests}: {
-													Query: Q(`suite:a,b:*`),
-													Data:  &pass,
-												},
-											},
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-			post: Tree{
-				TreeNode: Node{
-					Children: Children{
-						query.TreeNodeChildKey{`suite`, query.Suite}: {
-							Query: Q(`suite`),
-							Children: Children{
-								query.TreeNodeChildKey{`a`, query.Files}: {
-									Query: Q(`suite:a`),
-									Children: Children{
-										query.TreeNodeChildKey{`b`, query.Files}: {
-											Query: Q(`suite:a,b`),
-											Children: Children{
-												query.TreeNodeChildKey{`c`, query.Tests}: {
-													Query: Q(`suite:a,b:c`),
-													Children: Children{
-														query.TreeNodeChildKey{`*`, query.Cases}: {
-															Query: Q(`suite:a,b:c:*`),
-															Data:  &pass,
-														},
-													},
-												},
-											},
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	} {
-		tree := test.pre
-		if err := tree.Split(test.in.Query, test.in.Data); err != nil {
-			t.Errorf("NewTree(%v): %v", test.in, err)
-			continue
-		}
-		if diff := cmp.Diff(tree, test.post); diff != "" {
-			t.Errorf("Split(%v) tree was not as expected:\n%v", test.in, diff)
-		}
-	}
-}
-
-func TestList(t *testing.T) {
-	type QueryData = query.QueryData[string]
-
-	tree, err := NewTree(t,
-		QueryData{Query: Q(`suite:*`), Data: skip},
-		QueryData{Query: Q(`suite:a,*`), Data: failure},
-		QueryData{Query: Q(`suite:a,b,*`), Data: failure},
-		QueryData{Query: Q(`suite:a,b:c:*`), Data: failure},
-		QueryData{Query: Q(`suite:a,b:c:d;*`), Data: failure},
-		QueryData{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
-		QueryData{Query: Q(`suite:h,b:c:f="g";*`), Data: abort},
-		QueryData{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
-	)
-	if err != nil {
-		t.Fatalf("NewTree() returned %v", err)
-	}
-
-	got := tree.List()
-	expect := []QueryData{
-		{Query: Q(`suite:*`), Data: skip},
-		{Query: Q(`suite:a,*`), Data: failure},
-		{Query: Q(`suite:a,b,*`), Data: failure},
-		{Query: Q(`suite:a,b:c:*`), Data: failure},
-		{Query: Q(`suite:a,b:c:d;*`), Data: failure},
-		{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
-		{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
-		{Query: Q(`suite:h,b:c:f="g";*`), Data: abort},
-	}
-	if diff := cmp.Diff(got, expect); diff != "" {
-		t.Errorf("List() was not as expected:\n%v", diff)
-	}
-}
-
-// reducer is used by Reduce() and ReduceUnder() tests for reducing the tree.
-// reducer returns a pointer to the common string if all strings in data are
-// equal, otherwise returns nil
-func reducer(data []string) *string {
-	if s := container.NewSet(data...); len(s) == 1 {
-		item := s.One()
-		return &item
-	}
-	return nil
-}
-
-func TestReduce(t *testing.T) {
-	type QueryData = query.QueryData[string]
-
-	type Test struct {
-		name   string
-		in     []QueryData
-		expect []QueryData
-	}
-	for _, test := range []Test{
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Different file results - A",
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Different file results - B",
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-				{Query: Q(`suite:a,d,*`), Data: skip},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-				{Query: Q(`suite:a,d,*`), Data: skip},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Different test results",
-			in: []QueryData{
-				{Query: Q(`suite:a,b:*`), Data: failure},
-				{Query: Q(`suite:a,c:*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b:*`), Data: failure},
-				{Query: Q(`suite:a,c:*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Same file results",
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-				{Query: Q(`suite:a,c,*`), Data: failure},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:*`), Data: failure},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Same test results",
-			in: []QueryData{
-				{Query: Q(`suite:a,b:*`), Data: failure},
-				{Query: Q(`suite:a,c:*`), Data: failure},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:*`), Data: failure},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "File vs test",
-			in: []QueryData{
-				{Query: Q(`suite:a:b,c*`), Data: failure},
-				{Query: Q(`suite:a,b,c*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,*`), Data: pass},
-				{Query: Q(`suite:a:*`), Data: failure},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Sibling cases, no reduce",
-			in: []QueryData{
-				{Query: Q(`suite:a:b:c;d=e;f=g;*`), Data: failure},
-				{Query: Q(`suite:a:b:c;d=e;f=h;*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a:b:c;d=e;f=g;*`), Data: failure},
-				{Query: Q(`suite:a:b:c;d=e;f=h;*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Sibling cases, reduce to test",
-			in: []QueryData{
-				{Query: Q(`suite:a:b:c=1;d="x";*`), Data: failure},
-				{Query: Q(`suite:a:b:c=1;d="y";*`), Data: failure},
-				{Query: Q(`suite:a:z:*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a:b:*`), Data: failure},
-				{Query: Q(`suite:a:z:*`), Data: pass},
-			},
-		},
-	} {
-		tree, err := NewTree(t, test.in...)
-		if err != nil {
-			t.Errorf("Test '%v':\nNewTree() returned %v", test.name, err)
-			continue
-		}
-		tree.Reduce(reducer)
-		results := tree.List()
-		if diff := cmp.Diff(results, test.expect); diff != "" {
-			t.Errorf("Test '%v':\n%v", test.name, diff)
-		}
-	}
-}
-
-func TestReduceUnder(t *testing.T) {
-	type QueryData = query.QueryData[string]
-
-	type Test struct {
-		location  string
-		to        query.Query
-		in        []QueryData
-		expect    []QueryData
-		expectErr error
-	}
-	for _, test := range []Test{
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			to:       Q(`suite:a,b,*`),
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			to:       Q(`suite:a,*`),
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,*`), Data: failure},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			to:       Q(`suite:*`),
-			in: []QueryData{
-				{Query: Q(`suite:a,b:*`), Data: failure},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:*`), Data: failure},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			to:       Q(`suite:a,*`),
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			to:       Q(`suite:a,*`),
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: pass},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			to:       Q(`suite:a`),
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: pass},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			to:       Q(`suite:x`),
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: pass},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: pass},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-			expectErr: query.ErrNoDataForQuery{
-				Query: Q(`suite:x`),
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			to:       Q(`suite:a,b,c,*`),
-			in: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: pass},
-			},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: pass},
-			},
-			expectErr: query.ErrNoDataForQuery{
-				Query: Q(`suite:a,b,c`),
-			},
-		},
-	} {
-		tree, err := NewTree(t, test.in...)
-		if err != nil {
-			t.Errorf("\n%v NewTree(): %v", test.location, err)
-			continue
-		}
-		err = tree.ReduceUnder(test.to, reducer)
-		if diff := cmp.Diff(err, test.expectErr); diff != "" {
-			t.Errorf("\n%v ReduceUnder(): %v", test.location, err)
-		}
-		results := tree.List()
-		if diff := cmp.Diff(results, test.expect); diff != "" {
-			t.Errorf("\n%v List(): %v", test.location, diff)
-		}
-	}
-}
-
-func TestReplace(t *testing.T) {
-	type QueryData = query.QueryData[string]
-
-	type Test struct {
-		name        string
-		base        []QueryData
-		replacement QueryData
-		expect      []QueryData
-		expectErr   error
-	}
-	for _, test := range []Test{
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Replace file. Direct",
-			base: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: failure},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-			replacement: QueryData{Q(`suite:a,b,*`), skip},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: skip},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Replace file. Indirect",
-			base: []QueryData{
-				{Query: Q(`suite:a,b,c,*`), Data: failure},
-				{Query: Q(`suite:a,b,d,*`), Data: pass},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-			replacement: QueryData{Q(`suite:a,b,*`), skip},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: skip},
-				{Query: Q(`suite:a,c,*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "File vs Test",
-			base: []QueryData{
-				{Query: Q(`suite:a,b:c,*`), Data: crash},
-				{Query: Q(`suite:a,b:d,*`), Data: abort},
-				{Query: Q(`suite:a,b,c,*`), Data: failure},
-				{Query: Q(`suite:a,b,d,*`), Data: pass},
-			},
-			replacement: QueryData{Q(`suite:a,b,*`), skip},
-			expect: []QueryData{
-				{Query: Q(`suite:a,b,*`), Data: skip},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Cases. * with *",
-			base: []QueryData{
-				{Query: Q(`suite:file:test:*`), Data: failure},
-			},
-			replacement: QueryData{Q(`suite:file:test:*`), pass},
-			expect: []QueryData{
-				{Query: Q(`suite:file:test:*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Cases. Mixed with *",
-			base: []QueryData{
-				{Query: Q(`suite:file:test:a=1,*`), Data: failure},
-				{Query: Q(`suite:file:test:a=2,*`), Data: skip},
-				{Query: Q(`suite:file:test:a=3,*`), Data: crash},
-			},
-			replacement: QueryData{Q(`suite:file:test:*`), pass},
-			expect: []QueryData{
-				{Query: Q(`suite:file:test:*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Cases. Replace partial - (a=1)",
-			base: []QueryData{
-				{Query: Q(`suite:file:test:a=1;b=x;*`), Data: failure},
-				{Query: Q(`suite:file:test:a=1;b=y;*`), Data: failure},
-				{Query: Q(`suite:file:test:a=2;b=y;*`), Data: failure},
-			},
-			replacement: QueryData{Q(`suite:file:test:a=1;*`), pass},
-			expect: []QueryData{
-				{Query: Q(`suite:file:test:a=1;*`), Data: pass},
-				{Query: Q(`suite:file:test:a=2;b=y;*`), Data: failure},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Cases. Replace partial - (b=y)",
-			base: []QueryData{
-				{Query: Q(`suite:file:test:a=1;b=x;*`), Data: failure},
-				{Query: Q(`suite:file:test:a=1;b=y;*`), Data: failure},
-				{Query: Q(`suite:file:test:a=2;b=y;*`), Data: failure},
-			},
-			replacement: QueryData{Q(`suite:file:test:b=y;*`), pass},
-			expect: []QueryData{
-				{Query: Q(`suite:file:test:a=1;b=x;*`), Data: failure},
-				{Query: Q(`suite:file:test:b=y;*`), Data: pass},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Error. No data for query - short",
-			base: []QueryData{
-				{Query: Q(`suite:file:test:a=1;b=x;*`), Data: failure},
-			},
-			replacement: QueryData{Q(`suite:missing:*`), pass},
-			expect: []QueryData{
-				{Query: Q(`suite:file:test:a=1;b=x;*`), Data: failure},
-			},
-			expectErr: query.ErrNoDataForQuery{Q(`suite:missing`)},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			name: "Error. No data for query - long",
-			base: []QueryData{
-				{Query: Q(`suite:file:test:*`), Data: failure},
-			},
-			replacement: QueryData{Q(`suite:file:test,missing,*`), pass},
-			expect: []QueryData{
-				{Query: Q(`suite:file:test:*`), Data: failure},
-			},
-			expectErr: query.ErrNoDataForQuery{Q(`suite:file:test,missing`)},
-		},
-	} {
-		tree, err := NewTree(t, test.base...)
-		if err != nil {
-			t.Errorf("Test '%v':\nNewTree(): %v", test.name, err)
-			continue
-		}
-		err = tree.Replace(test.replacement.Query, test.replacement.Data)
-		if diff := cmp.Diff(err, test.expectErr); diff != "" {
-			t.Errorf("Test '%v':\nReplace() error: %v", test.name, err)
-			continue
-		}
-		if diff := cmp.Diff(tree.List(), test.expect); diff != "" {
-			t.Errorf("Test '%v':\n%v", test.name, diff)
-		}
-	}
-}
-
 func TestGlob(t *testing.T) {
 	type QueryData = query.QueryData[string]
 
diff --git a/tools/src/cts/result/mvt.go b/tools/src/cts/result/mvt.go
deleted file mode 100644
index 32059a6..0000000
--- a/tools/src/cts/result/mvt.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2022 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-//    contributors may be used to endorse or promote products derived from
-//    this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package result
-
-import (
-	"sort"
-
-	"dawn.googlesource.com/dawn/tools/src/cts/query"
-)
-
-// MinimalVariantTags accepts a list of tag-sets (e.g GPU tags, OS tags, etc),
-// and returns an optimized list of variants, folding together variants that
-// have identical result query-to-status mappings, and removing redundant tags.
-//
-// MinimalVariantTags will attempt to remove variant tags starting with the
-// first set of tags in tagSets, then second, and so on. If a tag-set cannot
-// be removed, then the tags of the set are left alone, and the algorithm will
-// progress to the next tag-set.
-//
-// MinimalVariantTags assumes that there are no duplicate results (same query,
-// same tags) in l.
-func (l List) MinimalVariantTags(tagSets []Tags) []Variant {
-	type VariantData struct {
-		// The variant tags
-		tags Variant
-		// The query -> status for all results in l that have this variant's
-		// tags.
-		queryToStatus map[query.Query]Status
-	}
-
-	variants := []VariantData{}
-
-	// Build the initial list of variants from l.
-	// Bin result [query -> status] to the variant.
-	{
-		variantIndices := map[string]int{}
-		for _, r := range l {
-			key := TagsToString(r.Tags)
-			if idx, found := variantIndices[key]; !found {
-				variantIndices[key] = len(variants)
-				variants = append(variants, VariantData{
-					tags: Variant(r.Tags.Clone()),
-					queryToStatus: map[query.Query]Status{
-						r.Query: r.Status,
-					},
-				})
-			} else {
-				variants[idx].queryToStatus[r.Query] = r.Status
-			}
-		}
-	}
-
-	// canReduce checks that the variant would match the same results if the
-	// tags were reduced to 'tags'. Returns true if the variant's tags could
-	// be reduced, otherwise false.
-	canReduce := func(variant VariantData, tags Tags) bool {
-		for _, r := range l.FilterByTags(tags) {
-			existing, found := variant.queryToStatus[r.Query]
-			if !found {
-				// Removing the tag has expanded the set of queries.
-				return false
-			}
-			if existing != r.Status {
-				// Removing the tag has resulted in two queries with different
-				// results.
-				return false
-			}
-		}
-		return true
-	}
-
-	// tryToRemoveTags will remove all the tags in 'tags' from all variants
-	// iff doing so does not affect the set of results filtered by each variant.
-	// If it was possible to remove the tags, then variants that now have the
-	// same tags may be folded together, reducing the total number of variants.
-	tryToRemoveTags := func(tags Tags) {
-		newVariants := make([]VariantData, 0, len(variants))
-
-		for _, v := range variants {
-			// Does the variant even contain these tags?
-			if !v.tags.ContainsAny(tags) {
-				// Nope. Skip the canReduce() call, and keep the variant.
-				newVariants = append(newVariants, v)
-				continue
-			}
-
-			// Build the new set of tags with 'tags' removed.
-			newTags := v.tags.Clone()
-			newTags.RemoveAll(tags)
-
-			// Check wether removal of these tags affected the outcome.
-			if !canReduce(v, newTags) {
-				// Removing these tags resulted in differences.
-				return // Abort
-			}
-			newVariants = append(newVariants, VariantData{newTags, v.queryToStatus})
-		}
-
-		// Remove variants that are now subsets of others.
-		// Start by sorting the variants by number of tags.
-		// This ensures that the variants with fewer tags (fewer constraints)
-		// come first.
-		sort.Slice(newVariants, func(i, j int) bool {
-			return len(newVariants[i].tags) < len(newVariants[j].tags)
-		})
-
-		// Now check each variant's tags against the previous variant tags.
-		// As we've sorted, we know that supersets (fewer-tags) come before
-		// subsets (more-tags).
-		variants = []VariantData{}
-
-	nextVariant:
-		for i, v1 := range newVariants { // for variants 0..N
-			for _, v2 := range newVariants[:i] { // for variants 0..i
-				if v1.tags.ContainsAll(v2.tags) {
-					continue nextVariant // v1 is a subset of v2. Omit.
-				}
-			}
-			variants = append(variants, v1)
-		}
-	}
-
-	// Attempt to remove the tag sets from the variants, one by one.
-	for _, tags := range tagSets {
-		tryToRemoveTags(tags)
-	}
-
-	// Return the final set of unique variants
-	out := make([]Variant, len(variants))
-	for i, v := range variants {
-		out[i] = v.tags
-	}
-	return out
-}
diff --git a/tools/src/cts/result/mvt_test.go b/tools/src/cts/result/mvt_test.go
deleted file mode 100644
index d1df908..0000000
--- a/tools/src/cts/result/mvt_test.go
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2022 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-//    contributors may be used to endorse or promote products derived from
-//    this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package result_test
-
-import (
-	"fmt"
-	"testing"
-
-	"dawn.googlesource.com/dawn/tools/src/cts/result"
-	"dawn.googlesource.com/dawn/tools/src/fileutils"
-	"github.com/google/go-cmp/cmp"
-)
-
-func TestMinimalVariantTags(t *testing.T) {
-	type Test struct {
-		location string
-		results  result.List
-		expect   []result.Variant
-	}
-	for _, test := range []Test{
-		{ //////////////////////////////////////////////////////////////////////
-			location: fileutils.ThisLine(),
-			results:  result.List{},
-			expect:   []result.Variant{},
-		}, { ///////////////////////////////////////////////////////////////////
-			// Single variant, that can be entirely optimized away
-			location: fileutils.ThisLine(),
-			results: result.List{
-				{Query: Q("a:b,c:d,*"), Tags: T("a0", "b1", "c2"), Status: result.Pass},
-			},
-			expect: []result.Variant{T()},
-		}, { ///////////////////////////////////////////////////////////////////
-			// Multiple variants on the same query.
-			// Can also be entirely optimized away.
-			location: fileutils.ThisLine(),
-			results: result.List{
-				{Query: Q("a:b,c:d,*"), Tags: T("a0", "b1", "c2"), Status: result.Pass},
-				{Query: Q("a:b,c:d,*"), Tags: T("a1", "b2", "c0"), Status: result.Pass},
-				{Query: Q("a:b,c:d,*"), Tags: T("a2", "b1", "c0"), Status: result.Pass},
-			},
-			expect: []result.Variant{T()},
-		}, { ///////////////////////////////////////////////////////////////////
-			// Two variants where the 1st and 2nd tag-sets are redundant.
-			location: fileutils.ThisLine(),
-			results: result.List{
-				{Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass},
-				{Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure},
-			},
-			expect: []result.Variant{T("c0"), T("c1")},
-		}, { ///////////////////////////////////////////////////////////////////
-			// Two variants where the 1st and 3rd tag-sets are redundant.
-			location: fileutils.ThisLine(),
-			results: result.List{
-				{Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass},
-				{Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure},
-				{Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c1"), Status: result.Pass},
-				{Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c0"), Status: result.Failure},
-			},
-			expect: []result.Variant{T("b0"), T("b1")},
-		}, { ///////////////////////////////////////////////////////////////////
-			// Two variants where the 2nd and 3rd tag-sets are redundant.
-			location: fileutils.ThisLine(),
-			results: result.List{
-				{Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass},
-				{Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure},
-				{Query: Q("a:b,c:d,*"), Tags: T("a0", "b1", "c1"), Status: result.Pass},
-				{Query: Q("a:b,c:d,*"), Tags: T("a1", "b0", "c0"), Status: result.Failure},
-			},
-			expect: []result.Variant{T("a0"), T("a1")},
-		}, { ///////////////////////////////////////////////////////////////////
-			// Check that variants aren't optimized to expand the set of results
-			// they target, even if results are uniform
-			location: fileutils.ThisLine(),
-			results: result.List{
-				{Query: Q("a:b,c:d0,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass},
-				{Query: Q("a:b,c:d1,*"), Tags: T("a1", "b1", "c1"), Status: result.Pass},
-			},
-			expect: []result.Variant{T("c0"), T("c1")},
-		}, { ///////////////////////////////////////////////////////////////////
-			// Exercise the optimizations to skip checks on tag removals that
-			// aren't found in all variants
-			location: fileutils.ThisLine(),
-			results: result.List{
-				{Query: Q("a:b,c:d0,*"), Tags: T("a0"), Status: result.Pass},
-				{Query: Q("a:b,c:d1,*"), Tags: T("b0"), Status: result.Pass},
-				{Query: Q("a:b,c:d2,*"), Tags: T("c0"), Status: result.Pass},
-			},
-			expect: []result.Variant{T("a0"), T("b0"), T("c0")},
-		},
-	} {
-		preReduce := fmt.Sprint(test.results)
-		got := test.results.MinimalVariantTags([]result.Tags{
-			T("a0", "a1", "a2"),
-			T("b0", "b1", "b2"),
-			T("c0", "c1", "c2"),
-		})
-		postReduce := fmt.Sprint(test.results)
-		if diff := cmp.Diff(got, test.expect); diff != "" {
-			t.Errorf("%v MinimalVariantTags() diff:\n%v", test.location, diff)
-		}
-		if diff := cmp.Diff(preReduce, postReduce); diff != "" {
-			t.Errorf("%v MinimalVariantTags() modified original list:\n%v", test.location, diff)
-		}
-	}
-}
diff --git a/tools/src/cts/result/result.go b/tools/src/cts/result/result.go
index 9f24b9b..a3a9c7d 100644
--- a/tools/src/cts/result/result.go
+++ b/tools/src/cts/result/result.go
@@ -186,19 +186,6 @@
 // Lists of test results by execution mode.
 type ResultsByExecutionMode map[ExecutionMode]List
 
-// Variant is a collection of tags that uniquely identify a test
-// configuration (e.g the combination of OS, GPU, validation-modes, etc).
-type Variant = Tags
-
-// Variants returns the list of unique tags (variants) across all results.
-func (l List) Variants() []Variant {
-	tags := container.NewMap[string, Variant]()
-	for _, r := range l {
-		tags.Add(TagsToString(r.Tags), r.Tags)
-	}
-	return tags.Values()
-}
-
 // TransformTags returns the list of results with the tags transformed using f.
 // TransformTags assumes that f will return the same output for the same input.
 func (l List) TransformTags(f func(Tags) Tags) List {
@@ -328,14 +315,6 @@
 	})
 }
 
-// FilterByVariant returns the results that exactly match the given tags
-func (l List) FilterByVariant(tags Tags) List {
-	str := TagsToString(tags)
-	return l.Filter(func(r Result) bool {
-		return len(r.Tags) == len(tags) && TagsToString(r.Tags) == str
-	})
-}
-
 // FilterByQuery returns the results that match the given query
 func (l List) FilterByQuery(q query.Query) List {
 	return l.Filter(func(r Result) bool {
@@ -358,21 +337,6 @@
 	return set
 }
 
-// StatusTree is a query tree of statuses
-type StatusTree = query.Tree[Status]
-
-// StatusTree returns a query.Tree from the List, with the Status as the tree
-// node data.
-func (l List) StatusTree() (StatusTree, error) {
-	tree := StatusTree{}
-	for _, r := range l {
-		if err := tree.Add(r.Query, r.Status); err != nil {
-			return StatusTree{}, err
-		}
-	}
-	return tree, nil
-}
-
 // Load loads the result list from the file with the given path
 func Load(path string) (ResultsByExecutionMode, error) {
 	file, err := os.Open(path)
diff --git a/tools/src/cts/result/result_test.go b/tools/src/cts/result/result_test.go
index 28b7007..456348f 100644
--- a/tools/src/cts/result/result_test.go
+++ b/tools/src/cts/result/result_test.go
@@ -116,120 +116,6 @@
 	}
 }
 
-func TestVariants(t *testing.T) {
-	type Test struct {
-		results result.List
-		expect  []result.Tags
-	}
-	for _, test := range []Test{
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags(),
-				},
-			},
-			expect: []result.Tags{
-				result.NewTags(),
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x"),
-				},
-			},
-			expect: []result.Tags{
-				result.NewTags("x"),
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-			},
-			expect: []result.Tags{
-				result.NewTags("x", "y"),
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-				result.Result{
-					Query:  Q(`b`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-			},
-			expect: []result.Tags{
-				result.NewTags("x", "y"),
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-				result.Result{
-					Query:  Q(`b`),
-					Status: result.Pass,
-					Tags:   result.NewTags("y", "z"),
-				},
-			},
-			expect: []result.Tags{
-				result.NewTags("x", "y"),
-				result.NewTags("y", "z"),
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-				result.Result{
-					Query:  Q(`b`),
-					Status: result.Pass,
-					Tags:   result.NewTags("y", "z"),
-				},
-				result.Result{
-					Query:  Q(`c`),
-					Status: result.Pass,
-					Tags:   result.NewTags("z", "x"),
-				},
-				result.Result{
-					Query:  Q(`d`),
-					Status: result.Pass,
-					Tags:   result.NewTags("y", "z"),
-				},
-			},
-			expect: []result.Tags{
-				result.NewTags("x", "y"),
-				result.NewTags("x", "z"),
-				result.NewTags("y", "z"),
-			},
-		},
-	} {
-		got := test.results.Variants()
-		if diff := cmp.Diff(got, test.expect); diff != "" {
-			t.Errorf("Results:\n%v\nUniqueTags() was not as expected:\n%v", test.results, diff)
-		}
-	}
-}
-
 func TestTransformTags(t *testing.T) {
 	type Test struct {
 		results   result.List
@@ -832,96 +718,6 @@
 	}
 }
 
-func TestFilterByVariant(t *testing.T) {
-	type Test struct {
-		results result.List
-		tags    result.Tags
-		expect  result.List
-	}
-	for _, test := range []Test{
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x"),
-				},
-				result.Result{
-					Query:  Q(`b`),
-					Status: result.Failure,
-					Tags:   result.NewTags("y"),
-				},
-				result.Result{
-					Query:  Q(`c`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-			},
-			tags: result.NewTags("x", "y"),
-			expect: result.List{
-				result.Result{
-					Query:  Q(`c`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x"),
-				},
-				result.Result{
-					Query:  Q(`b`),
-					Status: result.Failure,
-					Tags:   result.NewTags("y"),
-				},
-				result.Result{
-					Query:  Q(`c`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-			},
-			tags: result.NewTags("x"),
-			expect: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x"),
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				result.Result{
-					Query:  Q(`a`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x"),
-				},
-				result.Result{
-					Query:  Q(`b`),
-					Status: result.Failure,
-					Tags:   result.NewTags("y"),
-				},
-				result.Result{
-					Query:  Q(`c`),
-					Status: result.Pass,
-					Tags:   result.NewTags("x", "y"),
-				},
-			},
-			tags:   result.NewTags("q"),
-			expect: result.List{},
-		},
-	} {
-		got := test.results.FilterByVariant(test.tags)
-		if diff := cmp.Diff(got, test.expect); diff != "" {
-			t.Errorf("Results:\n%v\nFilterByVariant(%v) was not as expected:\n%v", test.results, test.tags, diff)
-		}
-	}
-}
-
 func TestStatuses(t *testing.T) {
 	type Test struct {
 		results result.List
@@ -992,67 +788,6 @@
 	}
 }
 
-func TestStatusTree(t *testing.T) {
-	type Node = query.TreeNode[result.Status]
-	type Children = query.TreeNodeChildren[result.Status]
-	type ChildKey = query.TreeNodeChildKey
-
-	pass := result.Pass
-
-	type Test struct {
-		results   result.List
-		expectErr error
-		expect    result.StatusTree
-	}
-	for _, test := range []Test{
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{},
-			expect:  result.StatusTree{},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				{Query: Q(`suite:a:*`), Status: result.Pass},
-			},
-			expect: result.StatusTree{
-				TreeNode: Node{
-					Children: Children{
-						ChildKey{Name: `suite`, Target: query.Suite}: &Node{
-							Query: Q(`suite`),
-							Children: Children{
-								ChildKey{Name: `a`, Target: query.Files}: &Node{
-									Query: Q(`suite:a`),
-									Children: Children{
-										ChildKey{Name: `*`, Target: query.Tests}: &Node{
-											Query: Q(`suite:a:*`),
-											Data:  &pass,
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{ //////////////////////////////////////////////////////////////////////
-			results: result.List{
-				{Query: Q(`suite:a:*`), Status: result.Pass},
-				{Query: Q(`suite:a:*`), Status: result.Failure},
-			},
-			expectErr: query.ErrDuplicateData{Query: Q(`suite:a:*`)},
-		},
-	} {
-		got, err := test.results.StatusTree()
-		if diff := cmp.Diff(err, test.expectErr); diff != "" {
-			t.Errorf("Results:\n%v\nStatusTree() error was not as expected:\n%v", test.results, diff)
-			continue
-		}
-		if diff := cmp.Diff(got, test.expect); diff != "" {
-			t.Errorf("Results:\n%v\nStatusTree() was not as expected:\n%v", test.results, diff)
-		}
-	}
-}
-
 func TestReadWrite(t *testing.T) {
 	in := result.ResultsByExecutionMode{
 		"bar": result.List{