From 87d772a7d708fec12f48cd8adc0dedff6e1025da Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 26 Aug 2024 10:15:20 +0200 Subject: Adding upstream version 1.47.0. Signed-off-by: Daniel Baumann --- .../go.d.plugin/modules/snmp/snmp_test.go | 520 --------------------- 1 file changed, 520 deletions(-) delete mode 100644 src/go/collectors/go.d.plugin/modules/snmp/snmp_test.go (limited to 'src/go/collectors/go.d.plugin/modules/snmp/snmp_test.go') diff --git a/src/go/collectors/go.d.plugin/modules/snmp/snmp_test.go b/src/go/collectors/go.d.plugin/modules/snmp/snmp_test.go deleted file mode 100644 index 04d9db3f9..000000000 --- a/src/go/collectors/go.d.plugin/modules/snmp/snmp_test.go +++ /dev/null @@ -1,520 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -package snmp - -import ( - "errors" - "fmt" - "os" - "strings" - "testing" - - "github.com/golang/mock/gomock" - "github.com/gosnmp/gosnmp" - snmpmock "github.com/gosnmp/gosnmp/mocks" - "github.com/netdata/netdata/go/go.d.plugin/agent/module" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -var ( - dataConfigJSON, _ = os.ReadFile("testdata/config.json") - dataConfigYAML, _ = os.ReadFile("testdata/config.yaml") -) - -func Test_testDataIsValid(t *testing.T) { - for name, data := range map[string][]byte{ - "dataConfigJSON": dataConfigJSON, - "dataConfigYAML": dataConfigYAML, - } { - require.NotNil(t, data, name) - } -} - -func TestSNMP_ConfigurationSerialize(t *testing.T) { - module.TestConfigurationSerialize(t, &SNMP{}, dataConfigJSON, dataConfigYAML) -} - -func TestSNMP_Init(t *testing.T) { - tests := map[string]struct { - prepareSNMP func() *SNMP - wantFail bool - }{ - "fail with default config": { - wantFail: true, - prepareSNMP: func() *SNMP { - return New() - }, - }, - "fail when 'charts' not set": { - wantFail: true, - prepareSNMP: func() *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - snmp.ChartsInput = nil - return snmp - }, - }, - "fail when using SNMPv3 but 'user.name' not set": { - wantFail: true, - prepareSNMP: func() *SNMP { - snmp := New() - snmp.Config = prepareV3Config() - snmp.User.Name = "" - return snmp - }, - }, - "fail when using SNMPv3 but 'user.level' is invalid": { - wantFail: true, - prepareSNMP: func() *SNMP { - snmp := New() - snmp.Config = prepareV3Config() - snmp.User.SecurityLevel = "invalid" - return snmp - }, - }, - "fail when using SNMPv3 but 'user.auth_proto' is invalid": { - wantFail: true, - prepareSNMP: func() *SNMP { - snmp := New() - snmp.Config = prepareV3Config() - snmp.User.AuthProto = "invalid" - return snmp - }, - }, - "fail when using SNMPv3 but 'user.priv_proto' is invalid": { - wantFail: true, - prepareSNMP: func() *SNMP { - snmp := New() - snmp.Config = prepareV3Config() - snmp.User.PrivProto = "invalid" - return snmp - }, - }, - "success when using SNMPv1 with valid config": { - wantFail: false, - prepareSNMP: func() *SNMP { - snmp := New() - snmp.Config = prepareV1Config() - return snmp - }, - }, - "success when using SNMPv2 with valid config": { - wantFail: false, - prepareSNMP: func() *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - return snmp - }, - }, - "success when using SNMPv3 with valid config": { - wantFail: false, - prepareSNMP: func() *SNMP { - snmp := New() - snmp.Config = prepareV3Config() - return snmp - }, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - snmp := test.prepareSNMP() - - if test.wantFail { - assert.Error(t, snmp.Init()) - } else { - assert.NoError(t, snmp.Init()) - } - }) - } -} - -func TestSNMP_Check(t *testing.T) { - tests := map[string]struct { - prepareSNMP func(m *snmpmock.MockHandler) *SNMP - wantFail bool - }{ - "success when 'max_request_size' > returned OIDs": { - wantFail: false, - prepareSNMP: func(m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - - m.EXPECT().Get(gomock.Any()).Return(&gosnmp.SnmpPacket{ - Variables: []gosnmp.SnmpPDU{ - {Value: 10, Type: gosnmp.Gauge32}, - {Value: 20, Type: gosnmp.Gauge32}, - }, - }, nil).Times(1) - - return snmp - }, - }, - "success when 'max_request_size' < returned OIDs": { - wantFail: false, - prepareSNMP: func(m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - snmp.Config.Options.MaxOIDs = 1 - - m.EXPECT().Get(gomock.Any()).Return(&gosnmp.SnmpPacket{ - Variables: []gosnmp.SnmpPDU{ - {Value: 10, Type: gosnmp.Gauge32}, - {Value: 20, Type: gosnmp.Gauge32}, - }, - }, nil).Times(2) - - return snmp - }, - }, - "success when using 'multiply_range'": { - wantFail: false, - prepareSNMP: func(m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareConfigWithIndexRange(prepareV2Config, 0, 1) - - m.EXPECT().Get(gomock.Any()).Return(&gosnmp.SnmpPacket{ - Variables: []gosnmp.SnmpPDU{ - {Value: 10, Type: gosnmp.Gauge32}, - {Value: 20, Type: gosnmp.Gauge32}, - {Value: 30, Type: gosnmp.Gauge32}, - {Value: 40, Type: gosnmp.Gauge32}, - }, - }, nil).Times(1) - - return snmp - }, - }, - "fail when snmp client Get fails": { - wantFail: true, - prepareSNMP: func(m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - - m.EXPECT().Get(gomock.Any()).Return(nil, errors.New("mock Get() error")).Times(1) - - return snmp - }, - }, - "fail when all OIDs type is unsupported": { - wantFail: true, - prepareSNMP: func(m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - - m.EXPECT().Get(gomock.Any()).Return(&gosnmp.SnmpPacket{ - Variables: []gosnmp.SnmpPDU{ - {Value: nil, Type: gosnmp.NoSuchInstance}, - {Value: nil, Type: gosnmp.NoSuchInstance}, - }, - }, nil).Times(1) - - return snmp - }, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - mockSNMP, cleanup := mockInit(t) - defer cleanup() - - newSNMPClient = func() gosnmp.Handler { return mockSNMP } - defaultMockExpects(mockSNMP) - - snmp := test.prepareSNMP(mockSNMP) - require.NoError(t, snmp.Init()) - - if test.wantFail { - assert.Error(t, snmp.Check()) - } else { - assert.NoError(t, snmp.Check()) - } - }) - } -} - -func TestSNMP_Collect(t *testing.T) { - tests := map[string]struct { - prepareSNMP func(m *snmpmock.MockHandler) *SNMP - wantCollected map[string]int64 - }{ - "success when collecting supported type": { - prepareSNMP: func(m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareConfigWithIndexRange(prepareV2Config, 0, 3) - - m.EXPECT().Get(gomock.Any()).Return(&gosnmp.SnmpPacket{ - Variables: []gosnmp.SnmpPDU{ - {Value: 10, Type: gosnmp.Counter32}, - {Value: 20, Type: gosnmp.Counter64}, - {Value: 30, Type: gosnmp.Gauge32}, - {Value: 1, Type: gosnmp.Boolean}, - {Value: 40, Type: gosnmp.Gauge32}, - {Value: 50, Type: gosnmp.TimeTicks}, - {Value: 60, Type: gosnmp.Uinteger32}, - {Value: 70, Type: gosnmp.Integer}, - }, - }, nil).Times(1) - - return snmp - }, - wantCollected: map[string]int64{ - "1.3.6.1.2.1.2.2.1.10.0": 10, - "1.3.6.1.2.1.2.2.1.16.0": 20, - "1.3.6.1.2.1.2.2.1.10.1": 30, - "1.3.6.1.2.1.2.2.1.16.1": 1, - "1.3.6.1.2.1.2.2.1.10.2": 40, - "1.3.6.1.2.1.2.2.1.16.2": 50, - "1.3.6.1.2.1.2.2.1.10.3": 60, - "1.3.6.1.2.1.2.2.1.16.3": 70, - }, - }, - "success when collecting supported and unsupported type": { - prepareSNMP: func(m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareConfigWithIndexRange(prepareV2Config, 0, 2) - - m.EXPECT().Get(gomock.Any()).Return(&gosnmp.SnmpPacket{ - Variables: []gosnmp.SnmpPDU{ - {Value: 10, Type: gosnmp.Counter32}, - {Value: 20, Type: gosnmp.Counter64}, - {Value: 30, Type: gosnmp.Gauge32}, - {Value: nil, Type: gosnmp.NoSuchInstance}, - {Value: nil, Type: gosnmp.NoSuchInstance}, - {Value: nil, Type: gosnmp.NoSuchInstance}, - }, - }, nil).Times(1) - - return snmp - }, - wantCollected: map[string]int64{ - "1.3.6.1.2.1.2.2.1.10.0": 10, - "1.3.6.1.2.1.2.2.1.16.0": 20, - "1.3.6.1.2.1.2.2.1.10.1": 30, - }, - }, - "fails when collecting unsupported type": { - prepareSNMP: func(m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareConfigWithIndexRange(prepareV2Config, 0, 2) - - m.EXPECT().Get(gomock.Any()).Return(&gosnmp.SnmpPacket{ - Variables: []gosnmp.SnmpPDU{ - {Value: nil, Type: gosnmp.NoSuchInstance}, - {Value: nil, Type: gosnmp.NoSuchInstance}, - {Value: nil, Type: gosnmp.NoSuchObject}, - {Value: "192.0.2.0", Type: gosnmp.NsapAddress}, - {Value: []uint8{118, 101, 116}, Type: gosnmp.OctetString}, - {Value: ".1.3.6.1.2.1.4.32.1.5.2.1.4.10.19.0.0.16", Type: gosnmp.ObjectIdentifier}, - }, - }, nil).Times(1) - - return snmp - }, - wantCollected: nil, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - mockSNMP, cleanup := mockInit(t) - defer cleanup() - - newSNMPClient = func() gosnmp.Handler { return mockSNMP } - defaultMockExpects(mockSNMP) - - snmp := test.prepareSNMP(mockSNMP) - require.NoError(t, snmp.Init()) - - collected := snmp.Collect() - - assert.Equal(t, test.wantCollected, collected) - }) - } -} - -func TestSNMP_Cleanup(t *testing.T) { - tests := map[string]struct { - prepareSNMP func(t *testing.T, m *snmpmock.MockHandler) *SNMP - }{ - "cleanup call if snmpClient initialized": { - prepareSNMP: func(t *testing.T, m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - require.NoError(t, snmp.Init()) - - m.EXPECT().Close().Times(1) - - return snmp - }, - }, - "cleanup call does not panic if snmpClient not initialized": { - prepareSNMP: func(t *testing.T, m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - require.NoError(t, snmp.Init()) - snmp.snmpClient = nil - - return snmp - }, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - mockSNMP, cleanup := mockInit(t) - defer cleanup() - - newSNMPClient = func() gosnmp.Handler { return mockSNMP } - defaultMockExpects(mockSNMP) - - snmp := test.prepareSNMP(t, mockSNMP) - assert.NotPanics(t, snmp.Cleanup) - }) - } -} - -func TestSNMP_Charts(t *testing.T) { - tests := map[string]struct { - prepareSNMP func(t *testing.T, m *snmpmock.MockHandler) *SNMP - wantNumCharts int - }{ - "without 'multiply_range': got expected number of charts": { - wantNumCharts: 1, - prepareSNMP: func(t *testing.T, m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareV2Config() - require.NoError(t, snmp.Init()) - - return snmp - }, - }, - "with 'multiply_range': got expected number of charts": { - wantNumCharts: 10, - prepareSNMP: func(t *testing.T, m *snmpmock.MockHandler) *SNMP { - snmp := New() - snmp.Config = prepareConfigWithIndexRange(prepareV2Config, 0, 9) - require.NoError(t, snmp.Init()) - - return snmp - }, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - mockSNMP, cleanup := mockInit(t) - defer cleanup() - - newSNMPClient = func() gosnmp.Handler { return mockSNMP } - defaultMockExpects(mockSNMP) - - snmp := test.prepareSNMP(t, mockSNMP) - assert.Equal(t, test.wantNumCharts, len(*snmp.Charts())) - }) - } -} - -func mockInit(t *testing.T) (*snmpmock.MockHandler, func()) { - mockCtl := gomock.NewController(t) - cleanup := func() { mockCtl.Finish() } - mockSNMP := snmpmock.NewMockHandler(mockCtl) - - return mockSNMP, cleanup -} - -func defaultMockExpects(m *snmpmock.MockHandler) { - m.EXPECT().Target().AnyTimes() - m.EXPECT().Port().AnyTimes() - m.EXPECT().Retries().AnyTimes() - m.EXPECT().Timeout().AnyTimes() - m.EXPECT().MaxOids().AnyTimes() - m.EXPECT().Version().AnyTimes() - m.EXPECT().Community().AnyTimes() - m.EXPECT().SetTarget(gomock.Any()).AnyTimes() - m.EXPECT().SetPort(gomock.Any()).AnyTimes() - m.EXPECT().SetRetries(gomock.Any()).AnyTimes() - m.EXPECT().SetMaxOids(gomock.Any()).AnyTimes() - m.EXPECT().SetLogger(gomock.Any()).AnyTimes() - m.EXPECT().SetTimeout(gomock.Any()).AnyTimes() - m.EXPECT().SetCommunity(gomock.Any()).AnyTimes() - m.EXPECT().SetVersion(gomock.Any()).AnyTimes() - m.EXPECT().SetSecurityModel(gomock.Any()).AnyTimes() - m.EXPECT().SetMsgFlags(gomock.Any()).AnyTimes() - m.EXPECT().SetSecurityParameters(gomock.Any()).AnyTimes() - m.EXPECT().Connect().Return(nil).AnyTimes() -} - -func prepareConfigWithIndexRange(p func() Config, start, end int) Config { - if start > end || start < 0 || end < 1 { - panic(fmt.Sprintf("invalid index range ('%d'-'%d')", start, end)) - } - cfg := p() - for i := range cfg.ChartsInput { - cfg.ChartsInput[i].IndexRange = []int{start, end} - } - return cfg -} - -func prepareV3Config() Config { - cfg := prepareV2Config() - cfg.Options.Version = gosnmp.Version3.String() - cfg.User = User{ - Name: "name", - SecurityLevel: "authPriv", - AuthProto: strings.ToLower(gosnmp.MD5.String()), - AuthKey: "auth_key", - PrivProto: strings.ToLower(gosnmp.AES.String()), - PrivKey: "priv_key", - } - return cfg -} - -func prepareV2Config() Config { - cfg := prepareV1Config() - cfg.Options.Version = gosnmp.Version2c.String() - return cfg -} - -func prepareV1Config() Config { - return Config{ - UpdateEvery: defaultUpdateEvery, - Hostname: defaultHostname, - Community: defaultCommunity, - Options: Options{ - Port: defaultPort, - Retries: defaultRetries, - Timeout: defaultTimeout, - Version: gosnmp.Version1.String(), - MaxOIDs: defaultMaxOIDs, - }, - ChartsInput: []ChartConfig{ - { - ID: "test_chart1", - Title: "This is Test Chart1", - Units: "kilobits/s", - Family: "family", - Type: module.Area.String(), - Priority: module.Priority, - Dimensions: []DimensionConfig{ - { - OID: "1.3.6.1.2.1.2.2.1.10", - Name: "in", - Algorithm: module.Incremental.String(), - Multiplier: 8, - Divisor: 1000, - }, - { - OID: "1.3.6.1.2.1.2.2.1.16", - Name: "out", - Algorithm: module.Incremental.String(), - Multiplier: 8, - Divisor: 1000, - }, - }, - }, - }, - } -} -- cgit v1.2.3