master
go 160 lines 4.04 KB
Raw
1 package snmputils
2
3 import (
4 "testing"
5
6 "github.com/gosnmp/gosnmp"
7 "github.com/stretchr/testify/assert"
8 "github.com/stretchr/testify/require"
9 )
10
11 func withOverrides(t *testing.T, o *overrides) func() {
12 t.Helper()
13 prev := overridesData
14 overridesData = o
15 return func() { overridesData = prev }
16 }
17
18 func TestOverrides_OnUnknownOID(t *testing.T) {
19 cases := map[string]struct {
20 oid string
21 overrides *overrides
22 wantCat string
23 wantModel string
24 }{
25 "create_from_override_with_normalization": {
26 oid: "1.3.6.1.4.1.99999.42", // not in base DB
27 overrides: &overrides{
28 EnterpriseNumbers: enterpriseNumbersOverrides{OrgToVendor: map[string]string{}},
29 SysObjectIDs: sysObjectIDOverrides{
30 OIDOverrides: map[string]sysObjectIDOverride{
31 "1.3.6.1.4.1.99999.42": {
32 Category: "UTM", // will normalize
33 Model: "XR-1000", // set model
34 },
35 },
36 CategoryMap: map[string]string{
37 "UTM": "Firewall",
38 },
39 },
40 },
41 wantCat: "Firewall",
42 wantModel: "XR-1000",
43 },
44 }
45
46 for name, tc := range cases {
47 t.Run(name, func(t *testing.T) {
48 defer withOverrides(t, tc.overrides)()
49
50 si := &SysInfo{SysObjectID: tc.oid}
51 updateMetadata(si)
52
53 assert.Equal(t, tc.wantCat, si.Category)
54 assert.Equal(t, tc.wantModel, si.Model)
55 })
56 }
57 }
58
59 func TestOrgToVendorMapping(t *testing.T) {
60 cases := map[string]struct {
61 oid string
62 }{
63 "maps_org_to_vendor_when_override_present": {oid: "1.3.6.1.4.1.2505.3"},
64 }
65
66 for name, tc := range cases {
67 t.Run(name, func(t *testing.T) {
68 rawOrg := lookupEnterpriseNumber(tc.oid)
69 if rawOrg == "" {
70 t.Skip("no organization resolved for test OID; skipping")
71 }
72
73 defer withOverrides(t, &overrides{
74 EnterpriseNumbers: enterpriseNumbersOverrides{
75 OrgToVendor: map[string]string{
76 rawOrg: "CanonicalVendor",
77 },
78 },
79 SysObjectIDs: sysObjectIDOverrides{
80 OIDOverrides: map[string]sysObjectIDOverride{},
81 CategoryMap: map[string]string{},
82 },
83 })()
84
85 si := &SysInfo{SysObjectID: tc.oid}
86 updateMetadata(si)
87
88 assert.Equal(t, "CanonicalVendor", si.Vendor, "vendor mapping via org_to_vendor failed")
89 })
90 }
91 }
92
93 func TestLookupEnterpriseNumber(t *testing.T) {
94 cases := map[string]struct {
95 oid string
96 wantNonEmpty bool
97 }{
98 "known_pen_should_resolve_org": {oid: "1.3.6.1.4.1.2505.3", wantNonEmpty: true},
99 "not_under_enterprise_returns_empty": {oid: "1.3.6.1.2.1.1.2.0", wantNonEmpty: false},
100 "too_short_returns_empty": {oid: "1.3.6.1.4.1", wantNonEmpty: false},
101 "trailing_dot_returns_empty": {oid: "1.3.6.1.4.1.", wantNonEmpty: false},
102 }
103
104 for name, tc := range cases {
105 t.Run(name, func(t *testing.T) {
106 got := lookupEnterpriseNumber(tc.oid)
107 if tc.wantNonEmpty {
108 require.NotEmpty(t, got, "expected non-empty org for oid %s", tc.oid)
109 } else {
110 assert.Empty(t, got, "expected empty org for oid %s, but got %s", tc.oid, got)
111 }
112 })
113 }
114 }
115
116 func TestPduToString(t *testing.T) {
117 cases := map[string]struct {
118 pdu gosnmp.SnmpPDU
119 want string
120 wantErr bool
121 }{
122 "octet_string": {
123 pdu: gosnmp.SnmpPDU{Type: gosnmp.OctetString, Value: []byte("hello\nworld")},
124 want: "hello\nworld",
125 },
126 "integer": {
127 pdu: gosnmp.SnmpPDU{Type: gosnmp.Integer, Value: int(42)},
128 want: "42",
129 },
130 "counter32": {
131 pdu: gosnmp.SnmpPDU{Type: gosnmp.Counter32, Value: uint32(7)},
132 want: "7",
133 },
134 "object_identifier_trims_dot": {
135 pdu: gosnmp.SnmpPDU{Type: gosnmp.ObjectIdentifier, Value: ".1.3.6.1.2.1.1.1.0"},
136 want: "1.3.6.1.2.1.1.1.0",
137 },
138 }
139
140 for name, tc := range cases {
141 t.Run(name, func(t *testing.T) {
142 got, err := PduToString(tc.pdu)
143 if tc.wantErr {
144 require.Error(t, err)
145 return
146 }
147 require.NoError(t, err)
148 assert.Equal(t, tc.want, got)
149 })
150 }
151 }
152
153 func TestAllMetadataYAMLsLoadAndMerge(t *testing.T) {
154 dir := getSnmpMetadataDir()
155 require.NotEmpty(t, dir, "metadata dir must resolve in tests")
156
157 agg, err := loadOverridesFromDir(dir)
158 require.NoError(t, err, "every YAML must parse strictly without errors")
159 require.NotNil(t, agg, "aggregate overrides must not be nil")
160 }