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  }