commit 895cd3a3e3c9e453ee2a1e494f486dd5df3326e7 Author: Damian Johnson atagar@torproject.org Date: Tue Jan 16 12:00:31 2018 -0800
Split size tests into their own module --- stem/client/__init__.py | 122 +++++++++++++++++++++++----------------------- test/settings.cfg | 1 + test/unit/client/size.py | 50 +++++++++++++++++++ test/unit/client/types.py | 43 +--------------- 4 files changed, 113 insertions(+), 103 deletions(-)
diff --git a/stem/client/__init__.py b/stem/client/__init__.py index defa09fa..3b38f8bb 100644 --- a/stem/client/__init__.py +++ b/stem/client/__init__.py @@ -61,67 +61,6 @@ ADDR_INT = { }
-class Certificate(collections.namedtuple('Certificate', ['type', 'value'])): - """ - Relay certificate as defined in tor-spec section 4.2. Certificate types - are... - - ==================== =========== - Type Value Description - ==================== =========== - 1 Link key certificate certified by RSA1024 identity - 2 RSA1024 Identity certificate - 3 RSA1024 AUTHENTICATE cell link certificate - ==================== =========== - - :var int type: certificate type - :var bytes value: certificate value - """ - - -class Address(collections.namedtuple('Address', ['type', 'type_int', 'value', 'value_bin'])): - """ - Relay address. - - :var stem.client.AddrType type: address type - :var int type_int: integer value of the address type - :var unicode value: address value - :var bytes value_bin: encoded address value - """ - - @staticmethod - def pack(addr): - """ - Bytes payload for an address. - """ - - raise NotImplementedError('Not yet available') - - @staticmethod - def pop(content): - if not content: - raise ValueError('Payload empty where an address was expected') - elif len(content) < 2: - raise ValueError('Insuffient data for address headers') - - addr_type_int, content = Size.CHAR.pop(content) - addr_type = ADDR_INT.get(addr_type_int, AddrType.UNKNOWN) - addr_length, content = Size.CHAR.pop(content) - - if len(content) < addr_length: - raise ValueError('Address specified a payload of %i bytes, but only had %i' % (addr_length, len(content))) - - # TODO: add support for other address types - - address_bin, content = content[:addr_length], content[addr_length:] - address = None - - if addr_type == AddrType.IPv4 and len(address_bin) == 4: - address = '.'.join([str(Size.CHAR.unpack(address_bin[i])) for i in range(4)]) - - return Address(addr_type, addr_type_int, address, address_bin), content - - class Size(object): """ Unsigned `struct.pack format @@ -189,6 +128,67 @@ class Size(object): return self.unpack(content[:self.size]), content[self.size:]
+class Certificate(collections.namedtuple('Certificate', ['type', 'value'])): + """ + Relay certificate as defined in tor-spec section 4.2. Certificate types + are... + + ==================== =========== + Type Value Description + ==================== =========== + 1 Link key certificate certified by RSA1024 identity + 2 RSA1024 Identity certificate + 3 RSA1024 AUTHENTICATE cell link certificate + ==================== =========== + + :var int type: certificate type + :var bytes value: certificate value + """ + + +class Address(collections.namedtuple('Address', ['type', 'type_int', 'value', 'value_bin'])): + """ + Relay address. + + :var stem.client.AddrType type: address type + :var int type_int: integer value of the address type + :var unicode value: address value + :var bytes value_bin: encoded address value + """ + + @staticmethod + def pack(addr): + """ + Bytes payload for an address. + """ + + raise NotImplementedError('Not yet available') + + @staticmethod + def pop(content): + if not content: + raise ValueError('Payload empty where an address was expected') + elif len(content) < 2: + raise ValueError('Insuffient data for address headers') + + addr_type_int, content = Size.CHAR.pop(content) + addr_type = ADDR_INT.get(addr_type_int, AddrType.UNKNOWN) + addr_length, content = Size.CHAR.pop(content) + + if len(content) < addr_length: + raise ValueError('Address specified a payload of %i bytes, but only had %i' % (addr_length, len(content))) + + # TODO: add support for other address types + + address_bin, content = content[:addr_length], content[addr_length:] + address = None + + if addr_type == AddrType.IPv4 and len(address_bin) == 4: + address = '.'.join([str(Size.CHAR.unpack(address_bin[i])) for i in range(4)]) + + return Address(addr_type, addr_type_int, address, address_bin), content + + setattr(Size, 'CHAR', Size('CHAR', 1, '!B')) setattr(Size, 'SHORT', Size('SHORT', 2, '!H')) setattr(Size, 'LONG', Size('LONG', 4, '!L')) diff --git a/test/settings.cfg b/test/settings.cfg index d4e1a6c3..96e2d302 100644 --- a/test/settings.cfg +++ b/test/settings.cfg @@ -230,6 +230,7 @@ test.unit_tests |test.unit.response.protocolinfo.TestProtocolInfoResponse |test.unit.response.mapaddress.TestMapAddressResponse |test.unit.client.types.TestClientTypes +|test.unit.client.size.TestSize |test.unit.client.cell.TestCell |test.unit.connection.authentication.TestAuthenticate |test.unit.connection.connect.TestConnect diff --git a/test/unit/client/size.py b/test/unit/client/size.py new file mode 100644 index 00000000..6078139c --- /dev/null +++ b/test/unit/client/size.py @@ -0,0 +1,50 @@ +""" +Unit tests for stem.client.Size. +""" + +import re +import unittest + +from stem.client import Size + + +class TestSize(unittest.TestCase): + def test_attributes(self): + self.assertEqual('CHAR', Size.CHAR.name) + self.assertEqual('!B', Size.CHAR.format) + + self.assertEqual(1, Size.CHAR.size) + self.assertEqual(2, Size.SHORT.size) + self.assertEqual(4, Size.LONG.size) + self.assertEqual(8, Size.LONG_LONG.size) + + def test_pack(self): + self.assertEqual('\x12', Size.CHAR.pack(18)) + self.assertEqual('\x00\x12', Size.SHORT.pack(18)) + self.assertEqual('\x00\x00\x00\x12', Size.LONG.pack(18)) + self.assertEqual('\x00\x00\x00\x00\x00\x00\x00\x12', Size.LONG_LONG.pack(18)) + + self.assertRaisesRegexp(ValueError, 'Size.pack encodes an integer, but was a str', Size.CHAR.pack, 'hi') + + bad_size = Size('BAD_SIZE', 1, '!H') + self.assertRaisesRegexp(ValueError, re.escape("'\x00\x12' is the wrong size for a BAD_SIZE field"), bad_size.pack, 18) + + def test_unpack(self): + self.assertEqual(18, Size.CHAR.unpack('\x12')) + self.assertEqual(18, Size.SHORT.unpack('\x00\x12')) + self.assertEqual(18, Size.LONG.unpack('\x00\x00\x00\x12')) + self.assertEqual(18, Size.LONG_LONG.unpack('\x00\x00\x00\x00\x00\x00\x00\x12')) + + self.assertEqual(ord('a'), Size.CHAR.unpack('a')) + self.assertEqual(24930, Size.SHORT.unpack('ab')) + + self.assertRaisesRegexp(ValueError, re.escape("'\x00\x12' is the wrong size for a CHAR field"), Size.CHAR.unpack, '\x00\x12') + + def test_pop(self): + self.assertEqual((18, ''), Size.CHAR.pop('\x12')) + + self.assertEqual((0, '\x12'), Size.CHAR.pop('\x00\x12')) + self.assertEqual((18, ''), Size.SHORT.pop('\x00\x12')) + + self.assertRaisesRegexp(ValueError, "'' is the wrong size for a CHAR field", Size.CHAR.pop, '') + self.assertRaisesRegexp(ValueError, re.escape("'\x12' is the wrong size for a SHORT field"), Size.SHORT.pop, '\x12') diff --git a/test/unit/client/types.py b/test/unit/client/types.py index a4d69a19..a85a0b8d 100644 --- a/test/unit/client/types.py +++ b/test/unit/client/types.py @@ -2,10 +2,9 @@ Unit tests for the types in stem.client. """
-import re import unittest
-from stem.client import Address, Size +from stem.client import Address
class TestClientTypes(unittest.TestCase): @@ -17,43 +16,3 @@ class TestClientTypes(unittest.TestCase): self.assertEqual(4, addr.type_int) self.assertEqual('127.0.0.1', addr.value) self.assertEqual('\x7f\x00\x00\x01', addr.value_bin) - - def test_size_attributes(self): - self.assertEqual('CHAR', Size.CHAR.name) - self.assertEqual('!B', Size.CHAR.format) - - self.assertEqual(1, Size.CHAR.size) - self.assertEqual(2, Size.SHORT.size) - self.assertEqual(4, Size.LONG.size) - self.assertEqual(8, Size.LONG_LONG.size) - - def test_size_pack(self): - self.assertEqual('\x12', Size.CHAR.pack(18)) - self.assertEqual('\x00\x12', Size.SHORT.pack(18)) - self.assertEqual('\x00\x00\x00\x12', Size.LONG.pack(18)) - self.assertEqual('\x00\x00\x00\x00\x00\x00\x00\x12', Size.LONG_LONG.pack(18)) - - self.assertRaisesRegexp(ValueError, 'Size.pack encodes an integer, but was a str', Size.CHAR.pack, 'hi') - - bad_size = Size('BAD_SIZE', 1, '!H') - self.assertRaisesRegexp(ValueError, re.escape("'\x00\x12' is the wrong size for a BAD_SIZE field"), bad_size.pack, 18) - - def test_size_unpack(self): - self.assertEqual(18, Size.CHAR.unpack('\x12')) - self.assertEqual(18, Size.SHORT.unpack('\x00\x12')) - self.assertEqual(18, Size.LONG.unpack('\x00\x00\x00\x12')) - self.assertEqual(18, Size.LONG_LONG.unpack('\x00\x00\x00\x00\x00\x00\x00\x12')) - - self.assertEqual(ord('a'), Size.CHAR.unpack('a')) - self.assertEqual(24930, Size.SHORT.unpack('ab')) - - self.assertRaisesRegexp(ValueError, re.escape("'\x00\x12' is the wrong size for a CHAR field"), Size.CHAR.unpack, '\x00\x12') - - def test_size_pop(self): - self.assertEqual((18, ''), Size.CHAR.pop('\x12')) - - self.assertEqual((0, '\x12'), Size.CHAR.pop('\x00\x12')) - self.assertEqual((18, ''), Size.SHORT.pop('\x00\x12')) - - self.assertRaisesRegexp(ValueError, "'' is the wrong size for a CHAR field", Size.CHAR.pop, '') - self.assertRaisesRegexp(ValueError, re.escape("'\x12' is the wrong size for a SHORT field"), Size.SHORT.pop, '\x12')
tor-commits@lists.torproject.org