def wait_until_element_changes(self, interval='5s', timeout='180s', error_on_timeout=False): """ Wait until the marked element has been changed """ timeout_sec = DateTime.convert_time(timeout) name = self._current_name count = 0 id = self._browsers[name]['mark_element_id'] xpath = self._browsers[name]['mark_element_xpath'] element = self._selenium.get_webelement(xpath) element_id = element.id while count < timeout_sec and element_id == id: BuiltIn().log_to_console('.', 'STDOUT', True) delta = DateTime.convert_time(interval) time.sleep(delta) count += delta element_count = self._selenium.get_element_count(xpath) if element_count > 0: element = self._selenium.get_webelement(xpath) element_id = element.id else: element_id = -1 if count >= timeout_sec: BuiltIn().log('Timeout happened but element is still not changed') if error_on_timeout: raise Exception( 'ERR: Timeout while waiting for element status changed') BuiltIn().log('Waited for element status changed')
def wait_until_finish(self,interval='30s',timeout=u'30m',verbose=False): """ Waits until the test finished or timeout *Notes*: This is a blocking keyword """ step = DateTime.convert_time(interval) BuiltIn().log("Wait (max=%s) until the test finished" % timeout) if not self._test_id: BuiltIn().log("WARN: No running test") else: cli = self._clients[self._cur_name] ix = cli['connection'] count = 0 wait_time = DateTime.convert_time(timeout) progress = 0 service = self._base_url + '/bps/tests/operations/getrts' data = {'runid':self._test_id} while progress < 100.0 and count < wait_time: result = ix.post(service,json=data,verify=False) if result.status_code != requests.codes.ok: BuiltIn().log(result.text) raise Exception('ERROR: could not get status of the test') # BuiltIn().log(result.json()) progress = int(result.json().get('progress')) time.sleep(step) count += step if verbose: BuiltIn().log("progress = %d%%" % progress) BuiltIn().log_to_console("progress = %d%%" % progress) else: BuiltIn().log_to_console('.','STDOUT',True) BuiltIn().log("The tested finished in %d second" % (count))
def get_current_datetime(self, time_format='%H:%M:%S', delta_time='0s', dir='+', **kwargs): """ Returns the current date time with vendor format ``delta_time`` will be added or subtracted to current time, default is ``0s`` ``time_format`` decides the time part of the output. Example result are : | May 24 04:14:25 | May 4 04:14:25 *Note:* The date part is padded by space, and the result is allways 15 characters """ delta = DateTime.convert_time(delta_time) if dir == '-': current_time = datetime.now() - timedelta(seconds=delta) else: current_time = datetime.now() + timedelta(seconds=delta) padded_day = datetime.strftime(current_time, "%d").rjust(2) format = "%%b %s %s" % (padded_day, time_format) result = datetime.strftime(current_time, format) BuiltIn().log("Got current datetime and convert to Juniper format") return result
def tcpdump(self, params, timeout=''): """ Uses tcpdump (for packet capture) and wait The keyword ignores detail output of the command """ BuiltIn().log('Run tcpdump command') cmd = 'sudo tcpdump ' + params proc1 = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setpgrp) # proc1 = subprocess.Popen(cmd,shell=True,stderr=subprocess.STDOUT,preexec_fn=os.setpgrp) if timeout != '': time.sleep(DateTime.convert_time(timeout)) # output1 = proc1.stdout.readline() # output2 = subprocess.check_output('sudo kill %s' % proc1.pid,stderr=subprocess.STDOUT,shell=True) output2 = subprocess.check_output('sudo kill %s' % proc1.pid, shell=True) output1 = b'\n'.join(proc1.stdout.readlines()) time.sleep(1) BuiltIn().log(output1) # BuiltIn().log(output2) BuiltIn().log('Executed tcpdump command')
def tcpdump_to_file(self, filename='capture.pcap', params='', timeout='10s'): """ Uses tcpdump (for packet capture) and wait The keyword ignores detail output of the command. By default, the keyword only captures 10s """ BuiltIn().log('Run tcpdump command') result_file = '%s/%s' % (Common.get_result_path(), filename) cmd = 'sudo tcpdump %s -w %s' % (params, result_file) proc1 = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setpgrp) time.sleep(DateTime.convert_time(timeout)) output2 = subprocess.check_output('sudo kill %s' % proc1.pid, shell=True) output1 = b'\n'.join(proc1.stdout.readlines()) # change owner of the captured file username = Common.current_username() usergroup = Common.current_usergroup() output = subprocess.check_output('sudo chown %s:%s %s' % (username, usergroup, result_file), shell=True) time.sleep(1) BuiltIn().log(output1) BuiltIn().log('Executed tcpdump command `%s`' % cmd)
def _with_reconnect(keyword, self, *args, **kwargs): """ local method that provide a fail safe reconnect when read/write """ max_count = int(Common.GLOBAL['default']['max-retry-for-connect']) interval = DateTime.convert_time( Common.GLOBAL['default']['interval-between-retry']) count = 0 while count < max_count: try: return keyword(self, *args, **kwargs) except (RuntimeError, EOFError, OSError, KeyError, SSHException) as err: BuiltIn().log('Error while trying keyword `%s`' % keyword.__name__) count = count + 1 if count < max_count: BuiltIn().log(' Try reconnection %d(th) after %d seconds ' % (count, interval)) BuiltIn().log_to_console('.', 'STDOUT', True) time.sleep(interval) self.reconnect(self._current_name) else: err_msg = "ERROR: error while processing command. Tunning ``terminal-timeout`` in RENAT config file or check your command" BuiltIn().log(err_msg) BuiltIn().log("ErrorType: %s" % type(err)) BuiltIn().log("Detail error is:") BuiltIn().log(err) BuiltIn().log(traceback.format_exc()) raise
def wait_until_connected(self, timeout_str='5m'): """ Waits until ports become enabled and connected """ BuiltIn().log("Waiting for all ports become enable ...") timeout = DateTime.convert_time(timeout_str) cli = self._clients[self._cur_name] ix = cli['connection'] count = 0 port_ok = False while not port_ok and count < timeout: try: BuiltIn().log(" checking port status ...") vport_list = ix.getList(ix.getRoot(), 'vport') port_ok = len(vport_list) > 0 for port in vport_list: state = ix.getAttribute(port, '-isConnected') port_ok = port_ok and (state == 'true') except IxNetwork.IxNetError as err: port_ok = False BuiltIn().log("err type %s" % type(err)) BuiltIn().log(err) raise Exception("ERROR: errors found on ixnetwork ports") time.sleep(5) count = count + 5 if (count >= timeout): raise Exception("ERROR: errors found on ixnetwork ports") BuiltIn().log("Finished checking ports, state is %s (%d seconds elapsed)" % (port_ok, count)) return port_ok
def wait_cmd(self, exec_id, timeout=u'0s'): """ Waits until a background command finishes or timeout """ time_s = DateTime.convert_time(timeout) thread = self._cmd_threads[exec_id]['thread'] thread.join(time_s) BuiltIn().log("Waited until cmd thread finished")
def stop_test(self,wait=u'5s'): """ Stops a running test """ cli = self._clients[self._cur_name] ix = cli['connection'] if self._test_id: service = self._base_url + '/bps/tests/operations/stop' data = {'testid':self._test_id} result = ix.post(service,json=data,verify=False) if result.status_code != requests.codes.ok: BuiltIn().log(result.text) raise Exception('ERROR: could not stop test `%s`' % self._test_id) else: BuiltIn().log('No runnning test') time.sleep(DateTime.convert_time(wait)) if 'real-port' in Common.LOCAL['tester'][self._cur_name]: ports = Common.LOCAL['tester'][self._cur_name]['real-port'] service = self._base_url + '/bps/ports/operations/unreserve' for item in ports: payload = {'slot':item['card'],'portList':[item['port']]} result = ix.post(service,json=payload,verify=False) if result.status_code != requests.codes.ok: BuiltIn().log(result.text) raise Exception('ERROR: could not release ports `%s`' %json.dumps(payload)) BuiltIn().log(' Unreserved port `%s:%s`' % (item['card'],item['port'])) BuiltIn().log("Stopped `%s` test and released ports" % self._test_id)
def click_button_menu(self,menu,delay=u'10s'): """ Clicks the `menu` button """ xpath = '//button[normalize-space(.)="%s"]' % menu self._selenium.click_element(xpath) time.sleep(DateTime.convert_time(delay)) BuiltIn().log('Clicked on FIC menu button `%s`' % menu)
def set_ajax_wait(self, wait_time='2s'): """ Set the ajax wait time """ old_value = self._ajax_wait self._ajax_wait = DateTime.convert_time(wait_time) BuiltIn().log("Set the ajax wait_time to `%d` seconds") return old_value
def cmd_and_wait_for(self, command, keyword, interval='30s', max_num=10, error_with_max_num=True): """ Execute a command and expect ``keyword`` occurs in the output. If not wait for ``interval`` and repeat the process again After ``max_num``, if ``error_with_max_num`` is ``True`` then the keyword will fail. Ortherwise the test continues. """ num = 1 BuiltIn().log("Execute command `%s` and wait for `%s`" % (command, keyword)) while num <= max_num: BuiltIn().log(" %d: command is `%s`" % (num, command)) output = self.cmd(command) if keyword in output: BuiltIn().log("Found keyword `%s` and stopped the loop" % keyword) break else: num = num + 1 time.sleep(DateTime.convert_time(interval)) BuiltIn().log_to_console('.', 'STDOUT', True) if error_with_max_num and num > max_num: msg = "ERROR: Could not found keyword `%s`" % keyword BuiltIn().log(msg) raise Exception(msg) BuiltIn().log("Executed command `%s` and waited for keyword `%s`" % (command, keyword))
def pause(msg="", time_out='3h', error_on_timeout=True, default_input=''): """ Displays the message ``msg`` and pauses the test execution and wait for user input In case of ``error_on_timeout`` is True(default), the keyword will raise an error when timeout occurs. Otherwise, it will continue the test. *Notes:* If the variable ``${RENAT_BATCH}`` was defined, the keyword will print out the message and keeps running without pausing. Examples: | Common.`Pause` | Waiting... | 10s | error_on_timeout=${TRUE} | default input | | Common.`Pause` | Waiting... | 10s | """ BuiltIn().log("Pause and wait `%s` for user input" % time_out) BuiltIn().log_to_console(msg) input = None wait = DateTime.convert_time(time_out) renat_batch = BuiltIn().get_variable_value('${RENAT_BATCH}') if renat_batch is None: i, o, e = select.select([sys.stdin], [], [], wait) if i: input = sys.stdin.readline().strip() BuiltIn().log("User input detected. Input was `%s`" % input) else: if not error_on_timeout: input = default_input BuiltIn().log("Pause finished with time out. Input was `%s`" % input) else: raise Exception("ERROR: timeout while waiting for user input") else: BuiltIn().log("Pausing is ignored in batch mode") return input
def go_to_page(self, page, wait_time='5s'): """ Goto a page within this site The site is assumed the location defined by login-url by default or by `Set Site keyword """ url = '%s/%s' % (self._site, page) self._selenium.go_to(url) time.sleep(DateTime.convert_time(wait_time)) BuiltIn().log("Went to page %s" % url)
def to_time(time): total_seconds = DateTime.convert_time(time, result_format='number') seconds, fraction = divmod(total_seconds, 1) minutes, second = divmod(seconds, 60) hour, minute = divmod(minutes, 60) return datetime.time(hour=int(hour), minute=int(minute), second=int(second), microsecond=int(fraction * 1000000))
def menu(self, order, wait='2s', capture_all=False, prefix='menu_', suffix='.png', partial_match=False): """ Access to Arbor menu Parameters - ``order`` is the list of top menu items separated by '/' - ``wait`` is the wait time after the last item is clicked - if ``capture_all`` is ``True`` then a screenshot is captured for each menu item automtically. In this case, the image file is appended by ``prefix`` and ``suffix``. - by default, the system try to match the menu item in full, when ``partial_match`` is ``True``, partial match is applied. Examples: | Arbor.`Menu` | order=Alerts/Ongoing | | Arbor.`Capture Screenshot` | | Arbor.`Menu` | order=Alerts/All Alerts | | Arbor.`Capture Screenshot` | | Arbor.`Menu` | order=System/Status/Deployment Status | | Arbor.`Capture Screenshot` | | Arbor.`Menu` | order=System/Status/Signaling Status/Appliance Status | partial_match=${TRUE} | | Arbor.`Capture Screenshot` | """ self.switch(self._current_name) self.clean_status_msg() index = 0 items = order.split('/') for item in items: BuiltIn().log(" Access to menu item %s" % item) index += 1 if index > 1: menu = '//li[not(contains(@class,\'top_level\'))]' else: menu = '' if partial_match: xpath = "xpath=%s//a[contains(.,'%s')]" % (menu, item) else: xpath = "xpath=%s//a[.='%s']" % (menu, item) self._driver.mouse_over(xpath) # self._driver.click_element(xpath) time.sleep(1) # self._driver.wait_until_element_is_visible(xpath) if capture_all: capture_name = '%s%s%s' % (prefix, item, suffix) self._driver.capture_page_screenshot(capture_name) self.verbose_capture() if index == len(items): self._driver.click_link(xpath) time.sleep(DateTime.convert_time(wait))
def write(self, str_cmd, str_wait='0s', start_screen_mode=False): """ Sends ``str_cmd`` to the target node and return after ``str_wait`` time. If ``start_screen_mode`` is ``True``, the channel will be shifted to ``Screen Mode``. Default value of ``screen_mode`` is False. In ``normal mode``, a ``new line`` char will be added automatically to the ``str_cmd`` and the command return the output it could get at that time from the terminal and also logs that to the log file. In ``screen Mode``, if it is necessary you need to add the ``new line`` char by your own and the ouput is not be logged or returned from the keyword. Parameters: - ``str_cmd``: the command - ``str_wait``: time to wait after apply the command - ``start_screen_mode``: whether start the ``screen mode`` right after writes the command Special input likes Ctrl-C etc. could be used with global variable ${CTRL-<char>} Returns the output after writing the command the the channel. When `str_wait` is not `0s`, the keyword read and return the output after waiting `str_wait`. Otherwise, the keyword return with no output. *Notes:* This is a non-blocking command. Examples: | VChannel.`Write` | monitor interface traffic | start_screen_mode=${TRUE} | | VChannel.`Write` | ${CTRL_C} | # simulates Ctrl-C | """ # # self.read() wait = DateTime.convert_time(str_wait) channel = self._channels[self._current_name] if channel['screen']: screen_mode = True else: screen_mode = False if start_screen_mode: self.start_screen_mode() # because we've just start the screen mode but the node has not yet # start the screen_mode, a newline is necessary here result = self._with_reconnect(self._write, str_cmd + Common.newline, wait) else: result = self._with_reconnect(self._write, str_cmd, wait) BuiltIn().log("Screen=%s, wrote '%s'" % (screen_mode, str_cmd)) return result
def run_until_keyword_fails(retry, retry_interval, name, *args): r""" Execute a robot keyword repeatedly until it either fails or the timeout value is exceeded. Note: Opposite of robot keyword "Wait Until Keyword Succeeds". Description of argument(s): retry Max timeout time in hour(s). retry_interval Time interval in minute(s) for looping. name Robot keyword to execute. args Robot keyword arguments. """ # Convert the retry time in seconds retry_seconds = DateTime.convert_time(retry) timeout = time.time() + int(retry_seconds) # Convert the interval time in seconds interval_seconds = DateTime.convert_time(retry_interval) interval = int(interval_seconds) BuiltIn().log(timeout) BuiltIn().log(interval) while True: status = BuiltIn().run_keyword_and_return_status(name, *args) # Return if keywords returns as failure. if status is False: BuiltIn().log("Failed as expected") return False # Return if retry timeout as success. elif time.time() > timeout > 0: BuiltIn().log("Max retry timeout") return True time.sleep(interval) BuiltIn().log(time.time()) return True
def choose_left_menu(self,menu,delay=u"10s"): """ Selects FIC left menu Usable menus are: `Port`, `Router`, `Connection`, `History` """ xpath = '//button[normalize-space(.)="%s"]' % menu self._selenium.mouse_over(xpath) time.sleep(3) self._selenium.click_element(xpath) time.sleep(DateTime.convert_time(delay)) BuiltIn().log("Selected left menu `%s`" % menu)
def send_mks_cmd(self, cmd, wait=u'5s'): """ Sends command to current web console and wait for a while By default, `wait` time is ``2s`` and the keyword will automaticall add a ``Newline`` char after sending the `cmd` """ driver = BuiltIn().get_library_instance('SeleniumLibrary') driver.press_key('mainCanvas', cmd) driver.press_key('mainCanvas', "\\13") time.sleep(DateTime.convert_time(wait)) BuiltIn().log('Sent command `%s` to web console' % cmd)
def stop_repeat_cmd(self, exec_id, timeout=u'0s'): """ Stops a runnin Repeat Command by its `exec_id` - `exec_id`: an ID return when using Cmd """ time_s = DateTime.convert_time(timeout) thread = self._cmd_threads[exec_id]['thread'] stop = self._cmd_threads[exec_id]['stop'] if stop: stop.set() thread.join(time_s) BuiltIn().log("Stopped a repeated command")
def stop_all_protocols(self, wait_time='30s'): """ Stop all running protocols """ wait = DateTime.convert_time(wait_time) cli = self._clients[self._cur_name] ix = cli['connection'] ix.execute('stopAllProtocols') time.sleep(wait) BuiltIn().log("Stopped all protocols")
def start_traffic(self, wait_time='30s'): """ Starts the current traffic settiing and wait for ``wait_time``. *Note:* This is a asynchronus action. After called, traffic will take a while before start to come out, the the keyword will finish immediatly. """ wait = DateTime.convert_time(wait_time) cli = self._clients[self._cur_name] ix = cli['connection'] ix.execute('start', ix.getRoot() + 'traffic') time.sleep(wait)
def start_test(self,trial='0',timeout='5m'): """ Starts the test and wait until it finishes or timeout """ cli = self._clients[self._cur_name] avaproxy = cli['connection'] res = Common.send(avaproxy,'ava::start_test/%s' % trial) BuiltIn().log('Started the test with trial mode is `%s`' % trial) res = Common.send(avaproxy,'ava::wait_until_finish/%d' % DateTime.convert_time(timeout)) if res != 'ava::ok' : raise Exception('Error happened before the test finishes\n%s' % res) BuiltIn().log('Finished the test with result: %s' % res) return res
def start_test(self,timeout='5m'): """ Starts the test and wait until it finishes or timeout """ cli = self._clients[self._cur_name] avaproxy = cli['connection'] res = Common.send(avaproxy,'ava::start_test') BuiltIn().log('Started the test') res = Common.send(avaproxy,'ava::wait_until_finish/%d' % DateTime.convert_time(timeout)) if res != 'ava::ok' : raise 'Error happened before the test finishes `%s`' % res BuiltIn().log('Finished the test') return res
def wait_until_loaded(self,interval=u"5s",timeout=u"60s"): """ Waits until the loading icon disappear """ BuiltIn().log("Wait until the page is loaded") on_progress = True time_max= DateTime.convert_time(timeout) t = DateTime.convert_time(interval) timer = 0 progress_div = '//div[@id="ficComApiProgress"]' div_count = self._selenium.get_element_count(progress_div) on_progress = (div_count > 0) while on_progress and timer < time_max: div_count = self._selenium.get_element_count(progress_div) on_progress = (div_count > 0) BuiltIn().log(" Wait for more `%d` seconds" % t) time.sleep(t) timer += t if timer >= time_max: BuiltIn().log("WRN: timeout occurr while wating for loading finishes") # time.sleep(t) BuiltIn().log("Waited for '%d' seconds until loading finsihed" % timer)
def start_capture(self, wait_time='30s'): """ Start packet capture Target ports are set by the configuration file or by [Set Capture] keyword """ wait = DateTime.convert_time(wait_time) cli = self._clients[self._cur_name] ix = cli['connection'] ix.execute('startCapture') time.sleep(wait) BuiltIn().log("Started packet capture")
def ping_until_ok(node,wait_str='5s',extra='-c 3'): """ Ping a ``node`` until it gets response. Then wait for more ``wait_str`` Default ``extra`` option is ``-c 3`` """ device = LOCAL['node'][node]['device'] ip = GLOBAL['device'][device]['ip'] result = os.system("ping %s %s" % (extra,ip)) wait = DateTime.convert_time(wait_str) time.sleep(wait) BuiltIn().log("Pinged to host `%s(%s)` with result = %d" % (node,ip,result)) return result
def flap_interface(self,intf,time_str='10s'): """ Simulates an interface flap for interface ``intf`` Disables the interface and wait for a while before turning it up again """ self._vchannel.cmd("configure") self._vchannel.cmd("set interface " + intf + " disable") self._vchannel.cmd("commit") time.sleep(DateTime.convert_time(time_str)) self._vchannel.cmd("delete interface " + intf + " disable") self._vchannel.cmd("commit") self._vchannel.cmd("exit") BuiltIn().log("Disabled interface `%s`" % (intf))
def start_protocol(self, wait_time='1m'): """ Starts all protocols and wait for ``wait_time`` Default ``wait_time`` is 1 minute. Make sure ``wait_time`` is big engouh to start all protocols. """ cli = self._clients[self._cur_name] ix = cli['connection'] result = ix.execute('startAllProtocols') if result != '::ixNet::OK': raise Exception("Error while starting protocols: " + result) wait = DateTime.convert_time(wait_time) time.sleep(wait) # wait enough for protocol to start BuiltIn().log("Started all protocols")