[tor-commits] [stem/master] Fix python3 compatibility for tests

atagar at torproject.org atagar at torproject.org
Mon Feb 26 01:35:58 UTC 2018


commit 17d571d0414df0691b54888614ab92dc8171c72e
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Feb 25 17:34:56 2018 -0800

    Fix python3 compatibility for tests
    
    Mostly just the usual bytes/unicode issues with new additions.
---
 stem/client/cell.py             |  8 ++---
 stem/client/datatype.py         | 10 +++---
 stem/descriptor/remote.py       |  3 ++
 test/task.py                    |  2 +-
 test/unit/client/address.py     | 24 +++++++-------
 test/unit/client/cell.py        | 70 ++++++++++++++++++++---------------------
 test/unit/client/certificate.py | 18 +++++------
 test/unit/client/kdf.py         | 24 +++++++-------
 test/unit/client/size.py        | 26 +++++++--------
 test/unit/descriptor/remote.py  | 18 +++++------
 10 files changed, 103 insertions(+), 100 deletions(-)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index c5f8f20b..a3a0f7f0 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -46,7 +46,7 @@ import sys
 
 from stem import UNDEFINED
 from stem.client.datatype import HASH_LEN, ZERO, Address, Certificate, CloseReason, RelayCommand, Size, split
-from stem.util import _hash_attr, datetime_to_unix
+from stem.util import _hash_attr, datetime_to_unix, str_type, str_tools
 
 FIXED_PAYLOAD_LEN = 509
 AUTH_CHALLENGE_SIZE = 32
@@ -307,7 +307,7 @@ class RelayCell(CircuitCell):
       # isinstance() isn't such a great option.
 
       digest = Size.LONG.unpack(digest.digest()[:4])
-    elif isinstance(digest, str):
+    elif isinstance(digest, (bytes, str_type)):
       digest = Size.LONG.unpack(digest[:4])
     elif isinstance(digest, int):
       pass
@@ -316,7 +316,7 @@ class RelayCell(CircuitCell):
 
     super(RelayCell, self).__init__(circ_id)
     self.command, self.command_int = RelayCommand.get(command)
-    self.data = data
+    self.data = str_tools._to_bytes(data)
     self.recognized = recognized
     self.digest = digest
     self.stream_id = stream_id
@@ -619,7 +619,7 @@ class CertsCell(Cell):
     self.certificates = certs
 
   def pack(self, link_protocol):
-    return CertsCell._pack(link_protocol, Size.CHAR.pack(len(self.certificates)) + ''.join([cert.pack() for cert in self.certificates]))
+    return CertsCell._pack(link_protocol, Size.CHAR.pack(len(self.certificates)) + b''.join([cert.pack() for cert in self.certificates]))
 
   @classmethod
   def _unpack(cls, content, circ_id, link_protocol):
diff --git a/stem/client/datatype.py b/stem/client/datatype.py
index 352a643e..687c5081 100644
--- a/stem/client/datatype.py
+++ b/stem/client/datatype.py
@@ -121,7 +121,7 @@ import stem.util.enum
 
 from stem.util import _hash_attr
 
-ZERO = '\x00'
+ZERO = b'\x00'
 HASH_LEN = 20
 KEY_LEN = 16
 
@@ -354,17 +354,17 @@ class Address(Field):
     if self.type == AddrType.IPv4:
       if stem.util.connection.is_valid_ipv4_address(value):
         self.value = value
-        self.value_bin = ''.join([Size.CHAR.pack(int(v)) for v in value.split('.')])
+        self.value_bin = b''.join([Size.CHAR.pack(int(v)) for v in value.split('.')])
       else:
         if len(value) != 4:
           raise ValueError('Packed IPv4 addresses should be four bytes, but was: %s' % repr(value))
 
-        self.value = '.'.join([str(Size.CHAR.unpack(value[i])) for i in range(4)])
+        self.value = '.'.join([str(Size.CHAR.unpack(value[i:i + 1])) for i in range(4)])
         self.value_bin = value
     elif self.type == AddrType.IPv6:
       if stem.util.connection.is_valid_ipv6_address(value):
         self.value = stem.util.connection.expand_ipv6_address(value).lower()
-        self.value_bin = ''.join([Size.SHORT.pack(int(v, 16)) for v in self.value.split(':')])
+        self.value_bin = b''.join([Size.SHORT.pack(int(v, 16)) for v in self.value.split(':')])
       else:
         if len(value) != 16:
           raise ValueError('Packed IPv6 addresses should be sixteen bytes, but was: %s' % repr(value))
@@ -460,7 +460,7 @@ class KDF(collections.namedtuple('KDF', ['key_hash', 'forward_digest', 'backward
     #
     #   K = H(K0 | [00]) | H(K0 | [01]) | H(K0 | [02]) | ...
 
-    derived_key = ''
+    derived_key = b''
     counter = 0
 
     while len(derived_key) < KEY_LEN * 2 + HASH_LEN * 3:
diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index d2a6867c..9181dbcf 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -1132,6 +1132,9 @@ class FallbackDirectory(Directory):
     :raises: **ValueError** if content is malformed
     """
 
+    if isinstance(content, bytes):
+      content = str_tools._to_unicode(content)
+
     matches = {}
 
     for line in content.splitlines():
diff --git a/test/task.py b/test/task.py
index b28833bd..89437c77 100644
--- a/test/task.py
+++ b/test/task.py
@@ -95,7 +95,7 @@ def _import_tests():
   for module in (CONFIG['test.unit_tests'].splitlines() + CONFIG['test.integ_tests'].splitlines()):
     try:
       importlib.import_module(module.rsplit('.', 1)[0])
-    except Exception as exc:
+    except:
       raise ImportError(traceback.format_exc())
 
 
diff --git a/test/unit/client/address.py b/test/unit/client/address.py
index 09fcee95..aaa5fc0e 100644
--- a/test/unit/client/address.py
+++ b/test/unit/client/address.py
@@ -21,13 +21,13 @@ class TestAddress(unittest.TestCase):
 
   def test_constructor(self):
     test_data = (
-      ((4, '\x7f\x00\x00\x01'), ExpectedAddress(AddrType.IPv4, 4, '127.0.0.1', '\x7f\x00\x00\x01')),
-      ((4, 'aq\x0f\x02'), ExpectedAddress(AddrType.IPv4, 4, '97.113.15.2', 'aq\x0f\x02')),
-      ((6, ' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:0000:0000:0000:ff00:0042:8329', ' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)')),
-      ((AddrType.IPv4, '127.0.0.1'), ExpectedAddress(AddrType.IPv4, 4, '127.0.0.1', '\x7f\x00\x00\x01')),
-      ((AddrType.IPv4, '97.113.15.2'), ExpectedAddress(AddrType.IPv4, 4, '97.113.15.2', 'aq\x0f\x02')),
-      ((AddrType.IPv6, '2001:0db8:0000:0000:0000:ff00:0042:8329'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:0000:0000:0000:ff00:0042:8329', ' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)')),
-      ((AddrType.IPv6, '2001:0DB8:AC10:FE01::'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:ac10:fe01:0000:0000:0000:0000', ' \x01\r\xb8\xac\x10\xfe\x01\x00\x00\x00\x00\x00\x00\x00\x00')),  # collaped and different case
+      ((4, b'\x7f\x00\x00\x01'), ExpectedAddress(AddrType.IPv4, 4, '127.0.0.1', b'\x7f\x00\x00\x01')),
+      ((4, b'aq\x0f\x02'), ExpectedAddress(AddrType.IPv4, 4, '97.113.15.2', b'aq\x0f\x02')),
+      ((6, b' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:0000:0000:0000:ff00:0042:8329', b' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)')),
+      ((AddrType.IPv4, '127.0.0.1'), ExpectedAddress(AddrType.IPv4, 4, '127.0.0.1', b'\x7f\x00\x00\x01')),
+      ((AddrType.IPv4, '97.113.15.2'), ExpectedAddress(AddrType.IPv4, 4, '97.113.15.2', b'aq\x0f\x02')),
+      ((AddrType.IPv6, '2001:0db8:0000:0000:0000:ff00:0042:8329'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:0000:0000:0000:ff00:0042:8329', b' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)')),
+      ((AddrType.IPv6, '2001:0DB8:AC10:FE01::'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:ac10:fe01:0000:0000:0000:0000', b' \x01\r\xb8\xac\x10\xfe\x01\x00\x00\x00\x00\x00\x00\x00\x00')),  # collaped and different case
     )
 
     for (addr_type, addr_value), expected in test_data:
@@ -55,18 +55,18 @@ class TestAddress(unittest.TestCase):
 
   def test_packing(self):
     test_data = {
-      '\x04\x04\x7f\x00\x00\x01': Address('127.0.0.1'),
-      '\x06\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)': Address('2001:0db8:0000:0000:0000:ff00:0042:8329'),
+      b'\x04\x04\x7f\x00\x00\x01': Address('127.0.0.1'),
+      b'\x06\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)': Address('2001:0db8:0000:0000:0000:ff00:0042:8329'),
     }
 
     for cell_bytes, address in test_data.items():
       self.assertEqual(cell_bytes, address.pack())
       self.assertEqual(address, Address.unpack(cell_bytes))
 
-    addr, content = Address.pop('\x04\x04\x7f\x00\x00\x01\x01\x04\x04aq\x0f\x02\x00\x00\x00\x00')
-    self.assertEqual('\x01\x04\x04aq\x0f\x02\x00\x00\x00\x00', content)
+    addr, content = Address.pop(b'\x04\x04\x7f\x00\x00\x01\x01\x04\x04aq\x0f\x02\x00\x00\x00\x00')
+    self.assertEqual(b'\x01\x04\x04aq\x0f\x02\x00\x00\x00\x00', content)
 
     self.assertEqual(AddrType.IPv4, addr.type)
     self.assertEqual(4, addr.type_int)
     self.assertEqual('127.0.0.1', addr.value)
-    self.assertEqual('\x7f\x00\x00\x01', addr.value_bin)
+    self.assertEqual(b'\x7f\x00\x00\x01', addr.value_bin)
diff --git a/test/unit/client/cell.py b/test/unit/client/cell.py
index 19744c6d..f066cc4f 100644
--- a/test/unit/client/cell.py
+++ b/test/unit/client/cell.py
@@ -26,55 +26,55 @@ from stem.client.cell import (
 )
 
 RANDOM_PAYLOAD = os.urandom(FIXED_PAYLOAD_LEN)
-CHALLENGE = '\x89Y\t\x99\xb2\x1e\xd9*V\xb6\x1bn\n\x05\xd8/\xe3QH\x85\x13Z\x17\xfc\x1c\x00{\xa9\xae\x83^K'
+CHALLENGE = b'\x89Y\t\x99\xb2\x1e\xd9*V\xb6\x1bn\n\x05\xd8/\xe3QH\x85\x13Z\x17\xfc\x1c\x00{\xa9\xae\x83^K'
 
 PADDING_CELLS = {
-  '\x00\x00\x00' + RANDOM_PAYLOAD: RANDOM_PAYLOAD,
+  b'\x00\x00\x00' + RANDOM_PAYLOAD: RANDOM_PAYLOAD,
 }
 
 RELAY_CELLS = {
-  '\x00\x01\x03\r\x00\x00\x00\x01!\xa3?\xec' + ZERO * 500: ('RELAY_BEGIN_DIR', 13, 1, 1, '', 564346860),
-  '\x00\x01\x03\x02\x00\x00\x00\x01\x15:m\xe0\x00&GET /tor/server/authority HTTP/1.0\r\n\r\n' + ZERO * 460: ('RELAY_DATA', 2, 1, 1, 'GET /tor/server/authority HTTP/1.0\r\n\r\n', 356150752),
+  b'\x00\x01\x03\r\x00\x00\x00\x01!\xa3?\xec' + ZERO * 500: ('RELAY_BEGIN_DIR', 13, 1, 1, b'', 564346860),
+  b'\x00\x01\x03\x02\x00\x00\x00\x01\x15:m\xe0\x00&GET /tor/server/authority HTTP/1.0\r\n\r\n' + ZERO * 460: ('RELAY_DATA', 2, 1, 1, b'GET /tor/server/authority HTTP/1.0\r\n\r\n', 356150752),
 }
 
 DESTROY_CELLS = {
-  '\x80\x00\x00\x00\x04\x00' + ZERO * 508: (2147483648, CloseReason.NONE, 0),
-  '\x80\x00\x00\x00\x04\x03' + ZERO * 508: (2147483648, CloseReason.REQUESTED, 3),
+  b'\x80\x00\x00\x00\x04\x00' + ZERO * 508: (2147483648, CloseReason.NONE, 0),
+  b'\x80\x00\x00\x00\x04\x03' + ZERO * 508: (2147483648, CloseReason.REQUESTED, 3),
 }
 
 CREATE_FAST_CELLS = {
-  ('\x80\x00\x00\x00\x05\x92O\x0c\xcb\xa8\xac\xfb\xc9\x7f\xd0\rz\x1a\x03u\x91\xceas\xce' + ZERO * 489): (2147483648, '\x92O\x0c\xcb\xa8\xac\xfb\xc9\x7f\xd0\rz\x1a\x03u\x91\xceas\xce'),
+  (b'\x80\x00\x00\x00\x05\x92O\x0c\xcb\xa8\xac\xfb\xc9\x7f\xd0\rz\x1a\x03u\x91\xceas\xce' + ZERO * 489): (2147483648, b'\x92O\x0c\xcb\xa8\xac\xfb\xc9\x7f\xd0\rz\x1a\x03u\x91\xceas\xce'),
 }
 
 CREATED_FAST_CELLS = {
-  ('\x80\x00\x00\x00\x06\x92O\x0c\xcb\xa8\xac\xfb\xc9\x7f\xd0\rz\x1a\x03u\x91\xceas\xce\x13Z\x99\xb2\x1e\xb6\x05\x85\x17\xfc\x1c\x00{\xa9\xae\x83^K\x99\xb2' + ZERO * 469): (2147483648, '\x92O\x0c\xcb\xa8\xac\xfb\xc9\x7f\xd0\rz\x1a\x03u\x91\xceas\xce', '\x13Z\x99\xb2\x1e\xb6\x05\x85\x17\xfc\x1c\x00{\xa9\xae\x83^K\x99\xb2'),
+  (b'\x80\x00\x00\x00\x06\x92O\x0c\xcb\xa8\xac\xfb\xc9\x7f\xd0\rz\x1a\x03u\x91\xceas\xce\x13Z\x99\xb2\x1e\xb6\x05\x85\x17\xfc\x1c\x00{\xa9\xae\x83^K\x99\xb2' + ZERO * 469): (2147483648, b'\x92O\x0c\xcb\xa8\xac\xfb\xc9\x7f\xd0\rz\x1a\x03u\x91\xceas\xce', b'\x13Z\x99\xb2\x1e\xb6\x05\x85\x17\xfc\x1c\x00{\xa9\xae\x83^K\x99\xb2'),
 }
 
 VERSIONS_CELLS = {
-  '\x00\x00\x07\x00\x00': [],
-  '\x00\x00\x07\x00\x02\x00\x01': [1],
-  '\x00\x00\x07\x00\x06\x00\x01\x00\x02\x00\x03': [1, 2, 3],
+  b'\x00\x00\x07\x00\x00': [],
+  b'\x00\x00\x07\x00\x02\x00\x01': [1],
+  b'\x00\x00\x07\x00\x06\x00\x01\x00\x02\x00\x03': [1, 2, 3],
 }
 
 NETINFO_CELLS = {
-  '\x00\x00\x08ZZ\xb6\x90\x04\x04\x7f\x00\x00\x01\x01\x04\x04aq\x0f\x02' + ZERO * (FIXED_PAYLOAD_LEN - 17): (datetime.datetime(2018, 1, 14, 1, 46, 56), Address('127.0.0.1'), [Address('97.113.15.2')]),
+  b'\x00\x00\x08ZZ\xb6\x90\x04\x04\x7f\x00\x00\x01\x01\x04\x04aq\x0f\x02' + ZERO * (FIXED_PAYLOAD_LEN - 17): (datetime.datetime(2018, 1, 14, 1, 46, 56), Address('127.0.0.1'), [Address('97.113.15.2')]),
 }
 
 VPADDING_CELLS = {
-  '\x00\x00\x80\x00\x00': '',
-  '\x00\x00\x80\x00\x01\x08': '\x08',
-  '\x00\x00\x80\x00\x02\x08\x11': '\x08\x11',
-  '\x00\x00\x80\x01\xfd' + RANDOM_PAYLOAD: RANDOM_PAYLOAD,
+  b'\x00\x00\x80\x00\x00': b'',
+  b'\x00\x00\x80\x00\x01\x08': b'\x08',
+  b'\x00\x00\x80\x00\x02\x08\x11': b'\x08\x11',
+  b'\x00\x00\x80\x01\xfd' + RANDOM_PAYLOAD: RANDOM_PAYLOAD,
 }
 
 CERTS_CELLS = {
-  '\x00\x00\x81\x00\x01\x00': [],
-  '\x00\x00\x81\x00\x04\x01\x01\x00\x00': [Certificate(1, '')],
-  '\x00\x00\x81\x00\x05\x01\x01\x00\x01\x08': [Certificate(1, '\x08')],
+  b'\x00\x00\x81\x00\x01\x00': [],
+  b'\x00\x00\x81\x00\x04\x01\x01\x00\x00': [Certificate(1, b'')],
+  b'\x00\x00\x81\x00\x05\x01\x01\x00\x01\x08': [Certificate(1, b'\x08')],
 }
 
 AUTH_CHALLENGE_CELLS = {
-  '\x00\x00\x82\x00&%s\x00\x02\x00\x01\x00\x03' % CHALLENGE: (CHALLENGE, [1, 3]),
+  b'\x00\x00\x82\x00&%s\x00\x02\x00\x01\x00\x03' % CHALLENGE: (CHALLENGE, [1, 3]),
 }
 
 
@@ -100,15 +100,15 @@ class TestCell(unittest.TestCase):
     self.assertRaises(ValueError, Cell.by_value, None)
 
   def test_unpack_not_implemented(self):
-    self.assertRaisesRegexp(NotImplementedError, 'Unpacking not yet implemented for AUTHORIZE cells', Cell.pop, '\x00\x00\x84\x00\x06\x00\x01\x00\x02\x00\x03', 2)
+    self.assertRaisesRegexp(NotImplementedError, 'Unpacking not yet implemented for AUTHORIZE cells', Cell.pop, b'\x00\x00\x84\x00\x06\x00\x01\x00\x02\x00\x03', 2)
 
   def test_unpack_for_new_link(self):
     expected_certs = (
-      (CertType.LINK, 1, '0\x82\x02F0\x82\x01\xaf'),
-      (CertType.IDENTITY, 2, '0\x82\x01\xc90\x82\x012'),
-      (CertType.UNKNOWN, 4, '\x01\x04\x00\x06m\x1f'),
-      (CertType.UNKNOWN, 5, '\x01\x05\x00\x06m\n\x01'),
-      (CertType.UNKNOWN, 7, '\x1a\xa5\xb3\xbd\x88\xb1C'),
+      (CertType.LINK, 1, b'0\x82\x02F0\x82\x01\xaf'),
+      (CertType.IDENTITY, 2, b'0\x82\x01\xc90\x82\x012'),
+      (CertType.UNKNOWN, 4, b'\x01\x04\x00\x06m\x1f'),
+      (CertType.UNKNOWN, 5, b'\x01\x05\x00\x06m\n\x01'),
+      (CertType.UNKNOWN, 7, b'\x1a\xa5\xb3\xbd\x88\xb1C'),
     )
 
     content = test_data('new_link_cells')
@@ -126,7 +126,7 @@ class TestCell(unittest.TestCase):
       self.assertTrue(certs_cell.certificates[i].value.startswith(cert_prefix))
 
     auth_challenge_cell, content = Cell.pop(content, 2)
-    self.assertEqual(AuthChallengeCell([1, 3], '\x89Y\t\x99\xb2\x1e\xd9*V\xb6\x1bn\n\x05\xd8/\xe3QH\x85\x13Z\x17\xfc\x1c\x00{\xa9\xae\x83^K'), auth_challenge_cell)
+    self.assertEqual(AuthChallengeCell([1, 3], b'\x89Y\t\x99\xb2\x1e\xd9*V\xb6\x1bn\n\x05\xd8/\xe3QH\x85\x13Z\x17\xfc\x1c\x00{\xa9\xae\x83^K'), auth_challenge_cell)
 
     netinfo_cell, content = Cell.pop(content, 2)
     self.assertEqual(NetinfoCell, type(netinfo_cell))
@@ -134,7 +134,7 @@ class TestCell(unittest.TestCase):
     self.assertEqual(Address('127.0.0.1'), netinfo_cell.receiver_address)
     self.assertEqual([Address('97.113.15.2')], netinfo_cell.sender_addresses)
 
-    self.assertEqual('', content)  # check that we've consumed all of the bytes
+    self.assertEqual(b'', content)  # check that we've consumed all of the bytes
 
   def test_padding_cell(self):
     for cell_bytes, payload in PADDING_CELLS.items():
@@ -154,7 +154,7 @@ class TestCell(unittest.TestCase):
       self.assertEqual(digest, cell.digest)
       self.assertEqual(stream_id, cell.stream_id)
 
-    digest = hashlib.sha1('hi')
+    digest = hashlib.sha1(b'hi')
     self.assertEqual(3257622417, RelayCell(5, 'RELAY_BEGIN_DIR', '', digest, 564346860).digest)
     self.assertEqual(3257622417, RelayCell(5, 'RELAY_BEGIN_DIR', '', digest.digest(), 564346860).digest)
     self.assertEqual(3257622417, RelayCell(5, 'RELAY_BEGIN_DIR', '', 3257622417, 564346860).digest)
@@ -171,7 +171,7 @@ class TestCell(unittest.TestCase):
       self.assertEqual(reason, cell.reason)
       self.assertEqual(reason_int, cell.reason_int)
 
-    self.assertRaisesRegexp(ValueError, 'Circuit closure reason should be a single byte, but was 2', Cell.pop, '\x80\x00\x00\x00\x04\x01\x01' + ZERO * 507, 5)
+    self.assertRaisesRegexp(ValueError, 'Circuit closure reason should be a single byte, but was 2', Cell.pop, b'\x80\x00\x00\x00\x04\x01\x01' + ZERO * 507, 5)
 
   def test_create_fast_cell(self):
     for cell_bytes, (circ_id, key_material) in CREATE_FAST_CELLS.items():
@@ -222,12 +222,12 @@ class TestCell(unittest.TestCase):
 
     # extra bytes after the last certificate should be ignored
 
-    self.assertEqual([Certificate(1, '\x08')], Cell.pop('\x00\x00\x81\x00\x07\x01\x01\x00\x01\x08\x06\x04', 2)[0].certificates)
+    self.assertEqual([Certificate(1, '\x08')], Cell.pop(b'\x00\x00\x81\x00\x07\x01\x01\x00\x01\x08\x06\x04', 2)[0].certificates)
 
     # ... but truncated or missing certificates should error
 
-    self.assertRaisesRegexp(ValueError, 'CERTS cell should have a certificate with 3 bytes, but only had 1 remaining', Cell.pop, '\x00\x00\x81\x00\x05\x01\x01\x00\x03\x08', 2)
-    self.assertRaisesRegexp(ValueError, 'CERTS cell indicates it should have 2 certificates, but only contained 1', Cell.pop, '\x00\x00\x81\x00\x05\x02\x01\x00\x01\x08', 2)
+    self.assertRaisesRegexp(ValueError, 'CERTS cell should have a certificate with 3 bytes, but only had 1 remaining', Cell.pop, b'\x00\x00\x81\x00\x05\x01\x01\x00\x03\x08', 2)
+    self.assertRaisesRegexp(ValueError, 'CERTS cell indicates it should have 2 certificates, but only contained 1', Cell.pop, b'\x00\x00\x81\x00\x05\x02\x01\x00\x01\x08', 2)
 
   def test_auth_challenge_cell(self):
     for cell_bytes, (challenge, methods) in AUTH_CHALLENGE_CELLS.items():
@@ -237,5 +237,5 @@ class TestCell(unittest.TestCase):
       self.assertEqual(challenge, cell.challenge)
       self.assertEqual(methods, cell.methods)
 
-    self.assertRaisesRegexp(ValueError, 'AUTH_CHALLENGE cell should have a payload of 38 bytes, but only had 16', Cell.pop, '\x00\x00\x82\x00&%s\x00\x02\x00\x01\x00\x03' % CHALLENGE[:10], 2)
-    self.assertRaisesRegexp(ValueError, 'AUTH_CHALLENGE should have 3 methods, but only had 4 bytes for it', Cell.pop, '\x00\x00\x82\x00&%s\x00\x03\x00\x01\x00\x03' % CHALLENGE, 2)
+    self.assertRaisesRegexp(ValueError, 'AUTH_CHALLENGE cell should have a payload of 38 bytes, but only had 16', Cell.pop, b'\x00\x00\x82\x00&%s\x00\x02\x00\x01\x00\x03' % CHALLENGE[:10], 2)
+    self.assertRaisesRegexp(ValueError, 'AUTH_CHALLENGE should have 3 methods, but only had 4 bytes for it', Cell.pop, b'\x00\x00\x82\x00&%s\x00\x03\x00\x01\x00\x03' % CHALLENGE, 2)
diff --git a/test/unit/client/certificate.py b/test/unit/client/certificate.py
index b6782acc..a15779f5 100644
--- a/test/unit/client/certificate.py
+++ b/test/unit/client/certificate.py
@@ -10,11 +10,11 @@ from stem.client.datatype import CertType, Certificate
 class TestCertificate(unittest.TestCase):
   def test_constructor(self):
     test_data = (
-      ((1, '\x7f\x00\x00\x01'), (CertType.LINK, 1, '\x7f\x00\x00\x01')),
-      ((2, '\x7f\x00\x00\x01'), (CertType.IDENTITY, 2, '\x7f\x00\x00\x01')),
-      ((3, '\x7f\x00\x00\x01'), (CertType.AUTHENTICATE, 3, '\x7f\x00\x00\x01')),
-      ((4, '\x7f\x00\x00\x01'), (CertType.UNKNOWN, 4, '\x7f\x00\x00\x01')),
-      ((CertType.IDENTITY, '\x7f\x00\x00\x01'), (CertType.IDENTITY, 2, '\x7f\x00\x00\x01')),
+      ((1, b'\x7f\x00\x00\x01'), (CertType.LINK, 1, b'\x7f\x00\x00\x01')),
+      ((2, b'\x7f\x00\x00\x01'), (CertType.IDENTITY, 2, b'\x7f\x00\x00\x01')),
+      ((3, b'\x7f\x00\x00\x01'), (CertType.AUTHENTICATE, 3, b'\x7f\x00\x00\x01')),
+      ((4, b'\x7f\x00\x00\x01'), (CertType.UNKNOWN, 4, b'\x7f\x00\x00\x01')),
+      ((CertType.IDENTITY, b'\x7f\x00\x00\x01'), (CertType.IDENTITY, 2, b'\x7f\x00\x00\x01')),
     )
 
     for (cert_type, cert_value), (expected_type, expected_type_int, expected_value) in test_data:
@@ -30,10 +30,10 @@ class TestCertificate(unittest.TestCase):
     self.assertEqual('hello', cert.value)
 
   def test_packing(self):
-    cert, content = Certificate.pop('\x02\x00\x04\x00\x00\x01\x01\x04\x04aq\x0f\x02\x00\x00\x00\x00')
-    self.assertEqual('\x04\x04aq\x0f\x02\x00\x00\x00\x00', content)
+    cert, content = Certificate.pop(b'\x02\x00\x04\x00\x00\x01\x01\x04\x04aq\x0f\x02\x00\x00\x00\x00')
+    self.assertEqual(b'\x04\x04aq\x0f\x02\x00\x00\x00\x00', content)
 
     self.assertEqual(CertType.IDENTITY, cert.type)
     self.assertEqual(2, cert.type_int)
-    self.assertEqual('\x00\x00\x01\x01', cert.value)
-    self.assertEqual('\x02\x00\x04\x00\x00\x01\x01', cert.pack())
+    self.assertEqual(b'\x00\x00\x01\x01', cert.value)
+    self.assertEqual(b'\x02\x00\x04\x00\x00\x01\x01', cert.pack())
diff --git a/test/unit/client/kdf.py b/test/unit/client/kdf.py
index f3922538..b9fcb9ce 100644
--- a/test/unit/client/kdf.py
+++ b/test/unit/client/kdf.py
@@ -6,22 +6,22 @@ import unittest
 
 from stem.client.datatype import KDF
 
-KEY_1 = '\xec\xec.\xeb7R\xf2\n\xcb\xce\x97\xf4\x86\x82\x19#\x10\x0f\x08\xf0\xa2Z\xdeJ\x8f2\x8cc\xf6\xfa\x0e\t\x83f\xc5\xe2\xb3\x94\xa8\x13'
-KEY_2 = '\xe0v\xe4\xfaTB\x91\x1c\x81Gz\xa0\tI\xcb{\xc56\xcfV\xc2\xa0\x19\x9c\x98\x9a\x06\x0e\xc5\xfa\xb0z\x83\xa6\x10\xf6r"<b'
+KEY_1 = b'\xec\xec.\xeb7R\xf2\n\xcb\xce\x97\xf4\x86\x82\x19#\x10\x0f\x08\xf0\xa2Z\xdeJ\x8f2\x8cc\xf6\xfa\x0e\t\x83f\xc5\xe2\xb3\x94\xa8\x13'
+KEY_2 = b'\xe0v\xe4\xfaTB\x91\x1c\x81Gz\xa0\tI\xcb{\xc56\xcfV\xc2\xa0\x19\x9c\x98\x9a\x06\x0e\xc5\xfa\xb0z\x83\xa6\x10\xf6r"<b'
 
 
 class TestKDF(unittest.TestCase):
   def test_parsing(self):
     k1 = KDF.from_value(KEY_1)
-    self.assertEqual('\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6', k1.key_hash)
-    self.assertEqual('\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,', k1.forward_digest)
-    self.assertEqual('*\xe5scX\xbb+\xca \xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1', k1.backward_digest)
-    self.assertEqual('\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03', k1.forward_key)
-    self.assertEqual('U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86', k1.backward_key)
+    self.assertEqual(b'\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6', k1.key_hash)
+    self.assertEqual(b'\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,', k1.forward_digest)
+    self.assertEqual(b'*\xe5scX\xbb+\xca \xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1', k1.backward_digest)
+    self.assertEqual(b'\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03', k1.forward_key)
+    self.assertEqual(b'U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86', k1.backward_key)
 
     k2 = KDF.from_value(KEY_1)
-    self.assertEqual('\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6', k2.key_hash)
-    self.assertEqual('\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,', k2.forward_digest)
-    self.assertEqual('*\xe5scX\xbb+\xca \xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1', k2.backward_digest)
-    self.assertEqual('\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03', k2.forward_key)
-    self.assertEqual('U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86', k2.backward_key)
+    self.assertEqual(b'\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6', k2.key_hash)
+    self.assertEqual(b'\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,', k2.forward_digest)
+    self.assertEqual(b'*\xe5scX\xbb+\xca \xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1', k2.backward_digest)
+    self.assertEqual(b'\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03', k2.forward_key)
+    self.assertEqual(b'U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86', k2.backward_key)
diff --git a/test/unit/client/size.py b/test/unit/client/size.py
index 59416662..392c77ff 100644
--- a/test/unit/client/size.py
+++ b/test/unit/client/size.py
@@ -19,10 +19,10 @@ class TestSize(unittest.TestCase):
     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.assertEqual(b'\x12', Size.CHAR.pack(18))
+    self.assertEqual(b'\x00\x12', Size.SHORT.pack(18))
+    self.assertEqual(b'\x00\x00\x00\x12', Size.LONG.pack(18))
+    self.assertEqual(b'\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')
 
@@ -30,21 +30,21 @@ class TestSize(unittest.TestCase):
     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(18, Size.CHAR.unpack(b'\x12'))
+    self.assertEqual(18, Size.SHORT.unpack(b'\x00\x12'))
+    self.assertEqual(18, Size.LONG.unpack(b'\x00\x00\x00\x12'))
+    self.assertEqual(18, Size.LONG_LONG.unpack(b'\x00\x00\x00\x00\x00\x00\x00\x12'))
 
-    self.assertEqual(ord('a'), Size.CHAR.unpack('a'))
-    self.assertEqual(24930, Size.SHORT.unpack('ab'))
+    self.assertEqual(ord('a'), Size.CHAR.unpack(b'a'))
+    self.assertEqual(24930, Size.SHORT.unpack(b'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((18, b''), Size.CHAR.pop(b'\x12'))
 
-    self.assertEqual((0, '\x12'), Size.CHAR.pop('\x00\x12'))
-    self.assertEqual((18, ''), Size.SHORT.pop('\x00\x12'))
+    self.assertEqual((0, b'\x12'), Size.CHAR.pop(b'\x00\x12'))
+    self.assertEqual((18, b''), Size.SHORT.pop(b'\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/descriptor/remote.py b/test/unit/descriptor/remote.py
index 9409544c..ac150d5c 100644
--- a/test/unit/descriptor/remote.py
+++ b/test/unit/descriptor/remote.py
@@ -300,17 +300,17 @@ class TestDescriptorDownloader(unittest.TestCase):
 
   @patch(URL_OPEN)
   def test_fallback_directories_from_remote_empty(self, urlopen_mock):
-    urlopen_mock.return_value = io.BytesIO('')
+    urlopen_mock.return_value = io.BytesIO(b'')
     self.assertRaisesRegexp(IOError, 'did not have any content', stem.descriptor.remote.FallbackDirectory.from_remote)
 
   @patch(URL_OPEN)
   def test_fallback_directories_from_remote_no_header(self, urlopen_mock):
-    urlopen_mock.return_value = io.BytesIO('\n'.join(FALLBACK_DIR_CONTENT.splitlines()[1:]))
+    urlopen_mock.return_value = io.BytesIO(b'\n'.join(FALLBACK_DIR_CONTENT.splitlines()[1:]))
     self.assertRaisesRegexp(IOError, 'does not have a type field indicating it is fallback directory metadata', stem.descriptor.remote.FallbackDirectory.from_remote)
 
   @patch(URL_OPEN)
   def test_fallback_directories_from_remote_malformed_header(self, urlopen_mock):
-    urlopen_mock.return_value = io.BytesIO(FALLBACK_DIR_CONTENT.replace('version=2.0.0', 'version'))
+    urlopen_mock.return_value = io.BytesIO(FALLBACK_DIR_CONTENT.replace(b'version=2.0.0', b'version'))
     self.assertRaisesRegexp(IOError, 'Malformed fallback directory header line: /\* version \*/', stem.descriptor.remote.FallbackDirectory.from_remote)
 
   def test_fallback_directories_from_str(self):
@@ -328,12 +328,12 @@ class TestDescriptorDownloader(unittest.TestCase):
 
   def test_fallback_directories_from_str_malformed(self):
     test_values = {
-      FALLBACK_ENTRY.replace('id=0756B7CD4DFC8182BE23143FAC0642F515182CEB', ''): 'Malformed fallback address line:',
-      FALLBACK_ENTRY.replace('5.9.110.236', '5.9.110'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid IPv4 address: 5.9.110',
-      FALLBACK_ENTRY.replace(':9030', ':7814713228'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid dir_port: 7814713228',
-      FALLBACK_ENTRY.replace('orport=9001', 'orport=7814713228'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid or_port: 7814713228',
-      FALLBACK_ENTRY.replace('ipv6=[2a01', 'ipv6=[:::'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid IPv6 address: ::::4f8:162:51e2::2',
-      FALLBACK_ENTRY.replace('nickname=rueckgrat', 'nickname=invalid~nickname'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid nickname: invalid~nickname',
+      FALLBACK_ENTRY.replace(b'id=0756B7CD4DFC8182BE23143FAC0642F515182CEB', b''): 'Malformed fallback address line:',
+      FALLBACK_ENTRY.replace(b'5.9.110.236', b'5.9.110'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid IPv4 address: 5.9.110',
+      FALLBACK_ENTRY.replace(b':9030', b':7814713228'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid dir_port: 7814713228',
+      FALLBACK_ENTRY.replace(b'orport=9001', b'orport=7814713228'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid or_port: 7814713228',
+      FALLBACK_ENTRY.replace(b'ipv6=[2a01', b'ipv6=[:::'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid IPv6 address: ::::4f8:162:51e2::2',
+      FALLBACK_ENTRY.replace(b'nickname=rueckgrat', b'nickname=invalid~nickname'): '0756B7CD4DFC8182BE23143FAC0642F515182CEB has an invalid nickname: invalid~nickname',
     }
 
     for entry, expected in test_values.items():



More information about the tor-commits mailing list