github.com/aristanetworks/goarista@v0.0.0-20240514173732-cca2755bbd44/cmd/test2influxdb/main_test.go (about) 1 // Copyright (c) 2018 Arista Networks, Inc. 2 // Use of this source code is governed by the Apache License 2.0 3 // that can be found in the COPYING file. 4 5 package main 6 7 import ( 8 "os" 9 "testing" 10 "time" 11 12 "github.com/aristanetworks/goarista/test" 13 client "github.com/influxdata/influxdb1-client/v2" 14 ) 15 16 type mockedConn struct { 17 bp client.BatchPoints 18 } 19 20 func (m *mockedConn) Ping(timeout time.Duration) (time.Duration, string, error) { 21 return time.Duration(0), "", nil 22 } 23 24 func (m *mockedConn) Write(bp client.BatchPoints) error { 25 m.bp = bp 26 return nil 27 } 28 29 func (m *mockedConn) Query(q client.Query) (*client.Response, error) { 30 return nil, nil 31 } 32 33 func (m *mockedConn) QueryAsChunk(q client.Query) (*client.ChunkedResponse, error) { 34 return nil, nil 35 } 36 37 func (m *mockedConn) Close() error { 38 return nil 39 } 40 41 func newPoint(t *testing.T, measurement string, tags map[string]string, 42 fields map[string]interface{}, timeString string) *client.Point { 43 t.Helper() 44 timestamp, err := time.Parse(time.RFC3339Nano, timeString) 45 if err != nil { 46 t.Fatal(err) 47 } 48 p, err := client.NewPoint(measurement, tags, fields, timestamp) 49 if err != nil { 50 t.Fatal(err) 51 } 52 return p 53 } 54 55 func TestRunWithTestData(t *testing.T) { 56 // Verify tags and fields set by flags are set in records 57 flagTags.Set("tag=foo") 58 flagFields.Set("field=true") 59 defer func() { 60 flagTags = nil 61 flagFields = nil 62 }() 63 64 f, err := os.Open("testdata/output.txt") 65 if err != nil { 66 t.Fatal(err) 67 } 68 defer f.Close() 69 70 makeTags := func(pkg, resultType string) map[string]string { 71 return map[string]string{"package": pkg, "type": resultType, "tag": "foo"} 72 } 73 makeFields := func(pass, elapsed float64, test string) map[string]interface{} { 74 m := map[string]interface{}{"pass": pass, "elapsed": elapsed, "field": true} 75 if test != "" { 76 m["test"] = test 77 } 78 return m 79 } 80 81 expected := []*client.Point{ 82 newPoint(t, 83 "result", 84 makeTags("pkg/passed", "test"), 85 makeFields(1, 0, "TestPass"), 86 "2018-03-08T10:33:12.344165231-08:00", 87 ), 88 newPoint(t, 89 "result", 90 makeTags("pkg/passed", "package"), 91 makeFields(1, 0.013, ""), 92 "2018-03-08T10:33:12.34533033-08:00", 93 ), 94 newPoint(t, 95 "result", 96 makeTags("pkg/panic", "test"), 97 makeFields(0, 600.029, "TestPanic"), 98 "2018-03-08T10:33:20.272440286-08:00", 99 ), 100 newPoint(t, 101 "result", 102 makeTags("pkg/failed", "test"), 103 makeFields(0, 0.18, "TestFail"), 104 "2018-03-08T10:33:27.158860934-08:00", 105 ), 106 newPoint(t, 107 "result", 108 makeTags("pkg/failed", "package"), 109 makeFields(0, 0.204, ""), 110 "2018-03-08T10:33:27.161302093-08:00", 111 ), 112 newPoint(t, 113 "result", 114 makeTags("pkg/panic", "package"), 115 makeFields(0, 0, ""), 116 "2018-03-08T10:33:20.273440286-08:00", 117 ), 118 } 119 120 var mc mockedConn 121 if err := run(&mc, f); err != nil { 122 t.Fatal(err) 123 } 124 125 if diff := test.Diff(expected, mc.bp.Points()); diff != "" { 126 t.Errorf("unexpected diff: %s", diff) 127 } 128 } 129 130 func TestTagsFlag(t *testing.T) { 131 for tc, expected := range map[string]tags{ 132 "abc=def": tags{tag{key: "abc", value: "def"}}, 133 "abc=def,ghi=klm": tags{tag{key: "abc", value: "def"}, tag{key: "ghi", value: "klm"}}, 134 } { 135 t.Run(tc, func(t *testing.T) { 136 var ts tags 137 ts.Set(tc) 138 if diff := test.Diff(expected, ts); diff != "" { 139 t.Errorf("unexpected diff from Set: %s", diff) 140 } 141 142 if s := ts.String(); s != tc { 143 t.Errorf("unexpected diff from String: %q vs. %q", tc, s) 144 } 145 }) 146 } 147 } 148 149 func TestFieldsFlag(t *testing.T) { 150 for tc, expected := range map[string]fields{ 151 "str=abc": fields{field{key: "str", value: "abc"}}, 152 "bool=true": fields{field{key: "bool", value: true}}, 153 "bool=false": fields{field{key: "bool", value: false}}, 154 "float64=42": fields{field{key: "float64", value: float64(42)}}, 155 "float64=42.123": fields{field{key: "float64", value: float64(42.123)}}, 156 "int64=42i": fields{field{key: "int64", value: int64(42)}}, 157 "str=abc,bool=true,float64=42,int64=42i": fields{field{key: "str", value: "abc"}, 158 field{key: "bool", value: true}, 159 field{key: "float64", value: float64(42)}, 160 field{key: "int64", value: int64(42)}}, 161 } { 162 t.Run(tc, func(t *testing.T) { 163 var fs fields 164 fs.Set(tc) 165 if diff := test.Diff(expected, fs); diff != "" { 166 t.Errorf("unexpected diff from Set: %s", diff) 167 } 168 169 if s := fs.String(); s != tc { 170 t.Errorf("unexpected diff from String: %q vs. %q", tc, s) 171 } 172 }) 173 } 174 } 175 176 func TestRunWithBenchmarkData(t *testing.T) { 177 // Verify tags and fields set by flags are set in records 178 flagTags.Set("tag=foo") 179 flagFields.Set("field=true") 180 defaultMeasurement := *flagMeasurement 181 *flagMeasurement = "benchmarks" 182 *flagBenchOnly = true 183 defer func() { 184 flagTags = nil 185 flagFields = nil 186 *flagMeasurement = defaultMeasurement 187 *flagBenchOnly = false 188 }() 189 190 f, err := os.Open("testdata/bench-output.txt") 191 if err != nil { 192 t.Fatal(err) 193 } 194 defer f.Close() 195 196 makeTags := func(pkg, benchmark string) map[string]string { 197 return map[string]string{ 198 "package": pkg, 199 "benchmark": benchmark, 200 "tag": "foo", 201 } 202 } 203 makeFields := func(nsPerOp, mbPerS, bPerOp, allocsPerOp float64) map[string]interface{} { 204 m := map[string]interface{}{ 205 "field": true, 206 } 207 if nsPerOp > 0 { 208 m[fieldNsPerOp] = nsPerOp 209 } 210 if mbPerS > 0 { 211 m[fieldMBPerS] = mbPerS 212 } 213 if bPerOp > 0 { 214 m[fieldAllocedBytesPerOp] = bPerOp 215 } 216 if allocsPerOp > 0 { 217 m[fieldAllocsPerOp] = allocsPerOp 218 } 219 return m 220 } 221 222 expected := []*client.Point{ 223 newPoint(t, 224 "benchmarks", 225 makeTags("arista/pkg", "BenchmarkPassed-8"), 226 makeFields(127, 0, 16, 1), 227 "2018-11-08T15:53:12.935603594-08:00", 228 ), 229 newPoint(t, 230 "benchmarks", 231 makeTags("arista/pkg/subpkg1", "BenchmarkLogged-8"), 232 makeFields(120, 0, 16, 1), 233 "2018-11-08T15:53:14.359792815-08:00", 234 ), 235 newPoint(t, 236 "benchmarks", 237 makeTags("arista/pkg/subpkg2", "BenchmarkSetBytes-8"), 238 makeFields(120, 8.31, 16, 1), 239 "2018-11-08T15:53:15.717036333-08:00", 240 ), 241 newPoint(t, 242 "benchmarks", 243 makeTags("arista/pkg/subpkg3", "BenchmarkWithSubs/sub_1-8"), 244 makeFields(118, 0, 16, 1), 245 "2018-11-08T15:53:17.952644273-08:00", 246 ), 247 newPoint(t, 248 "benchmarks", 249 makeTags("arista/pkg/subpkg3", "BenchmarkWithSubs/sub_2-8"), 250 makeFields(117, 0, 16, 1), 251 "2018-11-08T15:53:20.443187742-08:00", 252 ), 253 } 254 255 var mc mockedConn 256 err = run(&mc, f) 257 switch err.(type) { 258 case duplicateTestsErr: 259 default: 260 t.Fatal(err) 261 } 262 263 // parseBenchmarkOutput arranges the data in maps so the generated points 264 // are in random order. Therefore, we're diffing as map instead of a slice 265 pointsAsMap := func(points []*client.Point) map[string]*client.Point { 266 m := make(map[string]*client.Point, len(points)) 267 for _, p := range points { 268 m[p.String()] = p 269 } 270 return m 271 } 272 expectedMap := pointsAsMap(expected) 273 actualMap := pointsAsMap(mc.bp.Points()) 274 if diff := test.Diff(expectedMap, actualMap); diff != "" { 275 t.Errorf("unexpected diff: %s\nexpected: %v\nactual: %v", diff, expectedMap, actualMap) 276 } 277 }