PageRenderTime 93ms CodeModel.GetById 45ms app.highlight 44ms RepoModel.GetById 1ms app.codeStats 0ms

/historical/hive_test.py

https://bitbucket.org/lindenlab/apiary/
Python | 287 lines | 257 code | 6 blank | 24 comment | 0 complexity | 95c578d508d0e244018c414471e52228 MD5 | raw file
  1#
  2# $LicenseInfo:firstyear=2010&license=mit$
  3# 
  4# Copyright (c) 2010, Linden Research, Inc.
  5# 
  6# Permission is hereby granted, free of charge, to any person obtaining a copy
  7# of this software and associated documentation files (the "Software"), to deal
  8# in the Software without restriction, including without limitation the rights
  9# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10# copies of the Software, and to permit persons to whom the Software is
 11# furnished to do so, subject to the following conditions:
 12# 
 13# The above copyright notice and this permission notice shall be included in
 14# all copies or substantial portions of the Software.
 15# 
 16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22# THE SOFTWARE.
 23# $/LicenseInfo$
 24#
 25
 26import sys
 27import time
 28import thread
 29import unittest
 30
 31import hive
 32
 33
 34def create_worker(cls):
 35    thread.start_new_thread(hive.run_worker, (cls,))
 36
 37
 38class SimpleWorker(hive.Worker):
 39    def __init__(self, options, arguments):
 40        hive.Worker.__init__(self, options, arguments)
 41        self._result = ''
 42    
 43    def start(self):
 44        self._result = '('
 45    
 46    def event(self, data):
 47        self._result += data
 48    
 49    def end(self):
 50        self._result += ')'
 51        return self._result
 52        
 53    def main(self):
 54        #print "worker up..."
 55        hive.Worker.main(self)
 56        #print "worker down..."
 57
 58
 59class SimpleCentral(hive.Central):
 60    def __init__(self, options, arguments):
 61        hive.Central.__init__(self, options, arguments)
 62        self.results = []
 63        self._events = []
 64        self._startfn = self.start
 65        self._eventfn = self.event
 66        self._endfn = self.end
 67    
 68    def addstart(self, seq):
 69        self._events.append([self._startfn, seq])
 70    
 71    def addevent(self, seq, data):
 72        self._events.append([self._eventfn, seq, data])
 73    
 74    def addend(self, seq):
 75        self._events.append([self._endfn, seq])
 76    
 77    def addstringseq(self, seq, data):
 78        self.addstart(seq)
 79        for c in data:
 80            self.addevent(seq, c)
 81        self.addend(seq)
 82    
 83    def addsleep(self, t=0.25):
 84        self._events.append([time.sleep, t])
 85        
 86    def next(self):
 87        if not self._events:
 88            return False
 89        e = self._events.pop(0)
 90        e[0](*e[1:])
 91        return True
 92    
 93    def result(self, seq, data):
 94        self.results.append(data)
 95
 96
 97class HiveTestCase(unittest.TestCase):
 98    def setUp(self):
 99        self.options = hive.Hive(None, None).default_options()
100        self._transport = None
101        self._open = False
102        self._threads = []
103        hive.clean(self.options)
104        
105    def tearDown(self):
106        self.close()
107        self.join_workers()
108        hive.clean(self.options)
109        
110    def connect(self):
111        if self._transport is None:
112            self._transport = hive.Transport(self.options)
113            self.send = self._transport.send
114            self.recv = self._transport.recv
115        self._transport.connect()
116        self._open = True
117                
118    def close(self):
119        if self._open:
120            self._transport.close()
121            self._open = False
122    
123    def start_workers(self, cls=SimpleWorker, n=1):
124        threads = hive.start_workers(cls, n, self.options, [])
125        f = sys._getframe(1)
126        name = "Worker-%s:%d-" % (f.f_code.co_name, f.f_lineno)
127        for i in xrange(0,len(threads)):
128            threads[i].setName(name + str(i+1))
129        self._threads += threads
130        
131    def join_workers(self):
132        for t in self._threads:
133            t.join(5.0)
134            if t.isAlive():
135                raise Exception("thread %s never died" % t.getName())
136        self._threads = []
137
138
139class TestWorker(HiveTestCase):
140    def testAMQP(self):
141        self.connect()
142        qname = self._transport.queue()
143        self.send(qname, 'Hello')
144        d = self.recv(qname)
145        self.assertEqual(d, 'Hello')
146        self.close()
147
148    def testNoWork(self):
149        self.start_workers(SimpleWorker, 1)
150        
151        time.sleep(0.1)
152        self.connect()
153        self._transport.queue('worker-job')
154        self.close()
155
156        self.join_workers()
157        
158
159class TestBasics(HiveTestCase):
160
161    def testEmptyCentral(self):
162        c = SimpleCentral(self.options, [])
163        c.main()
164        
165    def testOneSeq(self):
166        c = SimpleCentral(self.options, [])
167        c.addstringseq('aaa', 'abc')
168
169        self.start_workers(SimpleWorker, 1)
170
171        c.main()
172        
173        r = ','.join(c.results)
174        self.assert_('(abc)' in r)
175        
176        self.join_workers()
177
178    def testTwoSeq(self):
179        c = SimpleCentral(self.options, [])
180        c.addstringseq('aaa', 'abc')
181        c.addstringseq('xxx', 'xyz')
182        
183        self.start_workers(SimpleWorker, 1)
184        
185        c.main()
186        r = ','.join(c.results)
187        self.assert_('(abc)' in r)
188        self.assert_('(xyz)' in r)
189        
190        self.join_workers()
191
192        
193    def testTwoSeq2(self):
194        c = SimpleCentral(self.options, [])
195        c.addstringseq('aaa', 'abc')
196        c.addstringseq('xxx', 'xyz')
197        
198        self.start_workers(SimpleWorker, 2)
199        
200        c.main()
201        r = ','.join(c.results)
202        self.assert_('(abc)' in r)
203        self.assert_('(xyz)' in r)
204
205        self.join_workers()
206
207    def testTwoSeq2Interleaved(self):
208        c = SimpleCentral(self.options, [])
209        c.addstart('aaa')
210        c.addstart('xxx')
211        c.addsleep()
212        c.addevent('aaa', 'a')
213        c.addevent('xxx', 'x')
214        c.addsleep()
215        c.addevent('xxx', 'y')
216        c.addevent('aaa', 'b')
217        c.addsleep()
218        c.addevent('aaa', 'c')
219        c.addevent('xxx', 'z')
220        c.addsleep()
221        c.addend('aaa')
222        c.addend('xxx')
223        
224        self.start_workers(SimpleWorker, 2)
225        
226        c.main()
227        r = ','.join(c.results)
228        self.assert_('(abc)' in r)
229        self.assert_('(xyz)' in r)
230        
231        self.join_workers()
232
233
234
235
236class TestTimeouts(HiveTestCase):
237    def setUp(self):
238        HiveTestCase.setUp(self)
239        self.options.timeout = 0.5
240
241    def testWorkerNoJobsTimeout(self):
242        # Worker w/no jobs stops after timeout
243        w = SimpleWorker(self.options, [])
244        t = time.time()
245        self.assertRaises(hive.TimeoutError, w.main)
246        t = time.time() - t
247        self.assert_(t < 1.0, "%f < 1.0" % t)
248    
249    def testWorkerNoEndTimeout(self):
250        # Worker w/job, but no job end, stops after timeout
251        self.connect()
252        qname = self._transport.queue()
253        self.send(qname, 'Hello')
254        self.send(qname, 'Hold on...')
255        self._transport.queue('worker-job')
256        self.send('worker-job', qname)
257        
258        w = SimpleWorker(self.options, [])
259        t = time.time()
260        self.assertRaises(hive.TimeoutError, w.main)
261        t = time.time() - t
262        self.assert_(t < 1.0, "%f < 1.0" % t)
263        
264    def testCentralNoWorkersTimeout(self):
265        # Central w/no workers stops after timeout
266        c = SimpleCentral(self.options, [])
267        c.addstringseq('aaa', 'abc') # needs to have some work, or just exits!
268        t = time.time()
269        self.assertRaises(hive.TimeoutError, c.main)
270        t = time.time() - t
271        self.assert_(t < 1.0, "%f < 1.0" % t)
272
273    def xtestCentralNoWorkersCantStartTimeout(self):
274        # Central w/no workers stops after timeout, when stalled on starting
275        c = SimpleCentral(self.options, [])
276        c.addstringseq('aaa', 'abc') # needs to three units of work...
277        c.addstringseq('bbb', 'def') 
278        c.addstringseq('ccc', 'ghi') # ...so this one stalls on starting
279        t = time.time()
280        self.assertRaises(hive.TimeoutError, c.main)
281        t = time.time() - t
282        self.assert_(t < 1.0, "%f < 1.0" % t)
283
284
285
286if __name__ == '__main__':
287    unittest.main()