Robot Framework Integrated Development Environment (RIDE)
__init__.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework 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 import time
17 
18 from robotide.lib.robot.utils import (Sortable, py2to3, secs_to_timestr, timestr_to_secs,
19  IRONPYTHON, JYTHON, WINDOWS)
20 from robotide.lib.robot.errors import TimeoutError, DataError, FrameworkError
21 
22 if JYTHON:
23  from .jython import Timeout
24 elif IRONPYTHON:
25  from .ironpython import Timeout
26 elif WINDOWS:
27  from .windows import Timeout
28 else:
29  from .posix import Timeout
30 
31 
32 @py2to3
33 class _Timeout(Sortable):
34 
35  def __init__(self, timeout=None, message='', variables=None):
36  self.stringstring = timeout or ''
37  self.messagemessage = message
38  self.secssecs = -1
39  self.starttimestarttime = -1
40  self.errorerror = None
41  if variables:
42  self.replace_variablesreplace_variables(variables)
43 
44  @property
45  active = property
46 
47  def active(self):
48  return self.starttimestarttime > 0
49 
50  def replace_variables(self, variables):
51  try:
52  self.stringstring = variables.replace_string(self.stringstring)
53  if not self:
54  return
55  self.secssecs = timestr_to_secs(self.stringstring)
56  self.stringstring = secs_to_timestr(self.secssecs)
57  self.messagemessage = variables.replace_string(self.messagemessage)
58  except (DataError, ValueError) as err:
59  self.secssecs = 0.000001 # to make timeout active
60  self.errorerror = (u'Setting %s timeout failed: %s'
61  % (self.type.lower(), err))
62 
63  def start(self):
64  if self.secssecs > 0:
65  self.starttimestarttime = time.time()
66 
67  def time_left(self):
68  if not self.activeactiveactive:
69  return -1
70  elapsed = time.time() - self.starttimestarttime
71  # Timeout granularity is 1ms. Without rounding some timeout tests fail
72  # intermittently on Windows, probably due to threading.Event.wait().
73  return round(self.secssecs - elapsed, 3)
74 
75  def timed_out(self):
76  return self.activeactiveactive and self.time_lefttime_left() <= 0
77 
78  def run(self, runnable, args=None, kwargs=None):
79  if self.errorerror:
80  raise DataError(self.errorerror)
81  if not self.activeactiveactive:
82  raise FrameworkError('Timeout is not active')
83  timeout = self.time_lefttime_left()
84  error = TimeoutError(self._timeout_error_timeout_error_timeout_error,
85  test_timeout=isinstance(self, TestTimeout))
86  if timeout <= 0:
87  raise error
88  executable = lambda: runnable(*(args or ()), **(kwargs or {}))
89  return Timeout(timeout, error).execute(executable)
90 
91  def get_message(self):
92  if not self.activeactiveactive:
93  return '%s timeout not active.' % self.type
94  if not self.timed_outtimed_out():
95  return '%s timeout %s active. %s seconds left.' \
96  % (self.type, self.stringstring, self.time_lefttime_left())
97  return self._timeout_error_timeout_error_timeout_error
98 
99  @property
100  _timeout_error = property
101 
102  def _timeout_error(self):
103  if self.messagemessage:
104  return self.messagemessage
105  return '%s timeout %s exceeded.' % (self.type, self.stringstring)
106 
107  def __unicode__(self):
108  return self.stringstring
109 
110  def __nonzero__(self):
111  return bool(self.stringstring and self.stringstring.upper() != 'NONE')
112 
113  @property
114  _sort_key = property
115 
116  def _sort_key(self):
117  return not self.activeactiveactive, self.time_lefttime_left()
118 
119  def __eq__(self, other):
120  return self is other
121 
122  def __hash__(self):
123  return id(self)
124 
125 
127  type = 'Test'
128 
131  _keyword_timeout_occurred = False
132 
133  def __init__(self, timeout=None, message='', variables=None, rpa=False):
134  if rpa:
135  self.typetypetype = 'Task'
136  _Timeout.__init__(self, timeout, message, variables)
137 
138  def set_keyword_timeout(self, timeout_occurred):
139  if timeout_occurred:
140  self._keyword_timeout_occurred_keyword_timeout_occurred_keyword_timeout_occurred = True
141 
143  return self.timed_outtimed_out() or self._keyword_timeout_occurred_keyword_timeout_occurred_keyword_timeout_occurred
144 
145 
147  type = 'Keyword'
Used when variable does not exist.
Definition: errors.py:67
Can be used when the core framework goes to unexpected state.
Definition: errors.py:59
def __init__(self, timeout=None, message='', variables=None, rpa=False)
Definition: __init__.py:133
def set_keyword_timeout(self, timeout_occurred)
Definition: __init__.py:138
def run(self, runnable, args=None, kwargs=None)
Definition: __init__.py:78
def __init__(self, timeout=None, message='', variables=None)
Definition: __init__.py:35
def secs_to_timestr(secs, compact=False)
Converts time in seconds to a string representation.
Definition: robottime.py:126
def timestr_to_secs(timestr, round_to=3)
Parses time like '1h 10s', '01:00:10' or '42' and returns seconds.
Definition: robottime.py:45