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 }