blob: c7839620357222e99adaff4da31910aff6c10aef [file] [log] [blame]
Chris Piro20c81ad2013-03-07 11:32:48 -05001#!/usr/bin/env python
2
3#
4# Licensed to the Apache Software Foundation (ASF) under one
5# or more contributor license agreements. See the NOTICE file
6# distributed with this work for additional information
7# regarding copyright ownership. The ASF licenses this file
8# to you under the Apache License, Version 2.0 (the
9# "License"); you may not use this file except in compliance
10# with the License. You may obtain a copy of the License at
11#
12# http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing,
15# software distributed under the License is distributed on an
16# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17# KIND, either express or implied. See the License for the
18# specific language governing permissions and limitations
19# under the License.
20#
21
22import datetime
23import glob
24import sys
Roger Meierd52edba2014-08-07 17:03:47 +020025import os
Chris Piro20c81ad2013-03-07 11:32:48 -050026import time
27import unittest
28
Roger Meierd52edba2014-08-07 17:03:47 +020029basepath = os.path.abspath(os.path.dirname(__file__))
30sys.path.insert(0, basepath+'/gen-py.tornado')
31sys.path.insert(0, glob.glob(os.path.join(basepath, '../../lib/py/build/lib.*'))[0])
Chris Piro20c81ad2013-03-07 11:32:48 -050032
33try:
34 __import__('tornado')
35except ImportError:
36 print "module `tornado` not found, skipping test"
37 sys.exit(0)
38
Roger Meierd52edba2014-08-07 17:03:47 +020039from tornado import gen
40from tornado.testing import AsyncTestCase, get_unused_port, gen_test
Chris Piro20c81ad2013-03-07 11:32:48 -050041
42from thrift import TTornado
43from thrift.protocol import TBinaryProtocol
Roger Meierd52edba2014-08-07 17:03:47 +020044from thrift.transport.TTransport import TTransportException
Chris Piro20c81ad2013-03-07 11:32:48 -050045
46from ThriftTest import ThriftTest
47from ThriftTest.ttypes import *
48
49
50class TestHandler(object):
51 def __init__(self, test_instance):
52 self.test_instance = test_instance
53
Roger Meierd52edba2014-08-07 17:03:47 +020054 def testVoid(self):
55 pass
Chris Piro20c81ad2013-03-07 11:32:48 -050056
Roger Meierd52edba2014-08-07 17:03:47 +020057 def testString(self, s):
58 return s
Chris Piro20c81ad2013-03-07 11:32:48 -050059
Roger Meierd52edba2014-08-07 17:03:47 +020060 def testByte(self, b):
61 return b
Chris Piro20c81ad2013-03-07 11:32:48 -050062
Roger Meierd52edba2014-08-07 17:03:47 +020063 def testI16(self, i16):
64 return i16
Chris Piro20c81ad2013-03-07 11:32:48 -050065
Roger Meierd52edba2014-08-07 17:03:47 +020066 def testI32(self, i32):
67 return i32
Chris Piro20c81ad2013-03-07 11:32:48 -050068
Roger Meierd52edba2014-08-07 17:03:47 +020069 def testI64(self, i64):
70 return i64
Chris Piro20c81ad2013-03-07 11:32:48 -050071
Roger Meierd52edba2014-08-07 17:03:47 +020072 def testDouble(self, dub):
73 return dub
Chris Piro20c81ad2013-03-07 11:32:48 -050074
Roger Meierd52edba2014-08-07 17:03:47 +020075 def testStruct(self, thing):
76 return thing
Chris Piro20c81ad2013-03-07 11:32:48 -050077
Roger Meierd52edba2014-08-07 17:03:47 +020078 def testException(self, s):
Chris Piro20c81ad2013-03-07 11:32:48 -050079 if s == 'Xception':
80 x = Xception()
81 x.errorCode = 1001
82 x.message = s
83 raise x
84 elif s == 'throw_undeclared':
85 raise ValueError("foo")
Chris Piro20c81ad2013-03-07 11:32:48 -050086
Roger Meierd52edba2014-08-07 17:03:47 +020087 def testOneway(self, seconds):
Chris Piro20c81ad2013-03-07 11:32:48 -050088 start = time.time()
Roger Meierd52edba2014-08-07 17:03:47 +020089
Chris Piro20c81ad2013-03-07 11:32:48 -050090 def fire_oneway():
91 end = time.time()
92 self.test_instance.stop((start, end, seconds))
93
Roger Meierd52edba2014-08-07 17:03:47 +020094 self.test_instance.io_loop.add_timeout(
Chris Piro20c81ad2013-03-07 11:32:48 -050095 datetime.timedelta(seconds=seconds),
96 fire_oneway)
97
Roger Meierd52edba2014-08-07 17:03:47 +020098 def testNest(self, thing):
99 return thing
Chris Piro20c81ad2013-03-07 11:32:48 -0500100
Roger Meierd52edba2014-08-07 17:03:47 +0200101 @gen.coroutine
102 def testMap(self, thing):
103 yield gen.moment
104 raise gen.Return(thing)
Chris Piro20c81ad2013-03-07 11:32:48 -0500105
Roger Meierd52edba2014-08-07 17:03:47 +0200106 def testSet(self, thing):
107 return thing
Chris Piro20c81ad2013-03-07 11:32:48 -0500108
Roger Meierd52edba2014-08-07 17:03:47 +0200109 def testList(self, thing):
110 return thing
Chris Piro20c81ad2013-03-07 11:32:48 -0500111
Roger Meierd52edba2014-08-07 17:03:47 +0200112 def testEnum(self, thing):
113 return thing
Chris Piro20c81ad2013-03-07 11:32:48 -0500114
Roger Meierd52edba2014-08-07 17:03:47 +0200115 def testTypedef(self, thing):
116 return thing
Chris Piro20c81ad2013-03-07 11:32:48 -0500117
118
119class ThriftTestCase(AsyncTestCase):
Chris Piro20c81ad2013-03-07 11:32:48 -0500120 def setUp(self):
Roger Meierd52edba2014-08-07 17:03:47 +0200121 super(ThriftTestCase, self).setUp()
122
Chris Piro20c81ad2013-03-07 11:32:48 -0500123 self.port = get_unused_port()
Chris Piro20c81ad2013-03-07 11:32:48 -0500124
125 # server
126 self.handler = TestHandler(self)
127 self.processor = ThriftTest.Processor(self.handler)
128 self.pfactory = TBinaryProtocol.TBinaryProtocolFactory()
129
Roger Meierd52edba2014-08-07 17:03:47 +0200130 self.server = TTornado.TTornadoServer(self.processor, self.pfactory, io_loop=self.io_loop)
Chris Piro20c81ad2013-03-07 11:32:48 -0500131 self.server.bind(self.port)
132 self.server.start(1)
133
134 # client
Roger Meierd52edba2014-08-07 17:03:47 +0200135 transport = TTornado.TTornadoStreamTransport('localhost', self.port, io_loop=self.io_loop)
Chris Piro20c81ad2013-03-07 11:32:48 -0500136 pfactory = TBinaryProtocol.TBinaryProtocolFactory()
Roger Meierd52edba2014-08-07 17:03:47 +0200137 self.io_loop.run_sync(transport.open)
Chris Piro20c81ad2013-03-07 11:32:48 -0500138 self.client = ThriftTest.Client(transport, pfactory)
Chris Piro20c81ad2013-03-07 11:32:48 -0500139
Roger Meierd52edba2014-08-07 17:03:47 +0200140 @gen_test
Chris Piro20c81ad2013-03-07 11:32:48 -0500141 def test_void(self):
Roger Meierd52edba2014-08-07 17:03:47 +0200142 v = yield self.client.testVoid()
143 self.assertEqual(v, None)
Chris Piro20c81ad2013-03-07 11:32:48 -0500144
Roger Meierd52edba2014-08-07 17:03:47 +0200145 @gen_test
Chris Piro20c81ad2013-03-07 11:32:48 -0500146 def test_string(self):
Roger Meierd52edba2014-08-07 17:03:47 +0200147 v = yield self.client.testString('Python')
148 self.assertEqual(v, 'Python')
Chris Piro20c81ad2013-03-07 11:32:48 -0500149
Roger Meierd52edba2014-08-07 17:03:47 +0200150 @gen_test
Chris Piro20c81ad2013-03-07 11:32:48 -0500151 def test_byte(self):
Roger Meierd52edba2014-08-07 17:03:47 +0200152 v = yield self.client.testByte(63)
153 self.assertEqual(v, 63)
Chris Piro20c81ad2013-03-07 11:32:48 -0500154
Roger Meierd52edba2014-08-07 17:03:47 +0200155 @gen_test
Chris Piro20c81ad2013-03-07 11:32:48 -0500156 def test_i32(self):
Roger Meierd52edba2014-08-07 17:03:47 +0200157 v = yield self.client.testI32(-1)
158 self.assertEqual(v, -1)
Chris Piro20c81ad2013-03-07 11:32:48 -0500159
Roger Meierd52edba2014-08-07 17:03:47 +0200160 v = yield self.client.testI32(0)
161 self.assertEqual(v, 0)
Chris Piro20c81ad2013-03-07 11:32:48 -0500162
Roger Meierd52edba2014-08-07 17:03:47 +0200163 @gen_test
Chris Piro20c81ad2013-03-07 11:32:48 -0500164 def test_i64(self):
Roger Meierd52edba2014-08-07 17:03:47 +0200165 v = yield self.client.testI64(-34359738368)
166 self.assertEqual(v, -34359738368)
Chris Piro20c81ad2013-03-07 11:32:48 -0500167
Roger Meierd52edba2014-08-07 17:03:47 +0200168 @gen_test
Chris Piro20c81ad2013-03-07 11:32:48 -0500169 def test_double(self):
Roger Meierd52edba2014-08-07 17:03:47 +0200170 v = yield self.client.testDouble(-5.235098235)
171 self.assertEqual(v, -5.235098235)
Chris Piro20c81ad2013-03-07 11:32:48 -0500172
Roger Meierd52edba2014-08-07 17:03:47 +0200173 @gen_test
Chris Piro20c81ad2013-03-07 11:32:48 -0500174 def test_struct(self):
175 x = Xtruct()
176 x.string_thing = "Zero"
177 x.byte_thing = 1
178 x.i32_thing = -3
179 x.i64_thing = -5
Roger Meierd52edba2014-08-07 17:03:47 +0200180 y = yield self.client.testStruct(x)
Chris Piro20c81ad2013-03-07 11:32:48 -0500181
Roger Meierd52edba2014-08-07 17:03:47 +0200182 self.assertEqual(y.string_thing, "Zero")
183 self.assertEqual(y.byte_thing, 1)
184 self.assertEqual(y.i32_thing, -3)
185 self.assertEqual(y.i64_thing, -5)
Chris Piro20c81ad2013-03-07 11:32:48 -0500186
187 def test_oneway(self):
Roger Meierd52edba2014-08-07 17:03:47 +0200188 self.client.testOneway(0.5)
Chris Piro20c81ad2013-03-07 11:32:48 -0500189 start, end, seconds = self.wait(timeout=1)
190 self.assertAlmostEquals(seconds, (end - start), places=3)
191
Roger Meierd52edba2014-08-07 17:03:47 +0200192 @gen_test
193 def test_map(self):
194 """
195 TestHandler.testMap is a coroutine, this test checks if gen.Return() from a coroutine works.
196 """
197 expected = {1: 1}
198 res = yield self.client.testMap(expected)
199 self.assertEqual(res, expected)
200
201 @gen_test
202 def test_exception(self):
203 yield self.client.testException('Safe')
204
205 try:
206 yield self.client.testException('Xception')
207 except Xception as ex:
208 self.assertEqual(ex.errorCode, 1001)
209 self.assertEqual(ex.message, 'Xception')
210 else:
211 self.fail("should have gotten exception")
212 try:
213 yield self.client.testException('throw_undeclared')
214 except TTransportException as ex:
215 pass
216 else:
217 self.fail("should have gotten exception")
218
Chris Piro20c81ad2013-03-07 11:32:48 -0500219
220def suite():
221 suite = unittest.TestSuite()
222 loader = unittest.TestLoader()
223 suite.addTest(loader.loadTestsFromTestCase(ThriftTestCase))
224 return suite
225
226
227if __name__ == '__main__':
228 unittest.TestProgram(defaultTest='suite',
229 testRunner=unittest.TextTestRunner(verbosity=1))