def test_bulkget(self): data = readbytes('bulk_get_response.hex') expected = BulkResult( { '1.3.6.1.2.1.1.1.0': OctetString( b'Linux 7e68e60fe303 4.4.0-28-generic ' b'#47-Ubuntu SMP Fri Jun 24 10:09:13 UTC 2016 x86_64') }, { '1.3.6.1.2.1.3.1.1.1.10.1.172.17.0.1': Integer(10), '1.3.6.1.2.1.3.1.1.2.10.1.172.17.0.1': OctetString(b'\x02B\xe2\xc5\x8d\t'), '1.3.6.1.2.1.3.1.1.3.10.1.172.17.0.1': IpAddress(b'\xac\x11\x00\x01'), '1.3.6.1.2.1.4.1.0': Integer(1), '1.3.6.1.2.1.4.3.0': Counter(57) }) with patch('puresnmp.api.raw.send') as mck: mck.return_value = data result = bulkget('::1', 'public', ['1.3.6.1.2.1.1.1'], ['1.3.6.1.2.1.3.1'], max_list_size=5) self.assertEqual(result, expected)
async def test_bulkget(self): expected = BulkResult( {'1.3.6.1.2.1.1.1.0': b'Linux 7e68e60fe303 4.4.0-28-generic ' b'#47-Ubuntu SMP Fri Jun 24 10:09:13 UTC 2016 x86_64'}, {'1.3.6.1.2.1.3.1.1.1.10.1.172.17.0.1': 10, '1.3.6.1.2.1.3.1.1.2.10.1.172.17.0.1': b'\x02B\xe2\xc5\x8d\t', '1.3.6.1.2.1.3.1.1.3.10.1.172.17.0.1': b'\xac\x11\x00\x01', '1.3.6.1.2.1.4.1.0': 1, '1.3.6.1.2.1.4.3.0': 57}) with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncMock) as mck: mck.bulkget.return_value = BulkResult({ '1.3.6.1.2.1.1.1.0': OctetString( b'Linux 7e68e60fe303 4.4.0-28-generic ' b'#47-Ubuntu SMP Fri Jun 24 10:09:13 UTC 2016 x86_64') }, { '1.3.6.1.2.1.3.1.1.1.10.1.172.17.0.1': Integer(10), '1.3.6.1.2.1.3.1.1.2.10.1.172.17.0.1': OctetString( b'\x02B\xe2\xc5\x8d\t'), '1.3.6.1.2.1.3.1.1.3.10.1.172.17.0.1': IpAddress( b'\xac\x11\x00\x01'), '1.3.6.1.2.1.4.1.0': Integer(1), '1.3.6.1.2.1.4.3.0': Counter(57) }) result = await bulkget('::1', 'public', ['1.3.6.1.2.1.1.1'], ['1.3.6.1.2.1.3.1'], max_list_size=5) assert result == expected
async def test_multi_walk(self): response_1 = readbytes('multiwalk_response_1.hex') response_2 = readbytes('multiwalk_response_2.hex') response_3 = readbytes('multiwalk_response_3.hex') expected = [VarBind( ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.1'), Integer(1) ), VarBind( ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.1'), OctetString(b'lo') ), VarBind( ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.78'), Integer(78) ), VarBind( ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.78'), OctetString(b'eth0') )] with patch('puresnmp.aio.api.raw.Transport') as mck: mck().send = AsyncMock() mck().get_request_id.return_value = 0 mck().send.side_effect = [response_1, response_2, response_3] result = [] async for x in multiwalk('::1', 'public', [ '1.3.6.1.2.1.2.2.1.1', '1.3.6.1.2.1.2.2.1.2' ]): result.append(x) # TODO (advanced): should order matter in the following result? assert len(result) == len(expected)
def test_bulktable(self, mck_transport): responses = readbytes_multiple('bulktable_response.hex') mck_transport().send.side_effect = responses request_ids = [1, 2, 3, 4, 5] mck_transport().get_request_id.side_effect = request_ids result = list(bulktable('127.0.0.1', 'private', '1.3.6.1.2.1.2.2')) expected = [{ '0': '1', '1': Integer(1), '2': OctetString(b'lo'), '3': Integer(24), '4': Integer(65536), '5': Gauge(10000000), '6': OctetString(b''), '7': Integer(1), '8': Integer(1), '9': TimeTicks(0), '10': Counter(172), '11': Counter(2), '12': Counter(0), '13': Counter(0), '14': Counter(0), '15': Counter(0), '16': Counter(172), '17': Counter(2), '18': Counter(0), '19': Counter(0), '20': Counter(0), '21': Gauge(0), '22': ObjectIdentifier(0, 0), }, { '0': '4', '1': Integer(4), '2': OctetString(b'eth0'), '3': Integer(6), '4': Integer(1500), '5': Gauge(4294967295), '6': OctetString(b'\x02B\xac\x11\x00\x02'), '7': Integer(1), '8': Integer(1), '9': TimeTicks(0), '10': Counter(548760), '11': Counter(3888), '12': Counter(0), '13': Counter(0), '14': Counter(0), '15': Counter(0), '16': Counter(186660), '17': Counter(1875), '18': Counter(0), '19': Counter(0), '20': Counter(0), '21': Gauge(0), '22': ObjectIdentifier(0, 0), }] self.assertEqual(sorted(result, key=lambda x: x['0']), expected)
async def test_set_string_absolute(self): expected = (b'foo') with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncMock) as mck: mck.multiset.return_value = { ObjectIdentifier.from_string('1.2.3'): OctetString(b'foo') } result = await set('::1', 'private', '.1.2.3', OctetString(b'foo')) assert result == expected
def test_set_string_absolute(self): expected = (b'foo') with patch('puresnmp.api.pythonic.raw') as mck: mck.multiset.return_value = { ObjectIdentifier.from_string('1.2.3'): OctetString(b'foo') } result = set('::1', 'private', '.1.2.3', OctetString(b'foo')) self.assertEqual(result, expected)
def test_table_base_oid(self, mck_walk): """ The "table" function should be capable of detecting the "num_base_nodes" value by itself """ mck_walk.return_value = [ VarBind('1.2.1.1.1.1.1', OctetString(b'row 1.1.1 col 1')), VarBind('1.2.1.1.2.1.1', OctetString(b'row 2.1.1 col 1')), VarBind('1.2.1.2.1.1.1', OctetString(b'row 1.1.1 col 2')), VarBind('1.2.1.2.2.1.1', OctetString(b'row 2.1.1 col 2')), ] result = table('192.0.2.1', 'private', '1.2') expected = [ { '0': '1.1.1', '1': OctetString('row 1.1.1 col 1'), '2': OctetString('row 1.1.1 col 2') }, { '0': '2.1.1', '1': OctetString('row 2.1.1 col 1'), '2': OctetString('row 2.1.1 col 2') }, ] self.assertEqual(sorted(result, key=lambda x: x['0']), expected)
def test_multiset_absolute(self): with patch('puresnmp.api.pythonic.raw') as mck: mck.multiset.return_value = { '1.3.6.1.2.1.1.4.0': OctetString(b'*****@*****.**'), '1.3.6.1.2.1.1.5.0': OctetString(b'*****@*****.**'), } result = multiset('::1', 'private', [ ('.1.3.6.1.2.1.1.4.0', OctetString(b'*****@*****.**')), ('.1.3.6.1.2.1.1.5.0', OctetString(b'*****@*****.**')), ]) expected = { '1.3.6.1.2.1.1.4.0': b'*****@*****.**', '1.3.6.1.2.1.1.5.0': b'*****@*****.**', } self.assertEqual(result, expected)
async def test_table(self): with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncGenMock) as mck: oid = ObjectIdentifier.from_string mck.walk.return_value = [ VarBind(oid('1.2.1.1'), OctetString(b'test-11')), VarBind(oid('1.2.2.1'), OctetString(b'test-21')), VarBind(oid('1.2.1.2'), OctetString(b'test-21')), VarBind(oid('1.2.2.2'), OctetString(b'test-22')), ] result = await table('1.2.3.4', 'private', ['1.2']) expected = [ {'0': '1', '1': b'test-11', '2': b'test-21'}, {'0': '2', '1': b'test-21', '2': b'test-22'}, ] assert len(result) == len(expected)
async def test_multiset_absolute(self): with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncMock) as mck: mck.multiset.return_value = { '1.3.6.1.2.1.1.4.0': OctetString(b'*****@*****.**'), '1.3.6.1.2.1.1.5.0': OctetString(b'*****@*****.**'), } result = await multiset('::1', 'private', [ ('.1.3.6.1.2.1.1.4.0', OctetString(b'*****@*****.**')), ('.1.3.6.1.2.1.1.5.0', OctetString(b'*****@*****.**')), ]) expected = { '1.3.6.1.2.1.1.4.0': b'*****@*****.**', '1.3.6.1.2.1.1.5.0': b'*****@*****.**', } assert result == expected
async def test_bulkwalk(self): request_ids = [1001613222, 1001613223, 1001613224] with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncGenMock) as mck: mck.multiwalk.return_value = [ VarBind('1.3.6.1.2.1.2.2.1.1.1', Integer(1)), VarBind('1.3.6.1.2.1.2.2.1.1.10', Integer(10)), VarBind('1.3.6.1.2.1.2.2.1.2.1', OctetString(b"lo")), VarBind('1.3.6.1.2.1.2.2.1.22.10', ObjectIdentifier(0, 0)) ] result = [] async for x in bulkwalk('127.0.0.1', 'private', ['1.3.6.1.2.1.2.2'], bulk_size=20): result.append(x) expected = [ VarBind('1.3.6.1.2.1.2.2.1.1.1', 1), VarBind('1.3.6.1.2.1.2.2.1.1.10', 10), VarBind('1.3.6.1.2.1.2.2.1.2.1', b"lo"), VarBind('1.3.6.1.2.1.2.2.1.22.10', '0.0'), ] assert result == expected
def test_set(self): self.transport.send.return_value = readbytes('apiv1/set_response.hex') result = snmp.set('127.0.0.1', 'private', '1.3.6.1.2.1.1.6.0', OctetString(b'Hello')) self.assertEqual(result, b'On the move') self.assertTrue(self.transport.send.called, 'method was not called') self.assertIsInstance(result, bytes)
def test_multiset(self): response = readbytes('apiv1/multiset_response.hex') self.transport.send.return_value = response result = snmp.multiset('127.0.0.1', 'private', [('1.3.6.1.2.1.1.4.0', OctetString(b'foo')), ('1.3.6.1.2.1.1.6.0', OctetString(b'bar'))]) expected = {'1.3.6.1.2.1.1.4.0': b'foo', '1.3.6.1.2.1.1.6.0': b'bar'} self.assertEqual(result, expected) self.assertTrue(self.transport.send.called, 'method was not called') self.assertIsInstance(result, dict) key_types = {type(key) for key in result.keys()} if six.PY3: self.assertEqual(key_types, {str}) else: self.assertEqual(key_types, {unicode}) value_types = {type(value) for value in result.values()} self.assertEqual(value_types, {bytes})
async def test_get_string(self): expected = (b'Linux d24cf7f36138 4.4.0-28-generic #47-Ubuntu SMP ' b'Fri Jun 24 10:09:13 UTC 2016 x86_64') with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncMock) as mck: mck.get.return_value = OctetString( b'Linux d24cf7f36138 4.4.0-28-generic #47-Ubuntu SMP ' b'Fri Jun 24 10:09:13 UTC 2016 x86_64') result = await get('::1', 'private', '1.2.3') assert result == expected
def test_get_string(self): expected = (b'Linux d24cf7f36138 4.4.0-28-generic #47-Ubuntu SMP ' b'Fri Jun 24 10:09:13 UTC 2016 x86_64') with patch('puresnmp.api.pythonic.raw') as mck: mck.get.return_value = OctetString( b'Linux d24cf7f36138 4.4.0-28-generic #47-Ubuntu SMP ' b'Fri Jun 24 10:09:13 UTC 2016 x86_64') result = get('::1', 'private', '1.2.3') self.assertEqual(result, expected)
def test_get_string(self): data = readbytes('get_sysdescr_01.hex') expected = OctetString( b'Linux d24cf7f36138 4.4.0-28-generic #47-Ubuntu SMP ' b'Fri Jun 24 10:09:13 UTC 2016 x86_64') with patch('puresnmp.api.raw.send') as mck: mck.return_value = data result = get('::1', 'private', '1.2.3') self.assertEqual(result, expected)
async def test_get_string(self): data = readbytes('get_sysdescr_01.hex') expected = OctetString( b'Linux d24cf7f36138 4.4.0-28-generic #47-Ubuntu SMP ' b'Fri Jun 24 10:09:13 UTC 2016 x86_64') with patch('puresnmp.aio.api.raw.send', new_callable=AsyncMock) as mck: mck.return_value = data result = await get('::1', 'private', '1.2.3') assert result == expected
def test_get_call_args(self): data = readbytes('dummy.hex') # any dump would do packet = Sequence(Integer(Version.V2C), OctetString('public'), GetNextRequest(0, ObjectIdentifier(1, 2, 3))) with patch('puresnmp.api.raw.send') as mck, \ patch('puresnmp.api.raw.get_request_id') as mck2: mck2.return_value = 0 mck.return_value = data getnext('::1', 'public', '1.2.3') mck.assert_called_with('::1', 161, to_bytes(packet), timeout=2)
def test_set_multiple_varbind(self): """ SET responses should only contain one varbind. """ data = readbytes('set_response_multiple.hex') with patch('puresnmp.send') as mck: mck.return_value = data with self.assertRaisesRegex(SnmpError, 'varbind'): set('::1', 'private', '1.3.6.1.2.1.1.4.0', OctetString(b'*****@*****.**'))
def test_multiset(self): """ Test setting multiple OIDs at once. NOTE: The OID '1.3.6.1.2.1.1.5.0' below is manually edited for unit-testing. It probably has a different type in the real world! """ data = readbytes('multiset_response.hex') with patch('puresnmp.api.raw.send') as mck: mck.return_value = data result = multiset('::1', 'private', [ ('1.3.6.1.2.1.1.4.0', OctetString(b'*****@*****.**')), ('1.3.6.1.2.1.1.5.0', OctetString(b'*****@*****.**')), ]) expected = { '1.3.6.1.2.1.1.4.0': OctetString(b'*****@*****.**'), '1.3.6.1.2.1.1.5.0': OctetString(b'*****@*****.**'), } self.assertEqual(result, expected)
async def test_get_call_args(self): data = readbytes('dummy.hex') # any dump would do packet = Sequence(Integer(Version.V2C), OctetString('public'), GetNextRequest(0, ObjectIdentifier(1, 2, 3))) with patch('puresnmp.aio.api.raw.Transport') as mck: mck().send = AsyncMock() mck().get_request_id.return_value = 0 mck().send.return_value = data await getnext('::1', 'public', '1.2.3') mck.assert_called_with(timeout=6) mck().send.assert_called_with('::1', 161, to_bytes(packet))
def test_get_call_args_issue_22(self): data = readbytes('dummy.hex') # any dump would do packet = Sequence(Integer(Version.V2C), OctetString('public'), BulkGetRequest(0, 0, 2, ObjectIdentifier(1, 2, 3))) with patch('puresnmp.api.raw.Transport') as mck: mck().send.return_value = data mck().get_request_id.return_value = 0 with six.assertRaisesRegex(self, TypeError, 'OIDS.*list'): # we need to wrap this in a list to consume the generator. list(bulkwalk('::1', 'public', '1.2.3', bulk_size=2))
def test_54_endofmibview(): data = readbytes('gh-issues/54-endofmibview.hex') with patch('puresnmp.api.raw.Transport') as ptch: ptch().send.return_value = data ptch().get_request_id.return_value = 123 result = bulkget('192.0.2.1', 'private', [], ['1.2.3'], max_list_size=10) assert result.scalars == {} expected_lists = { '1.3.6.1.4.1.12325.1.303.1.9.1.3.1.0': OctetString(b'\x00' * 404), '1.3.6.1.4.1.12325.1.303.1.9.1.3.2.0': OctetString(b'\x00' * 404), '1.3.6.1.6.3.1.1.6.1.0': Integer(1103779487), '1.3.6.1.6.3.10.2.1.1.0': OctetString(b'\x80\x00\x08\xbe\x803740773355'), '1.3.6.1.6.3.10.2.1.2.0': Integer(1), '1.3.6.1.6.3.10.2.1.3.0': Integer(632), '1.3.6.1.6.3.10.2.1.4.0': Integer(1500), } assert result.listing == expected_lists
async def test_multiset(self): """ Test setting multiple OIDs at once. NOTE: The OID '1.3.6.1.2.1.1.5.0' below is manually edited for unit-testing. It probably has a different type in the real world! """ with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncMock) as mck: mck.multiset.return_value = { '1.3.6.1.2.1.1.4.0': OctetString(b'*****@*****.**'), '1.3.6.1.2.1.1.5.0': OctetString(b'*****@*****.**'), } result = await multiset('::1', 'private', [ ('1.3.6.1.2.1.1.4.0', OctetString(b'*****@*****.**')), ('1.3.6.1.2.1.1.5.0', OctetString(b'*****@*****.**')), ]) expected = { '1.3.6.1.2.1.1.4.0': b'*****@*****.**', '1.3.6.1.2.1.1.5.0': b'*****@*****.**', } assert result == expected
async def test_multiset(self): """ Test setting multiple OIDs at once. NOTE: The OID '1.3.6.1.2.1.1.5.0' below is manually edited for unit-testing. It probably has a different type in the real world! """ data = readbytes('multiset_response.hex') with patch('puresnmp.aio.api.raw.Transport') as mck: mck().send = AsyncMock() mck().get_request_id.return_value = 0 mck().send.return_value = data result = await multiset('::1', 'private', [ ('1.3.6.1.2.1.1.4.0', OctetString(b'*****@*****.**')), ('1.3.6.1.2.1.1.5.0', OctetString(b'*****@*****.**')), ]) expected = { '1.3.6.1.2.1.1.4.0': OctetString(b'*****@*****.**'), '1.3.6.1.2.1.1.5.0': OctetString(b'*****@*****.**'), } assert result == expected
def test_get_call_args(self): data = readbytes('dummy.hex') # any dump would do packet = Sequence( Integer(Version.V2C), OctetString('public'), BulkGetRequest(0, 1, 2, ObjectIdentifier(1, 2, 3), ObjectIdentifier(1, 2, 4))) with patch('puresnmp.send') as mck, \ patch('puresnmp.get_request_id') as mck2: mck2.return_value = 0 mck.return_value = data bulkget('::1', 'public', ['1.2.3'], ['1.2.4'], max_list_size=2) mck.assert_called_with('::1', 161, bytes(packet))
def test_get_call_args(self): data = readbytes('dummy.hex') # any dump would do packet = Sequence(Integer(Version.V2C), OctetString('public'), BulkGetRequest(0, 0, 2, ObjectIdentifier(1, 2, 3))) with patch('puresnmp.api.raw.send') as mck, \ patch('puresnmp.api.raw.get_request_id') as mck2: mck2.return_value = 0 mck.return_value = data # we need to wrap this in a list to consume the generator. list(bulkwalk('::1', 'public', ['1.2.3'], bulk_size=2)) mck.assert_called_with('::1', 161, to_bytes(packet), timeout=2)
def test_get_call_args(self): data = readbytes('dummy.hex') # any dump would do packet = Sequence( Integer(Version.V2C), OctetString('public'), BulkGetRequest(0, 1, 2, ObjectIdentifier(1, 2, 3), ObjectIdentifier(1, 2, 4))) with patch('puresnmp.api.raw.Transport') as mck: mck().send.return_value = data mck().get_request_id.return_value = 0 bulkget('::1', 'public', ['1.2.3'], ['1.2.4'], max_list_size=2) mck.assert_called_with(timeout=6) mck().send.assert_called_with('::1', 161, to_bytes(packet))
def test_traps(self): with patch('puresnmp.api.pythonic.raw') as mck: oid = ObjectIdentifier.from_string mck.traps.return_value = [ Trap(request_id=1, error_status=0, error_index=0, varbinds=[ VarBind(oid('1.2.1.1'), OctetString(b'fake-uptime')), VarBind(oid('1.2.1.2'), ObjectIdentifier(1, 2, 3, 4)), VarBind(oid('1.2.1.3'), Integer(13)), VarBind(oid('1.2.1.4'), OctetString(b'fake-value-2')), ]) ] result = [] for trap in traps(): result.append((trap.uptime, trap.oid, trap.values)) expected = [(b'fake-uptime', u'1.2.3.4', { u'1.2.1.3': 13, u'1.2.1.4': b'fake-value-2', })] self.assertEqual(result, expected)
def test_multi_walk(self): response_1 = readbytes('multiwalk_response_1.hex') response_2 = readbytes('multiwalk_response_2.hex') response_3 = readbytes('multiwalk_response_3.hex') expected = [ VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.1'), Integer(1)), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.1'), OctetString(b'lo')), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.78'), Integer(78)), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.78'), OctetString(b'eth0')) ] with patch('puresnmp.api.raw.send') as mck: mck.side_effect = [response_1, response_2, response_3] result = list( multiwalk('::1', 'public', ['1.3.6.1.2.1.2.2.1.1', '1.3.6.1.2.1.2.2.1.2'])) self.assertEqual(result, expected)