func TestWriteValueList(t *testing.T) { b := NewBuffer(0) vl := api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", Type: "gauge", }, Time: time.Unix(1426076671, 123000000), // Wed Mar 11 13:24:31 CET 2015 Interval: 10 * time.Second, Values: []api.Value{api.Derive(1)}, } if err := b.Write(vl); err != nil { t.Errorf("Write got %v, want nil", err) return } // ValueList with much the same fields, to test compression. vl = api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", PluginInstance: "test", Type: "gauge", }, Time: time.Unix(1426076681, 234000000), // Wed Mar 11 13:24:41 CET 2015 Interval: 10 * time.Second, Values: []api.Value{api.Derive(2)}, } if err := b.Write(vl); err != nil { t.Errorf("Write got %v, want nil", err) return } want := []byte{ // vl1 0, 0, 0, 16, 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', 0, 0, 2, 0, 11, 'g', 'o', 'l', 'a', 'n', 'g', 0, 0, 4, 0, 10, 'g', 'a', 'u', 'g', 'e', 0, // 1426076671.123 * 2^30 = 1531238166015458148.352 // 1531238166015458148 = 0x15400cffc7df3b64 0, 8, 0, 12, 0x15, 0x40, 0x0c, 0xff, 0xc7, 0xdf, 0x3b, 0x64, 0, 9, 0, 12, 0, 0, 0, 0x02, 0x80, 0, 0, 0, 0, 6, 0, 15, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, // vl2 0, 3, 0, 9, 't', 'e', 's', 't', 0, // 1426076681.234 * 2^30 = 1531238176872061730.816 // 1531238176872061731 = 0x15400d024ef9db23 0, 8, 0, 12, 0x15, 0x40, 0x0d, 0x02, 0x4e, 0xf9, 0xdb, 0x23, 0, 6, 0, 15, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, } got := b.buffer.Bytes() if !reflect.DeepEqual(got, want) { t.Errorf("got %v, want %v", got, want) } }
func TestDerive(t *testing.T) { d := NewDerive(api.Identifier{ Host: "example.com", Plugin: "golang", Type: "derive", }) for i := 0; i < 10; i++ { d.Add(i) } want := api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", Type: "derive", }, Values: []api.Value{api.Derive(45)}, } got := d.ValueList() if !reflect.DeepEqual(got, want) { t.Errorf("got %#v, want %#v", got, want) } s := expvar.Get("example.com/golang/derive").String() if s != "45" { t.Errorf("got %q, want %q", s, "45") } }
func parseValues(b []byte) ([]api.Value, error) { buffer := bytes.NewBuffer(b) var n uint16 if err := binary.Read(buffer, binary.BigEndian, &n); err != nil { return nil, err } if int(n*9) != buffer.Len() { return nil, ErrInvalid } types := make([]byte, n) values := make([]api.Value, n) if _, err := buffer.Read(types); err != nil { return nil, err } for i, typ := range types { switch typ { case dsTypeGauge: var v float64 if err := binary.Read(buffer, binary.LittleEndian, &v); err != nil { return nil, err } values[i] = api.Gauge(v) case dsTypeDerive: var v int64 if err := binary.Read(buffer, binary.BigEndian, &v); err != nil { return nil, err } values[i] = api.Derive(v) case dsTypeCounter: var v uint64 if err := binary.Read(buffer, binary.BigEndian, &v); err != nil { return nil, err } values[i] = api.Counter(v) default: return nil, ErrInvalid } } return values, nil }
func TestWriteValues(t *testing.T) { b := &Buffer{buffer: new(bytes.Buffer), size: DefaultBufferSize} b.writeValues([]api.Value{ api.Gauge(42), api.Derive(31337), api.Gauge(math.NaN()), }) want := []byte{0, 6, // pkg type 0, 33, // pkg len 0, 3, // num values 1, 2, 1, // gauge, derive, gauge 0, 0, 0, 0, 0, 0, 0x45, 0x40, // 42.0 0, 0, 0, 0, 0, 0, 0x7a, 0x69, // 31337 0, 0, 0, 0, 0, 0, 0xf8, 0x7f, // NaN } got := b.buffer.Bytes() if !reflect.DeepEqual(got, want) { t.Errorf("got %v, want %v", got, want) } }
// Add adds diff to d. func (d *Derive) Add(diff int) { d.mu.Lock() defer d.mu.Unlock() d.value += api.Derive(diff) }
func TestNewName(t *testing.T) { cases := []struct { vl api.ValueList index int want string }{ {api.ValueList{ Identifier: api.Identifier{ Plugin: "cpu", Type: "cpu", }, DSNames: []string{"value"}, Values: []api.Value{api.Derive(0)}, }, 0, "collectd_cpu"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "dns", Type: "dns_qtype", }, DSNames: []string{"value"}, Values: []api.Value{api.Derive(0)}, }, 0, "collectd_dns_dns_qtype"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "df", Type: "df", }, DSNames: []string{"used", "free"}, Values: []api.Value{api.Gauge(0), api.Gauge(1)}, }, 0, "collectd_df_used"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "df", Type: "df", }, DSNames: []string{"used", "free"}, Values: []api.Value{api.Gauge(0), api.Gauge(1)}, }, 1, "collectd_df_free"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "cpu", Type: "percent", }, DSNames: []string{"value"}, Values: []api.Value{api.Gauge(0)}, }, 0, "collectd_cpu_percent"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "interface", Type: "if_octets", }, DSNames: []string{"rx", "tx"}, Values: []api.Value{api.Counter(0), api.Counter(1)}, }, 0, "collectd_interface_if_octets_rx_total"}, {api.ValueList{ Identifier: api.Identifier{ Plugin: "interface", Type: "if_octets", }, DSNames: []string{"rx", "tx"}, Values: []api.Value{api.Counter(0), api.Counter(1)}, }, 1, "collectd_interface_if_octets_tx_total"}, } for _, c := range cases { got := newName(c.vl, c.index) if got != c.want { t.Errorf("newName(%v): got %q, want %q", c.vl, got, c.want) } } }
func TestWrite(t *testing.T) { cases := []struct { ValueList api.ValueList Graphite *Graphite Want string }{ { // case 0 ValueList: api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", PluginInstance: "example", Type: "gauge", TypeInstance: "answer", }, Time: time.Unix(1426975989, 1), Interval: 10 * time.Second, Values: []api.Value{api.Gauge(42)}, }, Graphite: &Graphite{ Prefix: "-->", Suffix: "<--", EscapeChar: "_", SeparateInstances: false, AlwaysAppendDS: true, }, Want: "-->example_com<--.golang-example.gauge-answer.value 42 1426975989\r\n", }, { // case 1 ValueList: api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", PluginInstance: "example", Type: "gauge", TypeInstance: "answer", }, Time: time.Unix(1426975989, 1), Interval: 10 * time.Second, Values: []api.Value{api.Derive(1337)}, }, Graphite: &Graphite{ Prefix: "collectd.", Suffix: "", EscapeChar: "@", SeparateInstances: true, AlwaysAppendDS: false, }, Want: "[email protected] 1337 1426975989\r\n", }, { // case 2 ValueList: api.ValueList{ Identifier: api.Identifier{ Host: "example.com", Plugin: "golang", Type: "gauge", }, Time: time.Unix(1426975989, 1), Interval: 10 * time.Second, Values: []api.Value{api.Gauge(42), api.Derive(1337)}, }, Graphite: &Graphite{ Prefix: "collectd.", Suffix: "", EscapeChar: "_", SeparateInstances: true, AlwaysAppendDS: false, }, Want: "collectd.example_com.golang.gauge.0 42 1426975989\r\n" + "collectd.example_com.golang.gauge.1 1337 1426975989\r\n", }, } for i, c := range cases { buf := &bytes.Buffer{} c.Graphite.W = buf if err := c.Graphite.Write(c.ValueList); err != nil { t.Errorf("case %d: got %v, want %v", i, err, nil) } got := buf.String() if got != c.Want { t.Errorf("got %q, want %q", got, c.Want) } } }