2015-01-22 22:23:55 +00:00
|
|
|
package client_test
|
|
|
|
|
|
|
|
import (
|
2017-07-12 20:48:07 +00:00
|
|
|
"context"
|
2015-12-29 17:03:16 +00:00
|
|
|
"crypto/tls"
|
2015-01-23 00:18:24 +00:00
|
|
|
"encoding/json"
|
2015-12-29 17:03:16 +00:00
|
|
|
"errors"
|
2015-01-29 21:07:43 +00:00
|
|
|
"fmt"
|
2022-03-31 21:17:57 +00:00
|
|
|
"io"
|
2015-01-22 23:40:32 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2015-01-23 22:49:23 +00:00
|
|
|
"net/url"
|
2015-12-29 17:03:16 +00:00
|
|
|
"os"
|
2015-03-07 15:03:43 +00:00
|
|
|
"strings"
|
2015-01-22 22:23:55 +00:00
|
|
|
"testing"
|
2015-01-29 18:10:13 +00:00
|
|
|
"time"
|
2015-01-22 22:23:55 +00:00
|
|
|
|
2016-02-10 17:26:18 +00:00
|
|
|
"github.com/influxdata/influxdb/client"
|
2015-01-22 22:23:55 +00:00
|
|
|
)
|
|
|
|
|
2016-02-01 16:17:47 +00:00
|
|
|
func BenchmarkWrite(b *testing.B) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var data client.Response
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
config := client.Config{URL: *u}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bp := client.BatchPoints{
|
|
|
|
Points: []client.Point{
|
|
|
|
{Fields: map[string]interface{}{"value": 101}}},
|
|
|
|
}
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
r, err := c.Write(bp)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
if r != nil {
|
|
|
|
b.Fatalf("unexpected response. expected %v, actual %v", nil, r)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-30 01:31:14 +00:00
|
|
|
func BenchmarkUnmarshalJSON2Tags(b *testing.B) {
|
|
|
|
var bp client.BatchPoints
|
|
|
|
data := []byte(`
|
|
|
|
{
|
|
|
|
"database": "foo",
|
|
|
|
"retentionPolicy": "bar",
|
|
|
|
"points": [
|
|
|
|
{
|
|
|
|
"name": "cpu",
|
|
|
|
"tags": {
|
|
|
|
"host": "server01",
|
|
|
|
"region": "us-east1"
|
|
|
|
},
|
|
|
|
"time": 14244733039069373,
|
|
|
|
"precision": "n",
|
2015-05-30 02:27:06 +00:00
|
|
|
"fields": {
|
2015-05-30 01:31:14 +00:00
|
|
|
"value": 4541770385657154000
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if err := json.Unmarshal(data, &bp); err != nil {
|
2015-05-30 14:57:27 +00:00
|
|
|
b.Errorf("unable to unmarshal nanosecond data: %s", err.Error())
|
2015-05-30 01:31:14 +00:00
|
|
|
}
|
|
|
|
b.SetBytes(int64(len(data)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkUnmarshalJSON10Tags(b *testing.B) {
|
|
|
|
var bp client.BatchPoints
|
|
|
|
data := []byte(`
|
|
|
|
{
|
|
|
|
"database": "foo",
|
|
|
|
"retentionPolicy": "bar",
|
|
|
|
"points": [
|
|
|
|
{
|
|
|
|
"name": "cpu",
|
|
|
|
"tags": {
|
|
|
|
"host": "server01",
|
|
|
|
"region": "us-east1",
|
|
|
|
"tag1": "value1",
|
|
|
|
"tag2": "value2",
|
|
|
|
"tag2": "value3",
|
|
|
|
"tag4": "value4",
|
|
|
|
"tag5": "value5",
|
|
|
|
"tag6": "value6",
|
|
|
|
"tag7": "value7",
|
|
|
|
"tag8": "value8"
|
|
|
|
},
|
|
|
|
"time": 14244733039069373,
|
|
|
|
"precision": "n",
|
2015-05-30 02:27:06 +00:00
|
|
|
"fields": {
|
2015-05-30 01:31:14 +00:00
|
|
|
"value": 4541770385657154000
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if err := json.Unmarshal(data, &bp); err != nil {
|
2015-05-30 14:57:27 +00:00
|
|
|
b.Errorf("unable to unmarshal nanosecond data: %s", err.Error())
|
2015-05-30 01:31:14 +00:00
|
|
|
}
|
|
|
|
b.SetBytes(int64(len(data)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-22 22:23:55 +00:00
|
|
|
func TestNewClient(t *testing.T) {
|
2015-08-06 16:46:25 +00:00
|
|
|
config := client.Config{}
|
2015-01-22 22:23:55 +00:00
|
|
|
_, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
2015-01-22 23:40:32 +00:00
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
2015-01-22 22:23:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-22 23:40:32 +00:00
|
|
|
func TestClient_Ping(t *testing.T) {
|
|
|
|
ts := emptyTestServer()
|
|
|
|
defer ts.Close()
|
|
|
|
|
2015-01-23 22:49:23 +00:00
|
|
|
u, _ := url.Parse(ts.URL)
|
2015-08-06 16:46:25 +00:00
|
|
|
config := client.Config{URL: *u}
|
2015-01-22 23:40:32 +00:00
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
2015-01-26 21:12:58 +00:00
|
|
|
d, version, err := c.Ping()
|
2015-01-22 23:40:32 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
2016-05-02 17:56:27 +00:00
|
|
|
if d.Nanoseconds() == 0 {
|
|
|
|
t.Fatalf("expected a duration greater than zero. actual %v", d.Nanoseconds())
|
2015-01-22 23:40:32 +00:00
|
|
|
}
|
2015-01-26 21:12:58 +00:00
|
|
|
if version != "x.x" {
|
|
|
|
t.Fatalf("unexpected version. expected %s, actual %v", "x.x", version)
|
|
|
|
}
|
2015-01-22 23:40:32 +00:00
|
|
|
}
|
|
|
|
|
2015-01-22 22:23:55 +00:00
|
|
|
func TestClient_Query(t *testing.T) {
|
2015-01-23 00:18:24 +00:00
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2015-05-30 14:14:10 +00:00
|
|
|
var data client.Response
|
2015-01-23 00:18:24 +00:00
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
2015-01-23 22:49:23 +00:00
|
|
|
u, _ := url.Parse(ts.URL)
|
2015-08-06 16:46:25 +00:00
|
|
|
config := client.Config{URL: *u}
|
2015-01-22 22:23:55 +00:00
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
2015-01-22 23:40:32 +00:00
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
2015-01-22 22:23:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
query := client.Query{}
|
|
|
|
_, err = c.Query(query)
|
|
|
|
if err != nil {
|
2015-01-22 23:40:32 +00:00
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
2015-01-22 22:23:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-24 16:21:12 +00:00
|
|
|
func TestClient_Query_RP(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
params := r.URL.Query()
|
|
|
|
if got, exp := params.Get("db"), "db0"; got != exp {
|
|
|
|
t.Errorf("unexpected db query parameter: %s != %s", exp, got)
|
|
|
|
}
|
|
|
|
if got, exp := params.Get("rp"), "rp0"; got != exp {
|
|
|
|
t.Errorf("unexpected rp query parameter: %s != %s", exp, got)
|
|
|
|
}
|
|
|
|
var data client.Response
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
config := client.Config{URL: *u}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
query := client.Query{
|
|
|
|
Database: "db0",
|
|
|
|
RetentionPolicy: "rp0",
|
|
|
|
}
|
|
|
|
_, err = c.Query(query)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-30 18:03:03 +00:00
|
|
|
func TestClient_ChunkedQuery(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var data client.Response
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
enc := json.NewEncoder(w)
|
|
|
|
_ = enc.Encode(data)
|
|
|
|
_ = enc.Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
config := client.Config{URL: *u}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
query := client.Query{Chunked: true}
|
|
|
|
_, err = c.Query(query)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-12 20:48:07 +00:00
|
|
|
func TestClient_QueryContext(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var data client.Response
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
config := client.Config{URL: *u}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
query := client.Query{}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
_, err = c.QueryContext(ctx, query)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_QueryContext_Cancelled(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var data client.Response
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
config := client.Config{URL: *u}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
query := client.Query{}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
cancel()
|
|
|
|
|
|
|
|
_, err = c.QueryContext(ctx, query)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("Since context was cancelled an error was expected, but got nil.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_ChunkedQuery_WithContext(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var data client.Response
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
enc := json.NewEncoder(w)
|
|
|
|
_ = enc.Encode(data)
|
|
|
|
_ = enc.Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
config := client.Config{URL: *u}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
query := client.Query{Chunked: true}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
_, err = c.QueryContext(ctx, query)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 18:05:04 +00:00
|
|
|
func TestClient_BasicAuth(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
u, p, ok := r.BasicAuth()
|
|
|
|
|
|
|
|
if !ok {
|
2015-05-30 14:57:27 +00:00
|
|
|
t.Errorf("basic auth error")
|
2015-01-23 18:05:04 +00:00
|
|
|
}
|
|
|
|
if u != "username" {
|
|
|
|
t.Errorf("unexpected username, expected %q, actual %q", "username", u)
|
|
|
|
}
|
|
|
|
if p != "password" {
|
|
|
|
t.Errorf("unexpected password, expected %q, actual %q", "password", p)
|
|
|
|
}
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
2015-01-23 22:49:23 +00:00
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
u.User = url.UserPassword("username", "password")
|
2015-08-06 16:46:25 +00:00
|
|
|
config := client.Config{URL: *u, Username: "username", Password: "password"}
|
2015-01-23 18:05:04 +00:00
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
2015-01-26 21:12:58 +00:00
|
|
|
_, _, err = c.Ping()
|
2015-01-23 18:05:04 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-22 22:23:55 +00:00
|
|
|
func TestClient_Write(t *testing.T) {
|
2015-01-23 20:37:53 +00:00
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2022-03-31 21:17:57 +00:00
|
|
|
in, err := io.ReadAll(r.Body)
|
2017-10-04 20:53:45 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
} else if have, want := strings.TrimSpace(string(in)), `m0,host=server01 v1=2,v2=2i,v3=2u,v4="foobar",v5=true 0`; have != want {
|
|
|
|
t.Errorf("unexpected write protocol: %s != %s", have, want)
|
|
|
|
}
|
2015-05-30 14:14:10 +00:00
|
|
|
var data client.Response
|
2015-05-13 18:44:31 +00:00
|
|
|
w.WriteHeader(http.StatusNoContent)
|
2015-01-23 20:37:53 +00:00
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
2015-01-23 22:49:23 +00:00
|
|
|
u, _ := url.Parse(ts.URL)
|
2015-08-06 16:46:25 +00:00
|
|
|
config := client.Config{URL: *u}
|
2015-01-22 22:23:55 +00:00
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
2015-01-22 23:40:32 +00:00
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
2015-01-22 22:23:55 +00:00
|
|
|
}
|
|
|
|
|
2017-10-04 20:53:45 +00:00
|
|
|
bp := client.BatchPoints{
|
|
|
|
Points: []client.Point{
|
|
|
|
{
|
|
|
|
Measurement: "m0",
|
|
|
|
Tags: map[string]string{
|
|
|
|
"host": "server01",
|
|
|
|
},
|
|
|
|
Time: time.Unix(0, 0).UTC(),
|
|
|
|
Fields: map[string]interface{}{
|
|
|
|
"v1": float64(2),
|
|
|
|
"v2": int64(2),
|
|
|
|
"v3": uint64(2),
|
|
|
|
"v4": "foobar",
|
|
|
|
"v5": true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2015-05-13 19:13:37 +00:00
|
|
|
r, err := c.Write(bp)
|
2015-01-22 22:23:55 +00:00
|
|
|
if err != nil {
|
2015-01-22 23:40:32 +00:00
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
2015-01-22 22:23:55 +00:00
|
|
|
}
|
2015-05-13 19:13:37 +00:00
|
|
|
if r != nil {
|
|
|
|
t.Fatalf("unexpected response. expected %v, actual %v", nil, r)
|
|
|
|
}
|
2015-01-22 22:23:55 +00:00
|
|
|
}
|
2015-01-22 23:40:32 +00:00
|
|
|
|
2015-02-11 20:31:15 +00:00
|
|
|
func TestClient_UserAgent(t *testing.T) {
|
|
|
|
receivedUserAgent := ""
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
receivedUserAgent = r.UserAgent()
|
|
|
|
|
2015-05-30 14:14:10 +00:00
|
|
|
var data client.Response
|
2015-02-11 20:31:15 +00:00
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
_, err := http.Get(ts.URL)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
userAgent string
|
|
|
|
expected string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "Empty user agent",
|
|
|
|
userAgent: "",
|
2015-03-09 15:51:47 +00:00
|
|
|
expected: "InfluxDBClient",
|
2015-02-11 20:31:15 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Custom user agent",
|
|
|
|
userAgent: "Test Influx Client",
|
|
|
|
expected: "Test Influx Client",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
u, _ := url.Parse(ts.URL)
|
2015-08-06 16:46:25 +00:00
|
|
|
config := client.Config{URL: *u, UserAgent: test.userAgent}
|
2015-02-11 20:31:15 +00:00
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
receivedUserAgent = ""
|
|
|
|
query := client.Query{}
|
|
|
|
_, err = c.Query(query)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
2015-03-07 15:03:43 +00:00
|
|
|
if !strings.HasPrefix(receivedUserAgent, test.expected) {
|
2015-02-11 20:31:15 +00:00
|
|
|
t.Fatalf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent)
|
|
|
|
}
|
|
|
|
|
|
|
|
receivedUserAgent = ""
|
2015-03-06 17:29:32 +00:00
|
|
|
bp := client.BatchPoints{}
|
|
|
|
_, err = c.Write(bp)
|
2015-02-11 20:31:15 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
2015-03-07 15:03:43 +00:00
|
|
|
if !strings.HasPrefix(receivedUserAgent, test.expected) {
|
2015-02-11 20:31:15 +00:00
|
|
|
t.Fatalf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent)
|
|
|
|
}
|
|
|
|
|
|
|
|
receivedUserAgent = ""
|
|
|
|
_, _, err = c.Ping()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
2015-03-09 15:51:47 +00:00
|
|
|
if receivedUserAgent != test.expected {
|
2015-02-11 20:31:15 +00:00
|
|
|
t.Fatalf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-13 14:44:59 +00:00
|
|
|
func TestClient_Messages(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
w.Write([]byte(`{"results":[{"messages":[{"level":"warning","text":"deprecation test"}]}]}`))
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
config := client.Config{URL: *u}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
query := client.Query{}
|
|
|
|
resp, err := c.Query(query)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if got, exp := len(resp.Results), 1; got != exp {
|
|
|
|
t.Fatalf("unexpected number of results. expected %v, actual %v", exp, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
r := resp.Results[0]
|
|
|
|
if got, exp := len(r.Messages), 1; got != exp {
|
|
|
|
t.Fatalf("unexpected number of messages. expected %v, actual %v", exp, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
m := r.Messages[0]
|
|
|
|
if got, exp := m.Level, "warning"; got != exp {
|
|
|
|
t.Errorf("unexpected message level. expected %v, actual %v", exp, got)
|
|
|
|
}
|
|
|
|
if got, exp := m.Text, "deprecation test"; got != exp {
|
|
|
|
t.Errorf("unexpected message text. expected %v, actual %v", exp, got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-29 21:07:43 +00:00
|
|
|
func TestPoint_UnmarshalEpoch(t *testing.T) {
|
|
|
|
now := time.Now()
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
epoch int64
|
|
|
|
precision string
|
|
|
|
expected time.Time
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "nanoseconds",
|
|
|
|
epoch: now.UnixNano(),
|
|
|
|
precision: "n",
|
|
|
|
expected: now,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "microseconds",
|
|
|
|
epoch: now.Round(time.Microsecond).UnixNano() / int64(time.Microsecond),
|
|
|
|
precision: "u",
|
|
|
|
expected: now.Round(time.Microsecond),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "milliseconds",
|
|
|
|
epoch: now.Round(time.Millisecond).UnixNano() / int64(time.Millisecond),
|
|
|
|
precision: "ms",
|
|
|
|
expected: now.Round(time.Millisecond),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "seconds",
|
|
|
|
epoch: now.Round(time.Second).UnixNano() / int64(time.Second),
|
|
|
|
precision: "s",
|
|
|
|
expected: now.Round(time.Second),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "minutes",
|
|
|
|
epoch: now.Round(time.Minute).UnixNano() / int64(time.Minute),
|
|
|
|
precision: "m",
|
|
|
|
expected: now.Round(time.Minute),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "hours",
|
|
|
|
epoch: now.Round(time.Hour).UnixNano() / int64(time.Hour),
|
|
|
|
precision: "h",
|
|
|
|
expected: now.Round(time.Hour),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "max int64",
|
|
|
|
epoch: 9223372036854775807,
|
|
|
|
precision: "n",
|
|
|
|
expected: time.Unix(0, 9223372036854775807),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "100 years from now",
|
|
|
|
epoch: now.Add(time.Hour * 24 * 365 * 100).UnixNano(),
|
|
|
|
precision: "n",
|
|
|
|
expected: now.Add(time.Hour * 24 * 365 * 100),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Logf("testing %q\n", test.name)
|
2015-04-23 17:44:16 +00:00
|
|
|
data := []byte(fmt.Sprintf(`{"time": %d, "precision":"%s"}`, test.epoch, test.precision))
|
2015-01-29 21:07:43 +00:00
|
|
|
t.Logf("json: %s", string(data))
|
|
|
|
var p client.Point
|
|
|
|
err := json.Unmarshal(data, &p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. exptected: %v, actual: %v", nil, err)
|
|
|
|
}
|
2015-04-23 17:44:16 +00:00
|
|
|
if !p.Time.Equal(test.expected) {
|
|
|
|
t.Fatalf("Unexpected time. expected: %v, actual: %v", test.expected, p.Time)
|
2015-01-29 21:07:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPoint_UnmarshalRFC(t *testing.T) {
|
2015-01-30 18:28:15 +00:00
|
|
|
now := time.Now().UTC()
|
2015-01-29 21:07:43 +00:00
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
rfc string
|
|
|
|
now time.Time
|
|
|
|
expected time.Time
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "RFC3339Nano",
|
|
|
|
rfc: time.RFC3339Nano,
|
|
|
|
now: now,
|
|
|
|
expected: now,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "RFC3339",
|
|
|
|
rfc: time.RFC3339,
|
|
|
|
now: now.Round(time.Second),
|
|
|
|
expected: now.Round(time.Second),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Logf("testing %q\n", test.name)
|
|
|
|
ts := test.now.Format(test.rfc)
|
2015-04-23 17:44:16 +00:00
|
|
|
data := []byte(fmt.Sprintf(`{"time": %q}`, ts))
|
2015-01-29 21:07:43 +00:00
|
|
|
t.Logf("json: %s", string(data))
|
|
|
|
var p client.Point
|
|
|
|
err := json.Unmarshal(data, &p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. exptected: %v, actual: %v", nil, err)
|
|
|
|
}
|
2015-04-23 17:44:16 +00:00
|
|
|
if !p.Time.Equal(test.expected) {
|
|
|
|
t.Fatalf("Unexpected time. expected: %v, actual: %v", test.expected, p.Time)
|
2015-01-29 21:07:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-06 19:04:26 +00:00
|
|
|
func TestPoint_MarshalOmitempty(t *testing.T) {
|
|
|
|
now := time.Now().UTC()
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
point client.Point
|
|
|
|
now time.Time
|
|
|
|
expected string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "all empty",
|
2015-05-22 11:22:35 +00:00
|
|
|
point: client.Point{Measurement: "cpu", Fields: map[string]interface{}{"value": 1.1}},
|
2015-03-06 19:04:26 +00:00
|
|
|
now: now,
|
2015-05-22 11:22:35 +00:00
|
|
|
expected: `{"measurement":"cpu","fields":{"value":1.1}}`,
|
2015-03-06 19:04:26 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "with time",
|
2015-05-22 11:22:35 +00:00
|
|
|
point: client.Point{Measurement: "cpu", Fields: map[string]interface{}{"value": 1.1}, Time: now},
|
2015-03-06 19:04:26 +00:00
|
|
|
now: now,
|
2015-05-22 11:22:35 +00:00
|
|
|
expected: fmt.Sprintf(`{"measurement":"cpu","time":"%s","fields":{"value":1.1}}`, now.Format(time.RFC3339Nano)),
|
2015-03-06 19:04:26 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "with tags",
|
2015-05-22 11:22:35 +00:00
|
|
|
point: client.Point{Measurement: "cpu", Fields: map[string]interface{}{"value": 1.1}, Tags: map[string]string{"foo": "bar"}},
|
2015-03-06 19:04:26 +00:00
|
|
|
now: now,
|
2015-05-22 11:22:35 +00:00
|
|
|
expected: `{"measurement":"cpu","tags":{"foo":"bar"},"fields":{"value":1.1}}`,
|
2015-03-06 19:04:26 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "with precision",
|
2015-05-22 11:22:35 +00:00
|
|
|
point: client.Point{Measurement: "cpu", Fields: map[string]interface{}{"value": 1.1}, Precision: "ms"},
|
2015-03-06 19:04:26 +00:00
|
|
|
now: now,
|
2015-05-22 11:22:35 +00:00
|
|
|
expected: `{"measurement":"cpu","fields":{"value":1.1},"precision":"ms"}`,
|
2015-03-06 19:04:26 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Logf("testing %q\n", test.name)
|
|
|
|
b, err := json.Marshal(&test.point)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. exptected: %v, actual: %v", nil, err)
|
|
|
|
}
|
|
|
|
if test.expected != string(b) {
|
|
|
|
t.Fatalf("Unexpected result. expected: %v, actual: %v", test.expected, string(b))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-29 18:10:13 +00:00
|
|
|
func TestEpochToTime(t *testing.T) {
|
|
|
|
now := time.Now()
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
epoch int64
|
|
|
|
precision string
|
|
|
|
expected time.Time
|
|
|
|
}{
|
|
|
|
{name: "nanoseconds", epoch: now.UnixNano(), precision: "n", expected: now},
|
|
|
|
{name: "microseconds", epoch: now.Round(time.Microsecond).UnixNano() / int64(time.Microsecond), precision: "u", expected: now.Round(time.Microsecond)},
|
|
|
|
{name: "milliseconds", epoch: now.Round(time.Millisecond).UnixNano() / int64(time.Millisecond), precision: "ms", expected: now.Round(time.Millisecond)},
|
|
|
|
{name: "seconds", epoch: now.Round(time.Second).UnixNano() / int64(time.Second), precision: "s", expected: now.Round(time.Second)},
|
|
|
|
{name: "minutes", epoch: now.Round(time.Minute).UnixNano() / int64(time.Minute), precision: "m", expected: now.Round(time.Minute)},
|
|
|
|
{name: "hours", epoch: now.Round(time.Hour).UnixNano() / int64(time.Hour), precision: "h", expected: now.Round(time.Hour)},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Logf("testing %q\n", test.name)
|
|
|
|
tm, e := client.EpochToTime(test.epoch, test.precision)
|
|
|
|
if e != nil {
|
|
|
|
t.Fatalf("unexpected error: expected %v, actual: %v", nil, e)
|
|
|
|
}
|
2017-07-21 17:51:31 +00:00
|
|
|
if !tm.Equal(test.expected) {
|
2015-01-29 18:10:13 +00:00
|
|
|
t.Fatalf("unexpected time: expected %v, actual %v", test.expected, tm)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-22 23:40:32 +00:00
|
|
|
// helper functions
|
|
|
|
|
|
|
|
func emptyTestServer() *httptest.Server {
|
|
|
|
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2016-05-02 17:56:27 +00:00
|
|
|
time.Sleep(50 * time.Millisecond)
|
2015-01-26 21:12:58 +00:00
|
|
|
w.Header().Set("X-Influxdb-Version", "x.x")
|
2015-01-22 23:40:32 +00:00
|
|
|
}))
|
|
|
|
}
|
2015-03-06 17:29:32 +00:00
|
|
|
|
2015-04-23 17:44:16 +00:00
|
|
|
// Ensure that data with epoch times can be decoded.
|
2015-03-06 17:29:32 +00:00
|
|
|
func TestBatchPoints_Normal(t *testing.T) {
|
|
|
|
var bp client.BatchPoints
|
|
|
|
data := []byte(`
|
2015-03-27 00:45:36 +00:00
|
|
|
{
|
|
|
|
"database": "foo",
|
|
|
|
"retentionPolicy": "bar",
|
|
|
|
"points": [
|
|
|
|
{
|
|
|
|
"name": "cpu",
|
|
|
|
"tags": {
|
|
|
|
"host": "server01"
|
2015-03-06 17:29:32 +00:00
|
|
|
},
|
2015-04-23 17:44:16 +00:00
|
|
|
"time": 14244733039069373,
|
2015-03-06 17:29:32 +00:00
|
|
|
"precision": "n",
|
|
|
|
"values": {
|
|
|
|
"value": 4541770385657154000
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "cpu",
|
|
|
|
"tags": {
|
|
|
|
"host": "server01"
|
|
|
|
},
|
2015-04-23 17:44:16 +00:00
|
|
|
"time": 14244733039069380,
|
2015-03-06 17:29:32 +00:00
|
|
|
"precision": "n",
|
|
|
|
"values": {
|
|
|
|
"value": 7199311900554737000
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
if err := json.Unmarshal(data, &bp); err != nil {
|
2015-05-30 14:57:27 +00:00
|
|
|
t.Errorf("unable to unmarshal nanosecond data: %s", err.Error())
|
2015-03-06 17:29:32 +00:00
|
|
|
}
|
|
|
|
}
|
2015-05-28 19:10:21 +00:00
|
|
|
|
|
|
|
func TestClient_Timeout(t *testing.T) {
|
2015-08-27 18:02:22 +00:00
|
|
|
done := make(chan bool)
|
2015-05-28 19:10:21 +00:00
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2015-08-27 18:02:22 +00:00
|
|
|
<-done
|
2015-05-28 19:10:21 +00:00
|
|
|
}))
|
|
|
|
defer ts.Close()
|
2015-08-27 18:02:22 +00:00
|
|
|
defer func() { done <- true }()
|
2015-05-28 19:10:21 +00:00
|
|
|
u, _ := url.Parse(ts.URL)
|
2015-08-06 16:46:25 +00:00
|
|
|
config := client.Config{URL: *u, Timeout: 500 * time.Millisecond}
|
2015-05-28 19:10:21 +00:00
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
2015-12-09 19:52:10 +00:00
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
2015-05-28 19:10:21 +00:00
|
|
|
}
|
|
|
|
query := client.Query{}
|
|
|
|
_, err = c.Query(query)
|
|
|
|
if err == nil {
|
2015-12-09 19:52:10 +00:00
|
|
|
t.Fatalf("unexpected success. expected timeout error")
|
2015-12-10 01:29:38 +00:00
|
|
|
} else if !strings.Contains(err.Error(), "request canceled") &&
|
2021-01-08 17:46:22 +00:00
|
|
|
!strings.Contains(err.Error(), "use of closed network connection") &&
|
|
|
|
!strings.Contains(err.Error(), "Client.Timeout exceeded") {
|
2015-12-09 19:52:10 +00:00
|
|
|
t.Fatalf("unexpected error. expected 'request canceled' error, got %v", err)
|
2015-05-28 19:10:21 +00:00
|
|
|
}
|
2015-08-27 18:02:22 +00:00
|
|
|
}
|
2015-05-28 19:10:21 +00:00
|
|
|
|
2015-08-27 18:02:22 +00:00
|
|
|
func TestClient_NoTimeout(t *testing.T) {
|
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("skipping in short mode")
|
|
|
|
}
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
var data client.Response
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
config := client.Config{URL: *u}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
query := client.Query{}
|
|
|
|
_, err = c.Query(query)
|
2015-05-28 19:10:21 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
}
|
2015-10-31 03:19:07 +00:00
|
|
|
|
2018-02-06 15:52:47 +00:00
|
|
|
func TestClient_ParseConnectionString(t *testing.T) {
|
|
|
|
for _, tt := range []struct {
|
|
|
|
addr string
|
|
|
|
ssl bool
|
|
|
|
exp string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
addr: "localhost",
|
|
|
|
exp: "http://localhost:8086",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
addr: "localhost:8086",
|
|
|
|
exp: "http://localhost:8086",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
addr: "localhost:80",
|
|
|
|
exp: "http://localhost",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
addr: "localhost",
|
|
|
|
exp: "https://localhost:8086",
|
|
|
|
ssl: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
addr: "localhost:443",
|
|
|
|
exp: "https://localhost",
|
|
|
|
ssl: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
addr: "localhost:80",
|
|
|
|
exp: "https://localhost:80",
|
|
|
|
ssl: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
addr: "localhost:443",
|
|
|
|
exp: "http://localhost:443",
|
|
|
|
},
|
2020-01-21 18:23:46 +00:00
|
|
|
{
|
|
|
|
addr: "192.168.2.13:8086/boom",
|
|
|
|
exp: "http://192.168.2.13:8086/boom",
|
|
|
|
},
|
2020-01-21 22:58:55 +00:00
|
|
|
{
|
|
|
|
addr: "",
|
|
|
|
exp: "http://localhost:8086",
|
|
|
|
},
|
2018-02-06 15:52:47 +00:00
|
|
|
} {
|
|
|
|
name := tt.addr
|
|
|
|
if tt.ssl {
|
|
|
|
name += "+ssl"
|
|
|
|
}
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
u, err := client.ParseConnectionString(tt.addr, tt.ssl)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if got, want := u.String(), tt.exp; got != want {
|
|
|
|
t.Fatalf("unexpected connection string: got=%s want=%s", got, want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-31 03:19:07 +00:00
|
|
|
func TestClient_ParseConnectionString_IPv6(t *testing.T) {
|
|
|
|
path := "[fdf5:9ede:1875:0:a9ee:a600:8fe3:d495]:8086"
|
|
|
|
u, err := client.ParseConnectionString(path, false)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error, expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
if u.Host != path {
|
|
|
|
t.Fatalf("ipv6 parse failed, expected %s, actual %s", path, u.Host)
|
|
|
|
}
|
|
|
|
}
|
2015-12-29 17:03:16 +00:00
|
|
|
|
|
|
|
func TestClient_CustomCertificates(t *testing.T) {
|
|
|
|
// generated with:
|
|
|
|
// openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3650 -nodes -config influx.cnf
|
|
|
|
// influx.cnf:
|
|
|
|
// [req]
|
|
|
|
// distinguished_name = req_distinguished_name
|
|
|
|
// x509_extensions = v3_req
|
|
|
|
// prompt = no
|
|
|
|
// [req_distinguished_name]
|
|
|
|
// C = US
|
|
|
|
// ST = CA
|
|
|
|
// L = San Francisco
|
|
|
|
// O = InfluxDB
|
2016-02-10 20:50:12 +00:00
|
|
|
// CN = github.com/influxdata
|
2015-12-29 17:03:16 +00:00
|
|
|
// [v3_req]
|
|
|
|
// keyUsage = keyEncipherment, dataEncipherment
|
|
|
|
// extendedKeyUsage = serverAuth
|
|
|
|
// subjectAltName = @alt_names
|
|
|
|
// [alt_names]
|
|
|
|
// IP.1 = 127.0.0.1
|
|
|
|
//
|
|
|
|
key := `
|
|
|
|
-----BEGIN PRIVATE KEY-----
|
|
|
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLswqKJLxfhBRi
|
|
|
|
4qdj7+jpBxTAi4MewrcMPp+9YlbLke3F7w2DPrZVkYVeWmg8LyTPAigrXeadK6hv
|
|
|
|
qjRr05a7sMc5+ynivGbWUySWT+u17V85x6VR5TMIkJEOqpiIU8aYk0l+3UcrzVjS
|
|
|
|
1QZCUBoxVwAVaSR6AXTA8YrVXdk/AI3f22dYiBjFmV4LJJkGjTaCnlDKu54hMU1t
|
|
|
|
WTyFcoY9TBzZ1XA+ng5RQ/QADeL2PYrTW4s/mLI3jfKKD53EI4uM2FjW37ZfuxTa
|
|
|
|
mhCR7/lxM4COg9K70y5uebfqJvuoXAwXLOzVbdfF5b9fJFbL67kaK2tiMT3Wt39m
|
|
|
|
hXzclLTDAgMBAAECggEAK8mpElkjRUUXPMqMQSdpYe5rv5g973bb8n3jyMpC7i/I
|
|
|
|
dSwWM4hfmbVWfhnhHk7kErvb9raQxGiGJLrp2eP6Gw69RPGA54SodpoY21cCzHDi
|
|
|
|
b4FDQH+MoOKyy/xQHb4kitfejK70ha320huI5OhjOQgCtJeNh8yYVIGX3pX2BVyu
|
|
|
|
36UB9tfX1S5pbiHeih3vZGd322Muj/joNzIelnYRBnoO0xqvQ0S1Dk+dLCTHO0/m
|
|
|
|
u9AZN8c2TsRWZpJPMWwBv8LuABbE0e66/TSsrfklAn86ELCo44lZURDE7uPZ4pIH
|
|
|
|
FWtmf+nW5Hy6aPhy60E40MqotlejhWwB3ktY/m3JAQKBgQDuB4nhxzJA9lH9EaCt
|
|
|
|
byvJ9wGVvI3k79hOwc/Z2R3dNe+Ma+TJy+aBppvsLF4qz83aWC+canyasbHcPNR/
|
|
|
|
vXQGlsgKfucrmd1PfMV7uvOIkfOjK0E6mRC+jMuKtNTQrdtM1BU/Z7LY0iy0fNJ6
|
|
|
|
aNqhFdlJmmk0g+4bR4SAWB6FkwKBgQDbE/7r1u+GdJk/mhdjTi1aegr9lXb0l7L6
|
|
|
|
BCvOYhs/Z/pXfsaYPSXhgk2w+LiGk6BaEA2/4Sr0YS2MAAaIhBVeFBIXVpNrXB3K
|
|
|
|
Yg1jOEeLQ3qoVBeJFhJNrN9ZQx33HANC1W/Y1apMwaYqCRUGVQkrdcsN2KNea1z0
|
|
|
|
3qeYeCCSEQKBgCKZKeuNfrp+k1BLnaVYAW9r3ekb7SwXyMM53LJ3oqWiz10D2c+T
|
|
|
|
OcAirYtYr59dcTiJlPIRcGcz6PxwQxsGOLU0eYM9CvEFfmutYS8o73ksbdOL2AFi
|
|
|
|
elKYOIXC3yQuATBbq3L56b8mXaUmd5mfYBgGCv1t2ljtzFBext248UbNAoGBAIv1
|
|
|
|
2V24YiwnH6THf/ucfVMZNx5Mt8OJivk5YvcmLDw05HWzc5LdNe89PP871z963u3K
|
|
|
|
5c3ZP4UC9INFnOboY3JIJkqsr9/d6NZcECt8UBDDmoAhwSt+Y1EmiUZQn7s4NUkk
|
|
|
|
bKE919/Ts6GVTc5O013lkkUVS0HOG4QBH1dEH6LRAoGAStl11WA9tuKXiBl5XG/C
|
|
|
|
cq9mFPNJK3pEgd6YH874vEnYEEqENR4MFK3uWXus9Nm+VYxbUbPEzFF4kpsfukDg
|
|
|
|
/JAVqY4lUam7g6fyyaoIIPQEp7jGjbsUf46IjnUjFcaojOugA3EAfn9awREUDuJZ
|
|
|
|
cvh4WzEegcExTppINW1NB5E=
|
|
|
|
-----END PRIVATE KEY-----
|
|
|
|
`
|
|
|
|
cert := `
|
|
|
|
-----BEGIN CERTIFICATE-----
|
|
|
|
MIIDdjCCAl6gAwIBAgIJAMYGAwkxUV51MA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
|
|
|
|
BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzERMA8G
|
|
|
|
A1UECgwISW5mbHV4REIxETAPBgNVBAMMCGluZmx1eGRiMB4XDTE1MTIyOTAxNTg1
|
|
|
|
NloXDTI1MTIyNjAxNTg1NlowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYw
|
|
|
|
FAYDVQQHDA1TYW4gRnJhbmNpc2NvMREwDwYDVQQKDAhJbmZsdXhEQjERMA8GA1UE
|
|
|
|
AwwIaW5mbHV4ZGIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLswqK
|
|
|
|
JLxfhBRi4qdj7+jpBxTAi4MewrcMPp+9YlbLke3F7w2DPrZVkYVeWmg8LyTPAigr
|
|
|
|
XeadK6hvqjRr05a7sMc5+ynivGbWUySWT+u17V85x6VR5TMIkJEOqpiIU8aYk0l+
|
|
|
|
3UcrzVjS1QZCUBoxVwAVaSR6AXTA8YrVXdk/AI3f22dYiBjFmV4LJJkGjTaCnlDK
|
|
|
|
u54hMU1tWTyFcoY9TBzZ1XA+ng5RQ/QADeL2PYrTW4s/mLI3jfKKD53EI4uM2FjW
|
|
|
|
37ZfuxTamhCR7/lxM4COg9K70y5uebfqJvuoXAwXLOzVbdfF5b9fJFbL67kaK2ti
|
|
|
|
MT3Wt39mhXzclLTDAgMBAAGjQzBBMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgQw
|
|
|
|
MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZIhvcN
|
|
|
|
AQELBQADggEBAJxgHeduV9q2BuKnrt+sjXLGn/HwbMbgGbgFK6kUKJBWtv6Pa7JJ
|
|
|
|
m4teDmTMWiaeB2g4N2bmaWTuEZzzShNKG5roFeWm1ilFMAyzkb+VifN4YuDKH62F
|
|
|
|
3e259qsytiGbbJF3F//4sjfMw8qZVEPvspG1zKsASo0PpSOOUFmxcj0oMAXhnMrk
|
|
|
|
rRcbk6fufhyq0iZGl8ZLKTCrkjk0b3qlNs6UaRD9/XBB59VlQ8I338sfjV06edwY
|
|
|
|
jn5Amab0uyoFNEp70Y4WGxrxUTS1GAC1LCA13S7EnidD440UrnWALTarjmHAK6aW
|
|
|
|
war3JNM1mGB3o2iAtuOJlFIKLpI1x+1e8pI=
|
|
|
|
-----END CERTIFICATE-----
|
|
|
|
`
|
|
|
|
cer, err := tls.X509KeyPair([]byte(cert), []byte(key))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Received error: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var data client.Response
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_ = json.NewEncoder(w).Encode(data)
|
|
|
|
}))
|
|
|
|
server.TLS = &tls.Config{Certificates: []tls.Certificate{cer}}
|
|
|
|
server.TLS.BuildNameToCertificate()
|
|
|
|
server.StartTLS()
|
|
|
|
defer server.Close()
|
|
|
|
|
2022-03-31 21:17:57 +00:00
|
|
|
certFile, _ := os.CreateTemp("", "influx-cert-")
|
2015-12-29 17:03:16 +00:00
|
|
|
certFile.WriteString(cert)
|
|
|
|
certFile.Close()
|
|
|
|
defer os.Remove(certFile.Name())
|
|
|
|
|
|
|
|
u, _ := url.Parse(server.URL)
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
unsafeSsl bool
|
|
|
|
expected error
|
|
|
|
}{
|
|
|
|
{name: "validate certificates", unsafeSsl: false, expected: errors.New("error")},
|
|
|
|
{name: "not validate certificates", unsafeSsl: true, expected: nil},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
config := client.Config{URL: *u, UnsafeSsl: test.unsafeSsl}
|
|
|
|
c, err := client.NewClient(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
}
|
|
|
|
query := client.Query{}
|
|
|
|
_, err = c.Query(query)
|
|
|
|
|
|
|
|
if (test.expected == nil) != (err == nil) {
|
|
|
|
t.Fatalf("%s: expected %v. got %v. unsafeSsl: %v", test.name, test.expected, err, test.unsafeSsl)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-30 18:03:03 +00:00
|
|
|
|
|
|
|
func TestChunkedResponse(t *testing.T) {
|
|
|
|
s := `{"results":[{},{}]}{"results":[{}]}`
|
|
|
|
r := client.NewChunkedResponse(strings.NewReader(s))
|
|
|
|
resp, err := r.NextResponse()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
} else if actual := len(resp.Results); actual != 2 {
|
|
|
|
t.Fatalf("unexpected number of results. expected %v, actual %v", 2, actual)
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err = r.NextResponse()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
} else if actual := len(resp.Results); actual != 1 {
|
|
|
|
t.Fatalf("unexpected number of results. expected %v, actual %v", 1, actual)
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err = r.NextResponse()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
|
|
|
} else if resp != nil {
|
|
|
|
t.Fatalf("unexpected response. expected %v, actual %v", nil, resp)
|
|
|
|
}
|
|
|
|
}
|
2018-02-12 03:11:23 +00:00
|
|
|
|
|
|
|
func TestClient_Proxy(t *testing.T) {
|
|
|
|
pinged := false
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
|
|
|
if got, want := req.URL.String(), "http://example.com:8086/ping"; got != want {
|
|
|
|
t.Errorf("invalid url in request: got=%s want=%s", got, want)
|
|
|
|
}
|
|
|
|
resp.WriteHeader(http.StatusNoContent)
|
|
|
|
pinged = true
|
|
|
|
}))
|
|
|
|
defer server.Close()
|
|
|
|
|
|
|
|
proxyURL, _ := url.Parse(server.URL)
|
|
|
|
c, err := client.NewClient(client.Config{
|
|
|
|
URL: url.URL{
|
|
|
|
Scheme: "http",
|
|
|
|
Host: "example.com:8086",
|
|
|
|
},
|
|
|
|
Proxy: http.ProxyURL(proxyURL),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
}
|
|
|
|
if _, _, err := c.Ping(); err != nil {
|
|
|
|
t.Fatalf("could not ping server: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !pinged {
|
|
|
|
t.Fatalf("no http request was received")
|
|
|
|
}
|
|
|
|
}
|
2020-01-21 22:58:55 +00:00
|
|
|
|
|
|
|
func TestSplitPath(t *testing.T) {
|
|
|
|
tests := map[string]struct {
|
|
|
|
input string
|
|
|
|
expectedfirst string
|
|
|
|
expectedrest string
|
|
|
|
}{
|
|
|
|
"empty": {
|
|
|
|
input: "",
|
|
|
|
expectedfirst: "",
|
|
|
|
expectedrest: "",
|
|
|
|
},
|
|
|
|
"noslash": {
|
|
|
|
input: "foo",
|
|
|
|
expectedfirst: "foo",
|
|
|
|
expectedrest: "",
|
|
|
|
},
|
|
|
|
"ideal": {
|
|
|
|
input: "foo/bar/baz/cuux:8080",
|
|
|
|
expectedfirst: "foo",
|
|
|
|
expectedrest: "bar/baz/cuux:8080",
|
|
|
|
},
|
|
|
|
"trailingslash": {
|
|
|
|
input: "foo/",
|
|
|
|
expectedfirst: "foo",
|
|
|
|
expectedrest: "",
|
|
|
|
},
|
|
|
|
"onlyslash": {
|
|
|
|
input: "/",
|
|
|
|
expectedfirst: "",
|
|
|
|
expectedrest: "",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Parallel()
|
|
|
|
for name, test := range tests {
|
|
|
|
name, test := name, test
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
first, rest := client.SplitPath(test.input)
|
|
|
|
|
|
|
|
if gotfirst, gotrest, expectedfirst, expectedrest := first, rest, test.expectedfirst, test.expectedrest; gotfirst != expectedfirst || gotrest != expectedrest {
|
|
|
|
t.Fatalf("splitPath(%q) returned (%q, %q); expected (%q, %q)", test.input, gotfirst, gotrest, expectedfirst, expectedrest)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|