# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import time import unittest from nose.tools import raises from ryu.lib import hub hub.patch() class MyException(BaseException): pass class Test_hub(unittest.TestCase): """ Test case for ryu.lib.hub """ def setUp(self): pass def tearDown(self): pass # we want to test timeout first because the rest of tests rely on it. # thus test_0_ prefix. @raises(hub.Timeout) def test_0_timeout1(self): with hub.Timeout(0.1): hub.sleep(1) @raises(MyException) def test_0_timeout2(self): with hub.Timeout(0.1, MyException): hub.sleep(1) def test_0_timeout3(self): with hub.Timeout(1): hub.sleep(0.1) # sleep some more to ensure timer cancelation hub.sleep(2) def test_spawn_event1(self): def _child(ev, result): hub.sleep(1) result.append(1) ev.set() ev = hub.Event() result = [] with hub.Timeout(2): hub.spawn(_child, ev, result) ev.wait() assert len(result) == 1 def test_spawn_event2(self): def _child(ev, result): hub.sleep(1) result.append(1) ev.set() ev = hub.Event() result = [] with hub.Timeout(2): t = hub.spawn(_child, ev, result) ev.wait(timeout=0.5) assert len(result) == 0 ev.wait() assert len(result) == 1 def test_spawn_event3(self): def _child(ev, ev2, result): ev2.wait() hub.sleep(0.5) result.append(1) ev.set() ev = hub.Event() ev2 = hub.Event() result = [] with hub.Timeout(2): hub.spawn(_child, ev, ev2, result) hub.spawn(_child, ev, ev2, result) hub.sleep(0.5) ev2.set() # this should wake up the above created two threads ev.wait(timeout=1) assert len(result) == 2 def test_spawn_select1(self): import select import socket def _child(s1): hub.sleep(0.5) s1.send(b"hoge") s1, s2 = socket.socketpair() with hub.Timeout(1): hub.spawn(_child, s1) select.select([s2.fileno()], [], []) select.select([s2.fileno()], [], []) # return immediately @raises(MyException) def test_select1(self): import select import socket s1, s2 = socket.socketpair() with hub.Timeout(1, MyException): select.select([s2.fileno()], [], []) def test_select2(self): import select with hub.Timeout(1, MyException): select.select([], [], [], 0) # timeout immediately def test_select3(self): import select import socket s1, s2 = socket.socketpair() with hub.Timeout(1, MyException): list = [s1.fileno(), s2.fileno()] rlist, wlist, xlist = select.select(list, list, list) assert not s1.fileno() in rlist assert not s2.fileno() in rlist # the following two assertions are commented out because one of # them fails with eventlet-patched select. # assert s1.fileno() in wlist # assert s2.fileno() in wlist # note: eventlet-patched select returns at most one file. assert (s1.fileno() in wlist) or (s2.fileno() in wlist) assert not s1.fileno() in xlist assert not s2.fileno() in xlist def test_spawn_joinall(self): def _child(ev2, result): ev2.wait() hub.sleep(0.5) result.append(1) raise BaseException("this exception should not be propagated") ev2 = hub.Event() threads = [] result = [] with hub.Timeout(2): threads.append(hub.spawn(_child, ev2, result)) threads.append(hub.spawn(_child, ev2, result)) hub.sleep(0.5) ev2.set() # this should wake up the above created two threads hub.joinall(threads) assert len(result) == 2 def test_spawn_kill_joinall(self): def _child(ev2, result): ev2.wait() result.append(1) ev2 = hub.Event() threads = [] result = [] with hub.Timeout(2): threads.append(hub.spawn(_child, ev2, result)) threads.append(hub.spawn(_child, ev2, result)) hub.sleep(0.5) for t in threads: hub.kill(t) hub.joinall(threads) assert len(result) == 0 def test_spawn_kill_nowait_joinall(self): # XXX this test relies on the scheduling behaviour. # the intention here is, killing threads before they get active. def _child(result): result.append(1) threads = [] result = [] with hub.Timeout(2): threads.append(hub.spawn(_child, result)) for t in threads: hub.kill(t) hub.joinall(threads) assert len(result) == 0 def test_spawn_kill_die_joinall(self): def _child(result): result.append(1) threads = [] result = [] with hub.Timeout(2): threads.append(hub.spawn(_child, result)) threads.append(hub.spawn(_child, result)) hub.sleep(0.5) for t in threads: hub.kill(t) hub.joinall(threads) assert len(result) == 2 def test_spawn_exception_joinall(self): def _child(): raise Exception("hoge") threads = [] with hub.Timeout(2): threads.append(hub.spawn(_child)) threads.append(hub.spawn(_child)) hub.sleep(0.5) hub.joinall(threads) def test_event1(self): ev = hub.Event() ev.set() with hub.Timeout(1): ev.wait() # should return immediately def test_event2(self): ev = hub.Event() # allow multiple sets unlike eventlet Event ev.set() ev.set()