aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Nathaniel Manista <nathaniel@google.com>2015-03-07 00:18:51 +0000
committerGravatar Nathaniel Manista <nathaniel@google.com>2015-03-07 00:18:51 +0000
commit256ccca9231eeca83d5dbc903ce58894eb7498ac (patch)
treea4ae89351d49d73a9bd88ac82c8315bb476d17bc
parentdb13f68dab0e01acb9c0186eec423a0419326fd4 (diff)
Use server_host_override in interop client
Also refactor the interop package to perform client-server interop testing in a unit test.
-rw-r--r--src/python/interop/interop/_insecure_interop_test.py56
-rw-r--r--src/python/interop/interop/_interop_test_case.py55
-rw-r--r--src/python/interop/interop/_secure_interop_test.py63
-rw-r--r--src/python/interop/interop/client.py15
-rw-r--r--src/python/interop/interop/methods.py35
5 files changed, 208 insertions, 16 deletions
diff --git a/src/python/interop/interop/_insecure_interop_test.py b/src/python/interop/interop/_insecure_interop_test.py
new file mode 100644
index 0000000000..1fa6b8b3f8
--- /dev/null
+++ b/src/python/interop/interop/_insecure_interop_test.py
@@ -0,0 +1,56 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Insecure client-server interoperability as a unit test."""
+
+import unittest
+
+from grpc.early_adopter import implementations
+
+from interop import _interop_test_case
+from interop import methods
+
+
+class InsecureInteropTest(
+ _interop_test_case.InteropTestCase,
+ unittest.TestCase):
+
+ def setUp(self):
+ self.server = implementations.insecure_server(methods.SERVER_METHODS, 0)
+ self.server.start()
+ port = self.server.port()
+ self.stub = implementations.insecure_stub(
+ methods.CLIENT_METHODS, 'localhost', port)
+
+ def tearDown(self):
+ self.server.stop()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/python/interop/interop/_interop_test_case.py b/src/python/interop/interop/_interop_test_case.py
new file mode 100644
index 0000000000..fec8f1915d
--- /dev/null
+++ b/src/python/interop/interop/_interop_test_case.py
@@ -0,0 +1,55 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Common code for unit tests of the interoperability test code."""
+
+from interop import methods
+
+
+class InteropTestCase(object):
+ """Unit test methods.
+
+ This class must be mixed in with unittest.TestCase and a class that defines
+ setUp and tearDown methods that manage a stub attribute.
+ """
+
+ def testEmptyUnary(self):
+ methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub)
+
+ def testLargeUnary(self):
+ methods.TestCase.LARGE_UNARY.test_interoperability(self.stub)
+
+ def testServerStreaming(self):
+ methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub)
+
+ def testClientStreaming(self):
+ methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub)
+
+ def testPingPong(self):
+ methods.TestCase.PING_PONG.test_interoperability(self.stub)
diff --git a/src/python/interop/interop/_secure_interop_test.py b/src/python/interop/interop/_secure_interop_test.py
new file mode 100644
index 0000000000..cc9e93821a
--- /dev/null
+++ b/src/python/interop/interop/_secure_interop_test.py
@@ -0,0 +1,63 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Secure client-server interoperability as a unit test."""
+
+import unittest
+
+from grpc.early_adopter import implementations
+
+from interop import _interop_test_case
+from interop import methods
+from interop import resources
+
+_SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
+
+
+class SecureInteropTest(
+ _interop_test_case.InteropTestCase,
+ unittest.TestCase):
+
+ def setUp(self):
+ self.server = implementations.secure_server(
+ methods.SERVER_METHODS, 0, resources.private_key(),
+ resources.certificate_chain())
+ self.server.start()
+ port = self.server.port()
+ self.stub = implementations.secure_stub(
+ methods.CLIENT_METHODS, 'localhost', port,
+ resources.test_root_certificates(), None, None,
+ server_host_override=_SERVER_HOST_OVERRIDE)
+
+ def tearDown(self):
+ self.server.stop()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/python/interop/interop/client.py b/src/python/interop/interop/client.py
index f4a449ef9e..b674a64f9d 100644
--- a/src/python/interop/interop/client.py
+++ b/src/python/interop/interop/client.py
@@ -65,21 +65,30 @@ def _stub(args):
root_certificates = resources.test_root_certificates()
else:
root_certificates = resources.prod_root_certificates()
- # TODO(nathaniel): server host override.
stub = implementations.secure_stub(
methods.CLIENT_METHODS, args.server_host, args.server_port,
- root_certificates, None, None)
+ root_certificates, None, None,
+ server_host_override=args.server_host_override)
else:
stub = implementations.insecure_stub(
methods.CLIENT_METHODS, args.server_host, args.server_port)
return stub
+def _test_case_from_arg(test_case_arg):
+ for test_case in methods.TestCase:
+ if test_case_arg == test_case.value:
+ return test_case
+ else:
+ raise ValueError('No test case "%s"!' % test_case_arg)
+
+
def _test_interoperability():
args = _args()
stub = _stub(args)
- methods.test_interoperability(args.test_case, stub)
+ test_case = _test_case_from_arg(args.test_case)
+ test_case.test_interoperability(stub)
if __name__ == '__main__':
diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py
index 4da28ee775..2e15fac915 100644
--- a/src/python/interop/interop/methods.py
+++ b/src/python/interop/interop/methods.py
@@ -29,6 +29,7 @@
"""Implementations of interoperability test methods."""
+import enum
import threading
from grpc.early_adopter import utilities
@@ -265,16 +266,24 @@ def _ping_pong(stub):
pipe.close()
-def test_interoperability(test_case, stub):
- if test_case == 'empty_unary':
- _empty_unary(stub)
- elif test_case == 'large_unary':
- _large_unary(stub)
- elif test_case == 'server_streaming':
- _server_streaming(stub)
- elif test_case == 'client_streaming':
- _client_streaming(stub)
- elif test_case == 'ping_pong':
- _ping_pong(stub)
- else:
- raise NotImplementedError('Test case "%s" not implemented!')
+@enum.unique
+class TestCase(enum.Enum):
+ EMPTY_UNARY = 'empty_unary'
+ LARGE_UNARY = 'large_unary'
+ SERVER_STREAMING = 'server_streaming'
+ CLIENT_STREAMING = 'client_streaming'
+ PING_PONG = 'ping_pong'
+
+ def test_interoperability(self, stub):
+ if self is TestCase.EMPTY_UNARY:
+ _empty_unary(stub)
+ elif self is TestCase.LARGE_UNARY:
+ _large_unary(stub)
+ elif self is TestCase.SERVER_STREAMING:
+ _server_streaming(stub)
+ elif self is TestCase.CLIENT_STREAMING:
+ _client_streaming(stub)
+ elif self is TestCase.PING_PONG:
+ _ping_pong(stub)
+ else:
+ raise NotImplementedError('Test case "%s" not implemented!' % self.name)