github.com/hashicorp/go-metrics@v0.5.3/sink_test.go (about)

     1  package metrics
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	"sync"
     7  	"testing"
     8  )
     9  
    10  type MockSink struct {
    11  	lock sync.Mutex
    12  
    13  	shutdown      bool
    14  	keys          [][]string
    15  	vals          []float32
    16  	precisionVals []float64
    17  	labels        [][]Label
    18  }
    19  
    20  func (m *MockSink) getKeys() [][]string {
    21  	m.lock.Lock()
    22  	defer m.lock.Unlock()
    23  
    24  	return m.keys
    25  }
    26  
    27  func (m *MockSink) SetGauge(key []string, val float32) {
    28  	m.SetGaugeWithLabels(key, val, nil)
    29  }
    30  func (m *MockSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
    31  	m.lock.Lock()
    32  	defer m.lock.Unlock()
    33  
    34  	m.keys = append(m.keys, key)
    35  	m.vals = append(m.vals, val)
    36  	m.labels = append(m.labels, labels)
    37  }
    38  func (m *MockSink) SetPrecisionGauge(key []string, val float64) {
    39  	m.SetPrecisionGaugeWithLabels(key, val, nil)
    40  }
    41  func (m *MockSink) SetPrecisionGaugeWithLabels(key []string, val float64, labels []Label) {
    42  	m.lock.Lock()
    43  	defer m.lock.Unlock()
    44  
    45  	m.keys = append(m.keys, key)
    46  	m.precisionVals = append(m.precisionVals, val)
    47  	m.labels = append(m.labels, labels)
    48  }
    49  func (m *MockSink) EmitKey(key []string, val float32) {
    50  	m.lock.Lock()
    51  	defer m.lock.Unlock()
    52  
    53  	m.keys = append(m.keys, key)
    54  	m.vals = append(m.vals, val)
    55  	m.labels = append(m.labels, nil)
    56  }
    57  func (m *MockSink) IncrCounter(key []string, val float32) {
    58  	m.IncrCounterWithLabels(key, val, nil)
    59  }
    60  func (m *MockSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
    61  	m.lock.Lock()
    62  	defer m.lock.Unlock()
    63  
    64  	m.keys = append(m.keys, key)
    65  	m.vals = append(m.vals, val)
    66  	m.labels = append(m.labels, labels)
    67  }
    68  func (m *MockSink) AddSample(key []string, val float32) {
    69  	m.AddSampleWithLabels(key, val, nil)
    70  }
    71  func (m *MockSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
    72  	m.lock.Lock()
    73  	defer m.lock.Unlock()
    74  
    75  	m.keys = append(m.keys, key)
    76  	m.vals = append(m.vals, val)
    77  	m.labels = append(m.labels, labels)
    78  }
    79  func (m *MockSink) Shutdown() {
    80  	m.lock.Lock()
    81  	defer m.lock.Unlock()
    82  
    83  	m.shutdown = true
    84  }
    85  
    86  func TestFanoutSink_Gauge(t *testing.T) {
    87  	m1 := &MockSink{}
    88  	m2 := &MockSink{}
    89  	fh := &FanoutSink{m1, m2}
    90  
    91  	k := []string{"test"}
    92  	v := float32(42.0)
    93  	fh.SetGauge(k, v)
    94  
    95  	if !reflect.DeepEqual(m1.keys[0], k) {
    96  		t.Fatalf("key not equal")
    97  	}
    98  	if !reflect.DeepEqual(m2.keys[0], k) {
    99  		t.Fatalf("key not equal")
   100  	}
   101  	if !reflect.DeepEqual(m1.vals[0], v) {
   102  		t.Fatalf("val not equal")
   103  	}
   104  	if !reflect.DeepEqual(m2.vals[0], v) {
   105  		t.Fatalf("val not equal")
   106  	}
   107  }
   108  
   109  func TestFanoutSink_Gauge_Labels(t *testing.T) {
   110  	m1 := &MockSink{}
   111  	m2 := &MockSink{}
   112  	fh := &FanoutSink{m1, m2}
   113  
   114  	k := []string{"test"}
   115  	v := float32(42.0)
   116  	l := []Label{{"a", "b"}}
   117  	fh.SetGaugeWithLabels(k, v, l)
   118  
   119  	if !reflect.DeepEqual(m1.keys[0], k) {
   120  		t.Fatalf("key not equal")
   121  	}
   122  	if !reflect.DeepEqual(m2.keys[0], k) {
   123  		t.Fatalf("key not equal")
   124  	}
   125  	if !reflect.DeepEqual(m1.vals[0], v) {
   126  		t.Fatalf("val not equal")
   127  	}
   128  	if !reflect.DeepEqual(m2.vals[0], v) {
   129  		t.Fatalf("val not equal")
   130  	}
   131  	if !reflect.DeepEqual(m1.labels[0], l) {
   132  		t.Fatalf("labels not equal")
   133  	}
   134  	if !reflect.DeepEqual(m2.labels[0], l) {
   135  		t.Fatalf("labels not equal")
   136  	}
   137  }
   138  
   139  func TestFanoutSink_Key(t *testing.T) {
   140  	m1 := &MockSink{}
   141  	m2 := &MockSink{}
   142  	fh := &FanoutSink{m1, m2}
   143  
   144  	k := []string{"test"}
   145  	v := float32(42.0)
   146  	fh.EmitKey(k, v)
   147  
   148  	if !reflect.DeepEqual(m1.keys[0], k) {
   149  		t.Fatalf("key not equal")
   150  	}
   151  	if !reflect.DeepEqual(m2.keys[0], k) {
   152  		t.Fatalf("key not equal")
   153  	}
   154  	if !reflect.DeepEqual(m1.vals[0], v) {
   155  		t.Fatalf("val not equal")
   156  	}
   157  	if !reflect.DeepEqual(m2.vals[0], v) {
   158  		t.Fatalf("val not equal")
   159  	}
   160  }
   161  
   162  func TestFanoutSink_Counter(t *testing.T) {
   163  	m1 := &MockSink{}
   164  	m2 := &MockSink{}
   165  	fh := &FanoutSink{m1, m2}
   166  
   167  	k := []string{"test"}
   168  	v := float32(42.0)
   169  	fh.IncrCounter(k, v)
   170  
   171  	if !reflect.DeepEqual(m1.keys[0], k) {
   172  		t.Fatalf("key not equal")
   173  	}
   174  	if !reflect.DeepEqual(m2.keys[0], k) {
   175  		t.Fatalf("key not equal")
   176  	}
   177  	if !reflect.DeepEqual(m1.vals[0], v) {
   178  		t.Fatalf("val not equal")
   179  	}
   180  	if !reflect.DeepEqual(m2.vals[0], v) {
   181  		t.Fatalf("val not equal")
   182  	}
   183  }
   184  
   185  func TestFanoutSink_Counter_Labels(t *testing.T) {
   186  	m1 := &MockSink{}
   187  	m2 := &MockSink{}
   188  	fh := &FanoutSink{m1, m2}
   189  
   190  	k := []string{"test"}
   191  	v := float32(42.0)
   192  	l := []Label{{"a", "b"}}
   193  	fh.IncrCounterWithLabels(k, v, l)
   194  
   195  	if !reflect.DeepEqual(m1.keys[0], k) {
   196  		t.Fatalf("key not equal")
   197  	}
   198  	if !reflect.DeepEqual(m2.keys[0], k) {
   199  		t.Fatalf("key not equal")
   200  	}
   201  	if !reflect.DeepEqual(m1.vals[0], v) {
   202  		t.Fatalf("val not equal")
   203  	}
   204  	if !reflect.DeepEqual(m2.vals[0], v) {
   205  		t.Fatalf("val not equal")
   206  	}
   207  	if !reflect.DeepEqual(m1.labels[0], l) {
   208  		t.Fatalf("labels not equal")
   209  	}
   210  	if !reflect.DeepEqual(m2.labels[0], l) {
   211  		t.Fatalf("labels not equal")
   212  	}
   213  }
   214  
   215  func TestFanoutSink_Sample(t *testing.T) {
   216  	m1 := &MockSink{}
   217  	m2 := &MockSink{}
   218  	fh := &FanoutSink{m1, m2}
   219  
   220  	k := []string{"test"}
   221  	v := float32(42.0)
   222  	fh.AddSample(k, v)
   223  
   224  	if !reflect.DeepEqual(m1.keys[0], k) {
   225  		t.Fatalf("key not equal")
   226  	}
   227  	if !reflect.DeepEqual(m2.keys[0], k) {
   228  		t.Fatalf("key not equal")
   229  	}
   230  	if !reflect.DeepEqual(m1.vals[0], v) {
   231  		t.Fatalf("val not equal")
   232  	}
   233  	if !reflect.DeepEqual(m2.vals[0], v) {
   234  		t.Fatalf("val not equal")
   235  	}
   236  }
   237  
   238  func TestFanoutSink_Sample_Labels(t *testing.T) {
   239  	m1 := &MockSink{}
   240  	m2 := &MockSink{}
   241  	fh := &FanoutSink{m1, m2}
   242  
   243  	k := []string{"test"}
   244  	v := float32(42.0)
   245  	l := []Label{{"a", "b"}}
   246  	fh.AddSampleWithLabels(k, v, l)
   247  
   248  	if !reflect.DeepEqual(m1.keys[0], k) {
   249  		t.Fatalf("key not equal")
   250  	}
   251  	if !reflect.DeepEqual(m2.keys[0], k) {
   252  		t.Fatalf("key not equal")
   253  	}
   254  	if !reflect.DeepEqual(m1.vals[0], v) {
   255  		t.Fatalf("val not equal")
   256  	}
   257  	if !reflect.DeepEqual(m2.vals[0], v) {
   258  		t.Fatalf("val not equal")
   259  	}
   260  	if !reflect.DeepEqual(m1.labels[0], l) {
   261  		t.Fatalf("labels not equal")
   262  	}
   263  	if !reflect.DeepEqual(m2.labels[0], l) {
   264  		t.Fatalf("labels not equal")
   265  	}
   266  }
   267  
   268  func TestNewMetricSinkFromURL(t *testing.T) {
   269  	for _, tc := range []struct {
   270  		desc      string
   271  		input     string
   272  		expect    reflect.Type
   273  		expectErr string
   274  	}{
   275  		{
   276  			desc:   "statsd scheme yields a StatsdSink",
   277  			input:  "statsd://someserver:123",
   278  			expect: reflect.TypeOf(&StatsdSink{}),
   279  		},
   280  		{
   281  			desc:   "statsite scheme yields a StatsiteSink",
   282  			input:  "statsite://someserver:123",
   283  			expect: reflect.TypeOf(&StatsiteSink{}),
   284  		},
   285  		{
   286  			desc:   "inmem scheme yields an InmemSink",
   287  			input:  "inmem://?interval=30s&retain=30s",
   288  			expect: reflect.TypeOf(&InmemSink{}),
   289  		},
   290  		{
   291  			desc:      "unknown scheme yields an error",
   292  			input:     "notasink://whatever",
   293  			expectErr: "unrecognized sink name: \"notasink\"",
   294  		},
   295  	} {
   296  		t.Run(tc.desc, func(t *testing.T) {
   297  			ms, err := NewMetricSinkFromURL(tc.input)
   298  			if tc.expectErr != "" {
   299  				if !strings.Contains(err.Error(), tc.expectErr) {
   300  					t.Fatalf("expected err: %q to contain: %q", err, tc.expectErr)
   301  				}
   302  			} else {
   303  				if err != nil {
   304  					t.Fatalf("unexpected err: %s", err)
   305  				}
   306  				got := reflect.TypeOf(ms)
   307  				if got != tc.expect {
   308  					t.Fatalf("expected return type to be %v, got: %v", tc.expect, got)
   309  				}
   310  			}
   311  		})
   312  	}
   313  }