forked from adamlaska/boulder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathasserts.go
More file actions
199 lines (181 loc) · 5.92 KB
/
asserts.go
File metadata and controls
199 lines (181 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package test
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"reflect"
"strings"
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
io_prometheus_client "github.com/prometheus/client_model/go"
)
// Assert a boolean
func Assert(t *testing.T, result bool, message string) {
t.Helper()
if !result {
t.Fatal(message)
}
}
// AssertNotNil checks an object to be non-nil
func AssertNotNil(t *testing.T, obj interface{}, message string) {
t.Helper()
if obj == nil {
t.Fatal(message)
}
}
// AssertNotError checks that err is nil
func AssertNotError(t *testing.T, err error, message string) {
t.Helper()
if err != nil {
t.Fatalf("%s: %s", message, err)
}
}
// AssertError checks that err is non-nil
func AssertError(t *testing.T, err error, message string) {
t.Helper()
if err == nil {
t.Fatalf("%s: expected error but received none", message)
}
}
// AssertErrorWraps checks that err can be unwrapped into the given target.
// NOTE: Has the side effect of actually performing that unwrapping.
func AssertErrorWraps(t *testing.T, err error, target interface{}) {
t.Helper()
if !errors.As(err, target) {
t.Fatalf("error does not wrap an error of the expected type: %q !> %+T", err.Error(), target)
}
}
// AssertErrorIs checks that err wraps the given error
func AssertErrorIs(t *testing.T, err error, target error) {
t.Helper()
if !errors.Is(err, target) {
t.Fatalf("error does not wrap expected error: %q !> %q", err.Error(), target.Error())
}
}
// AssertEquals uses the equality operator (==) to measure one and two
func AssertEquals(t *testing.T, one interface{}, two interface{}) {
t.Helper()
if reflect.TypeOf(one) != reflect.TypeOf(two) {
t.Fatalf("cannot test equality of different types: %T != %T", one, two)
}
if one != two {
t.Fatalf("%#v != %#v", one, two)
}
}
// AssertDeepEquals uses the reflect.DeepEqual method to measure one and two
func AssertDeepEquals(t *testing.T, one interface{}, two interface{}) {
t.Helper()
if !reflect.DeepEqual(one, two) {
t.Fatalf("[%+v] !(deep)= [%+v]", one, two)
}
}
// AssertMarshaledEquals marshals one and two to JSON, and then uses
// the equality operator to measure them
func AssertMarshaledEquals(t *testing.T, one interface{}, two interface{}) {
t.Helper()
oneJSON, err := json.Marshal(one)
AssertNotError(t, err, "Could not marshal 1st argument")
twoJSON, err := json.Marshal(two)
AssertNotError(t, err, "Could not marshal 2nd argument")
if !bytes.Equal(oneJSON, twoJSON) {
t.Fatalf("[%s] !(json)= [%s]", oneJSON, twoJSON)
}
}
// AssertUnmarshaledEquals unmarshals two JSON strings (got and expected) to
// a map[string]interface{} and then uses reflect.DeepEqual to check they are
// the same
func AssertUnmarshaledEquals(t *testing.T, got, expected string) {
t.Helper()
var gotMap, expectedMap map[string]interface{}
err := json.Unmarshal([]byte(got), &gotMap)
AssertNotError(t, err, "Could not unmarshal 'got'")
err = json.Unmarshal([]byte(expected), &expectedMap)
AssertNotError(t, err, "Could not unmarshal 'expected'")
if len(gotMap) != len(expectedMap) {
t.Errorf("Expected had %d keys, got had %d", len(gotMap), len(expectedMap))
}
for k, v := range expectedMap {
if !reflect.DeepEqual(v, gotMap[k]) {
t.Errorf("Field %q: Expected \"%v\", got \"%v\"", k, v, gotMap[k])
}
}
}
// AssertNotEquals uses the equality operator to measure that one and two
// are different
func AssertNotEquals(t *testing.T, one interface{}, two interface{}) {
t.Helper()
if one == two {
t.Fatalf("%#v == %#v", one, two)
}
}
// AssertByteEquals uses bytes.Equal to measure one and two for equality.
func AssertByteEquals(t *testing.T, one []byte, two []byte) {
t.Helper()
if !bytes.Equal(one, two) {
t.Fatalf("Byte [%s] != [%s]",
base64.StdEncoding.EncodeToString(one),
base64.StdEncoding.EncodeToString(two))
}
}
// AssertContains determines whether needle can be found in haystack
func AssertContains(t *testing.T, haystack string, needle string) {
t.Helper()
if !strings.Contains(haystack, needle) {
t.Fatalf("String [%s] does not contain [%s]", haystack, needle)
}
}
// AssertNotContains determines if needle is not found in haystack
func AssertNotContains(t *testing.T, haystack string, needle string) {
t.Helper()
if strings.Contains(haystack, needle) {
t.Fatalf("String [%s] contains [%s]", haystack, needle)
}
}
// AssertMetricEquals determines whether the value held by a prometheus Collector
// (e.g. Gauge, Counter, CounterVec, etc) is equal to the expected integer.
// In order to make useful assertions about just a subset of labels (e.g. for a
// CounterVec with fields "host" and "valid", being able to assert that two
// "valid": "true" increments occurred, without caring which host was tagged in
// each), takes a set of labels and ignores any metrics which have different
// label values.
// Only works for simple metrics (Counters and Gauges), or for the *count*
// (not value) of data points in a Histogram.
func AssertMetricWithLabelsEquals(t *testing.T, c prometheus.Collector, l prometheus.Labels, expected float64) {
ch := make(chan prometheus.Metric)
done := make(chan struct{})
go func() {
c.Collect(ch)
close(done)
}()
var total float64
timeout := time.After(time.Second)
loop:
for {
metric:
select {
case <-timeout:
t.Fatal("timed out collecting metrics")
case <-done:
break loop
case m := <-ch:
var iom io_prometheus_client.Metric
_ = m.Write(&iom)
for _, lp := range iom.Label {
// If any of the labels on this metric have the same name as but
// different value than a label in `l`, skip this metric.
val, ok := l[lp.GetName()]
if ok && lp.GetValue() != val {
break metric
}
}
// Exactly one of the Counter, Gauge, or Histogram values will be set by
// the .Write() operation, so add them all because the others will be 0.
total += iom.Counter.GetValue()
total += iom.Gauge.GetValue()
total += float64(iom.Histogram.GetSampleCount())
}
}
AssertEquals(t, total, expected)
}