blob: 28b7007c8f97edeafe1a9ff22b5810a221c14926 [file] [log] [blame]
// 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 (
"bytes"
"testing"
"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/fileutils"
"github.com/google/go-cmp/cmp"
)
var Q = query.Parse
func T(tags ...string) result.Tags {
return result.NewTags(tags...)
}
func TestStringAndParse(t *testing.T) {
type Test struct {
result result.Result
expect string
}
for _, test := range []Test{
{
result.Result{
Query: Q(`a`),
Status: result.Failure,
Duration: time.Second * 42,
MayExonerate: false,
},
`a Failure 42s false`,
}, {
result.Result{
Query: Q(`a:b,c,*`),
Tags: T("x"),
Status: result.Pass,
Duration: time.Second * 42,
MayExonerate: true,
},
`a:b,c,* x Pass 42s true`,
},
{
result.Result{
Query: Q(`a:b,c:d,*`),
Tags: T("zzz", "x", "yy"),
Status: result.Failure,
Duration: time.Second * 42,
MayExonerate: false,
},
`a:b,c:d,* x,yy,zzz Failure 42s false`,
},
} {
if diff := cmp.Diff(test.result.String(), test.expect); diff != "" {
t.Errorf("'%v'.String() was not as expected:\n%v", test.result, diff)
continue
}
_, parsed, err := result.Parse(test.expect)
if err != nil {
t.Errorf("Parse('%v') returned %v", test.expect, err)
continue
}
if diff := cmp.Diff(parsed, test.result); diff != "" {
t.Errorf("Parse('%v') was not as expected:\n%v", test.expect, diff)
}
}
}
func TestParseError(t *testing.T) {
for _, test := range []struct {
in, expect string
}{
{``, `unable to parse result ''`},
{`a b`, `unable to parse result 'a b'`},
{`a b c d e`, `unable to parse result 'a b c d e': time: invalid duration "d"`},
{`a b c 10s e`, `unable to parse result 'a b c 10s e': strconv.ParseBool: parsing "e": invalid syntax`},
} {
_, _, err := result.Parse(test.in)
got := ""
if err != nil {
got = err.Error()
}
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("Parse('%v'): %v", test, diff)
continue
}
}
}
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
transform func(result.Tags) result.Tags
expect result.List
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags(),
},
},
transform: func(t result.Tags) result.Tags { return t },
expect: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags(),
},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("x"),
},
},
transform: func(got result.Tags) result.Tags {
expect := result.NewTags("x")
if diff := cmp.Diff(got, expect); diff != "" {
t.Errorf("transform function's parameter was not as expected:\n%v", diff)
}
return got
},
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", "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"),
},
},
transform: func(l result.Tags) result.Tags {
l = l.Clone()
if l.Contains("x") {
l.Remove("x")
l.Add("X")
}
return l
},
expect: 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"),
},
},
},
} {
got := test.results.TransformTags(test.transform)
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("Results:\n%v\nTransformTags() was not as expected:\n%v", test.results, diff)
}
}
}
func TestReplaceDuplicates(t *testing.T) {
type Test struct {
location string
results result.List
fn func(result.Statuses) result.Status
expect result.List
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass, Duration: 1},
},
fn: func(result.Statuses) result.Status {
return result.Abort
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass, Duration: 1},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass, Duration: 1},
result.Result{Query: Q(`a`), Status: result.Pass, Duration: 3},
},
fn: func(result.Statuses) result.Status {
return result.Abort
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass, Duration: 2},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Pass},
},
fn: func(result.Statuses) result.Status {
return result.Abort
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Pass},
result.Result{Query: Q(`a`), Status: result.Skip},
},
fn: func(got result.Statuses) result.Status {
expect := result.NewStatuses(result.Pass, result.Skip)
if diff := cmp.Diff(got, expect); diff != "" {
t.Errorf("function's parameter was not as expected:\n%v", diff)
}
return result.Abort
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Abort},
result.Result{Query: Q(`b`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
results: result.List{
result.Result{Query: Q(`a`), Status: result.Failure, Duration: 1, MayExonerate: true},
result.Result{Query: Q(`a`), Status: result.Failure, Duration: 3, MayExonerate: true},
result.Result{Query: Q(`b`), Status: result.Failure, Duration: 1, MayExonerate: false},
result.Result{Query: Q(`b`), Status: result.Failure, Duration: 3, MayExonerate: false},
result.Result{Query: Q(`c`), Status: result.Pass, Duration: 1, MayExonerate: false},
result.Result{Query: Q(`c`), Status: result.Pass, Duration: 3, MayExonerate: false},
result.Result{Query: Q(`d`), Status: result.Failure, Duration: 1, MayExonerate: true},
result.Result{Query: Q(`d`), Status: result.Pass, Duration: 3, MayExonerate: false},
result.Result{Query: Q(`e`), Status: result.Failure, Duration: 1, MayExonerate: false},
result.Result{Query: Q(`e`), Status: result.Pass, Duration: 3, MayExonerate: true},
},
fn: func(result.Statuses) result.Status {
return result.Abort
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Failure, Duration: 2, MayExonerate: true},
result.Result{Query: Q(`b`), Status: result.Failure, Duration: 2, MayExonerate: false},
result.Result{Query: Q(`c`), Status: result.Pass, Duration: 2, MayExonerate: false},
result.Result{Query: Q(`d`), Status: result.Pass, Duration: 3, MayExonerate: false},
result.Result{Query: Q(`e`), Status: result.Failure, Duration: 1, MayExonerate: false},
},
},
} {
got := test.results.ReplaceDuplicates(test.fn)
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("\n%v ReplaceDuplicates() was not as expected:\n%v", test.location, diff)
}
}
}
func TestSort(t *testing.T) {
type Test struct {
results result.List
expect result.List
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Pass},
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`b`), Status: result.Pass},
result.Result{Query: Q(`a`), Status: result.Pass},
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`a`), Status: result.Skip},
},
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`a`), Status: result.Skip},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Skip,
Tags: result.NewTags(),
},
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags(),
},
},
expect: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags(),
},
result.Result{
Query: Q(`a`),
Status: result.Skip,
Tags: result.NewTags(),
},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("a"),
},
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("b"),
},
},
expect: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("a"),
},
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("b"),
},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("b"),
},
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("a"),
},
},
expect: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("a"),
},
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("b"),
},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`c`),
Status: result.RetryOnFailure,
Tags: result.NewTags("z"),
},
result.Result{
Query: Q(`a`),
Status: result.Crash,
Tags: result.NewTags("y"),
},
result.Result{
Query: Q(`b`),
Status: result.Slow,
Tags: result.NewTags("y"),
},
result.Result{
Query: Q(`b`),
Status: result.Skip,
Tags: result.NewTags("y"),
},
result.Result{
Query: Q(`a`),
Status: result.Crash,
Tags: result.NewTags("x"),
},
result.Result{
Query: Q(`aa`),
Status: result.Crash,
Tags: result.NewTags("x"),
},
result.Result{
Query: Q(`c`),
Status: result.Abort,
Tags: result.NewTags("z"),
},
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("x"),
},
},
expect: result.List{
result.Result{
Query: Q(`a`),
Status: result.Crash,
Tags: result.NewTags("x"),
},
result.Result{
Query: Q(`a`),
Status: result.Pass,
Tags: result.NewTags("x"),
},
result.Result{
Query: Q(`a`),
Status: result.Crash,
Tags: result.NewTags("y"),
},
result.Result{
Query: Q(`aa`),
Status: result.Crash,
Tags: result.NewTags("x"),
},
result.Result{
Query: Q(`b`),
Status: result.Skip,
Tags: result.NewTags("y"),
},
result.Result{
Query: Q(`b`),
Status: result.Slow,
Tags: result.NewTags("y"),
},
result.Result{
Query: Q(`c`),
Status: result.Abort,
Tags: result.NewTags("z"),
},
result.Result{
Query: Q(`c`),
Status: result.RetryOnFailure,
Tags: result.NewTags("z"),
},
},
},
} {
got := make(result.List, len(test.results))
copy(got, test.results)
got.Sort()
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("Results:\n%v\nSort() was not as expected:\n%v", test.results, diff)
}
}
}
func TestFilter(t *testing.T) {
type Test struct {
results result.List
f func(result.Result) bool
expect result.List
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
},
f: func(result.Result) bool { return true },
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Failure},
},
f: func(r result.Result) bool { return r.Query == Q("b") },
expect: result.List{
result.Result{Query: Q(`b`), Status: result.Failure},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Skip},
result.Result{Query: Q(`c`), Status: result.Pass},
},
f: func(r result.Result) bool { return r.Status == result.Pass },
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`c`), Status: result.Pass},
},
},
} {
got := test.results.Filter(test.f)
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("Results:\n%v\nFilter() was not as expected:\n%v", test.results, diff)
}
}
}
func TestFilterByStatus(t *testing.T) {
type Test struct {
results result.List
status result.Status
expect result.List
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Failure},
result.Result{Query: Q(`c`), Status: result.Pass},
},
status: result.Pass,
expect: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`c`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Failure},
},
status: result.Failure,
expect: result.List{
result.Result{Query: Q(`b`), Status: result.Failure},
},
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Failure},
},
status: result.RetryOnFailure,
expect: result.List{},
},
} {
got := test.results.FilterByStatus(test.status)
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("Results:\n%v\nFilterByStatus(%v) was not as expected:\n%v", test.results, test.status, diff)
}
}
}
func TestFilterByTags(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"),
},
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("q"),
expect: result.List{},
},
} {
got := test.results.FilterByTags(test.tags)
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("Results:\n%v\nFilterByTags(%v) was not as expected:\n%v", test.results, test.tags, diff)
}
}
}
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
expect container.Set[result.Status]
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
results: result.List{},
expect: container.NewSet[result.Status](),
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
},
},
expect: container.NewSet(result.Pass),
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
},
result.Result{
Query: Q(`b`),
Status: result.Pass,
},
},
expect: container.NewSet(result.Pass),
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
},
result.Result{
Query: Q(`b`),
Status: result.Skip,
},
},
expect: container.NewSet(result.Pass, result.Skip),
},
{ //////////////////////////////////////////////////////////////////////
results: result.List{
result.Result{
Query: Q(`a`),
Status: result.Pass,
},
result.Result{
Query: Q(`b`),
Status: result.Skip,
},
result.Result{
Query: Q(`c`),
Status: result.Failure,
},
},
expect: container.NewSet(result.Pass, result.Skip, result.Failure),
},
} {
got := test.results.Statuses()
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("Results:\n%v\nStatuses() was not as expected:\n%v", test.results, diff)
}
}
}
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{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:b,*`), Tags: T(`y`), Status: result.Failure},
{Query: Q(`suite:a:b:*`), Tags: T(`x`, `y`), Status: result.Skip},
{Query: Q(`suite:a:c,*`), Tags: T(`y`, `x`), Status: result.Failure},
{Query: Q(`suite:a,b:c,*`), Tags: T(`y`, `x`), Status: result.Crash},
{Query: Q(`suite:a,b:c:*`), Status: result.Slow},
},
"foo": result.List{
{Query: Q(`suite:d:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:e,*`), Tags: T(`y`), Status: result.Failure},
},
}
buf := &bytes.Buffer{}
if err := result.Write(buf, in); err != nil {
t.Fatalf("Write(): %v", err)
}
got, err := result.Read(buf)
if err != nil {
t.Fatalf("Read(): %v", err)
}
if diff := cmp.Diff(got, in); diff != "" {
t.Errorf("Read() was not as expected:\n%v", diff)
}
}
func TestMerge(t *testing.T) {
type Test struct {
location string
a, b result.List
expect result.List
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{},
b: result.List{},
expect: result.List{},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
b: result.List{},
expect: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{},
b: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
expect: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
b: result.List{
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
},
expect: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
},
b: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
expect: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
b: result.List{
{Query: Q(`suite:a:*`), Tags: T(`y`), Status: result.Pass},
},
expect: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:a:*`), Tags: T(`y`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{
{Query: Q(`suite:a:*`), Status: result.Pass},
},
b: result.List{
{Query: Q(`suite:a:*`), Status: result.Pass},
},
expect: result.List{
{Query: Q(`suite:a:*`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
b: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
expect: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Crash},
},
b: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Crash},
},
expect: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Crash},
},
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:c:*`), Tags: T(`x`), Status: result.Failure},
{Query: Q(`suite:d:*`), Tags: T(`x`), Status: result.Failure},
{Query: Q(`suite:e:*`), Tags: T(`x`), Status: result.Crash},
},
b: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Failure},
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:c:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:d:*`), Tags: T(`y`), Status: result.Pass},
{Query: Q(`suite:e:*`), Tags: T(`x`), Status: result.Pass},
},
expect: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.RetryOnFailure},
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:c:*`), Tags: T(`x`), Status: result.RetryOnFailure},
{Query: Q(`suite:d:*`), Tags: T(`x`), Status: result.Failure},
{Query: Q(`suite:d:*`), Tags: T(`y`), Status: result.Pass},
{Query: Q(`suite:e:*`), Tags: T(`x`), Status: result.Crash},
},
},
} {
got := result.Merge(test.a, test.b)
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("%v\nStatusTree() was not as expected:\n%v", test.location, diff)
}
}
}
func TestDeduplicate(t *testing.T) {
type Test struct {
location string
statuses result.Statuses
expect result.Status
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass),
expect: result.Pass,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Abort),
expect: result.Abort,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Failure),
expect: result.Failure,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Skip),
expect: result.Skip,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Crash),
expect: result.Crash,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Slow),
expect: result.Slow,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Unknown),
expect: result.Unknown,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.RetryOnFailure),
expect: result.RetryOnFailure,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Failure),
expect: result.RetryOnFailure,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Abort),
expect: result.Abort,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Skip),
expect: result.RetryOnFailure,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Crash),
expect: result.Crash,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Slow),
expect: result.RetryOnFailure,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Unknown),
expect: result.Unknown,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.RetryOnFailure),
expect: result.RetryOnFailure,
},
{ //////////////////////////////////////////////////////////////////////
location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Status("??"), result.Status("?!")),
expect: result.Unknown,
},
} {
got := result.Deduplicate(test.statuses)
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("\n%v Deduplicate() was not as expected:\n%v", test.location, diff)
}
}
}