1 # Some simple Queue module tests, plus some failure conditions
2 # to ensure the Queue locks remain stable
8 from test
.test_support
import verify
, TestFailed
, verbose
12 # Execute a function that blocks, and in a seperate thread, a function that
13 # triggers the release. Returns the result of the blocking function.
14 class _TriggerThread(threading
.Thread
):
15 def __init__(self
, fn
, args
):
18 self
.startedEvent
= threading
.Event()
19 threading
.Thread
.__init
__(self
)
22 self
.startedEvent
.set()
25 def _doBlockingTest(block_func
, block_args
, trigger_func
, trigger_args
):
26 t
= _TriggerThread(trigger_func
, trigger_args
)
29 return block_func(*block_args
)
31 # If we unblocked before our thread made the call, we failed!
32 if not t
.startedEvent
.isSet():
33 raise TestFailed("blocking function '%r' appeared not to block" %
35 t
.join(1) # make sure the thread terminates
37 raise TestFailed("trigger function '%r' appeared to not return" %
40 # A Queue subclass that can provoke failure at a moment's notice :)
41 class FailingQueueException(Exception):
44 class FailingQueue(Queue
.Queue
):
45 def __init__(self
, *args
):
46 self
.fail_next_put
= False
47 self
.fail_next_get
= False
48 Queue
.Queue
.__init
__(self
, *args
)
50 if self
.fail_next_put
:
51 self
.fail_next_put
= False
52 raise FailingQueueException
, "You Lose"
53 return Queue
.Queue
._put
(self
, item
)
55 if self
.fail_next_get
:
56 self
.fail_next_get
= False
57 raise FailingQueueException
, "You Lose"
58 return Queue
.Queue
._get
(self
)
60 def FailingQueueTest(q
):
62 raise RuntimeError, "Call this function with an empty queue"
63 for i
in range(queue_size
-1):
65 # Test a failing non-blocking put.
66 q
.fail_next_put
= True
68 q
.put("oops", block
=0)
69 raise TestFailed("The queue didn't fail when it should have")
70 except FailingQueueException
:
72 q
.fail_next_put
= True
74 q
.put("oops", timeout
=0.1)
75 raise TestFailed("The queue didn't fail when it should have")
76 except FailingQueueException
:
79 verify(q
.full(), "Queue should be full")
80 # Test a failing blocking put
81 q
.fail_next_put
= True
83 _doBlockingTest( q
.put
, ("full",), q
.get
, ())
84 raise TestFailed("The queue didn't fail when it should have")
85 except FailingQueueException
:
87 # Check the Queue isn't damaged.
88 # put failed, but get succeeded - re-add
90 # Test a failing timeout put
91 q
.fail_next_put
= True
93 _doBlockingTest( q
.put
, ("full", True, 0.2), q
.get
, ())
94 raise TestFailed("The queue didn't fail when it should have")
95 except FailingQueueException
:
97 # Check the Queue isn't damaged.
98 # put failed, but get succeeded - re-add
100 verify(q
.full(), "Queue should be full")
102 verify(not q
.full(), "Queue should not be full")
104 verify(q
.full(), "Queue should be full")
105 # Test a blocking put
106 _doBlockingTest( q
.put
, ("full",), q
.get
, ())
108 for i
in range(queue_size
):
110 verify(q
.empty(), "Queue should be empty")
112 q
.fail_next_get
= True
115 raise TestFailed("The queue didn't fail when it should have")
116 except FailingQueueException
:
118 verify(not q
.empty(), "Queue should not be empty")
119 q
.fail_next_get
= True
122 raise TestFailed("The queue didn't fail when it should have")
123 except FailingQueueException
:
125 verify(not q
.empty(), "Queue should not be empty")
127 verify(q
.empty(), "Queue should be empty")
128 q
.fail_next_get
= True
130 _doBlockingTest( q
.get
, (), q
.put
, ('empty',))
131 raise TestFailed("The queue didn't fail when it should have")
132 except FailingQueueException
:
134 # put succeeded, but get failed.
135 verify(not q
.empty(), "Queue should not be empty")
137 verify(q
.empty(), "Queue should be empty")
139 def SimpleQueueTest(q
):
141 raise RuntimeError, "Call this function with an empty queue"
142 # I guess we better check things actually queue correctly a little :)
145 verify(q
.get() == 111 and q
.get() == 222,
146 "Didn't seem to queue the correct data!")
147 for i
in range(queue_size
-1):
149 verify(not q
.full(), "Queue should not be full")
151 verify(q
.full(), "Queue should be full")
153 q
.put("full", block
=0)
154 raise TestFailed("Didn't appear to block with a full queue")
158 q
.put("full", timeout
=0.1)
159 raise TestFailed("Didn't appear to time-out with a full queue")
162 # Test a blocking put
163 _doBlockingTest( q
.put
, ("full",), q
.get
, ())
164 _doBlockingTest( q
.put
, ("full", True, 0.2), q
.get
, ())
166 for i
in range(queue_size
):
168 verify(q
.empty(), "Queue should be empty")
171 raise TestFailed("Didn't appear to block with an empty queue")
176 raise TestFailed("Didn't appear to time-out with an empty queue")
179 # Test a blocking get
180 _doBlockingTest(q
.get
, (), q
.put
, ('empty',))
181 _doBlockingTest(q
.get
, (True, 0.2), q
.put
, ('empty',))
184 q
=Queue
.Queue(queue_size
)
185 # Do it a couple of times on the same queue
189 print "Simple Queue tests seemed to work"
190 q
= FailingQueue(queue_size
)
194 print "Failing Queue tests seemed to work"