net-snmp 3.23.0 → 3.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,469 @@
1
+ const assert = require('assert');
2
+ const net = require('net');
3
+ const snmp = require('..');
4
+
5
+ describe('Subagent', function() {
6
+ let subagent;
7
+ let mockSocket;
8
+ let mockServer;
9
+
10
+ beforeEach(function() {
11
+ // Create a mock server to simulate master agent
12
+ mockServer = net.createServer();
13
+ mockSocket = {
14
+ connect: () => {},
15
+ on: () => {},
16
+ write: () => {},
17
+ end: () => {}
18
+ };
19
+
20
+ // Use the factory method instead of constructor
21
+ subagent = snmp.createSubagent({
22
+ master: 'localhost',
23
+ masterPort: 705,
24
+ timeout: 5,
25
+ description: 'Test Subagent'
26
+ });
27
+
28
+ // Mock socket connection to avoid actual networking
29
+ subagent.socket = mockSocket;
30
+ subagent.sessionID = 123;
31
+ });
32
+
33
+ afterEach(function() {
34
+ if (mockServer) {
35
+ mockServer.close();
36
+ }
37
+ if (subagent && typeof subagent.close === 'function') {
38
+ subagent.close();
39
+ }
40
+ });
41
+
42
+ describe('Constructor', function() {
43
+ it('creates subagent with default options', function() {
44
+ const sub = snmp.createSubagent({});
45
+ // Prevent actual network connection
46
+ sub.connectSocket = () => {};
47
+
48
+ assert.equal(sub.master, 'localhost');
49
+ assert.equal(sub.masterPort, 705);
50
+ assert.equal(sub.timeout, 0);
51
+ assert.equal(sub.descr, "Node net-snmp AgentX sub-agent");
52
+ assert(sub.mib);
53
+
54
+ // Clean up
55
+ if (typeof sub.close === 'function') {
56
+ sub.close();
57
+ }
58
+ });
59
+
60
+ it('creates subagent with custom options', function() {
61
+ const sub = snmp.createSubagent({
62
+ master: '192.168.1.1',
63
+ masterPort: 8080,
64
+ timeout: 10,
65
+ description: 'Custom Subagent'
66
+ });
67
+ // Prevent actual network connection
68
+ sub.connectSocket = () => {};
69
+
70
+ assert.equal(sub.master, '192.168.1.1');
71
+ assert.equal(sub.masterPort, 8080);
72
+ assert.equal(sub.timeout, 10);
73
+ assert.equal(sub.descr, 'Custom Subagent');
74
+
75
+ // Clean up
76
+ if (typeof sub.close === 'function') {
77
+ sub.close();
78
+ }
79
+ });
80
+ });
81
+
82
+ describe('Provider Management', function() {
83
+ let scalarProvider, tableProvider;
84
+
85
+ beforeEach(function() {
86
+ scalarProvider = {
87
+ name: "testScalar",
88
+ type: snmp.MibProviderType.Scalar,
89
+ oid: "1.3.6.1.4.1.8072.9999.1",
90
+ scalarType: snmp.ObjectType.Integer,
91
+ maxAccess: snmp.MaxAccess['read-write']
92
+ };
93
+
94
+ tableProvider = {
95
+ name: "testTable",
96
+ type: snmp.MibProviderType.Table,
97
+ oid: "1.3.6.1.4.1.8072.9999.2",
98
+ maxAccess: snmp.MaxAccess['not-accessible'],
99
+ tableColumns: [
100
+ {
101
+ number: 1,
102
+ name: "testIndex",
103
+ type: snmp.ObjectType.Integer,
104
+ maxAccess: snmp.MaxAccess['not-accessible']
105
+ },
106
+ {
107
+ number: 2,
108
+ name: "testValue",
109
+ type: snmp.ObjectType.OctetString,
110
+ maxAccess: snmp.MaxAccess['read-write']
111
+ },
112
+ {
113
+ number: 3,
114
+ name: "testReadOnly",
115
+ type: snmp.ObjectType.Integer,
116
+ maxAccess: snmp.MaxAccess['read-only']
117
+ }
118
+ ],
119
+ tableIndex: [{ columnName: "testIndex" }]
120
+ };
121
+ });
122
+
123
+ it('registers scalar provider', function() {
124
+ let pduSent = null;
125
+ subagent.sendPdu = (pdu, callback) => {
126
+ pduSent = pdu;
127
+ if (callback) callback(null, { error: 0 });
128
+ };
129
+
130
+ subagent.registerProvider(scalarProvider);
131
+
132
+ assert(pduSent);
133
+ assert.equal(pduSent.pduType, snmp.AgentXPduType.Register);
134
+ assert.equal(pduSent.oid, scalarProvider.oid);
135
+ assert(subagent.getProvider('testScalar'));
136
+ });
137
+
138
+ it('registers table provider', function() {
139
+ let pduSent = null;
140
+ subagent.sendPdu = (pdu, callback) => {
141
+ pduSent = pdu;
142
+ if (callback) callback(null, { error: 0 });
143
+ };
144
+
145
+ subagent.registerProvider(tableProvider);
146
+
147
+ assert(pduSent);
148
+ assert.equal(pduSent.pduType, snmp.AgentXPduType.Register);
149
+ assert.equal(pduSent.oid, tableProvider.oid);
150
+ assert(subagent.getProvider('testTable'));
151
+ });
152
+
153
+ it('unregisters provider', function() {
154
+ subagent.getMib().registerProvider(scalarProvider);
155
+
156
+ let pduSent = null;
157
+ subagent.sendPdu = (pdu, callback) => {
158
+ pduSent = pdu;
159
+ if (callback) callback(null, { error: 0 });
160
+ };
161
+
162
+ subagent.unregisterProvider('testScalar');
163
+
164
+ assert(pduSent);
165
+ assert.equal(pduSent.pduType, snmp.AgentXPduType.Unregister);
166
+ assert.equal(pduSent.oid, scalarProvider.oid);
167
+ });
168
+ });
169
+
170
+ describe('Administrative PDUs', function() {
171
+ it('sends ping PDU', function() {
172
+ let pduSent = null;
173
+ subagent.sendPdu = (pdu, callback) => {
174
+ pduSent = pdu;
175
+ if (callback) callback(null, { error: 0 });
176
+ };
177
+
178
+ subagent.ping();
179
+
180
+ assert(pduSent);
181
+ assert.equal(pduSent.pduType, snmp.AgentXPduType.Ping);
182
+ assert.equal(pduSent.sessionID, 123);
183
+ });
184
+
185
+ it('sends notify PDU', function() {
186
+ let pduSent = null;
187
+ subagent.sendPdu = (pdu, callback) => {
188
+ pduSent = pdu;
189
+ if (callback) callback(null, { error: 0 });
190
+ };
191
+
192
+ const varbinds = [
193
+ {
194
+ oid: '1.3.6.1.2.1.1.1.0',
195
+ type: snmp.ObjectType.OctetString,
196
+ value: 'test notification'
197
+ }
198
+ ];
199
+
200
+ subagent.notify('1.3.6.1.6.3.1.1.5.1', varbinds);
201
+
202
+ assert(pduSent);
203
+ assert.equal(pduSent.pduType, snmp.AgentXPduType.Notify);
204
+ assert(Array.isArray(pduSent.varbinds));
205
+ assert.equal(pduSent.varbinds.length, 3); // sysUpTime + snmpTrapOID + user varbinds
206
+ });
207
+
208
+ it('adds agent capabilities', function() {
209
+ let pduSent = null;
210
+ subagent.sendPdu = (pdu, callback) => {
211
+ pduSent = pdu;
212
+ if (callback) callback(null, { error: 0 });
213
+ };
214
+
215
+ subagent.addAgentCaps('1.3.6.1.2.1.1', 'Test capability');
216
+
217
+ assert(pduSent);
218
+ assert.equal(pduSent.pduType, snmp.AgentXPduType.AddAgentCaps);
219
+ assert.equal(pduSent.oid, '1.3.6.1.2.1.1');
220
+ assert.equal(pduSent.descr, 'Test capability');
221
+ });
222
+
223
+ it('removes agent capabilities', function() {
224
+ let pduSent = null;
225
+ subagent.sendPdu = (pdu, callback) => {
226
+ pduSent = pdu;
227
+ if (callback) callback(null, { error: 0 });
228
+ };
229
+
230
+ subagent.removeAgentCaps('1.3.6.1.2.1.1');
231
+
232
+ assert(pduSent);
233
+ assert.equal(pduSent.pduType, snmp.AgentXPduType.RemoveAgentCaps);
234
+ assert.equal(pduSent.oid, '1.3.6.1.2.1.1');
235
+ });
236
+ });
237
+
238
+ describe('Utility Methods', function() {
239
+ it('returns correct MIB instance', function() {
240
+ assert(subagent.getMib());
241
+ assert.equal(typeof subagent.getMib().registerProvider, 'function');
242
+ });
243
+
244
+ it('emits close event', function(done) {
245
+ subagent.on('close', () => {
246
+ done();
247
+ });
248
+ subagent.onClose();
249
+ });
250
+
251
+ it('emits error event', function(done) {
252
+ const testError = new Error('Test error');
253
+ subagent.on('error', (error) => {
254
+ assert.equal(error, testError);
255
+ done();
256
+ });
257
+ subagent.onError(testError);
258
+ });
259
+ });
260
+
261
+ describe('Subagent Enhanced Tests for PR #280', function() {
262
+ // Tests for new functionality from PR #280
263
+
264
+ describe('isAllowed Method (Access Control)', function() {
265
+ let scalarProvider, tableProvider;
266
+
267
+ beforeEach(function() {
268
+ scalarProvider = {
269
+ name: "testScalar",
270
+ type: snmp.MibProviderType.Scalar,
271
+ oid: "1.3.6.1.4.1.8072.9999.1",
272
+ scalarType: snmp.ObjectType.Integer,
273
+ maxAccess: snmp.MaxAccess['read-write']
274
+ };
275
+
276
+ tableProvider = {
277
+ name: "testTable",
278
+ type: snmp.MibProviderType.Table,
279
+ oid: "1.3.6.1.4.1.8072.9999.2",
280
+ maxAccess: snmp.MaxAccess['not-accessible'],
281
+ tableColumns: [
282
+ {
283
+ number: 1,
284
+ name: "testIndex",
285
+ type: snmp.ObjectType.Integer,
286
+ maxAccess: snmp.MaxAccess['not-accessible']
287
+ },
288
+ {
289
+ number: 2,
290
+ name: "testValue",
291
+ type: snmp.ObjectType.OctetString,
292
+ maxAccess: snmp.MaxAccess['read-write']
293
+ },
294
+ {
295
+ number: 3,
296
+ name: "testReadOnly",
297
+ type: snmp.ObjectType.Integer,
298
+ maxAccess: snmp.MaxAccess['read-only']
299
+ }
300
+ ],
301
+ tableIndex: [{ columnName: "testIndex" }]
302
+ };
303
+
304
+ subagent.getMib().registerProvider(scalarProvider);
305
+ subagent.getMib().registerProvider(tableProvider);
306
+ subagent.getMib().addTableRow('testTable', [1, 'test', 42]);
307
+ });
308
+
309
+ it('allows read access to read-write scalar', function() {
310
+ if (typeof subagent.isAllowed === 'function') {
311
+ const result = subagent.isAllowed(snmp.AgentXPduType.Get, scalarProvider, null);
312
+ assert.equal(result, true);
313
+ }
314
+ });
315
+
316
+ it('allows write access to read-write scalar', function() {
317
+ if (typeof subagent.isAllowed === 'function') {
318
+ const result = subagent.isAllowed(snmp.AgentXPduType.TestSet, scalarProvider, null);
319
+ assert.equal(result, true);
320
+ }
321
+ });
322
+
323
+ it('allows read access to read-only table column', function() {
324
+ if (typeof subagent.isAllowed === 'function') {
325
+ const instanceNode = subagent.getMib().lookup('1.3.6.1.4.1.8072.9999.2.3.1');
326
+ if (instanceNode) {
327
+ const result = subagent.isAllowed(snmp.AgentXPduType.Get, tableProvider, instanceNode);
328
+ assert.equal(result, true);
329
+ }
330
+ }
331
+ });
332
+
333
+ it('denies write access to read-only table column', function() {
334
+ if (typeof subagent.isAllowed === 'function') {
335
+ const instanceNode = subagent.getMib().lookup('1.3.6.1.4.1.8072.9999.2.3.1');
336
+ if (instanceNode) {
337
+ const result = subagent.isAllowed(snmp.AgentXPduType.TestSet, tableProvider, instanceNode);
338
+ assert.equal(result, false);
339
+ }
340
+ }
341
+ });
342
+ });
343
+
344
+ describe('Set Operations Transaction Management', function() {
345
+ let scalarProvider;
346
+
347
+ beforeEach(function() {
348
+ scalarProvider = {
349
+ name: "testScalar",
350
+ type: snmp.MibProviderType.Scalar,
351
+ oid: "1.3.6.1.4.1.8072.9999.1",
352
+ scalarType: snmp.ObjectType.Integer,
353
+ maxAccess: snmp.MaxAccess['read-write']
354
+ };
355
+
356
+ subagent.getMib().registerProvider(scalarProvider);
357
+ subagent.getMib().setScalarValue('testScalar', 100);
358
+ });
359
+
360
+ it('manages set transactions correctly', function() {
361
+ // Create proper AgentXPdu objects using createFromVariables
362
+ const testSetPdu = snmp.AgentXPdu.createFromVariables({
363
+ pduType: snmp.AgentXPduType.TestSet,
364
+ sessionID: subagent.sessionID,
365
+ transactionID: 123,
366
+ varbinds: [{
367
+ oid: '1.3.6.1.4.1.8072.9999.1.0',
368
+ type: snmp.ObjectType.Integer,
369
+ value: 200
370
+ }]
371
+ });
372
+
373
+ subagent.testSet(testSetPdu);
374
+ assert(subagent.setTransactions[123]);
375
+
376
+ const cleanupSetPdu = snmp.AgentXPdu.createFromVariables({
377
+ pduType: snmp.AgentXPduType.CleanupSet,
378
+ sessionID: subagent.sessionID,
379
+ transactionID: 123
380
+ });
381
+
382
+ subagent.cleanupSet(cleanupSetPdu);
383
+ assert(!subagent.setTransactions[123]);
384
+ });
385
+
386
+ it('handles unexpected transaction IDs', function() {
387
+ const commitSetPdu = snmp.AgentXPdu.createFromVariables({
388
+ pduType: snmp.AgentXPduType.CommitSet,
389
+ sessionID: subagent.sessionID,
390
+ transactionID: 999
391
+ });
392
+
393
+ assert.throws(() => {
394
+ subagent.commitSet(commitSetPdu);
395
+ }, /Unexpected CommitSet PDU/);
396
+ });
397
+ });
398
+
399
+ describe('Bulk Set Handler', function() {
400
+ let scalarProvider1, scalarProvider2;
401
+
402
+ beforeEach(function() {
403
+ scalarProvider1 = {
404
+ name: "testScalar1",
405
+ type: snmp.MibProviderType.Scalar,
406
+ oid: "1.3.6.1.4.1.8072.9999.1",
407
+ scalarType: snmp.ObjectType.Integer,
408
+ maxAccess: snmp.MaxAccess['read-write']
409
+ };
410
+
411
+ scalarProvider2 = {
412
+ name: "testScalar2",
413
+ type: snmp.MibProviderType.Scalar,
414
+ oid: "1.3.6.1.4.1.8072.9999.2",
415
+ scalarType: snmp.ObjectType.Integer,
416
+ maxAccess: snmp.MaxAccess['read-write']
417
+ };
418
+
419
+ subagent.getMib().registerProvider(scalarProvider1);
420
+ subagent.getMib().registerProvider(scalarProvider2);
421
+ subagent.getMib().setScalarValue('testScalar1', 100);
422
+ subagent.getMib().setScalarValue('testScalar2', 200);
423
+ });
424
+
425
+ it('sets bulk set handler correctly', function() {
426
+ const handler = (mibRequests, mib, testSet) => {
427
+ return snmp.ErrorStatus.NoError;
428
+ };
429
+
430
+ if (typeof subagent.setBulkSetHandler === 'function') {
431
+ subagent.setBulkSetHandler(handler);
432
+ assert.equal(subagent.bulkSetHandler, handler);
433
+ }
434
+ });
435
+ });
436
+
437
+ describe('Value Validation', function() {
438
+ let scalarProvider;
439
+
440
+ beforeEach(function() {
441
+ scalarProvider = {
442
+ name: "testScalar",
443
+ type: snmp.MibProviderType.Scalar,
444
+ oid: "1.3.6.1.4.1.8072.9999.1",
445
+ scalarType: snmp.ObjectType.Integer,
446
+ maxAccess: snmp.MaxAccess['read-write'],
447
+ constraints: {
448
+ ranges: [{ min: 1, max: 100 }]
449
+ }
450
+ };
451
+
452
+ subagent.getMib().registerProvider(scalarProvider);
453
+ subagent.getMib().setScalarValue('testScalar', 50);
454
+ });
455
+
456
+ it('validates integer constraints', function() {
457
+ // This tests the underlying validation that would be used in set operations
458
+ const instanceNode = subagent.getMib().lookup('1.3.6.1.4.1.8072.9999.1.0');
459
+ if (instanceNode && typeof instanceNode.validateValue === 'function') {
460
+ const validResult = instanceNode.validateValue(snmp.ObjectType.Integer, 75);
461
+ assert.equal(validResult, true);
462
+
463
+ const invalidResult = instanceNode.validateValue(snmp.ObjectType.Integer, 150);
464
+ assert.equal(invalidResult, false);
465
+ }
466
+ });
467
+ });
468
+ });
469
+ });