def test_walk(self): response_1 = readbytes('walk_response_1.hex') response_2 = readbytes('walk_response_2.hex') response_3 = readbytes('walk_response_3.hex') num_call = 0 def mocked_responses(*args, **kwargs): nonlocal num_call num_call += 1 if num_call == 1: return response_1 elif num_call == 2: return response_2 elif num_call == 3: return response_3 else: raise AssertionError('Expected no more than 3 calls!') expected = [ VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.1'), 10000000), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.13'), 4294967295) ] with patch('puresnmp.send') as mck: mck.side_effect = mocked_responses result = list(walk('::1', 'public', '1.3.6.1.2.1.2.2.1.5')) self.assertEqual(result, expected)
async def test_multi_walk(self): expected = [ VarBind('1.3.6.1.2.1.2.2.1.1.1', 1), VarBind('1.3.6.1.2.1.2.2.1.2.1', b'lo'), VarBind('1.3.6.1.2.1.2.2.1.1.78', 78), VarBind('1.3.6.1.2.1.2.2.1.2.78', b'eth0') ] with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncGenMock) as mck: mck.multiwalk.return_value = [ VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.1'), 1), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.1'), b'lo'), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.78'), 78), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.78'), b'eth0') ] 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)
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_multi_walk(self): expected = [ VarBind('1.3.6.1.2.1.2.2.1.1.1', 1), VarBind('1.3.6.1.2.1.2.2.1.2.1', b'lo'), VarBind('1.3.6.1.2.1.2.2.1.1.78', 78), VarBind('1.3.6.1.2.1.2.2.1.2.78', b'eth0') ] with patch('puresnmp.api.pythonic.raw') as mck: mck.multiwalk.return_value = [ VarBind( ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.1'), 1, ), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.1'), b'lo'), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.78'), 78), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.78'), b'eth0') ] 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'])) # TODO (advanced): should order matter in the following result? six.assertCountEqual(self, result, 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)
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.send') as mck, \ patch('puresnmp.api.raw.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, to_bytes(packet), timeout=2)
def test_walk(self): expected = [ VarBind('1.3.6.1.2.1.2.2.1.5.1', 10000000), VarBind('1.3.6.1.2.1.2.2.1.5.13', 4294967295) ] with patch('puresnmp.api.pythonic.raw') as mck: mck.walk.return_value = [ VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.1'), Gauge(10000000)), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.13'), Integer(4294967295)) ] result = list(walk('::1', 'public', '1.3.6.1.2.1.2.2.1.5')) self.assertEqual(result, expected)
async def test_get_oid(self): data = readbytes('get_sysoid_01.hex') expected = ObjectIdentifier.from_string('1.3.6.1.4.1.8072.3.2.10') 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
async def test_get_oid(self): expected = ('1.3.6.1.4.1.8072.3.2.10') with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncMock) as mck: mck.get.return_value = ObjectIdentifier.from_string( '1.3.6.1.4.1.8072.3.2.10') result = await get('::1', 'private', '1.2.3') 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_walk(self): response_1 = readbytes('walk_response_1.hex') response_2 = readbytes('walk_response_2.hex') response_3 = readbytes('walk_response_3.hex') expected = [ VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.1'), Gauge(10000000)), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.13'), Gauge(4294967295)) ] with patch('puresnmp.api.raw.send') as mck: mck.side_effect = [response_1, response_2, response_3] result = list(walk('::1', 'public', '1.3.6.1.2.1.2.2.1.5')) self.assertEqual(result, expected)
def test_get_oid(self): data = readbytes('get_sysoid_01.hex') expected = ObjectIdentifier.from_string('1.3.6.1.4.1.8072.3.2.10') with patch('puresnmp.api.raw.send') as mck: mck.return_value = data result = get('::1', 'private', '1.2.3') self.assertEqual(result, expected)
def test_get_oid(self): expected = ('1.3.6.1.4.1.8072.3.2.10') with patch('puresnmp.api.pythonic.raw') as mck: mck.get.return_value = ObjectIdentifier.from_string( '1.3.6.1.4.1.8072.3.2.10') result = get('::1', 'private', '1.2.3') self.assertEqual(result, 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)
async def test_get_oid(self): data = readbytes('get_sysoid_01.hex') expected = ObjectIdentifier.from_string('1.3.6.1.4.1.8072.3.2.10') with patch('puresnmp.aio.api.raw.Transport') as mck: mck().send = AsyncMock() mck().send.return_value = data mck().get_request_id.return_value = 0 result = await get('::1', 'private', '1.2.3') assert result == expected
async def test_walk(self): response_1 = readbytes('walk_response_1.hex') response_2 = readbytes('walk_response_2.hex') response_3 = readbytes('walk_response_3.hex') expected = [ VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.1'), Gauge(10000000)), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.13'), Gauge(4294967295)) ] with patch('puresnmp.aio.api.raw.send', new_callable=AsyncMock) as mck: mck.side_effect = [response_1, response_2, response_3] result = [] async for x in walk('::1', 'public', '1.3.6.1.2.1.2.2.1.5'): result.append(x) assert result == expected
async def test_walk(self): expected = [ VarBind('1.3.6.1.2.1.2.2.1.5.1', 10000000), VarBind('1.3.6.1.2.1.2.2.1.5.13', 4294967295) ] with patch('puresnmp.aio.api.pythonic.raw', new_callable=AsyncGenMock) as mck: mck.walk.return_value = [ VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.1'), Gauge(10000000)), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.13'), Integer(4294967295)) ] result = [] async for x in walk('::1', 'public', '1.3.6.1.2.1.2.2.1.5'): result.append(x) assert 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.send', new_callable=AsyncMock) as mck, \ patch('puresnmp.aio.api.raw.get_request_id') as mck2: mck2.return_value = 0 mck.return_value = data await getnext('::1', 'public', '1.2.3') mck.assert_called_with('::1', 161, to_bytes(packet), timeout=6)
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.send') as mck, \ patch('puresnmp.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, bytes(packet))
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.Transport') as mck: mck().send.return_value = data mck().get_request_id.return_value = 0 getnext('::1', 'public', '1.2.3') mck.assert_called_with(timeout=6) mck().send.assert_called_with('::1', 161, to_bytes(packet))
async def test_walk(self): response_1 = readbytes('walk_response_1.hex') response_2 = readbytes('walk_response_2.hex') response_3 = readbytes('walk_response_3.hex') expected = [ VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.1'), Gauge(10000000)), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.5.13'), Gauge(4294967295)) ] with patch('puresnmp.aio.api.raw.Transport') as mck: mck().send = AsyncMock() mck().send.side_effect = [response_1, response_2, response_3] mck().get_request_id.return_value = 0 result = [] async for x in walk('::1', 'public', '1.3.6.1.2.1.2.2.1.5'): result.append(x) assert result == expected
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_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_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'), 1), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.1'), b'lo'), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.1.78'), 78), VarBind(ObjectIdentifier.from_string('1.3.6.1.2.1.2.2.1.2.78'), b'eth0') ] with patch('puresnmp.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'])) # TODO (advanced): should order matter in the following result? self.assertCountEqual(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)
async 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.aio.api.raw.send', new_callable=AsyncMock) as mck, \ patch('puresnmp.aio.api.raw.get_request_id') as mck2: mck2.return_value = 0 mck.return_value = data with pytest.raises(TypeError, match=r'OIDS.*list'): # we need to wrap this in a list to consume the generator. async for x in bulkwalk('::1', 'public', '1.2.3', bulk_size=2): pass
async 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.aio.api.raw.Transport') as mck: mck().send = AsyncMock() mck().get_request_id.return_value = 0 mck().send.return_value = data # we need to wrap this in a list to consume the generator. async for x in bulkwalk('::1', 'public', ['1.2.3'], bulk_size=2): pass mck.assert_called_with(timeout=6) mck().send.assert_called_with('::1', 161, to_bytes(packet))
def test_multiget(self): data = readbytes('multiget_response.hex') expected = [ ObjectIdentifier.from_string('1.3.6.1.4.1.8072.3.2.10'), OctetString(b"Linux 7fbf2f0c363d 4.4.0-28-generic " b"#47-Ubuntu SMP Fri Jun 24 10:09:13 " b"UTC 2016 x86_64") ] with patch('puresnmp.api.raw.send') as mck: mck.return_value = data result = multiget('::1', 'private', [ '1.3.6.1.2.1.1.2.0', '1.3.6.1.2.1.1.1.0', ]) self.assertEqual(result, expected)
def test_walk_endless_loop(self): ''' In rare cases, some devices fall into an endless loop by returning the requested OID on a "getnext" call during a "walk" operation. A SNMP client behaving according to the SNMP spec will fall into an endless loop. This test fakes such a case and revents the loop. ''' response_binds = [ VarBind(ObjectIdentifier(1, 2, 3), Integer(123)), VarBind(ObjectIdentifier(1, 2, 4), Integer(124)), VarBind(ObjectIdentifier(1, 2, 5), Integer(125)), VarBind(ObjectIdentifier(1, 2, 5), Integer(125)), # same OID VarBind(ObjectIdentifier(1, 2, 5), Integer(125)), # same OID VarBind(ObjectIdentifier(1, 2, 5), Integer(125)), # same OID ] response_packets = [ Sequence(Integer(1), OctetString(b'public'), GetResponse(234, [bind])) for bind in response_binds ] response_bytes = [to_bytes(packet) for packet in response_packets] handler = CapturingHandler() logger = getLogger('puresnmp') logger.addHandler(handler) with patch('puresnmp.api.raw.Transport') as mck: mck().send.side_effect = response_bytes mck().get_request_id.return_value = 0 result = list(walk('::1', 'private', '1.2', errors='warn')) logger.removeHandler(handler) # The last OID in the mocked responses is decreasing so we want to read # just up to that point. expected = [ VarBind(ObjectIdentifier(1, 2, 3), Integer(123)), VarBind(ObjectIdentifier(1, 2, 4), Integer(124)), VarBind(ObjectIdentifier(1, 2, 5), Integer(125)), ] self.assertEqual(result, expected) # We also want to make sure that we have a proper warning about this handler.assertContains(WARNING, r'.*1.2.5.*')