vitess.io/vitess@v0.16.2/go/stats/opentsdb/opentsdb_test.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package opentsdb
    18  
    19  import (
    20  	"encoding/json"
    21  	"expvar"
    22  	"reflect"
    23  	"sort"
    24  	"testing"
    25  	"time"
    26  
    27  	"vitess.io/vitess/go/stats"
    28  )
    29  
    30  func TestOpenTsdbCounter(t *testing.T) {
    31  	name := "counter_name"
    32  	c := stats.NewCounter(name, "counter description")
    33  	c.Add(1)
    34  
    35  	checkOutput(t, name, `
    36  		[
    37  		  {
    38  		    "metric": "vtgate.counter_name",
    39  		    "timestamp": 1234,
    40  		    "value": 1,
    41  		    "tags": {
    42  		      "host": "localhost"
    43  		    }
    44  		  }
    45  		]`)
    46  }
    47  
    48  func TestOpenTsdbCounterFunc(t *testing.T) {
    49  	name := "counter_fn_name"
    50  	stats.NewCounterFunc(name, "help", func() int64 {
    51  		return 2
    52  	})
    53  	checkOutput(t, name, `
    54  		[
    55  		  {
    56  		    "metric": "vtgate.counter_fn_name",
    57  		    "timestamp": 1234,
    58  		    "value": 2,
    59  		    "tags": {
    60  		      "host": "localhost"
    61  		    }
    62  		  }
    63  		]`)
    64  }
    65  
    66  func TestGaugesWithMultiLabels(t *testing.T) {
    67  	name := "gauges_with_multi_labels_name"
    68  	gauges := stats.NewGaugesWithMultiLabels(name, "help", []string{"flavor", "texture"})
    69  	gauges.Add([]string{"sour", "brittle"}, 3)
    70  
    71  	checkOutput(t, name, `
    72  		[
    73  			{
    74  		    "metric": "vtgate.gauges_with_multi_labels_name",
    75  		    "timestamp": 1234,
    76  		    "value": 3,
    77  		    "tags": {
    78  		      "flavor": "sour",
    79  		      "host": "localhost",
    80  		      "texture": "brittle"
    81  		    }
    82  		  }
    83  		]`)
    84  }
    85  
    86  type myVar bool
    87  
    88  func (mv *myVar) String() string {
    89  	return `{"myKey": 1.2}`
    90  }
    91  
    92  func TestExpvar(t *testing.T) {
    93  	name := "blah_expvar"
    94  	expvar.Publish(name, new(myVar))
    95  	checkOutput(t, name, `
    96  		[
    97  		  {
    98  		    "metric": "vtgate.expvar.blah_expvar.mykey",
    99  		    "timestamp": 1234,
   100  		    "value": 1.2,
   101  		    "tags": {
   102  		      "host": "localhost"
   103  		    }
   104  		  }
   105  		]`)
   106  }
   107  
   108  func TestOpenTsdbTimings(t *testing.T) {
   109  	name := "blah_timings"
   110  	cats := []string{"cat1", "cat2"}
   111  	timing := stats.NewTimings(name, "help", "category", cats...)
   112  	timing.Add("cat1", time.Duration(1000000000))
   113  	timing.Add("cat1", time.Duration(1))
   114  
   115  	checkOutput(t, name, `
   116  		[
   117  		  {
   118  		    "metric": "vtgate.blah_timings.1000000",
   119  		    "timestamp": 1234,
   120  		    "value": 0,
   121  		    "tags": {
   122  		      "category": "cat1",
   123  		      "host": "localhost"
   124  		    }
   125  		  },
   126  		  {
   127  		    "metric": "vtgate.blah_timings.1000000",
   128  		    "timestamp": 1234,
   129  		    "value": 0,
   130  		    "tags": {
   131  		      "category": "cat2",
   132  		      "host": "localhost"
   133  		    }
   134  		  },
   135  		  {
   136  		    "metric": "vtgate.blah_timings.10000000",
   137  		    "timestamp": 1234,
   138  		    "value": 0,
   139  		    "tags": {
   140  		      "category": "cat1",
   141  		      "host": "localhost"
   142  		    }
   143  		  },
   144  		  {
   145  		    "metric": "vtgate.blah_timings.10000000",
   146  		    "timestamp": 1234,
   147  		    "value": 0,
   148  		    "tags": {
   149  		      "category": "cat2",
   150  		      "host": "localhost"
   151  		    }
   152  		  },
   153  		  {
   154  		    "metric": "vtgate.blah_timings.100000000",
   155  		    "timestamp": 1234,
   156  		    "value": 0,
   157  		    "tags": {
   158  		      "category": "cat1",
   159  		      "host": "localhost"
   160  		    }
   161  		  },
   162  		  {
   163  		    "metric": "vtgate.blah_timings.100000000",
   164  		    "timestamp": 1234,
   165  		    "value": 0,
   166  		    "tags": {
   167  		      "category": "cat2",
   168  		      "host": "localhost"
   169  		    }
   170  		  },
   171  		  {
   172  		    "metric": "vtgate.blah_timings.1000000000",
   173  		    "timestamp": 1234,
   174  		    "value": 1,
   175  		    "tags": {
   176  		      "category": "cat1",
   177  		      "host": "localhost"
   178  		    }
   179  		  },
   180  		  {
   181  		    "metric": "vtgate.blah_timings.1000000000",
   182  		    "timestamp": 1234,
   183  		    "value": 0,
   184  		    "tags": {
   185  		      "category": "cat2",
   186  		      "host": "localhost"
   187  		    }
   188  		  },
   189  		  {
   190  		    "metric": "vtgate.blah_timings.10000000000",
   191  		    "timestamp": 1234,
   192  		    "value": 0,
   193  		    "tags": {
   194  		      "category": "cat1",
   195  		      "host": "localhost"
   196  		    }
   197  		  },
   198  		  {
   199  		    "metric": "vtgate.blah_timings.10000000000",
   200  		    "timestamp": 1234,
   201  		    "value": 0,
   202  		    "tags": {
   203  		      "category": "cat2",
   204  		      "host": "localhost"
   205  		    }
   206  		  },
   207  		  {
   208  		    "metric": "vtgate.blah_timings.500000",
   209  		    "timestamp": 1234,
   210  		    "value": 1,
   211  		    "tags": {
   212  		      "category": "cat1",
   213  		      "host": "localhost"
   214  		    }
   215  		  },
   216  		  {
   217  		    "metric": "vtgate.blah_timings.500000",
   218  		    "timestamp": 1234,
   219  		    "value": 0,
   220  		    "tags": {
   221  		      "category": "cat2",
   222  		      "host": "localhost"
   223  		    }
   224  		  },
   225  		  {
   226  		    "metric": "vtgate.blah_timings.5000000",
   227  		    "timestamp": 1234,
   228  		    "value": 0,
   229  		    "tags": {
   230  		      "category": "cat1",
   231  		      "host": "localhost"
   232  		    }
   233  		  },
   234  		  {
   235  		    "metric": "vtgate.blah_timings.5000000",
   236  		    "timestamp": 1234,
   237  		    "value": 0,
   238  		    "tags": {
   239  		      "category": "cat2",
   240  		      "host": "localhost"
   241  		    }
   242  		  },
   243  		  {
   244  		    "metric": "vtgate.blah_timings.50000000",
   245  		    "timestamp": 1234,
   246  		    "value": 0,
   247  		    "tags": {
   248  		      "category": "cat1",
   249  		      "host": "localhost"
   250  		    }
   251  		  },
   252  		  {
   253  		    "metric": "vtgate.blah_timings.50000000",
   254  		    "timestamp": 1234,
   255  		    "value": 0,
   256  		    "tags": {
   257  		      "category": "cat2",
   258  		      "host": "localhost"
   259  		    }
   260  		  },
   261  		  {
   262  		    "metric": "vtgate.blah_timings.500000000",
   263  		    "timestamp": 1234,
   264  		    "value": 0,
   265  		    "tags": {
   266  		      "category": "cat1",
   267  		      "host": "localhost"
   268  		    }
   269  		  },
   270  		  {
   271  		    "metric": "vtgate.blah_timings.500000000",
   272  		    "timestamp": 1234,
   273  		    "value": 0,
   274  		    "tags": {
   275  		      "category": "cat2",
   276  		      "host": "localhost"
   277  		    }
   278  		  },
   279  		  {
   280  		    "metric": "vtgate.blah_timings.5000000000",
   281  		    "timestamp": 1234,
   282  		    "value": 0,
   283  		    "tags": {
   284  		      "category": "cat1",
   285  		      "host": "localhost"
   286  		    }
   287  		  },
   288  		  {
   289  		    "metric": "vtgate.blah_timings.5000000000",
   290  		    "timestamp": 1234,
   291  		    "value": 0,
   292  		    "tags": {
   293  		      "category": "cat2",
   294  		      "host": "localhost"
   295  		    }
   296  		  },
   297  		  {
   298  		    "metric": "vtgate.blah_timings.count",
   299  		    "timestamp": 1234,
   300  		    "value": 2,
   301  		    "tags": {
   302  		      "category": "cat1",
   303  		      "host": "localhost"
   304  		    }
   305  		  },
   306  		  {
   307  		    "metric": "vtgate.blah_timings.count",
   308  		    "timestamp": 1234,
   309  		    "value": 0,
   310  		    "tags": {
   311  		      "category": "cat2",
   312  		      "host": "localhost"
   313  		    }
   314  		  },
   315  		  {
   316  		    "metric": "vtgate.blah_timings.inf",
   317  		    "timestamp": 1234,
   318  		    "value": 0,
   319  		    "tags": {
   320  		      "category": "cat1",
   321  		      "host": "localhost"
   322  		    }
   323  		  },
   324  		  {
   325  		    "metric": "vtgate.blah_timings.inf",
   326  		    "timestamp": 1234,
   327  		    "value": 0,
   328  		    "tags": {
   329  		      "category": "cat2",
   330  		      "host": "localhost"
   331  		    }
   332  		  },
   333  		  {
   334  		    "metric": "vtgate.blah_timings.time",
   335  		    "timestamp": 1234,
   336  		    "value": 1000000001,
   337  		    "tags": {
   338  		      "category": "cat1",
   339  		      "host": "localhost"
   340  		    }
   341  		  },
   342  		  {
   343  		    "metric": "vtgate.blah_timings.time",
   344  		    "timestamp": 1234,
   345  		    "value": 0,
   346  		    "tags": {
   347  		      "category": "cat2",
   348  		      "host": "localhost"
   349  		    }
   350  		  }
   351  		]`)
   352  }
   353  
   354  func checkOutput(t *testing.T, statName string, wantJSON string) {
   355  	backend := &openTSDBBackend{
   356  		prefix:     "vtgate",
   357  		commonTags: map[string]string{"host": "localhost"},
   358  	}
   359  	timestamp := int64(1234)
   360  
   361  	dc := &dataCollector{
   362  		settings:  backend,
   363  		timestamp: timestamp,
   364  	}
   365  	found := false
   366  	expvar.Do(func(kv expvar.KeyValue) {
   367  		if kv.Key == statName {
   368  			found = true
   369  
   370  			dc.addExpVar(kv)
   371  			sort.Sort(byMetric(dc.dataPoints))
   372  
   373  			gotBytes, err := json.MarshalIndent(dc.dataPoints, "", "  ")
   374  			if err != nil {
   375  				t.Errorf("Failed to marshal json: %v", err)
   376  				return
   377  			}
   378  			var got any
   379  			err = json.Unmarshal(gotBytes, &got)
   380  			if err != nil {
   381  				t.Errorf("Failed to marshal json: %v", err)
   382  				return
   383  			}
   384  
   385  			var want any
   386  			err = json.Unmarshal([]byte(wantJSON), &want)
   387  			if err != nil {
   388  				t.Errorf("Failed to marshal json: %v", err)
   389  				return
   390  			}
   391  
   392  			if !reflect.DeepEqual(got, want) {
   393  				t.Errorf("addExpVar(%#v) = %s, want %s", kv, string(gotBytes), wantJSON)
   394  			}
   395  		}
   396  	})
   397  	if !found {
   398  		t.Errorf("Stat %s not found?...", statName)
   399  	}
   400  }