commit 39528a51489598b970d1f64cd37a3a5de97fc4cb
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sat Dec 24 17:37:39 2011 -0800
General auth unit test for protocolinfo fetching
Unit tests for the general authentication function will be exercising it in
various error conditions by mocking out the functions it uses. This first test
exercises all of the use cases when the function needs to make a PROTOCOLINFO
query and, more importantly, lays the groundwork the rest of these unit tests
will use.
---
run_tests.py | 2 +
test/unit/connection/__init__.py | 2 +-
test/unit/connection/authentication.py | 81 ++++++++++++++++++++++++++++++++
3 files changed, 84 insertions(+), 1 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index ddea103..73cfb9c 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -16,6 +16,7 @@ import test.runner
import test.unit.version
import test.unit.socket.control_message
import test.unit.socket.control_line
+import test.unit.connection.authentication
import test.unit.connection.protocolinfo
import test.unit.util.enum
import test.unit.util.system
@@ -36,6 +37,7 @@ DIVIDER = "=" * 70
UNIT_TESTS = (("stem.socket.ControlMessage", test.unit.socket.control_message.TestControlMessage),
("stem.socket.ControlLine", test.unit.socket.control_line.TestControlLine),
("stem.types.Version", test.unit.version.TestVersion),
+ ("stem.connection.authenticate", test.unit.connection.authentication.TestAuthenticate),
("stem.connection.ProtocolInfoResponse", test.unit.connection.protocolinfo.TestProtocolInfoResponse),
("stem.util.enum", test.unit.util.enum.TestEnum),
("stem.util.system", test.unit.util.system.TestSystem),
diff --git a/test/unit/connection/__init__.py b/test/unit/connection/__init__.py
index f93234b..4eae0fa 100644
--- a/test/unit/connection/__init__.py
+++ b/test/unit/connection/__init__.py
@@ -2,5 +2,5 @@
Unit tests for stem.connection.
"""
-__all__ = ["protocolinfo"]
+__all__ = ["authentication", "protocolinfo"]
diff --git a/test/unit/connection/authentication.py b/test/unit/connection/authentication.py
new file mode 100644
index 0000000..a570bfe
--- /dev/null
+++ b/test/unit/connection/authentication.py
@@ -0,0 +1,81 @@
+"""
+Unit tests for the stem.connection.authenticate function.
+"""
+
+import StringIO
+import functools
+import unittest
+
+import stem.connection
+
+# Functors to replace get_protocolinfo and authenticate_*. All of them take any
+# number of arguments.
+def no_op():
+ def _no_op(*args):
+ pass
+
+ return _no_op
+
+def raise_exception(exception_type):
+ if not exception_type: return no_op()
+
+ def _raise(exc_type, *args):
+ raise exc_type
+
+ return functools.partial(_raise, exception_type)
+
+def get_protocolinfo(auth_methods):
+ control_message = "250-PROTOCOLINFO 1\r\n250 OK\r\n"
+ protocolinfo_response = stem.socket.recv_message(StringIO.StringIO(control_message))
+ stem.connection.ProtocolInfoResponse.convert(protocolinfo_response)
+ protocolinfo_response.auth_methods = auth_methods
+ return lambda *args: protocolinfo_response
+
+class TestAuthenticate(unittest.TestCase):
+ """
+ Under the covers the authentiate function really just translates a
+ PROTOCOLINFO response into authenticate_* calls, then does prioritization
+ on the exceptions if they all fail.
+
+ This monkey patches the various functions authenticate relies on to exercise
+ various error conditions, and make sure that the right exception is raised.
+ """
+
+ def setUp(self):
+ # preserves all of the functors we'll need to monkey patch, and make them
+ # no-ops
+
+ self.original_get_protocolinfo = stem.connection.get_protocolinfo
+ self.original_authenticate_none = stem.connection.authenticate_none
+ self.original_authenticate_password = stem.connection.authenticate_password
+ self.original_authenticate_cookie = stem.connection.authenticate_cookie
+
+ stem.connection.get_protocolinfo = no_op()
+ stem.connection.authenticate_none = no_op()
+ stem.connection.authenticate_password = no_op()
+ stem.connection.authenticate_cookie = no_op()
+
+ def tearDown(self):
+ # restore functions
+ stem.connection.get_protocolinfo = self.original_get_protocolinfo
+ stem.connection.authenticate_none = self.original_authenticate_none
+ stem.connection.authenticate_password = self.original_authenticate_password
+ stem.connection.authenticate_cookie = self.original_authenticate_cookie
+
+ def test_with_get_protocolinfo(self):
+ """
+ Tests the authenticate() function when it needs to make a get_protocolinfo.
+ """
+
+ # tests where get_protocolinfo succeeds
+ stem.connection.get_protocolinfo = get_protocolinfo((stem.connection.AuthMethod.NONE, ))
+ stem.connection.authenticate(None)
+
+ # tests where get_protocolinfo raises a ProtocolError
+ stem.connection.get_protocolinfo = raise_exception(stem.socket.ProtocolError)
+ self.assertRaises(stem.connection.IncorrectSocketType, stem.connection.authenticate, None)
+
+ # tests where get_protocolinfo raises a SocketError
+ stem.connection.get_protocolinfo = raise_exception(stem.socket.SocketError)
+ self.assertRaises(stem.connection.AuthenticationFailure, stem.connection.authenticate, None)
+