github.com/qxnw/lib4go@v0.0.0-20180426074627-c80c7e84b925/influxdb/v2/client_test.go (about) 1 package client 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "net/http/httptest" 8 "reflect" 9 "strings" 10 "sync" 11 "testing" 12 "time" 13 ) 14 15 func TestUDPClient_Query(t *testing.T) { 16 config := UDPConfig{Addr: "localhost:8089"} 17 c, err := NewUDPClient(config) 18 if err != nil { 19 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 20 } 21 defer c.Close() 22 query := Query{} 23 _, err = c.Query(query) 24 if err == nil { 25 t.Error("Querying UDP client should fail") 26 } 27 } 28 29 func TestUDPClient_Ping(t *testing.T) { 30 config := UDPConfig{Addr: "localhost:8089"} 31 c, err := NewUDPClient(config) 32 if err != nil { 33 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 34 } 35 defer c.Close() 36 37 rtt, version, err := c.Ping(0) 38 if rtt != 0 || version != "" || err != nil { 39 t.Errorf("unexpected error. expected (%v, '%v', %v), actual (%v, '%v', %v)", 0, "", nil, rtt, version, err) 40 } 41 } 42 43 func TestUDPClient_Write(t *testing.T) { 44 config := UDPConfig{Addr: "localhost:8089"} 45 c, err := NewUDPClient(config) 46 if err != nil { 47 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 48 } 49 defer c.Close() 50 51 bp, err := NewBatchPoints(BatchPointsConfig{}) 52 if err != nil { 53 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 54 } 55 56 fields := make(map[string]interface{}) 57 fields["value"] = 1.0 58 pt, _ := NewPoint("cpu", make(map[string]string), fields) 59 bp.AddPoint(pt) 60 61 err = c.Write(bp) 62 if err != nil { 63 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 64 } 65 } 66 67 func TestUDPClient_BadAddr(t *testing.T) { 68 config := UDPConfig{Addr: "foobar@wahoo"} 69 c, err := NewUDPClient(config) 70 if err == nil { 71 defer c.Close() 72 t.Error("Expected resolve error") 73 } 74 } 75 76 func TestUDPClient_Batches(t *testing.T) { 77 var logger writeLogger 78 var cl udpclient 79 80 cl.conn = &logger 81 cl.payloadSize = 20 // should allow for two points per batch 82 83 // expected point should look like this: "cpu a=1i" 84 fields := map[string]interface{}{"a": 1} 85 86 p, _ := NewPoint("cpu", nil, fields, time.Time{}) 87 88 bp, _ := NewBatchPoints(BatchPointsConfig{}) 89 90 for i := 0; i < 9; i++ { 91 bp.AddPoint(p) 92 } 93 94 if err := cl.Write(bp); err != nil { 95 t.Fatalf("Unexpected error during Write: %v", err) 96 } 97 98 if len(logger.writes) != 5 { 99 t.Errorf("Mismatched write count: got %v, exp %v", len(logger.writes), 5) 100 } 101 } 102 103 func TestUDPClient_Split(t *testing.T) { 104 var logger writeLogger 105 var cl udpclient 106 107 cl.conn = &logger 108 cl.payloadSize = 1 // force one field per point 109 110 fields := map[string]interface{}{"a": 1, "b": 2, "c": 3, "d": 4} 111 112 p, _ := NewPoint("cpu", nil, fields, time.Unix(1, 0)) 113 114 bp, _ := NewBatchPoints(BatchPointsConfig{}) 115 116 bp.AddPoint(p) 117 118 if err := cl.Write(bp); err != nil { 119 t.Fatalf("Unexpected error during Write: %v", err) 120 } 121 122 if len(logger.writes) != len(fields) { 123 t.Errorf("Mismatched write count: got %v, exp %v", len(logger.writes), len(fields)) 124 } 125 } 126 127 type writeLogger struct { 128 writes [][]byte 129 } 130 131 func (w *writeLogger) Write(b []byte) (int, error) { 132 w.writes = append(w.writes, append([]byte(nil), b...)) 133 return len(b), nil 134 } 135 136 func (w *writeLogger) Close() error { return nil } 137 138 func TestClient_Query(t *testing.T) { 139 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 140 var data Response 141 w.WriteHeader(http.StatusOK) 142 _ = json.NewEncoder(w).Encode(data) 143 })) 144 defer ts.Close() 145 146 config := HTTPConfig{Addr: ts.URL} 147 c, _ := NewHTTPClient(config) 148 defer c.Close() 149 150 query := Query{} 151 _, err := c.Query(query) 152 if err != nil { 153 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 154 } 155 } 156 157 func TestClient_ChunkedQuery(t *testing.T) { 158 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 159 var data Response 160 w.WriteHeader(http.StatusOK) 161 enc := json.NewEncoder(w) 162 _ = enc.Encode(data) 163 _ = enc.Encode(data) 164 })) 165 defer ts.Close() 166 167 config := HTTPConfig{Addr: ts.URL} 168 c, err := NewHTTPClient(config) 169 if err != nil { 170 t.Fatalf("unexpected error. expected %v, actual %v", nil, err) 171 } 172 173 query := Query{Chunked: true} 174 _, err = c.Query(query) 175 if err != nil { 176 t.Fatalf("unexpected error. expected %v, actual %v", nil, err) 177 } 178 } 179 180 func TestClient_BoundParameters(t *testing.T) { 181 var parameterString string 182 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 183 var data Response 184 r.ParseForm() 185 parameterString = r.FormValue("params") 186 w.WriteHeader(http.StatusOK) 187 _ = json.NewEncoder(w).Encode(data) 188 })) 189 defer ts.Close() 190 191 config := HTTPConfig{Addr: ts.URL} 192 c, _ := NewHTTPClient(config) 193 defer c.Close() 194 195 expectedParameters := map[string]interface{}{ 196 "testStringParameter": "testStringValue", 197 "testNumberParameter": 12.3, 198 } 199 200 query := Query{ 201 Parameters: expectedParameters, 202 } 203 204 _, err := c.Query(query) 205 if err != nil { 206 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 207 } 208 209 var actualParameters map[string]interface{} 210 211 err = json.Unmarshal([]byte(parameterString), &actualParameters) 212 if err != nil { 213 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 214 } 215 216 if !reflect.DeepEqual(expectedParameters, actualParameters) { 217 t.Errorf("unexpected parameters. expected %v, actual %v", expectedParameters, actualParameters) 218 } 219 } 220 221 func TestClient_BasicAuth(t *testing.T) { 222 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 223 u, p, ok := r.BasicAuth() 224 225 if !ok { 226 t.Errorf("basic auth error") 227 } 228 if u != "username" { 229 t.Errorf("unexpected username, expected %q, actual %q", "username", u) 230 } 231 if p != "password" { 232 t.Errorf("unexpected password, expected %q, actual %q", "password", p) 233 } 234 var data Response 235 w.WriteHeader(http.StatusOK) 236 _ = json.NewEncoder(w).Encode(data) 237 })) 238 defer ts.Close() 239 240 config := HTTPConfig{Addr: ts.URL, Username: "username", Password: "password"} 241 c, _ := NewHTTPClient(config) 242 defer c.Close() 243 244 query := Query{} 245 _, err := c.Query(query) 246 if err != nil { 247 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 248 } 249 } 250 251 func TestClient_Ping(t *testing.T) { 252 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 253 var data Response 254 w.WriteHeader(http.StatusNoContent) 255 _ = json.NewEncoder(w).Encode(data) 256 })) 257 defer ts.Close() 258 259 config := HTTPConfig{Addr: ts.URL} 260 c, _ := NewHTTPClient(config) 261 defer c.Close() 262 263 _, _, err := c.Ping(0) 264 if err != nil { 265 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 266 } 267 } 268 269 func TestClient_Concurrent_Use(t *testing.T) { 270 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 271 w.WriteHeader(http.StatusOK) 272 w.Write([]byte(`{}`)) 273 })) 274 defer ts.Close() 275 276 config := HTTPConfig{Addr: ts.URL} 277 c, _ := NewHTTPClient(config) 278 defer c.Close() 279 280 var wg sync.WaitGroup 281 wg.Add(3) 282 n := 1000 283 284 errC := make(chan error) 285 go func() { 286 defer wg.Done() 287 bp, err := NewBatchPoints(BatchPointsConfig{}) 288 if err != nil { 289 errC <- fmt.Errorf("got error %v", err) 290 return 291 } 292 293 for i := 0; i < n; i++ { 294 if err = c.Write(bp); err != nil { 295 errC <- fmt.Errorf("got error %v", err) 296 return 297 } 298 } 299 }() 300 301 go func() { 302 defer wg.Done() 303 var q Query 304 for i := 0; i < n; i++ { 305 if _, err := c.Query(q); err != nil { 306 errC <- fmt.Errorf("got error %v", err) 307 return 308 } 309 } 310 }() 311 312 go func() { 313 defer wg.Done() 314 for i := 0; i < n; i++ { 315 c.Ping(time.Second) 316 } 317 }() 318 319 go func() { 320 wg.Wait() 321 close(errC) 322 }() 323 324 for err := range errC { 325 if err != nil { 326 t.Error(err) 327 } 328 } 329 } 330 331 func TestClient_Write(t *testing.T) { 332 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 333 var data Response 334 w.WriteHeader(http.StatusNoContent) 335 _ = json.NewEncoder(w).Encode(data) 336 })) 337 defer ts.Close() 338 339 config := HTTPConfig{Addr: ts.URL} 340 c, _ := NewHTTPClient(config) 341 defer c.Close() 342 343 bp, err := NewBatchPoints(BatchPointsConfig{}) 344 if err != nil { 345 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 346 } 347 err = c.Write(bp) 348 if err != nil { 349 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 350 } 351 } 352 353 func TestClient_UserAgent(t *testing.T) { 354 receivedUserAgent := "" 355 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 356 receivedUserAgent = r.UserAgent() 357 358 var data Response 359 w.WriteHeader(http.StatusOK) 360 _ = json.NewEncoder(w).Encode(data) 361 })) 362 defer ts.Close() 363 364 _, err := http.Get(ts.URL) 365 if err != nil { 366 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 367 } 368 369 tests := []struct { 370 name string 371 userAgent string 372 expected string 373 }{ 374 { 375 name: "Empty user agent", 376 userAgent: "", 377 expected: "InfluxDBClient", 378 }, 379 { 380 name: "Custom user agent", 381 userAgent: "Test Influx Client", 382 expected: "Test Influx Client", 383 }, 384 } 385 386 for _, test := range tests { 387 388 config := HTTPConfig{Addr: ts.URL, UserAgent: test.userAgent} 389 c, _ := NewHTTPClient(config) 390 defer c.Close() 391 392 receivedUserAgent = "" 393 query := Query{} 394 _, err = c.Query(query) 395 if err != nil { 396 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 397 } 398 if !strings.HasPrefix(receivedUserAgent, test.expected) { 399 t.Errorf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent) 400 } 401 402 receivedUserAgent = "" 403 bp, _ := NewBatchPoints(BatchPointsConfig{}) 404 err = c.Write(bp) 405 if err != nil { 406 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 407 } 408 if !strings.HasPrefix(receivedUserAgent, test.expected) { 409 t.Errorf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent) 410 } 411 412 receivedUserAgent = "" 413 _, err := c.Query(query) 414 if err != nil { 415 t.Errorf("unexpected error. expected %v, actual %v", nil, err) 416 } 417 if receivedUserAgent != test.expected { 418 t.Errorf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent) 419 } 420 } 421 } 422 423 func TestClient_PointString(t *testing.T) { 424 const shortForm = "2006-Jan-02" 425 time1, _ := time.Parse(shortForm, "2013-Feb-03") 426 tags := map[string]string{"cpu": "cpu-total"} 427 fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0} 428 p, _ := NewPoint("cpu_usage", tags, fields, time1) 429 430 s := "cpu_usage,cpu=cpu-total idle=10.1,system=50.9,user=39 1359849600000000000" 431 if p.String() != s { 432 t.Errorf("Point String Error, got %s, expected %s", p.String(), s) 433 } 434 435 s = "cpu_usage,cpu=cpu-total idle=10.1,system=50.9,user=39 1359849600000" 436 if p.PrecisionString("ms") != s { 437 t.Errorf("Point String Error, got %s, expected %s", 438 p.PrecisionString("ms"), s) 439 } 440 } 441 442 func TestClient_PointWithoutTimeString(t *testing.T) { 443 tags := map[string]string{"cpu": "cpu-total"} 444 fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0} 445 p, _ := NewPoint("cpu_usage", tags, fields) 446 447 s := "cpu_usage,cpu=cpu-total idle=10.1,system=50.9,user=39" 448 if p.String() != s { 449 t.Errorf("Point String Error, got %s, expected %s", p.String(), s) 450 } 451 452 if p.PrecisionString("ms") != s { 453 t.Errorf("Point String Error, got %s, expected %s", 454 p.PrecisionString("ms"), s) 455 } 456 } 457 458 func TestClient_PointName(t *testing.T) { 459 tags := map[string]string{"cpu": "cpu-total"} 460 fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0} 461 p, _ := NewPoint("cpu_usage", tags, fields) 462 463 exp := "cpu_usage" 464 if p.Name() != exp { 465 t.Errorf("Error, got %s, expected %s", 466 p.Name(), exp) 467 } 468 } 469 470 func TestClient_PointTags(t *testing.T) { 471 tags := map[string]string{"cpu": "cpu-total"} 472 fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0} 473 p, _ := NewPoint("cpu_usage", tags, fields) 474 475 if !reflect.DeepEqual(tags, p.Tags()) { 476 t.Errorf("Error, got %v, expected %v", 477 p.Tags(), tags) 478 } 479 } 480 481 func TestClient_PointUnixNano(t *testing.T) { 482 const shortForm = "2006-Jan-02" 483 time1, _ := time.Parse(shortForm, "2013-Feb-03") 484 tags := map[string]string{"cpu": "cpu-total"} 485 fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0} 486 p, _ := NewPoint("cpu_usage", tags, fields, time1) 487 488 exp := int64(1359849600000000000) 489 if p.UnixNano() != exp { 490 t.Errorf("Error, got %d, expected %d", 491 p.UnixNano(), exp) 492 } 493 } 494 495 func TestClient_PointFields(t *testing.T) { 496 tags := map[string]string{"cpu": "cpu-total"} 497 fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0} 498 p, _ := NewPoint("cpu_usage", tags, fields) 499 500 pfields, err := p.Fields() 501 if err != nil { 502 t.Fatal(err) 503 } 504 if !reflect.DeepEqual(fields, pfields) { 505 t.Errorf("Error, got %v, expected %v", 506 pfields, fields) 507 } 508 } 509 510 func TestBatchPoints_PrecisionError(t *testing.T) { 511 _, err := NewBatchPoints(BatchPointsConfig{Precision: "foobar"}) 512 if err == nil { 513 t.Errorf("Precision: foobar should have errored") 514 } 515 516 bp, _ := NewBatchPoints(BatchPointsConfig{Precision: "ns"}) 517 err = bp.SetPrecision("foobar") 518 if err == nil { 519 t.Errorf("Precision: foobar should have errored") 520 } 521 } 522 523 func TestBatchPoints_SettersGetters(t *testing.T) { 524 bp, _ := NewBatchPoints(BatchPointsConfig{ 525 Precision: "ns", 526 Database: "db", 527 RetentionPolicy: "rp", 528 WriteConsistency: "wc", 529 }) 530 if bp.Precision() != "ns" { 531 t.Errorf("Expected: %s, got %s", bp.Precision(), "ns") 532 } 533 if bp.Database() != "db" { 534 t.Errorf("Expected: %s, got %s", bp.Database(), "db") 535 } 536 if bp.RetentionPolicy() != "rp" { 537 t.Errorf("Expected: %s, got %s", bp.RetentionPolicy(), "rp") 538 } 539 if bp.WriteConsistency() != "wc" { 540 t.Errorf("Expected: %s, got %s", bp.WriteConsistency(), "wc") 541 } 542 543 bp.SetDatabase("db2") 544 bp.SetRetentionPolicy("rp2") 545 bp.SetWriteConsistency("wc2") 546 err := bp.SetPrecision("s") 547 if err != nil { 548 t.Errorf("Did not expect error: %s", err.Error()) 549 } 550 551 if bp.Precision() != "s" { 552 t.Errorf("Expected: %s, got %s", bp.Precision(), "s") 553 } 554 if bp.Database() != "db2" { 555 t.Errorf("Expected: %s, got %s", bp.Database(), "db2") 556 } 557 if bp.RetentionPolicy() != "rp2" { 558 t.Errorf("Expected: %s, got %s", bp.RetentionPolicy(), "rp2") 559 } 560 if bp.WriteConsistency() != "wc2" { 561 t.Errorf("Expected: %s, got %s", bp.WriteConsistency(), "wc2") 562 } 563 }