blob: 7e6044d2bff51294757326bfc8b67137f94ece4a [file] [log] [blame]
Dan Talaycoea8ad802010-02-22 20:30:18 -08001
Matteo Scandoloa229eca2017-08-08 13:05:28 -07002# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
17
Dan Talaycoea8ad802010-02-22 20:30:18 -080018"""
19Utilities for the OpenFlow test framework
20"""
21
22import random
Rich Laneb64ce3d2012-07-26 15:37:57 -070023import time
Rich Lane4dfd5e12012-12-22 19:48:01 -080024import os
Rich Lane7e1d5c52012-12-24 14:08:32 -080025import fcntl
Rich Lane2e37ec22012-12-26 09:47:39 -080026import logging
Dan Talaycoea8ad802010-02-22 20:30:18 -080027
Rich Lanee55abf72012-07-26 20:11:42 -070028default_timeout = None # set by oft
Rich Lane48f6aed2014-03-23 15:51:02 -070029default_negative_timeout = None # set by oft
Rich Lanee55abf72012-07-26 20:11:42 -070030
Dan Talaycoea8ad802010-02-22 20:30:18 -080031def gen_xid():
32 return random.randrange(1,0xffffffff)
Rich Laneb64ce3d2012-07-26 15:37:57 -070033
34"""
35Wait on a condition variable until the given function returns non-None or a timeout expires.
36The condition variable must already be acquired.
Rich Lane8806bc42012-07-26 19:18:37 -070037The timeout value -1 means use the default timeout.
Rich Laneb64ce3d2012-07-26 15:37:57 -070038There is deliberately no support for an infinite timeout.
Rich Laneb64ce3d2012-07-26 15:37:57 -070039"""
Rich Lane8806bc42012-07-26 19:18:37 -070040def timed_wait(cv, fn, timeout=-1):
41 if timeout == -1:
Rich Lanee55abf72012-07-26 20:11:42 -070042 timeout = default_timeout
Rich Lane8806bc42012-07-26 19:18:37 -070043
Rich Laneb64ce3d2012-07-26 15:37:57 -070044 end_time = time.time() + timeout
45 while True:
Rich Laneb64ce3d2012-07-26 15:37:57 -070046 val = fn()
47 if val != None:
48 return val
49
50 remaining_time = end_time - time.time()
51 cv.wait(remaining_time)
Rich Lane8806bc42012-07-26 19:18:37 -070052
53 if time.time() > end_time:
54 return None
Rich Lane4dfd5e12012-12-22 19:48:01 -080055
56class EventDescriptor():
57 """
58 Similar to a condition variable, but can be passed to select().
59 Only supports one waiter.
60 """
61
62 def __init__(self):
63 self.pipe_rd, self.pipe_wr = os.pipe()
Rich Lane7e1d5c52012-12-24 14:08:32 -080064 fcntl.fcntl(self.pipe_wr, fcntl.F_SETFL, os.O_NONBLOCK)
Rich Lane4dfd5e12012-12-22 19:48:01 -080065
66 def __del__(self):
67 os.close(self.pipe_rd)
68 os.close(self.pipe_wr)
69
70 def notify(self):
Rich Lane7e1d5c52012-12-24 14:08:32 -080071 try:
72 os.write(self.pipe_wr, "x")
73 except OSError as e:
Rich Lane2e37ec22012-12-26 09:47:39 -080074 logging.warn("Failed to notify EventDescriptor: %s", e)
Rich Lane4dfd5e12012-12-22 19:48:01 -080075
76 def wait(self):
77 os.read(self.pipe_rd, 1)
78
79 def fileno(self):
80 return self.pipe_rd