github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/point_test.go (about)

     1  package query_test
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/davecgh/go-spew/spew"
     9  	"github.com/influxdata/influxdb/v2/influxql/query"
    10  	"github.com/influxdata/influxdb/v2/pkg/deep"
    11  )
    12  
    13  func TestPoint_Clone_Float(t *testing.T) {
    14  	p := &query.FloatPoint{
    15  		Name:  "cpu",
    16  		Tags:  ParseTags("host=server01"),
    17  		Time:  5,
    18  		Value: 2,
    19  		Aux:   []interface{}{float64(45)},
    20  	}
    21  	c := p.Clone()
    22  	if p == c {
    23  		t.Errorf("clone has the same address as the original: %v == %v", p, c)
    24  	}
    25  	if !deep.Equal(p, c) {
    26  		t.Errorf("mismatched point: %s", spew.Sdump(c))
    27  	}
    28  	if &p.Aux[0] == &c.Aux[0] {
    29  		t.Errorf("aux values share the same address: %v == %v", p.Aux, c.Aux)
    30  	} else if !deep.Equal(p.Aux, c.Aux) {
    31  		t.Errorf("mismatched aux fields: %v != %v", p.Aux, c.Aux)
    32  	}
    33  }
    34  
    35  func TestPoint_Clone_Integer(t *testing.T) {
    36  	p := &query.IntegerPoint{
    37  		Name:  "cpu",
    38  		Tags:  ParseTags("host=server01"),
    39  		Time:  5,
    40  		Value: 2,
    41  		Aux:   []interface{}{float64(45)},
    42  	}
    43  	c := p.Clone()
    44  	if p == c {
    45  		t.Errorf("clone has the same address as the original: %v == %v", p, c)
    46  	}
    47  	if !deep.Equal(p, c) {
    48  		t.Errorf("mismatched point: %s", spew.Sdump(c))
    49  	}
    50  	if &p.Aux[0] == &c.Aux[0] {
    51  		t.Errorf("aux values share the same address: %v == %v", p.Aux, c.Aux)
    52  	} else if !deep.Equal(p.Aux, c.Aux) {
    53  		t.Errorf("mismatched aux fields: %v != %v", p.Aux, c.Aux)
    54  	}
    55  }
    56  
    57  func TestPoint_Clone_String(t *testing.T) {
    58  	p := &query.StringPoint{
    59  		Name:  "cpu",
    60  		Tags:  ParseTags("host=server01"),
    61  		Time:  5,
    62  		Value: "clone",
    63  		Aux:   []interface{}{float64(45)},
    64  	}
    65  	c := p.Clone()
    66  	if p == c {
    67  		t.Errorf("clone has the same address as the original: %v == %v", p, c)
    68  	}
    69  	if !deep.Equal(p, c) {
    70  		t.Errorf("mismatched point: %s", spew.Sdump(c))
    71  	}
    72  	if &p.Aux[0] == &c.Aux[0] {
    73  		t.Errorf("aux values share the same address: %v == %v", p.Aux, c.Aux)
    74  	} else if !deep.Equal(p.Aux, c.Aux) {
    75  		t.Errorf("mismatched aux fields: %v != %v", p.Aux, c.Aux)
    76  	}
    77  }
    78  
    79  func TestPoint_Clone_Boolean(t *testing.T) {
    80  	p := &query.BooleanPoint{
    81  		Name:  "cpu",
    82  		Tags:  ParseTags("host=server01"),
    83  		Time:  5,
    84  		Value: true,
    85  		Aux:   []interface{}{float64(45)},
    86  	}
    87  	c := p.Clone()
    88  	if p == c {
    89  		t.Errorf("clone has the same address as the original: %v == %v", p, c)
    90  	}
    91  	if !deep.Equal(p, c) {
    92  		t.Errorf("mismatched point: %s", spew.Sdump(c))
    93  	}
    94  	if &p.Aux[0] == &c.Aux[0] {
    95  		t.Errorf("aux values share the same address: %v == %v", p.Aux, c.Aux)
    96  	} else if !deep.Equal(p.Aux, c.Aux) {
    97  		t.Errorf("mismatched aux fields: %v != %v", p.Aux, c.Aux)
    98  	}
    99  }
   100  
   101  func TestPoint_Clone_Nil(t *testing.T) {
   102  	var fp *query.FloatPoint
   103  	if p := fp.Clone(); p != nil {
   104  		t.Errorf("expected nil, got %v", p)
   105  	}
   106  
   107  	var ip *query.IntegerPoint
   108  	if p := ip.Clone(); p != nil {
   109  		t.Errorf("expected nil, got %v", p)
   110  	}
   111  
   112  	var sp *query.StringPoint
   113  	if p := sp.Clone(); p != nil {
   114  		t.Errorf("expected nil, got %v", p)
   115  	}
   116  
   117  	var bp *query.BooleanPoint
   118  	if p := bp.Clone(); p != nil {
   119  		t.Errorf("expected nil, got %v", p)
   120  	}
   121  }
   122  
   123  // TestPoint_Fields ensures that no additional fields are added to the point structs.
   124  // This struct is very sensitive and can effect performance unless handled carefully.
   125  // To avoid the struct becoming a dumping ground for every function that needs to store
   126  // miscellaneous information, this test is meant to ensure that new fields don't slip
   127  // into the struct.
   128  func TestPoint_Fields(t *testing.T) {
   129  	allowedFields := map[string]bool{
   130  		"Name":       true,
   131  		"Tags":       true,
   132  		"Time":       true,
   133  		"Nil":        true,
   134  		"Value":      true,
   135  		"Aux":        true,
   136  		"Aggregated": true,
   137  	}
   138  
   139  	for _, typ := range []reflect.Type{
   140  		reflect.TypeOf(query.FloatPoint{}),
   141  		reflect.TypeOf(query.IntegerPoint{}),
   142  		reflect.TypeOf(query.StringPoint{}),
   143  		reflect.TypeOf(query.BooleanPoint{}),
   144  	} {
   145  		f, ok := typ.FieldByNameFunc(func(name string) bool {
   146  			return !allowedFields[name]
   147  		})
   148  		if ok {
   149  			t.Errorf("found an unallowed field in %s: %s %s", typ, f.Name, f.Type)
   150  		}
   151  	}
   152  }
   153  
   154  // Ensure that tags can return a unique id.
   155  func TestTags_ID(t *testing.T) {
   156  	tags := query.NewTags(map[string]string{"foo": "bar", "baz": "bat"})
   157  	if id := tags.ID(); id != "baz\x00foo\x00bat\x00bar" {
   158  		t.Fatalf("unexpected id: %q", id)
   159  	}
   160  }
   161  
   162  // Ensure that a subset can be created from a tag set.
   163  func TestTags_Subset(t *testing.T) {
   164  	tags := query.NewTags(map[string]string{"a": "0", "b": "1", "c": "2"})
   165  	subset := tags.Subset([]string{"b", "c", "d"})
   166  	if keys := subset.Keys(); !reflect.DeepEqual(keys, []string{"b", "c", "d"}) {
   167  		t.Fatalf("unexpected keys: %+v", keys)
   168  	} else if v := subset.Value("a"); v != "" {
   169  		t.Fatalf("unexpected 'a' value: %s", v)
   170  	} else if v := subset.Value("b"); v != "1" {
   171  		t.Fatalf("unexpected 'b' value: %s", v)
   172  	} else if v := subset.Value("c"); v != "2" {
   173  		t.Fatalf("unexpected 'c' value: %s", v)
   174  	} else if v := subset.Value("d"); v != "" {
   175  		t.Fatalf("unexpected 'd' value: %s", v)
   176  	}
   177  }
   178  
   179  // ParseTags returns an instance of Tags for a comma-delimited list of key/values.
   180  func ParseTags(s string) query.Tags {
   181  	m := make(map[string]string)
   182  	for _, kv := range strings.Split(s, ",") {
   183  		a := strings.Split(kv, "=")
   184  		m[a[0]] = a[1]
   185  	}
   186  	return query.NewTags(m)
   187  }