[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Using mocking module for protocolinfo unit tests
commit 9a2b50138356f317220819b2351f666bd45564e1
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Fri Jan 27 18:53:39 2012 -0800
Using mocking module for protocolinfo unit tests
Expanding the mocking module to provide a ControlMessage (very frequently
needed in tests) and using the module to simplify the protocolinfo unit tests.
---
test/mocking.py | 38 +++++++++++++++++++----
test/unit/connection/protocolinfo.py | 54 +++++++++++++++-------------------
2 files changed, 55 insertions(+), 37 deletions(-)
diff --git a/test/mocking.py b/test/mocking.py
index f6bf98c..0d01a60 100644
--- a/test/mocking.py
+++ b/test/mocking.py
@@ -1,6 +1,11 @@
"""
Helper functions for creating mock objects and monkey patching to help with
-testing.
+testing. With python's builtin unit testing framework the setUp and test
+functions set up mocking, which is then reverted in the tearDown method by
+calling 'revert_mocking'.
+
+mock - replaces a function with an alternative implementation
+revert_mocking - reverts any changes made by the mock function
Mocking Functions
no_op - does nothing
@@ -10,10 +15,9 @@ Mocking Functions
return_none - returns None
raise_exception - raises an exception when called
-mock - replaces a function with an alternative implementation
-revert_mocking - reverts any changes made by the mock function
-
-get_protocolinfo_response - provides a ProtocolInfoResponse instance
+Instance Constructors
+ get_message - stem.socket.ControlMessage
+ get_protocolinfo_response - stem.connection.ProtocolInfoResponse
"""
import inspect
@@ -94,6 +98,27 @@ def revert_mocking():
MOCK_STATE.clear()
+def get_message(content, reformat = True):
+ """
+ Provides a ControlMessage with content modified to be parsable. This makes
+ the following changes unless 'reformat' is false...
+ - ensures the content ends with a newline
+ - newlines are replaced with a carrage return and newline pair
+
+ Arguments:
+ content (str) - base content for the controller message
+ reformat (str) - modifies content to be more accomidateing to being parsed
+
+ Returns:
+ stem.socket.ControlMessage instance
+ """
+
+ if reformat:
+ if not content.endswith("\n"): content += "\n"
+ content = content.replace("\n", "\r\n")
+
+ return stem.socket.recv_message(StringIO.StringIO(content))
+
def get_protocolinfo_response(**attributes):
"""
Provides a ProtocolInfoResponse, customized with the given attributes. The
@@ -107,8 +132,7 @@ def get_protocolinfo_response(**attributes):
stem.connection.ProtocolInfoResponse instance
"""
- control_message = "250-PROTOCOLINFO 1\r\n250 OK\r\n"
- protocolinfo_response = stem.socket.recv_message(StringIO.StringIO(control_message))
+ protocolinfo_response = get_message("250-PROTOCOLINFO 1\n250 OK")
stem.connection.ProtocolInfoResponse.convert(protocolinfo_response)
for attr in attributes:
diff --git a/test/unit/connection/protocolinfo.py b/test/unit/connection/protocolinfo.py
index bc0fef3..0f47fe1 100644
--- a/test/unit/connection/protocolinfo.py
+++ b/test/unit/connection/protocolinfo.py
@@ -3,51 +3,44 @@ Unit tests for the stem.connection.ProtocolInfoResponse class.
"""
import unittest
-import StringIO
import stem.connection
import stem.socket
import stem.version
+import test.mocking as mocking
NO_AUTH = """250-PROTOCOLINFO 1
250-AUTH METHODS=NULL
250-VERSION Tor="0.2.1.30"
-250 OK
-""".replace("\n", "\r\n")
+250 OK"""
PASSWORD_AUTH = """250-PROTOCOLINFO 1
250-AUTH METHODS=HASHEDPASSWORD
250-VERSION Tor="0.2.1.30"
-250 OK
-""".replace("\n", "\r\n")
+250 OK"""
COOKIE_AUTH = r"""250-PROTOCOLINFO 1
250-AUTH METHODS=COOKIE COOKIEFILE="/tmp/my data\\\"dir//control_auth_cookie"
250-VERSION Tor="0.2.1.30"
-250 OK
-""".replace("\n", "\r\n")
+250 OK"""
MULTIPLE_AUTH = """250-PROTOCOLINFO 1
250-AUTH METHODS=COOKIE,HASHEDPASSWORD COOKIEFILE="/home/atagar/.tor/control_auth_cookie"
250-VERSION Tor="0.2.1.30"
-250 OK
-""".replace("\n", "\r\n")
+250 OK"""
UNKNOWN_AUTH = """250-PROTOCOLINFO 1
250-AUTH METHODS=MAGIC,HASHEDPASSWORD,PIXIE_DUST
250-VERSION Tor="0.2.1.30"
-250 OK
-""".replace("\n", "\r\n")
+250 OK"""
MINIMUM_RESPONSE = """250-PROTOCOLINFO 5
-250 OK
-""".replace("\n", "\r\n")
+250 OK"""
RELATIVE_COOKIE_PATH = r"""250-PROTOCOLINFO 1
250-AUTH METHODS=COOKIE COOKIEFILE="./tor-browser_en-US/Data/control_auth_cookie"
250-VERSION Tor="0.2.1.30"
-250 OK
-""".replace("\n", "\r\n")
+250 OK"""
class TestProtocolInfoResponse(unittest.TestCase):
"""
@@ -61,7 +54,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
"""
# working case
- control_message = stem.socket.recv_message(StringIO.StringIO(NO_AUTH))
+ control_message = mocking.get_message(NO_AUTH)
stem.connection.ProtocolInfoResponse.convert(control_message)
# now this should be a ProtocolInfoResponse (ControlMessage subclass)
@@ -69,14 +62,15 @@ class TestProtocolInfoResponse(unittest.TestCase):
self.assertTrue(isinstance(control_message, stem.connection.ProtocolInfoResponse))
# exercise some of the ControlMessage functionality
+ raw_content = (NO_AUTH + "\n").replace("\n", "\r\n")
+ self.assertEquals(raw_content, control_message.raw_content())
self.assertTrue(str(control_message).startswith("PROTOCOLINFO 1"))
- self.assertEquals(NO_AUTH, control_message.raw_content())
# attempt to convert the wrong type
self.assertRaises(TypeError, stem.connection.ProtocolInfoResponse.convert, "hello world")
# attempt to convert a different message type
- bw_event_control_message = stem.socket.recv_message(StringIO.StringIO("650 BW 32326 2856\r\n"))
+ bw_event_control_message = mocking.get_message("650 BW 32326 2856")
self.assertRaises(stem.socket.ProtocolError, stem.connection.ProtocolInfoResponse.convert, bw_event_control_message)
def test_no_auth(self):
@@ -84,7 +78,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
Checks a response when there's no authentication.
"""
- control_message = stem.socket.recv_message(StringIO.StringIO(NO_AUTH))
+ control_message = mocking.get_message(NO_AUTH)
stem.connection.ProtocolInfoResponse.convert(control_message)
self.assertEquals(1, control_message.protocol_version)
@@ -98,7 +92,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
Checks a response with password authentication.
"""
- control_message = stem.socket.recv_message(StringIO.StringIO(PASSWORD_AUTH))
+ control_message = mocking.get_message(PASSWORD_AUTH)
stem.connection.ProtocolInfoResponse.convert(control_message)
self.assertEquals((stem.connection.AuthMethod.PASSWORD, ), control_message.auth_methods)
@@ -108,7 +102,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
characters.
"""
- control_message = stem.socket.recv_message(StringIO.StringIO(COOKIE_AUTH))
+ control_message = mocking.get_message(COOKIE_AUTH)
stem.connection.ProtocolInfoResponse.convert(control_message)
self.assertEquals((stem.connection.AuthMethod.COOKIE, ), control_message.auth_methods)
self.assertEquals("/tmp/my data\\\"dir//control_auth_cookie", control_message.cookie_path)
@@ -118,7 +112,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
Checks a response with multiple authentication methods.
"""
- control_message = stem.socket.recv_message(StringIO.StringIO(MULTIPLE_AUTH))
+ control_message = mocking.get_message(MULTIPLE_AUTH)
stem.connection.ProtocolInfoResponse.convert(control_message)
self.assertEquals((stem.connection.AuthMethod.COOKIE, stem.connection.AuthMethod.PASSWORD), control_message.auth_methods)
self.assertEquals("/home/atagar/.tor/control_auth_cookie", control_message.cookie_path)
@@ -128,7 +122,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
Checks a response with an unrecognized authtentication method.
"""
- control_message = stem.socket.recv_message(StringIO.StringIO(UNKNOWN_AUTH))
+ control_message = mocking.get_message(UNKNOWN_AUTH)
stem.connection.ProtocolInfoResponse.convert(control_message)
self.assertEquals((stem.connection.AuthMethod.UNKNOWN, stem.connection.AuthMethod.PASSWORD), control_message.auth_methods)
self.assertEquals(("MAGIC", "PIXIE_DUST"), control_message.unknown_auth_methods)
@@ -139,7 +133,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
information to be a valid response.
"""
- control_message = stem.socket.recv_message(StringIO.StringIO(MINIMUM_RESPONSE))
+ control_message = mocking.get_message(MINIMUM_RESPONSE)
stem.connection.ProtocolInfoResponse.convert(control_message)
self.assertEquals(5, control_message.protocol_version)
@@ -162,23 +156,23 @@ class TestProtocolInfoResponse(unittest.TestCase):
def call_mocking(command):
if command == stem.util.system.GET_PID_BY_NAME_PGREP % "tor":
return ["10"]
- if command == stem.util.system.GET_CWD_PWDX % 10:
+ elif command == stem.util.system.GET_CWD_PWDX % 10:
return ["10: /tmp/foo"]
- stem.util.system.CALL_MOCKING = call_mocking
+ mocking.mock(stem.util.system.call, call_mocking)
- control_message = stem.socket.recv_message(StringIO.StringIO(RELATIVE_COOKIE_PATH))
+ control_message = mocking.get_message(RELATIVE_COOKIE_PATH)
stem.connection.ProtocolInfoResponse.convert(control_message)
self.assertEquals("/tmp/foo/tor-browser_en-US/Data/control_auth_cookie", control_message.cookie_path)
# exercise cookie expansion where both calls fail (should work, just
# leaving the path unexpanded)
- stem.util.system.CALL_MOCKING = lambda cmd: None
- control_message = stem.socket.recv_message(StringIO.StringIO(RELATIVE_COOKIE_PATH))
+ mocking.mock(stem.util.system.call, mocking.return_none())
+ control_message = mocking.get_message(RELATIVE_COOKIE_PATH)
stem.connection.ProtocolInfoResponse.convert(control_message)
self.assertEquals("./tor-browser_en-US/Data/control_auth_cookie", control_message.cookie_path)
# reset system call mocking
- stem.util.system.CALL_MOCKING = None
+ mocking.revert_mocking()
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits