Ejemplo n.º 1
0
 def test_walk_multiple_return_binds(self):
     """
     A "WALK" response should only return one varbind.
     """
     data = readbytes('get_sysoid_01_error.hex')
     with patch('puresnmp.api.raw.send') as mck:
         mck.return_value = data
         with six.assertRaisesRegex(self, SnmpError, 'varbind'):
             next(walk('::1', 'private', '1.2.3'))
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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.*')
Ejemplo n.º 4
0
    def test_walk_increasing_oid_lenient(self):
        '''
        We want to be able to allow faulty SNMP implementations to at least try
        to fetch the values in a walk which are not increasing. It should read
        up to the values which are no longer increasing and emit a warning.
        '''
        logger = getLogger('puresnmp')
        handler = CapturingHandler()
        logger.addHandler(handler)

        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, 1), Integer(121)),  # non-increasing
        ]
        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]

        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'))

        # 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.1.*1.2.5.*')
        logger.removeHandler(handler)