github.com/bitly/statsdaemon@v0.7.3/statsdaemon_test.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"flag"
     6  	"math"
     7  	"math/rand"
     8  	"net"
     9  	"strconv"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  var commonPercentiles = Percentiles{
    18  	&Percentile{
    19  		99,
    20  		"99",
    21  	},
    22  }
    23  
    24  type TestUdpReader struct {
    25  	Pattern []byte
    26  }
    27  
    28  func (r *TestUdpReader) Read(p []byte) (int, error) {
    29  	return copy(p, r.Pattern), nil
    30  }
    31  
    32  type TestTcpReader struct {
    33  	Pattern  []byte
    34  	ReadSize int
    35  	off      int
    36  }
    37  
    38  func (r *TestTcpReader) Read(p []byte) (int, error) {
    39  	poff := 0
    40  	end := r.ReadSize
    41  	if end > len(p) {
    42  		end = len(p)
    43  	}
    44  	for poff < end {
    45  		c := copy(p[poff:end], r.Pattern[r.off:])
    46  		poff += c
    47  		r.off += c
    48  		if r.off == len(r.Pattern) {
    49  			r.off = 0
    50  		}
    51  	}
    52  	return end, nil
    53  }
    54  
    55  func TestParseLineGauge(t *testing.T) {
    56  	d := []byte("gaugor:333|g")
    57  	packet := parseLine(d)
    58  	assert.NotEqual(t, packet, nil)
    59  	assert.Equal(t, "gaugor", packet.Bucket)
    60  	assert.Equal(t, float64(333), packet.ValFlt)
    61  	assert.Equal(t, "", packet.ValStr)
    62  	assert.Equal(t, "g", packet.Modifier)
    63  	assert.Equal(t, float32(1), packet.Sampling)
    64  
    65  	d = []byte("gaugor:-10|g")
    66  	packet = parseLine(d)
    67  	assert.NotEqual(t, packet, nil)
    68  	assert.Equal(t, "gaugor", packet.Bucket)
    69  	assert.Equal(t, float64(10), packet.ValFlt)
    70  	assert.Equal(t, "-", packet.ValStr)
    71  	assert.Equal(t, "g", packet.Modifier)
    72  	assert.Equal(t, float32(1), packet.Sampling)
    73  
    74  	d = []byte("gaugor:+4|g")
    75  	packet = parseLine(d)
    76  	assert.NotEqual(t, packet, nil)
    77  	assert.Equal(t, "gaugor", packet.Bucket)
    78  	assert.Equal(t, float64(4), packet.ValFlt)
    79  	assert.Equal(t, "+", packet.ValStr)
    80  	assert.Equal(t, "g", packet.Modifier)
    81  	assert.Equal(t, float32(1), packet.Sampling)
    82  
    83  	// >max(int64) && <max(uint64)
    84  	d = []byte("gaugor:18446744073709551606|g")
    85  	packet = parseLine(d)
    86  	assert.NotEqual(t, packet, nil)
    87  	assert.Equal(t, "gaugor", packet.Bucket)
    88  	assert.Equal(t, float64(18446744073709551606), packet.ValFlt)
    89  	assert.Equal(t, "", packet.ValStr)
    90  	assert.Equal(t, "g", packet.Modifier)
    91  	assert.Equal(t, float32(1), packet.Sampling)
    92  
    93  	// float values
    94  	d = []byte("gaugor:3.3333|g")
    95  	packet = parseLine(d)
    96  	assert.NotEqual(t, packet, nil)
    97  	assert.Equal(t, "gaugor", packet.Bucket)
    98  	assert.Equal(t, float64(3.3333), packet.ValFlt)
    99  	assert.Equal(t, "", packet.ValStr)
   100  	assert.Equal(t, "g", packet.Modifier)
   101  	assert.Equal(t, float32(1), packet.Sampling)
   102  }
   103  
   104  func TestParseLineCount(t *testing.T) {
   105  	d := []byte("gorets:2|c|@0.1")
   106  	packet := parseLine(d)
   107  	assert.NotEqual(t, packet, nil)
   108  	assert.Equal(t, "gorets", packet.Bucket)
   109  	assert.Equal(t, float64(2), packet.ValFlt)
   110  	assert.Equal(t, "c", packet.Modifier)
   111  	assert.Equal(t, float32(0.1), packet.Sampling)
   112  
   113  	d = []byte("gorets:4|c")
   114  	packet = parseLine(d)
   115  	assert.NotEqual(t, packet, nil)
   116  	assert.Equal(t, "gorets", packet.Bucket)
   117  	assert.Equal(t, float64(4), packet.ValFlt)
   118  	assert.Equal(t, "c", packet.Modifier)
   119  	assert.Equal(t, float32(1), packet.Sampling)
   120  
   121  	d = []byte("gorets:-4|c")
   122  	packet = parseLine(d)
   123  	assert.NotEqual(t, packet, nil)
   124  	assert.Equal(t, "gorets", packet.Bucket)
   125  	assert.Equal(t, float64(-4), packet.ValFlt)
   126  	assert.Equal(t, "c", packet.Modifier)
   127  	assert.Equal(t, float32(1), packet.Sampling)
   128  
   129  	d = []byte("gorets:1.25|c")
   130  	packet = parseLine(d)
   131  	assert.NotEqual(t, packet, nil)
   132  	assert.Equal(t, "gorets", packet.Bucket)
   133  	assert.Equal(t, 1.25, packet.ValFlt)
   134  	assert.Equal(t, "c", packet.Modifier)
   135  	assert.Equal(t, float32(1), packet.Sampling)
   136  }
   137  
   138  func TestParseLineTimer(t *testing.T) {
   139  	d := []byte("glork:320|ms")
   140  	packet := parseLine(d)
   141  	assert.NotEqual(t, packet, nil)
   142  	assert.Equal(t, "glork", packet.Bucket)
   143  	assert.Equal(t, float64(320), packet.ValFlt)
   144  	assert.Equal(t, "ms", packet.Modifier)
   145  	assert.Equal(t, float32(1), packet.Sampling)
   146  
   147  	d = []byte("glork:320|ms|@0.1")
   148  	packet = parseLine(d)
   149  	assert.NotEqual(t, packet, nil)
   150  	assert.Equal(t, "glork", packet.Bucket)
   151  	assert.Equal(t, float64(320), packet.ValFlt)
   152  	assert.Equal(t, "ms", packet.Modifier)
   153  	assert.Equal(t, float32(0.1), packet.Sampling)
   154  
   155  	d = []byte("glork:3.7211|ms")
   156  	packet = parseLine(d)
   157  	assert.NotEqual(t, packet, nil)
   158  	assert.Equal(t, "glork", packet.Bucket)
   159  	assert.Equal(t, float64(3.7211), packet.ValFlt)
   160  	assert.Equal(t, "ms", packet.Modifier)
   161  	assert.Equal(t, float32(1), packet.Sampling)
   162  }
   163  
   164  func TestParseLineSet(t *testing.T) {
   165  	d := []byte("uniques:765|s")
   166  	packet := parseLine(d)
   167  	assert.NotEqual(t, packet, nil)
   168  	assert.Equal(t, "uniques", packet.Bucket)
   169  	assert.Equal(t, "765", packet.ValStr)
   170  	assert.Equal(t, "s", packet.Modifier)
   171  	assert.Equal(t, float32(1), packet.Sampling)
   172  }
   173  
   174  func TestParseLineMisc(t *testing.T) {
   175  	d := []byte("a.key.with-0.dash:4|c")
   176  	packet := parseLine(d)
   177  	assert.NotEqual(t, packet, nil)
   178  	assert.Equal(t, "a.key.with-0.dash", packet.Bucket)
   179  	assert.Equal(t, float64(4), packet.ValFlt)
   180  	assert.Equal(t, "c", packet.Modifier)
   181  	assert.Equal(t, float32(1), packet.Sampling)
   182  
   183  	d = []byte("a.key.with 0.space:4|c")
   184  	packet = parseLine(d)
   185  	assert.Equal(t, "a.key.with_0.space", packet.Bucket)
   186  	assert.Equal(t, float64(4), packet.ValFlt)
   187  	assert.Equal(t, "c", packet.Modifier)
   188  	assert.Equal(t, float32(1), packet.Sampling)
   189  
   190  	d = []byte("a.key.with/0.slash:4|c")
   191  	packet = parseLine(d)
   192  	assert.Equal(t, "a.key.with-0.slash", packet.Bucket)
   193  	assert.Equal(t, float64(4), packet.ValFlt)
   194  	assert.Equal(t, "c", packet.Modifier)
   195  	assert.Equal(t, float32(1), packet.Sampling)
   196  
   197  	d = []byte("a.key.with@#*&%$^_0.garbage:4|c")
   198  	packet = parseLine(d)
   199  	assert.Equal(t, "a.key.with_0.garbage", packet.Bucket)
   200  	assert.Equal(t, float64(4), packet.ValFlt)
   201  	assert.Equal(t, "c", packet.Modifier)
   202  	assert.Equal(t, float32(1), packet.Sampling)
   203  
   204  	flag.Set("prefix", "test.")
   205  	d = []byte("prefix:4|c")
   206  	packet = parseLine(d)
   207  	assert.Equal(t, "test.prefix", packet.Bucket)
   208  	assert.Equal(t, float64(4), packet.ValFlt)
   209  	assert.Equal(t, "c", packet.Modifier)
   210  	assert.Equal(t, float32(1), packet.Sampling)
   211  	flag.Set("prefix", "")
   212  
   213  	flag.Set("postfix", ".test")
   214  	d = []byte("postfix:4|c")
   215  	packet = parseLine(d)
   216  	assert.Equal(t, "postfix.test", packet.Bucket)
   217  	assert.Equal(t, float64(4), packet.ValFlt)
   218  	assert.Equal(t, "c", packet.Modifier)
   219  	assert.Equal(t, float32(1), packet.Sampling)
   220  	flag.Set("postfix", "")
   221  
   222  	d = []byte("a.key.with-0.dash:4|c\ngauge:3|g")
   223  	parser := NewParser(bytes.NewBuffer(d), true)
   224  	packet, more := parser.Next()
   225  	assert.Equal(t, more, true)
   226  	assert.Equal(t, "a.key.with-0.dash", packet.Bucket)
   227  	assert.Equal(t, float64(4), packet.ValFlt)
   228  	assert.Equal(t, "c", packet.Modifier)
   229  	assert.Equal(t, float32(1), packet.Sampling)
   230  
   231  	packet, more = parser.Next()
   232  	assert.Equal(t, more, false)
   233  	assert.Equal(t, "gauge", packet.Bucket)
   234  	assert.Equal(t, 3.0, packet.ValFlt)
   235  	assert.Equal(t, "", packet.ValStr)
   236  	assert.Equal(t, "g", packet.Modifier)
   237  	assert.Equal(t, float32(1), packet.Sampling)
   238  
   239  	d = []byte("a.key.with-0.dash:4\ngauge3|g")
   240  	packet = parseLine(d)
   241  	if packet != nil {
   242  		t.Fail()
   243  	}
   244  
   245  	d = []byte("a.key.with-0.dash:4")
   246  	packet = parseLine(d)
   247  	if packet != nil {
   248  		t.Fail()
   249  	}
   250  
   251  	d = []byte("gorets:5m")
   252  	packet = parseLine(d)
   253  	if packet != nil {
   254  		t.Fail()
   255  	}
   256  
   257  	d = []byte("gorets")
   258  	packet = parseLine(d)
   259  	if packet != nil {
   260  		t.Fail()
   261  	}
   262  
   263  	d = []byte("gorets:")
   264  	packet = parseLine(d)
   265  	if packet != nil {
   266  		t.Fail()
   267  	}
   268  
   269  	d = []byte("gorets:5|mg")
   270  	packet = parseLine(d)
   271  	if packet != nil {
   272  		t.Fail()
   273  	}
   274  
   275  	d = []byte("gorets:5|ms|@")
   276  	packet = parseLine(d)
   277  	if packet != nil {
   278  		t.Fail()
   279  	}
   280  
   281  	d = []byte("")
   282  	packet = parseLine(d)
   283  	if packet != nil {
   284  		t.Fail()
   285  	}
   286  
   287  	d = []byte("gorets:xxx|c")
   288  	packet = parseLine(d)
   289  	if packet != nil {
   290  		t.Fail()
   291  	}
   292  
   293  	d = []byte("gaugor:xxx|g")
   294  	packet = parseLine(d)
   295  	if packet != nil {
   296  		t.Fail()
   297  	}
   298  
   299  	d = []byte("gaugor:xxx|z")
   300  	packet = parseLine(d)
   301  	if packet != nil {
   302  		t.Fail()
   303  	}
   304  
   305  	d = []byte("deploys.test.myservice4:100|t")
   306  	packet = parseLine(d)
   307  	if packet != nil {
   308  		t.Fail()
   309  	}
   310  
   311  	d = []byte("up-to-colon:")
   312  	packet = parseLine(d)
   313  	if packet != nil {
   314  		t.Fail()
   315  	}
   316  
   317  	d = []byte("up-to-pipe:1|")
   318  	packet = parseLine(d)
   319  	if packet != nil {
   320  		t.Fail()
   321  	}
   322  }
   323  
   324  func TestMultiLine(t *testing.T) {
   325  	b := bytes.NewBuffer([]byte("a.key.with-0.dash:4|c\ngauge:3|g"))
   326  	parser := NewParser(b, true)
   327  
   328  	checkTwoPackets(t, parser, false)
   329  }
   330  
   331  func checkTwoPackets(t *testing.T, parser *MsgParser, inf bool) {
   332  	packet, more := parser.Next()
   333  	assert.NotEqual(t, packet, nil)
   334  	assert.Equal(t, more, true)
   335  	assert.Equal(t, "a.key.with-0.dash", packet.Bucket)
   336  	assert.Equal(t, float64(4), packet.ValFlt)
   337  	assert.Equal(t, "c", packet.Modifier)
   338  	assert.Equal(t, float32(1), packet.Sampling)
   339  
   340  	packet, more = parser.Next()
   341  	assert.NotEqual(t, packet, nil)
   342  	assert.Equal(t, more, inf)
   343  	assert.Equal(t, "gauge", packet.Bucket)
   344  	assert.Equal(t, 3.0, packet.ValFlt)
   345  	assert.Equal(t, "", packet.ValStr)
   346  	assert.Equal(t, "g", packet.Modifier)
   347  	assert.Equal(t, float32(1), packet.Sampling)
   348  }
   349  
   350  func TestMultiUdp(t *testing.T) {
   351  	r := &TestUdpReader{[]byte("a.key.with-0.dash:4|c\ngauge:3|g")}
   352  	parser := NewParser(r, false)
   353  
   354  	checkTwoPackets(t, parser, true)
   355  	checkTwoPackets(t, parser, true)
   356  	checkTwoPackets(t, parser, true)
   357  }
   358  
   359  func TestMultiTcp(t *testing.T) {
   360  	// reads 16 bytes at a time
   361  	r := &TestTcpReader{[]byte("a.key.with-0.dash:4|c\ngauge:3|g\n"), 16, 0}
   362  	parser := NewParser(r, true)
   363  
   364  	checkTwoPackets(t, parser, true)
   365  	checkTwoPackets(t, parser, true)
   366  	checkTwoPackets(t, parser, true)
   367  }
   368  
   369  func TestPacketHandlerReceiveCounter(t *testing.T) {
   370  	counters = make(map[string]float64)
   371  	*receiveCounter = "countme"
   372  
   373  	p := &Packet{
   374  		Bucket:   "gorets",
   375  		ValFlt:   100,
   376  		Modifier: "c",
   377  		Sampling: float32(1),
   378  	}
   379  	packetHandler(p)
   380  	assert.Equal(t, counters["countme"], float64(1))
   381  
   382  	packetHandler(p)
   383  	assert.Equal(t, counters["countme"], float64(2))
   384  }
   385  
   386  func TestPacketHandlerCount(t *testing.T) {
   387  	counters = make(map[string]float64)
   388  
   389  	p := &Packet{
   390  		Bucket:   "gorets",
   391  		ValFlt:   100,
   392  		Modifier: "c",
   393  		Sampling: float32(1),
   394  	}
   395  	packetHandler(p)
   396  	assert.Equal(t, counters["gorets"], float64(100))
   397  
   398  	p.ValFlt = float64(3)
   399  	packetHandler(p)
   400  	assert.Equal(t, counters["gorets"], float64(103))
   401  
   402  	p.ValFlt = float64(-4)
   403  	packetHandler(p)
   404  	assert.Equal(t, counters["gorets"], float64(99))
   405  
   406  	p.ValFlt = float64(-100)
   407  	packetHandler(p)
   408  	assert.Equal(t, counters["gorets"], float64(-1))
   409  }
   410  
   411  func TestPacketHandlerGauge(t *testing.T) {
   412  	gauges = make(map[string]float64)
   413  
   414  	p := &Packet{
   415  		Bucket:   "gaugor",
   416  		ValFlt:   333,
   417  		ValStr:   "",
   418  		Modifier: "g",
   419  		Sampling: float32(1),
   420  	}
   421  	packetHandler(p)
   422  	assert.Equal(t, gauges["gaugor"], float64(333))
   423  
   424  	// -10
   425  	p.ValFlt = 10
   426  	p.ValStr = "-"
   427  	packetHandler(p)
   428  	assert.Equal(t, gauges["gaugor"], float64(323))
   429  
   430  	// +4
   431  	p.ValFlt = 4
   432  	p.ValStr = "+"
   433  	packetHandler(p)
   434  	assert.Equal(t, gauges["gaugor"], float64(327))
   435  
   436  	// <0 overflow
   437  	p.ValFlt = 10
   438  	p.ValStr = ""
   439  	packetHandler(p)
   440  	p.ValFlt = 20
   441  	p.ValStr = "-"
   442  	packetHandler(p)
   443  	assert.Equal(t, gauges["gaugor"], float64(0))
   444  
   445  	// >MaxFloat64 overflow
   446  	p.ValFlt = float64(math.MaxFloat64 - 10)
   447  	p.ValStr = ""
   448  	packetHandler(p)
   449  	p.ValFlt = 20
   450  	p.ValStr = "+"
   451  	packetHandler(p)
   452  	assert.Equal(t, gauges["gaugor"], float64(math.MaxFloat64))
   453  }
   454  
   455  func TestPacketHandlerTimer(t *testing.T) {
   456  	timers = make(map[string]Float64Slice)
   457  
   458  	p := &Packet{
   459  		Bucket:   "glork",
   460  		ValFlt:   float64(320),
   461  		Modifier: "ms",
   462  		Sampling: float32(1),
   463  	}
   464  	packetHandler(p)
   465  	assert.Equal(t, len(timers["glork"]), 1)
   466  	assert.Equal(t, timers["glork"][0], float64(320))
   467  
   468  	p.ValFlt = float64(100)
   469  	packetHandler(p)
   470  	assert.Equal(t, len(timers["glork"]), 2)
   471  	assert.Equal(t, timers["glork"][1], float64(100))
   472  }
   473  
   474  func TestPacketHandlerSet(t *testing.T) {
   475  	sets = make(map[string][]string)
   476  
   477  	p := &Packet{
   478  		Bucket:   "uniques",
   479  		ValStr:   "765",
   480  		Modifier: "s",
   481  		Sampling: float32(1),
   482  	}
   483  	packetHandler(p)
   484  	assert.Equal(t, len(sets["uniques"]), 1)
   485  	assert.Equal(t, sets["uniques"][0], "765")
   486  
   487  	p.ValStr = "567"
   488  	packetHandler(p)
   489  	assert.Equal(t, len(sets["uniques"]), 2)
   490  	assert.Equal(t, sets["uniques"][1], "567")
   491  }
   492  
   493  func TestProcessCounters(t *testing.T) {
   494  
   495  	*persistCountKeys = int64(10)
   496  	counters = make(map[string]float64)
   497  	var buffer bytes.Buffer
   498  	now := int64(1418052649)
   499  
   500  	counters["gorets"] = float64(123)
   501  
   502  	num := processCounters(&buffer, now)
   503  	assert.Equal(t, num, int64(1))
   504  	assert.Equal(t, buffer.String(), "gorets 123 1418052649\n")
   505  
   506  	// run processCounters() enough times to make sure it purges items
   507  	for i := 0; i < int(*persistCountKeys)+10; i++ {
   508  		num = processCounters(&buffer, now)
   509  	}
   510  	lines := bytes.Split(buffer.Bytes(), []byte("\n"))
   511  
   512  	// expect two more lines - the good one and an empty one at the end
   513  	assert.Equal(t, len(lines), int(*persistCountKeys+2))
   514  	assert.Equal(t, string(lines[0]), "gorets 123 1418052649")
   515  	assert.Equal(t, string(lines[*persistCountKeys]), "gorets 0 1418052649")
   516  }
   517  
   518  func TestProcessTimers(t *testing.T) {
   519  	// Some data with expected mean of 20
   520  	timers = make(map[string]Float64Slice)
   521  	timers["response_time"] = []float64{0, 30, 30}
   522  
   523  	now := int64(1418052649)
   524  
   525  	var buffer bytes.Buffer
   526  	num := processTimers(&buffer, now, Percentiles{})
   527  
   528  	lines := bytes.Split(buffer.Bytes(), []byte("\n"))
   529  
   530  	assert.Equal(t, num, int64(1))
   531  	assert.Equal(t, string(lines[0]), "response_time.mean 20 1418052649")
   532  	assert.Equal(t, string(lines[1]), "response_time.upper 30 1418052649")
   533  	assert.Equal(t, string(lines[2]), "response_time.lower 0 1418052649")
   534  	assert.Equal(t, string(lines[3]), "response_time.count 3 1418052649")
   535  
   536  	num = processTimers(&buffer, now, Percentiles{})
   537  	assert.Equal(t, num, int64(0))
   538  }
   539  
   540  func TestProcessGauges(t *testing.T) {
   541  	flag.Set("delete-gauges", "false")
   542  	gauges = make(map[string]float64)
   543  	var buffer bytes.Buffer
   544  
   545  	now := int64(1418052649)
   546  
   547  	num := processGauges(&buffer, now)
   548  	assert.Equal(t, num, int64(0))
   549  	assert.Equal(t, buffer.String(), "")
   550  
   551  	p := &Packet{
   552  		Bucket:   "gaugor",
   553  		ValFlt:   12345,
   554  		ValStr:   "",
   555  		Modifier: "g",
   556  		Sampling: 1.0,
   557  	}
   558  	packetHandler(p)
   559  	num = processGauges(&buffer, now)
   560  	assert.Equal(t, num, int64(1))
   561  	num = processGauges(&buffer, now+20)
   562  	assert.Equal(t, num, int64(1))
   563  	assert.Equal(t, buffer.String(), "gaugor 12345 1418052649\ngaugor 12345 1418052669\n")
   564  
   565  	buffer = bytes.Buffer{}
   566  	p.ValFlt = 12346.75
   567  	packetHandler(p)
   568  	p.ValFlt = 12347.25
   569  	packetHandler(p)
   570  	num = processGauges(&buffer, now+40)
   571  	assert.Equal(t, num, int64(1))
   572  	assert.Equal(t, buffer.String(), "gaugor 12347.25 1418052689\n")
   573  }
   574  
   575  func TestProcessDeleteGauges(t *testing.T) {
   576  	flag.Set("delete-gauges", "true")
   577  	gauges = make(map[string]float64)
   578  	var buffer bytes.Buffer
   579  
   580  	now := int64(1418052649)
   581  
   582  	p := &Packet{
   583  		Bucket:   "gaugordelete",
   584  		ValFlt:   12345,
   585  		ValStr:   "",
   586  		Modifier: "g",
   587  		Sampling: 1.0,
   588  	}
   589  
   590  	packetHandler(p)
   591  	num := processGauges(&buffer, now)
   592  	assert.Equal(t, num, int64(1))
   593  	assert.Equal(t, buffer.String(), "gaugordelete 12345 1418052649\n")
   594  
   595  	num = processGauges(&buffer, now+20)
   596  	assert.Equal(t, num, int64(0))
   597  	assert.Equal(t, buffer.String(), "gaugordelete 12345 1418052649\n")
   598  }
   599  
   600  func TestProcessSets(t *testing.T) {
   601  	sets = make(map[string][]string)
   602  
   603  	now := int64(1418052649)
   604  
   605  	var buffer bytes.Buffer
   606  
   607  	// three unique values
   608  	sets["uniques"] = []string{"123", "234", "345"}
   609  	num := processSets(&buffer, now)
   610  	assert.Equal(t, num, int64(1))
   611  	assert.Equal(t, buffer.String(), "uniques 3 1418052649\n")
   612  
   613  	// one value is repeated
   614  	buffer.Reset()
   615  	sets["uniques"] = []string{"123", "234", "234"}
   616  	num = processSets(&buffer, now)
   617  	assert.Equal(t, num, int64(1))
   618  	assert.Equal(t, buffer.String(), "uniques 2 1418052649\n")
   619  
   620  	// make sure sets are purged
   621  	num = processSets(&buffer, now)
   622  	assert.Equal(t, num, int64(0))
   623  }
   624  
   625  func TestProcessTimersUpperPercentile(t *testing.T) {
   626  	// Some data with expected 75% of 2
   627  	timers = make(map[string]Float64Slice)
   628  	timers["response_time"] = []float64{0, 1, 2, 3}
   629  
   630  	now := int64(1418052649)
   631  
   632  	var buffer bytes.Buffer
   633  	num := processTimers(&buffer, now, Percentiles{
   634  		&Percentile{
   635  			75,
   636  			"75",
   637  		},
   638  	})
   639  
   640  	lines := bytes.Split(buffer.Bytes(), []byte("\n"))
   641  
   642  	assert.Equal(t, num, int64(1))
   643  	assert.Equal(t, string(lines[0]), "response_time.upper_75 2 1418052649")
   644  }
   645  
   646  func TestProcessTimersUpperPercentilePostfix(t *testing.T) {
   647  	flag.Set("postfix", ".test")
   648  	// Some data with expected 75% of 2
   649  	timers = make(map[string]Float64Slice)
   650  	timers["postfix_response_time.test"] = []float64{0, 1, 2, 3}
   651  
   652  	now := int64(1418052649)
   653  
   654  	var buffer bytes.Buffer
   655  	num := processTimers(&buffer, now, Percentiles{
   656  		&Percentile{
   657  			75,
   658  			"75",
   659  		},
   660  	})
   661  
   662  	lines := bytes.Split(buffer.Bytes(), []byte("\n"))
   663  
   664  	assert.Equal(t, num, int64(1))
   665  	assert.Equal(t, string(lines[0]), "postfix_response_time.upper_75.test 2 1418052649")
   666  	flag.Set("postfix", "")
   667  }
   668  
   669  func TestProcessTimesLowerPercentile(t *testing.T) {
   670  	timers = make(map[string]Float64Slice)
   671  	timers["time"] = []float64{0, 1, 2, 3}
   672  
   673  	now := int64(1418052649)
   674  
   675  	var buffer bytes.Buffer
   676  	num := processTimers(&buffer, now, Percentiles{
   677  		&Percentile{
   678  			-75,
   679  			"-75",
   680  		},
   681  	})
   682  
   683  	lines := bytes.Split(buffer.Bytes(), []byte("\n"))
   684  
   685  	assert.Equal(t, num, int64(1))
   686  	assert.Equal(t, string(lines[0]), "time.lower_75 1 1418052649")
   687  }
   688  
   689  func TestMultipleUDPSends(t *testing.T) {
   690  	addr := "127.0.0.1:8126"
   691  
   692  	address, _ := net.ResolveUDPAddr("udp", addr)
   693  	listener, err := net.ListenUDP("udp", address)
   694  	assert.Equal(t, nil, err)
   695  
   696  	ch := make(chan *Packet, MAX_UNPROCESSED_PACKETS)
   697  
   698  	wg := &sync.WaitGroup{}
   699  	wg.Add(1)
   700  	go func() {
   701  		parseTo(listener, false, ch)
   702  		wg.Done()
   703  	}()
   704  
   705  	conn, err := net.DialTimeout("udp", addr, 50*time.Millisecond)
   706  	assert.Equal(t, nil, err)
   707  
   708  	n, err := conn.Write([]byte("deploys.test.myservice:2|c"))
   709  	assert.Equal(t, nil, err)
   710  	assert.Equal(t, len("deploys.test.myservice:2|c"), n)
   711  
   712  	n, err = conn.Write([]byte("deploys.test.my:service:2|c"))
   713  
   714  	n, err = conn.Write([]byte("deploys.test.myservice:1|c"))
   715  	assert.Equal(t, nil, err)
   716  	assert.Equal(t, len("deploys.test.myservice:1|c"), n)
   717  
   718  	select {
   719  	case pack := <-ch:
   720  		assert.Equal(t, "deploys.test.myservice", pack.Bucket)
   721  		assert.Equal(t, float64(2), pack.ValFlt)
   722  		assert.Equal(t, "c", pack.Modifier)
   723  		assert.Equal(t, float32(1), pack.Sampling)
   724  	case <-time.After(50 * time.Millisecond):
   725  		t.Fatal("packet receive timeout")
   726  	}
   727  
   728  	select {
   729  	case pack := <-ch:
   730  		assert.Equal(t, "deploys.test.myservice", pack.Bucket)
   731  		assert.Equal(t, float64(1), pack.ValFlt)
   732  		assert.Equal(t, "c", pack.Modifier)
   733  		assert.Equal(t, float32(1), pack.Sampling)
   734  	case <-time.After(50 * time.Millisecond):
   735  		t.Fatal("packet receive timeout")
   736  	}
   737  
   738  	listener.Close()
   739  	wg.Wait()
   740  }
   741  
   742  func BenchmarkManyDifferentSensors(t *testing.B) {
   743  	r := rand.New(rand.NewSource(438))
   744  	for i := 0; i < 1000; i++ {
   745  		bucket := "response_time" + strconv.Itoa(i)
   746  		for i := 0; i < 10000; i++ {
   747  			a := float64(r.Uint32() % 1000)
   748  			timers[bucket] = append(timers[bucket], a)
   749  		}
   750  	}
   751  
   752  	for i := 0; i < 1000; i++ {
   753  		bucket := "count" + strconv.Itoa(i)
   754  		for i := 0; i < 10000; i++ {
   755  			a := float64(r.Uint32() % 1000)
   756  			counters[bucket] = a
   757  		}
   758  	}
   759  
   760  	for i := 0; i < 1000; i++ {
   761  		bucket := "gauge" + strconv.Itoa(i)
   762  		for i := 0; i < 10000; i++ {
   763  			a := float64(r.Uint32() % 1000)
   764  			gauges[bucket] = a
   765  		}
   766  	}
   767  
   768  	var buff bytes.Buffer
   769  	now := time.Now().Unix()
   770  	t.ResetTimer()
   771  	processTimers(&buff, now, commonPercentiles)
   772  	processCounters(&buff, now)
   773  	processGauges(&buff, now)
   774  }
   775  
   776  func BenchmarkOneBigTimer(t *testing.B) {
   777  	r := rand.New(rand.NewSource(438))
   778  	bucket := "response_time"
   779  	for i := 0; i < 10000000; i++ {
   780  		a := float64(r.Uint32() % 1000)
   781  		timers[bucket] = append(timers[bucket], a)
   782  	}
   783  
   784  	var buff bytes.Buffer
   785  	t.ResetTimer()
   786  	processTimers(&buff, time.Now().Unix(), commonPercentiles)
   787  }
   788  
   789  func BenchmarkLotsOfTimers(t *testing.B) {
   790  	r := rand.New(rand.NewSource(438))
   791  	for i := 0; i < 1000; i++ {
   792  		bucket := "response_time" + strconv.Itoa(i)
   793  		for i := 0; i < 10000; i++ {
   794  			a := float64(r.Uint32() % 1000)
   795  			timers[bucket] = append(timers[bucket], a)
   796  		}
   797  	}
   798  
   799  	var buff bytes.Buffer
   800  	t.ResetTimer()
   801  	processTimers(&buff, time.Now().Unix(), commonPercentiles)
   802  }
   803  
   804  func BenchmarkMsgParserUDP(b *testing.B) {
   805  	r := &TestUdpReader{[]byte("a.key.with-0.dash:4|c\ngauge.with.longish.nameofserver:3|g")}
   806  	parser := NewParser(r, false)
   807  
   808  	for i := 0; i < b.N; i++ {
   809  		packet, more := parser.Next()
   810  		if more == false || packet == nil || packet.Modifier != "c" {
   811  			b.Fail()
   812  		}
   813  
   814  		packet, more = parser.Next()
   815  		if more == false || packet == nil || packet.Modifier != "g" {
   816  			b.Fail()
   817  		}
   818  	}
   819  }
   820  
   821  func BenchmarkMsgParserTCP(b *testing.B) {
   822  	// reads 16 bytes at a time
   823  	r := &TestTcpReader{[]byte("a.key.with-0.dash:4|c\ngauge.with.longish.nameofserver:3|g\n"), 1500, 0}
   824  	parser := NewParser(r, true)
   825  
   826  	for i := 0; i < b.N; i++ {
   827  		packet, more := parser.Next()
   828  		if more == false || packet == nil || packet.Modifier != "c" {
   829  			b.Fail()
   830  		}
   831  
   832  		packet, more = parser.Next()
   833  		if more == false || packet == nil || packet.Modifier != "g" {
   834  			b.Fail()
   835  		}
   836  	}
   837  }
   838  
   839  func BenchmarkParseLineCounter(b *testing.B) {
   840  	d1 := []byte("a.key.with-0.dash:4|c|@0.5")
   841  	d2 := []byte("normal.key.space:1|c")
   842  
   843  	for i := 0; i < b.N; i++ {
   844  		parseLine(d1)
   845  		parseLine(d2)
   846  	}
   847  }
   848  func BenchmarkParseLineGauge(b *testing.B) {
   849  	d1 := []byte("gaugor.whatever:333.4|g")
   850  	d2 := []byte("gaugor.whatever:-5|g")
   851  
   852  	for i := 0; i < b.N; i++ {
   853  		parseLine(d1)
   854  		parseLine(d2)
   855  	}
   856  }
   857  func BenchmarkParseLineTimer(b *testing.B) {
   858  	d1 := []byte("glork.some.keyspace:3.7211|ms")
   859  	d2 := []byte("glork.some.keyspace:11223|ms")
   860  
   861  	for i := 0; i < b.N; i++ {
   862  		parseLine(d1)
   863  		parseLine(d2)
   864  	}
   865  }
   866  func BenchmarkParseLineSet(b *testing.B) {
   867  	d1 := []byte("setof.some.keyspace:hiya|s")
   868  	d2 := []byte("setof.some.keyspace:411|s")
   869  
   870  	for i := 0; i < b.N; i++ {
   871  		parseLine(d1)
   872  		parseLine(d2)
   873  	}
   874  }
   875  func BenchmarkPacketHandlerCounter(b *testing.B) {
   876  	d1 := parseLine([]byte("a.key.with-0.dash:4|c|@0.5"))
   877  	d2 := parseLine([]byte("normal.key.space:1|c"))
   878  	counters = make(map[string]float64)
   879  
   880  	for i := 0; i < b.N; i++ {
   881  		packetHandler(d1)
   882  		packetHandler(d2)
   883  	}
   884  }
   885  func BenchmarkPacketHandlerGauge(b *testing.B) {
   886  	d1 := parseLine([]byte("gaugor.whatever:333.4|g"))
   887  	d2 := parseLine([]byte("gaugor.whatever:-5|g"))
   888  	gauges = make(map[string]float64)
   889  
   890  	for i := 0; i < b.N; i++ {
   891  		packetHandler(d1)
   892  		packetHandler(d2)
   893  	}
   894  }
   895  func BenchmarkPacketHandlerTimer(b *testing.B) {
   896  	d1 := parseLine([]byte("glork.some.keyspace:3.7211|ms"))
   897  	d2 := parseLine([]byte("glork.some.keyspace:11223|ms"))
   898  	timers = make(map[string]Float64Slice)
   899  
   900  	for i := 0; i < b.N; i++ {
   901  		packetHandler(d1)
   902  		packetHandler(d2)
   903  	}
   904  }
   905  func BenchmarkPacketHandlerSet(b *testing.B) {
   906  	d1 := parseLine([]byte("setof.some.keyspace:hiya|s"))
   907  	d2 := parseLine([]byte("setof.some.keyspace:411|s"))
   908  	sets = make(map[string][]string)
   909  
   910  	for i := 0; i < b.N; i++ {
   911  		if i&0xff == 0xff {
   912  			sets = make(map[string][]string)
   913  		}
   914  		packetHandler(d1)
   915  		packetHandler(d2)
   916  	}
   917  }