github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/api/query/cache/index/aggregator.go (about)

     1  // Copyright 2018 The WPT Dashboard Project. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  package index
     6  
     7  import (
     8  	"github.com/web-platform-tests/wpt.fyi/api/query"
     9  	"github.com/web-platform-tests/wpt.fyi/shared"
    10  )
    11  
    12  type aggregator interface {
    13  	Add(t TestID) error
    14  	Done() []shared.SearchResult
    15  }
    16  
    17  type indexAggregator struct {
    18  	index
    19  
    20  	runIDs []RunID
    21  	agg    map[uint64]shared.SearchResult
    22  	opts   query.AggregationOpts
    23  }
    24  
    25  // nolint:gocognit // TODO: Fix gocognit lint error
    26  func (a *indexAggregator) Add(t TestID) error {
    27  	id := t.testID
    28  	ts := a.tests
    29  	r, ok := a.agg[id]
    30  	if !ok {
    31  		name, _, err := ts.GetName(t)
    32  		if err != nil {
    33  			return err
    34  		}
    35  
    36  		// nolint:exhaustruct // Not required since missing field has omitempty.
    37  		r = shared.SearchResult{
    38  			Test:         name,
    39  			LegacyStatus: nil,
    40  			Interop:      nil,
    41  			Diff:         nil,
    42  		}
    43  	}
    44  
    45  	if a.opts.IgnoreTestHarnessResult {
    46  		for _, id := range a.runIDs {
    47  			res := shared.TestStatus(a.runResults[id].GetResult(t))
    48  			if res.IsHarnessStatus() {
    49  				return nil
    50  			}
    51  		}
    52  	}
    53  
    54  	if a.opts.InteropFormat {
    55  		if r.Interop == nil {
    56  			r.Interop = make([]int, len(a.runIDs)+1)
    57  		}
    58  		passing := 0
    59  		for _, id := range a.runIDs {
    60  			res := shared.TestStatus(a.runResults[id].GetResult(t))
    61  			if res.IsPassOrOK() {
    62  				passing++
    63  			}
    64  		}
    65  		r.Interop[passing]++
    66  	}
    67  
    68  	results := r.LegacyStatus
    69  	if results == nil {
    70  		results = make([]shared.LegacySearchRunResult, len(a.runIDs))
    71  	}
    72  
    73  	for i, id := range a.runIDs {
    74  		res := shared.TestStatus(a.runResults[id].GetResult(t))
    75  		// nolint:godox // TODO: Switch to a consistent value for Total across all runs.
    76  		// Only include tests with non-UNKNOWN status for this run's total.
    77  		if res != shared.TestStatusUnknown {
    78  			results[i].NewAggProcess = true
    79  			// If we see a Harness "OK", we mark that we have seen one
    80  			// rather than adding it to the subtest total.
    81  			if res.IsHarnessStatus() {
    82  				results[i].Status = "O"
    83  			} else if res.IsPass() {
    84  				results[i].Total++
    85  				results[i].Passes++
    86  			} else {
    87  				results[i].Total++
    88  			}
    89  		}
    90  	}
    91  	if a.opts.IncludeSubtests {
    92  		if _, subtest, err := ts.GetName(t); err == nil && subtest != nil {
    93  			name := *subtest
    94  			r.Subtests = append(r.Subtests, name)
    95  		}
    96  	}
    97  	if a.opts.IncludeDiff && len(a.runIDs) == 2 {
    98  		if r.Diff == nil {
    99  			r.Diff = shared.TestDiff{0, 0, 0}
   100  		}
   101  		r.Diff.Append(
   102  			shared.TestStatus(a.runResults[a.runIDs[0]].GetResult(t)),
   103  			shared.TestStatus(a.runResults[a.runIDs[1]].GetResult(t)),
   104  			&a.opts.DiffFilter)
   105  	}
   106  	r.LegacyStatus = results
   107  	a.agg[id] = r
   108  
   109  	return nil
   110  }
   111  
   112  func (a *indexAggregator) Done() []shared.SearchResult {
   113  	res := make([]shared.SearchResult, 0, len(a.agg))
   114  	for _, r := range a.agg {
   115  		res = append(res, r)
   116  	}
   117  
   118  	return res
   119  }
   120  
   121  // nolint:ireturn // TODO: Fix ireturn lint error
   122  func newIndexAggregator(idx index, runIDs []RunID, opts query.AggregationOpts) aggregator {
   123  	return &indexAggregator{
   124  		index:  idx,
   125  		runIDs: runIDs,
   126  		agg:    make(map[uint64]shared.SearchResult),
   127  		opts:   opts,
   128  	}
   129  }