313 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Go
		
	
	
	
package collectd
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"collectd.org/api"
 | 
						|
	"collectd.org/network"
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
	"github.com/stretchr/testify/require"
 | 
						|
 | 
						|
	"github.com/influxdata/telegraf"
 | 
						|
)
 | 
						|
 | 
						|
type AuthMap struct {
 | 
						|
	Passwd map[string]string
 | 
						|
}
 | 
						|
 | 
						|
func (p *AuthMap) Password(user string) (string, error) {
 | 
						|
	return p.Passwd[user], nil
 | 
						|
}
 | 
						|
 | 
						|
type metricData struct {
 | 
						|
	name   string
 | 
						|
	tags   map[string]string
 | 
						|
	fields map[string]interface{}
 | 
						|
}
 | 
						|
 | 
						|
type testCase struct {
 | 
						|
	vl       []api.ValueList
 | 
						|
	expected []metricData
 | 
						|
}
 | 
						|
 | 
						|
var singleMetric = testCase{
 | 
						|
	[]api.ValueList{
 | 
						|
		api.ValueList{
 | 
						|
			Identifier: api.Identifier{
 | 
						|
				Host:           "xyzzy",
 | 
						|
				Plugin:         "cpu",
 | 
						|
				PluginInstance: "1",
 | 
						|
				Type:           "cpu",
 | 
						|
				TypeInstance:   "user",
 | 
						|
			},
 | 
						|
			Values: []api.Value{
 | 
						|
				api.Counter(42),
 | 
						|
			},
 | 
						|
			DSNames: []string(nil),
 | 
						|
		},
 | 
						|
	},
 | 
						|
	[]metricData{
 | 
						|
		metricData{
 | 
						|
			"cpu_value",
 | 
						|
			map[string]string{
 | 
						|
				"type_instance": "user",
 | 
						|
				"host":          "xyzzy",
 | 
						|
				"instance":      "1",
 | 
						|
				"type":          "cpu",
 | 
						|
			},
 | 
						|
			map[string]interface{}{
 | 
						|
				"value": float64(42),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
}
 | 
						|
 | 
						|
var multiMetric = testCase{
 | 
						|
	[]api.ValueList{
 | 
						|
		api.ValueList{
 | 
						|
			Identifier: api.Identifier{
 | 
						|
				Host:           "xyzzy",
 | 
						|
				Plugin:         "cpu",
 | 
						|
				PluginInstance: "0",
 | 
						|
				Type:           "cpu",
 | 
						|
				TypeInstance:   "user",
 | 
						|
			},
 | 
						|
			Values: []api.Value{
 | 
						|
				api.Derive(42),
 | 
						|
				api.Gauge(42),
 | 
						|
			},
 | 
						|
			DSNames: []string{"t1", "t2"},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	[]metricData{
 | 
						|
		metricData{
 | 
						|
			"cpu_0",
 | 
						|
			map[string]string{
 | 
						|
				"type_instance": "user",
 | 
						|
				"host":          "xyzzy",
 | 
						|
				"instance":      "0",
 | 
						|
				"type":          "cpu",
 | 
						|
			},
 | 
						|
			map[string]interface{}{
 | 
						|
				"value": float64(42),
 | 
						|
			},
 | 
						|
		},
 | 
						|
		metricData{
 | 
						|
			"cpu_1",
 | 
						|
			map[string]string{
 | 
						|
				"type_instance": "user",
 | 
						|
				"host":          "xyzzy",
 | 
						|
				"instance":      "0",
 | 
						|
				"type":          "cpu",
 | 
						|
			},
 | 
						|
			map[string]interface{}{
 | 
						|
				"value": float64(42),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
}
 | 
						|
 | 
						|
func TestNewCollectdParser(t *testing.T) {
 | 
						|
	parser, err := NewCollectdParser("", "", []string{}, "join")
 | 
						|
	require.Nil(t, err)
 | 
						|
	require.Equal(t, parser.popts.SecurityLevel, network.None)
 | 
						|
	require.NotNil(t, parser.popts.PasswordLookup)
 | 
						|
	require.Nil(t, parser.popts.TypesDB)
 | 
						|
}
 | 
						|
 | 
						|
func TestParse(t *testing.T) {
 | 
						|
	cases := []testCase{singleMetric, multiMetric}
 | 
						|
 | 
						|
	for _, tc := range cases {
 | 
						|
		buf, err := writeValueList(tc.vl)
 | 
						|
		require.Nil(t, err)
 | 
						|
		bytes, err := buf.Bytes()
 | 
						|
		require.Nil(t, err)
 | 
						|
 | 
						|
		parser := &CollectdParser{}
 | 
						|
		require.Nil(t, err)
 | 
						|
		metrics, err := parser.Parse(bytes)
 | 
						|
		require.Nil(t, err)
 | 
						|
 | 
						|
		assertEqualMetrics(t, tc.expected, metrics)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestParseMultiValueSplit(t *testing.T) {
 | 
						|
	buf, err := writeValueList(multiMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	bytes, err := buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	parser := &CollectdParser{ParseMultiValue: "split"}
 | 
						|
	metrics, err := parser.Parse(bytes)
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	assert.Equal(t, 2, len(metrics))
 | 
						|
}
 | 
						|
 | 
						|
func TestParse_DefaultTags(t *testing.T) {
 | 
						|
	buf, err := writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	bytes, err := buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	parser := &CollectdParser{}
 | 
						|
	parser.SetDefaultTags(map[string]string{
 | 
						|
		"foo": "bar",
 | 
						|
	})
 | 
						|
	require.Nil(t, err)
 | 
						|
	metrics, err := parser.Parse(bytes)
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	require.Equal(t, "bar", metrics[0].Tags()["foo"])
 | 
						|
}
 | 
						|
 | 
						|
func TestParse_SignSecurityLevel(t *testing.T) {
 | 
						|
	parser := &CollectdParser{}
 | 
						|
	popts := &network.ParseOpts{
 | 
						|
		SecurityLevel: network.Sign,
 | 
						|
		PasswordLookup: &AuthMap{
 | 
						|
			map[string]string{
 | 
						|
				"user0": "bar",
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	parser.SetParseOpts(popts)
 | 
						|
 | 
						|
	// Signed data
 | 
						|
	buf, err := writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	buf.Sign("user0", "bar")
 | 
						|
	bytes, err := buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	metrics, err := parser.Parse(bytes)
 | 
						|
	require.Nil(t, err)
 | 
						|
	assertEqualMetrics(t, singleMetric.expected, metrics)
 | 
						|
 | 
						|
	// Encrypted data
 | 
						|
	buf, err = writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	buf.Encrypt("user0", "bar")
 | 
						|
	bytes, err = buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	metrics, err = parser.Parse(bytes)
 | 
						|
	require.Nil(t, err)
 | 
						|
	assertEqualMetrics(t, singleMetric.expected, metrics)
 | 
						|
 | 
						|
	// Plain text data skipped
 | 
						|
	buf, err = writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	bytes, err = buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	metrics, err = parser.Parse(bytes)
 | 
						|
	require.Nil(t, err)
 | 
						|
	require.Equal(t, []telegraf.Metric{}, metrics)
 | 
						|
 | 
						|
	// Wrong password error
 | 
						|
	buf, err = writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	buf.Sign("x", "y")
 | 
						|
	bytes, err = buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	metrics, err = parser.Parse(bytes)
 | 
						|
	require.NotNil(t, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestParse_EncryptSecurityLevel(t *testing.T) {
 | 
						|
	parser := &CollectdParser{}
 | 
						|
	popts := &network.ParseOpts{
 | 
						|
		SecurityLevel: network.Encrypt,
 | 
						|
		PasswordLookup: &AuthMap{
 | 
						|
			map[string]string{
 | 
						|
				"user0": "bar",
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	parser.SetParseOpts(popts)
 | 
						|
 | 
						|
	// Signed data skipped
 | 
						|
	buf, err := writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	buf.Sign("user0", "bar")
 | 
						|
	bytes, err := buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	metrics, err := parser.Parse(bytes)
 | 
						|
	require.Nil(t, err)
 | 
						|
	require.Equal(t, []telegraf.Metric{}, metrics)
 | 
						|
 | 
						|
	// Encrypted data
 | 
						|
	buf, err = writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	buf.Encrypt("user0", "bar")
 | 
						|
	bytes, err = buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	metrics, err = parser.Parse(bytes)
 | 
						|
	require.Nil(t, err)
 | 
						|
	assertEqualMetrics(t, singleMetric.expected, metrics)
 | 
						|
 | 
						|
	// Plain text data skipped
 | 
						|
	buf, err = writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	bytes, err = buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	metrics, err = parser.Parse(bytes)
 | 
						|
	require.Nil(t, err)
 | 
						|
	require.Equal(t, []telegraf.Metric{}, metrics)
 | 
						|
 | 
						|
	// Wrong password error
 | 
						|
	buf, err = writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	buf.Sign("x", "y")
 | 
						|
	bytes, err = buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	metrics, err = parser.Parse(bytes)
 | 
						|
	require.NotNil(t, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestParseLine(t *testing.T) {
 | 
						|
	buf, err := writeValueList(singleMetric.vl)
 | 
						|
	require.Nil(t, err)
 | 
						|
	bytes, err := buf.Bytes()
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	parser, err := NewCollectdParser("", "", []string{}, "split")
 | 
						|
	require.Nil(t, err)
 | 
						|
	metric, err := parser.ParseLine(string(bytes))
 | 
						|
	require.Nil(t, err)
 | 
						|
 | 
						|
	assertEqualMetrics(t, singleMetric.expected, []telegraf.Metric{metric})
 | 
						|
}
 | 
						|
 | 
						|
func writeValueList(valueLists []api.ValueList) (*network.Buffer, error) {
 | 
						|
	buffer := network.NewBuffer(0)
 | 
						|
 | 
						|
	ctx := context.Background()
 | 
						|
	for _, vl := range valueLists {
 | 
						|
		err := buffer.Write(ctx, &vl)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return buffer, nil
 | 
						|
}
 | 
						|
 | 
						|
func assertEqualMetrics(t *testing.T, expected []metricData, received []telegraf.Metric) {
 | 
						|
	require.Equal(t, len(expected), len(received))
 | 
						|
	for i, m := range received {
 | 
						|
		require.Equal(t, expected[i].name, m.Name())
 | 
						|
		require.Equal(t, expected[i].tags, m.Tags())
 | 
						|
		require.Equal(t, expected[i].fields, m.Fields())
 | 
						|
	}
 | 
						|
}
 |