github.com/jgbaldwinbrown/perf@v0.1.1/benchproc/filter_test.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package benchproc
     6  
     7  import (
     8  	"fmt"
     9  	"testing"
    10  
    11  	"golang.org/x/perf/benchfmt"
    12  )
    13  
    14  func TestFilter(t *testing.T) {
    15  	res := r(t, "Name/n1=v3", "f1", "v1", "f2", "v2")
    16  	res.Values = []benchfmt.Value{
    17  		{100, "ns/op", 100e-9, "sec/op"},
    18  		{100, "B/op", 0, ""},
    19  	}
    20  	const ALL = 0b11
    21  	const NONE = 0
    22  
    23  	check := func(t *testing.T, query string, want uint) {
    24  		t.Helper()
    25  		f, err := NewFilter(query)
    26  		if err != nil {
    27  			t.Fatal(err)
    28  		}
    29  		m, _ := f.Match(res)
    30  		var got uint
    31  		for i := 0; i < 2; i++ {
    32  			if m.Test(i) {
    33  				got |= 1 << i
    34  			}
    35  		}
    36  		if got != want {
    37  			t.Errorf("%s: got %02b, want %02b", query, got, want)
    38  		} else if want == ALL && !m.All() {
    39  			t.Errorf("%s: want All", query)
    40  		} else if want == 0 && m.Any() {
    41  			t.Errorf("%s: want !Any", query)
    42  		}
    43  	}
    44  
    45  	t.Run("basic", func(t *testing.T) {
    46  		// File keys
    47  		check(t, "f1:v1", ALL)
    48  		check(t, "f1:v2", NONE)
    49  		// Name keys
    50  		check(t, "/n1:v3", ALL)
    51  		// Special keys
    52  		check(t, ".name:Name", ALL)
    53  		check(t, ".fullname:Name/n1=v3", ALL)
    54  	})
    55  
    56  	t.Run("units", func(t *testing.T) {
    57  		check(t, ".unit:ns/op", 0b01)  // Base unit
    58  		check(t, ".unit:sec/op", 0b01) // Tidied unit
    59  		check(t, ".unit:B/op", 0b10)
    60  		check(t, ".unit:foo", 0b00)
    61  	})
    62  
    63  	t.Run("boolean", func(t *testing.T) {
    64  		check(t, "*", ALL)
    65  		check(t, "f1:v1 OR f1:v2", ALL)
    66  		check(t, "f1:v1 AND f1:v2", NONE)
    67  		check(t, "f1:v1 f1:v2", NONE)
    68  		check(t, "f1:v1 f2:v2", ALL)
    69  		check(t, "-f1:v1", NONE)
    70  		check(t, "--f1:v1", ALL)
    71  		check(t, ".unit:(ns/op OR B/op)", 0b11)
    72  	})
    73  
    74  	t.Run("manyUnits", func(t *testing.T) {
    75  		res := res.Clone()
    76  		res.Values = make([]benchfmt.Value, 100)
    77  		for i := range res.Values {
    78  			res.Values[i].Unit = fmt.Sprintf("u%d", i)
    79  		}
    80  		// Test large unit matches through all operators.
    81  		f, err := NewFilter("f1:v1 AND --(f1:v2 OR .unit:(u0 OR u99))")
    82  		if err != nil {
    83  			t.Fatal(err)
    84  		}
    85  		m, _ := f.Match(res)
    86  		for i := 0; i < 100; i++ {
    87  			got := m.Test(i)
    88  			want := i == 0 || i == 99
    89  			if got != want {
    90  				t.Errorf("for unit u%d, got %v, want %v", i, got, want)
    91  			}
    92  		}
    93  	})
    94  }
    95  
    96  func TestMatch(t *testing.T) {
    97  	check := func(m Match, all, any bool) {
    98  		t.Helper()
    99  		if m.All() != all {
   100  			t.Errorf("match %+v: All should be %v, got %v", m, all, !all)
   101  		}
   102  		if m.Any() != any {
   103  			t.Errorf("match %+v: Any should be %v, got %v", m, any, !any)
   104  		}
   105  		if m.Test(-1) {
   106  			t.Errorf("match %+v: Test(-1) should be false, got true", m)
   107  		}
   108  		if m.Test(m.n + 1) {
   109  			t.Errorf("match %+v: Test(%v) should be false, got true", m, m.n+1)
   110  		}
   111  	}
   112  
   113  	// Check nil mask.
   114  	m := Match{n: 4, x: false}
   115  	check(m, false, false)
   116  	m = Match{n: 4, x: true}
   117  	check(m, true, true)
   118  
   119  	// Check mask with some bits set.
   120  	m = Match{n: 4, m: []uint32{0x1}}
   121  	check(m, false, true)
   122  	m = Match{n: 1, m: []uint32{0x1}}
   123  	check(m, true, true)
   124  
   125  	// Check that we ignore zeroed bits above n.
   126  	m = Match{n: 4, m: []uint32{0xf}}
   127  	check(m, true, true)
   128  
   129  	// Check that we ignore set bits above n.
   130  	m = Match{n: 4, m: []uint32{0xfffffff0}}
   131  	check(m, false, false)
   132  }