Permalink
Browse files

Improve testing framework

  • Loading branch information...
1 parent ff706fa commit 11548beb6e40b8e273b9ab0d056bbd41557f5f0b @steffann committed Jan 8, 2013
@@ -5,7 +5,6 @@
'''
from abc import ABCMeta, abstractmethod
from bitstring import ConstBitStream
-import type_registry
class LISPControlMessage(object):
@@ -38,6 +37,8 @@ def from_bytes(cls, bitstream):
Look at the type of the message, instantiate the correct class and
let it parse the message.
'''
+ import type_registry
+
# Convert to ConstBitStream (if not already provided)
if not isinstance(bitstream, ConstBitStream):
bitstream = ConstBitStream(bytes=bitstream)
@@ -164,8 +164,34 @@ def sanitize(self):
@classmethod
def from_bytes(cls, bitstream):
- '''
+ r'''
Parse the given packet and update properties accordingly
+
+ >>> data_hex = ('13000001ae92b5574f849cd00001ac10'
+ ... '1f0300015cfe1cbd00200001ac101f01')
+ >>> data = data_hex.decode('hex')
+ >>> message = LISPControlMessage.from_bytes(data)
+ >>> message.message_type
+ 1
+ >>> message.authoritative
+ False
+ >>> message.probe
+ True
+ >>> message.smr
+ True
+ >>> message.pitr
+ False
+ >>> message.smr_invoked
+ False
+ >>> message.nonce
+ '\xae\x92\xb5WO\x84\x9c\xd0'
+ >>> message.source_eid
+ IP('172.16.31.3')
+ >>> message.itr_rlocs
+ [IP('92.254.28.189')]
+ >>> message.eid_prefixes
+ [IP('172.16.31.1')]
+ >>> message.map_reply
'''
packet = cls()
@@ -234,8 +260,16 @@ def from_bytes(cls, bitstream):
return packet
def to_bytes(self):
- '''
+ r'''
Create bytes from properties
+
+ >>> message = LISPMapRequestMessage(itr_rlocs=[IP('192.0.2.1')],
+ ... eid_prefixes=[IP('2001:db8::/32')])
+ >>> hex = message.to_bytes().encode('hex')
+ >>> hex[:40]
+ '10000001000000000000000000000001c0000201'
+ >>> hex[40:]
+ '0020000220010db8000000000000000000000000'
'''
# Verify that properties make sense
self.sanitize()
@@ -4,6 +4,7 @@
@author: sander
'''
import numbers
+from pylisp.packet.control.base import LISPControlMessage
# Store supported message types and their classes
_type_classes = {}
@@ -13,13 +14,10 @@
def register_type_class(type_class):
- from base import LISPControlMessage
-
# Check for valid class
if not issubclass(type_class, LISPControlMessage):
- msg = 'Message type classes must be subclasses of {0}'
- class_name = LISPControlMessage.__class__.__name__
- raise ValueError(msg.format(class_name))
+ msg = 'Message type classes must be subclasses of LISPControlMessage'
+ raise ValueError(msg)
# Check for valid type numbers
type_nr = type_class.message_type
@@ -3,6 +3,7 @@
# Add the parent directory to the start of the path
if __name__ == '__main__':
import sys
+ sys.path.insert(0, '.')
sys.path.insert(0, '..')
from pylisp.packet.control import encapsulated_control_message
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+from IPy import IP
+from unittests.utils import PacketTest, PacketTestCreator
+
+# Add the parent directory to the start of the path
+if __name__ == '__main__':
+ import sys
+ sys.path.insert(0, '.')
+ sys.path.insert(0, '..')
+
+from pylisp.packet.control import map_request
+import doctest
+import unittest
+
+
+def load_tests(loader, tests, ignore):
+ '''
+ Add doctests to the test set
+ '''
+ tests.addTests(doctest.DocTestSuite(map_request))
+ return tests
+
+
+class MapRequestTestCase(unittest.TestCase):
+ __metaclass__ = PacketTestCreator
+
+ cases = [PacketTest(name='test_minimal_map_request',
+ desc='Generate a minimal map request',
+ cls=map_request.LISPMapRequestMessage,
+ params={'itr_rlocs': [IP('1.2.3.4')],
+ 'eid_prefixes': [IP('192.0.2.0/24')]},
+ bytes_hex='1000000100000000000000000000'
+ '00010102030400180001c0000200',
+ exception=(None, '')),
+ ]
+
+
+if __name__ == '__main__':
+ unittest.main()
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+
+# Add the parent directory to the start of the path
+if __name__ == '__main__':
+ import sys
+ sys.path.insert(0, '.')
+ sys.path.insert(0, '..')
+
+from copy import copy
+from pylisp.packet.control import type_registry
+from pylisp.packet.control.base import LISPControlMessage
+import doctest
+import unittest
+
+
+def load_tests(loader, tests, ignore):
+ '''
+ Add doctests to the test set
+ '''
+ tests.addTests(doctest.DocTestSuite(type_registry))
+ return tests
+
+
+class TypeRegistryTestCase(unittest.TestCase):
+ def setUp(self):
+ '''
+ Store a backup of the type registry
+ Because we're going to mess it up
+ '''
+ self.backup_type_registry = copy(type_registry._type_classes)
+ type_registry._type_classes = {}
+
+ def tearDown(self):
+ '''
+ Restore a clean copy of the type registry for further testing
+ '''
+ type_registry._type_classes = self.backup_type_registry
+
+ def test_register_type_class(self):
+ '''
+ Normal registration of a type class
+ '''
+ class ValidType(LISPControlMessage):
+ message_type = 1
+
+ type_registry.register_type_class(ValidType)
+ the_class = type_registry.get_type_class(1)
+ self.assertEqual(the_class, ValidType)
+
+ def test_wrong_class(self):
+ '''
+ Try to register a class of the wrong type
+ '''
+ class WrongType:
+ pass
+
+ with self.assertRaisesRegexp(ValueError, 'subclass'):
+ type_registry.register_type_class(WrongType)
+
+ def test_wrong_message_type(self):
+ '''
+ Try to register a class of the wrong type
+ '''
+ class WrongType(LISPControlMessage):
+ message_type = 16
+
+ with self.assertRaisesRegexp(ValueError, 'message.type'):
+ type_registry.register_type_class(WrongType)
+
+ def test_duplicate_registration_of_same_class(self):
+ '''
+ Try to register the same class twice
+ '''
+ class ValidType(LISPControlMessage):
+ message_type = 1
+
+ type_registry.register_type_class(ValidType)
+ the_class = type_registry.get_type_class(1)
+ self.assertEqual(the_class, ValidType)
+
+ type_registry.register_type_class(ValidType)
+ the_class = type_registry.get_type_class(1)
+ self.assertEqual(the_class, ValidType)
+
+ def test_bad_duplicate_registration(self):
+ '''
+ Try to register two classes for the same type
+ '''
+ class ValidType1(LISPControlMessage):
+ message_type = 1
+
+ class ValidType2(LISPControlMessage):
+ message_type = 1
+
+ type_registry.register_type_class(ValidType1)
+ the_class = type_registry.get_type_class(1)
+ self.assertEqual(the_class, ValidType1)
+
+ with self.assertRaisesRegexp(ValueError, 'bound'):
+ type_registry.register_type_class(ValidType2)
+
+ the_class = type_registry.get_type_class(1)
+ self.assertEqual(the_class, ValidType1)
+
+
+if __name__ == '__main__':
+ unittest.main()
Oops, something went wrong.

0 comments on commit 11548be

Please sign in to comment.