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