1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
"""
Unit tests for the stem.response.getinfo.GetInfoResponse class.
"""
import unittest
import stem.response
import stem.response.getinfo
import stem.socket
import stem.util.str_tools
from test import mocking
EMPTY_RESPONSE = '250 OK'
SINGLE_RESPONSE = """\
250-version=0.2.3.11-alpha-dev
250 OK"""
BATCH_RESPONSE = """\
250-version=0.2.3.11-alpha-dev
250-address=67.137.76.214
250-fingerprint=5FDE0422045DF0E1879A3738D09099EB4A0C5BA0
250 OK"""
MULTILINE_RESPONSE = """\
250-version=0.2.3.11-alpha-dev (git-ef0bc7f8f26a917c)
250+config-text=
ControlPort 9051
DataDirectory /home/atagar/.tor
ExitPolicy reject *:*
Log notice stdout
Nickname Unnamed
ORPort 9050
.
250 OK"""
NON_KEY_VALUE_ENTRY = """\
250-version=0.2.3.11-alpha-dev
250-address 67.137.76.214
250 OK"""
UNRECOGNIZED_KEY_ENTRY = """\
552 Unrecognized key "blackhole"
"""
MISSING_MULTILINE_NEWLINE = """\
250+config-text=ControlPort 9051
DataDirectory /home/atagar/.tor
.
250 OK"""
class TestGetInfoResponse(unittest.TestCase):
def test_empty_response(self):
"""
Parses a GETINFO reply without options (just calling "GETINFO").
"""
control_message = mocking.get_message(EMPTY_RESPONSE)
stem.response.convert('GETINFO', control_message)
# now this should be a GetInfoResponse (ControlMessage subclass)
self.assertTrue(isinstance(control_message, stem.response.ControlMessage))
self.assertTrue(isinstance(control_message, stem.response.getinfo.GetInfoResponse))
self.assertEqual({}, control_message.entries)
def test_single_response(self):
"""
Parses a GETINFO reply response for a single parameter.
"""
control_message = mocking.get_message(SINGLE_RESPONSE)
stem.response.convert('GETINFO', control_message)
self.assertEqual({'version': b'0.2.3.11-alpha-dev'}, control_message.entries)
def test_batch_response(self):
"""
Parses a GETINFO reply for muiltiple parameters.
"""
control_message = mocking.get_message(BATCH_RESPONSE)
stem.response.convert('GETINFO', control_message)
expected = {
'version': b'0.2.3.11-alpha-dev',
'address': b'67.137.76.214',
'fingerprint': b'5FDE0422045DF0E1879A3738D09099EB4A0C5BA0',
}
self.assertEqual(expected, control_message.entries)
def test_multiline_response(self):
"""
Parses a GETINFO reply for multiple parameters including a multi-line
value.
"""
control_message = mocking.get_message(MULTILINE_RESPONSE)
stem.response.convert('GETINFO', control_message)
expected = {
'version': b'0.2.3.11-alpha-dev (git-ef0bc7f8f26a917c)',
'config-text': b'\n'.join(stem.util.str_tools._to_bytes(MULTILINE_RESPONSE).splitlines()[2:8]),
}
self.assertEqual(expected, control_message.entries)
def test_invalid_non_mapping_content(self):
"""
Parses a malformed GETINFO reply containing a line that isn't a key=value
entry.
"""
control_message = mocking.get_message(NON_KEY_VALUE_ENTRY)
self.assertRaises(stem.ProtocolError, stem.response.convert, 'GETINFO', control_message)
def test_unrecognized_key_response(self):
"""
Parses a GETCONF reply that contains an error code with an unrecognized key.
"""
control_message = mocking.get_message(UNRECOGNIZED_KEY_ENTRY)
self.assertRaises(stem.InvalidArguments, stem.response.convert, 'GETINFO', control_message)
try:
stem.response.convert('GETINFO', control_message)
except stem.InvalidArguments as exc:
self.assertEqual(exc.arguments, ['blackhole'])
def test_invalid_multiline_content(self):
"""
Parses a malformed GETINFO reply with a multi-line entry missing a newline
between its key and value. This is a proper controller message, but
malformed according to the GETINFO's spec.
"""
control_message = mocking.get_message(MISSING_MULTILINE_NEWLINE)
self.assertRaises(stem.ProtocolError, stem.response.convert, 'GETINFO', control_message)
|