1#!/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 glob
23import os
24import sys
25import time
26
27basepath = os.path.abspath(os.path.dirname(__file__))
28sys.path.insert(0, os.path.join(basepath, 'gen-py.twisted'))
29sys.path.insert(0, glob.glob(os.path.join(basepath, '../../lib/py/build/lib.*'))[0])
30
31from thrift.Thrift import TApplicationException
32
33from ThriftTest import ThriftTest
34from ThriftTest.ttypes import Xception, Xtruct
35from thrift.transport import TTwisted
36from thrift.protocol import TBinaryProtocol
37
38from twisted.trial import unittest
39from twisted.internet import defer, reactor
40from twisted.internet.protocol import ClientCreator
41
42from zope.interface import implementer
43
44
45@implementer(ThriftTest.Iface)
46class TestHandler:
47    def __init__(self):
48        self.onewaysQueue = defer.DeferredQueue()
49
50    def testVoid(self):
51        pass
52
53    def testString(self, s):
54        return s
55
56    def testByte(self, b):
57        return b
58
59    def testI16(self, i16):
60        return i16
61
62    def testI32(self, i32):
63        return i32
64
65    def testI64(self, i64):
66        return i64
67
68    def testDouble(self, dub):
69        return dub
70
71    def testBinary(self, thing):
72        return thing
73
74    def testStruct(self, thing):
75        return thing
76
77    def testException(self, s):
78        if s == 'Xception':
79            raise Xception(1001, s)
80        elif s == "throw_undeclared":
81            raise ValueError("foo")
82
83    def testOneway(self, seconds):
84        def fireOneway(t):
85            self.onewaysQueue.put((t, time.time(), seconds))
86        reactor.callLater(seconds, fireOneway, time.time())
87        raise Exception('')
88
89    def testNest(self, thing):
90        return thing
91
92    def testMap(self, thing):
93        return thing
94
95    def testSet(self, thing):
96        return thing
97
98    def testList(self, thing):
99        return thing
100
101    def testEnum(self, thing):
102        return thing
103
104    def testTypedef(self, thing):
105        return thing
106
107
108class ThriftTestCase(unittest.TestCase):
109
110    @defer.inlineCallbacks
111    def setUp(self):
112        self.handler = TestHandler()
113        self.processor = ThriftTest.Processor(self.handler)
114        self.pfactory = TBinaryProtocol.TBinaryProtocolFactory()
115
116        self.server = reactor.listenTCP(
117            0, TTwisted.ThriftServerFactory(self.processor, self.pfactory), interface="127.0.0.1")
118
119        self.portNo = self.server.getHost().port
120
121        self.txclient = yield ClientCreator(reactor,
122                                            TTwisted.ThriftClientProtocol,
123                                            ThriftTest.Client,
124                                            self.pfactory).connectTCP("127.0.0.1", self.portNo)
125        self.client = self.txclient.client
126
127    @defer.inlineCallbacks
128    def tearDown(self):
129        yield self.server.stopListening()
130        self.txclient.transport.loseConnection()
131
132    @defer.inlineCallbacks
133    def testVoid(self):
134        self.assertEquals((yield self.client.testVoid()), None)
135
136    @defer.inlineCallbacks
137    def testString(self):
138        self.assertEquals((yield self.client.testString('Python')), 'Python')
139
140    @defer.inlineCallbacks
141    def testByte(self):
142        self.assertEquals((yield self.client.testByte(63)), 63)
143
144    @defer.inlineCallbacks
145    def testI32(self):
146        self.assertEquals((yield self.client.testI32(-1)), -1)
147        self.assertEquals((yield self.client.testI32(0)), 0)
148
149    @defer.inlineCallbacks
150    def testI64(self):
151        self.assertEquals((yield self.client.testI64(-34359738368)), -34359738368)
152
153    @defer.inlineCallbacks
154    def testDouble(self):
155        self.assertEquals((yield self.client.testDouble(-5.235098235)), -5.235098235)
156
157    # TODO: def testBinary(self) ...
158
159    @defer.inlineCallbacks
160    def testStruct(self):
161        x = Xtruct()
162        x.string_thing = "Zero"
163        x.byte_thing = 1
164        x.i32_thing = -3
165        x.i64_thing = -5
166        y = yield self.client.testStruct(x)
167
168        self.assertEquals(y.string_thing, "Zero")
169        self.assertEquals(y.byte_thing, 1)
170        self.assertEquals(y.i32_thing, -3)
171        self.assertEquals(y.i64_thing, -5)
172
173    @defer.inlineCallbacks
174    def testException(self):
175        try:
176            yield self.client.testException('Xception')
177            self.fail("should have gotten exception")
178        except Xception as x:
179            self.assertEquals(x.errorCode, 1001)
180            self.assertEquals(x.message, 'Xception')
181
182        try:
183            yield self.client.testException("throw_undeclared")
184            self.fail("should have gotten exception")
185        except TApplicationException:
186            pass
187
188        yield self.client.testException('Safe')
189
190    @defer.inlineCallbacks
191    def testOneway(self):
192        yield self.client.testOneway(1)
193        start, end, seconds = yield self.handler.onewaysQueue.get()
194        self.assertAlmostEquals(seconds, (end - start), places=1)
195        self.assertEquals((yield self.client.testI32(-1)), -1)
196