blob: a75d2660c9a1bca463fc3e9372b1e25f6edefd61 [file] [log] [blame]
Dan Talaycoea8ad802010-02-22 20:30:18 -08001
2"""
3Utilities for the OpenFlow test framework
4"""
5
6import random
Rich Laneb64ce3d2012-07-26 15:37:57 -07007import time
Rich Lane4dfd5e12012-12-22 19:48:01 -08008import os
Dan Talaycoea8ad802010-02-22 20:30:18 -08009
Rich Lanee55abf72012-07-26 20:11:42 -070010default_timeout = None # set by oft
11
Dan Talaycoea8ad802010-02-22 20:30:18 -080012def gen_xid():
13 return random.randrange(1,0xffffffff)
Rich Laneb64ce3d2012-07-26 15:37:57 -070014
15"""
16Wait on a condition variable until the given function returns non-None or a timeout expires.
17The condition variable must already be acquired.
Rich Lane8806bc42012-07-26 19:18:37 -070018The timeout value -1 means use the default timeout.
Rich Laneb64ce3d2012-07-26 15:37:57 -070019There is deliberately no support for an infinite timeout.
20TODO: get the default timeout from configuration
21"""
Rich Lane8806bc42012-07-26 19:18:37 -070022def timed_wait(cv, fn, timeout=-1):
23 if timeout == -1:
24 # TODO make this configurable
Rich Lanee55abf72012-07-26 20:11:42 -070025 timeout = default_timeout
Rich Lane8806bc42012-07-26 19:18:37 -070026
Rich Laneb64ce3d2012-07-26 15:37:57 -070027 end_time = time.time() + timeout
28 while True:
Rich Laneb64ce3d2012-07-26 15:37:57 -070029 val = fn()
30 if val != None:
31 return val
32
33 remaining_time = end_time - time.time()
34 cv.wait(remaining_time)
Rich Lane8806bc42012-07-26 19:18:37 -070035
36 if time.time() > end_time:
37 return None
Rich Lane4dfd5e12012-12-22 19:48:01 -080038
39class EventDescriptor():
40 """
41 Similar to a condition variable, but can be passed to select().
42 Only supports one waiter.
43 """
44
45 def __init__(self):
46 self.pipe_rd, self.pipe_wr = os.pipe()
47
48 def __del__(self):
49 os.close(self.pipe_rd)
50 os.close(self.pipe_wr)
51
52 def notify(self):
53 os.write(self.pipe_wr, "x")
54
55 def wait(self):
56 os.read(self.pipe_rd, 1)
57
58 def fileno(self):
59 return self.pipe_rd