1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
###################################################################################
# LAVA QA tool
# Copyright (C) 2015 Collabora Ltd.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US
###################################################################################
import time
from lqa_api.exit_codes import SUCCESS
# Default to a 3 hours timeout
WAIT_DEFAULT_TIMEOUT="3h"
class WaitQueue(list):
"""Wait queue for jobs. It is a subclass of the list object."""
def __init__(self):
# Default queue exit code is SUCCESS which means no job in the queue failed
self._queue_exit_code = SUCCESS
def addjob(self, job, add_cb=None):
"""Add job to the wait queue."""
self.append(job)
add_cb and add_cb(self, job)
def removejob(self, job, remove_cb=None):
"""Remove job from the wait queue."""
self.remove(job)
# Update queue exit code
self._update_exit_code(job)
remove_cb and remove_cb(self, job)
def has_jobs(self):
"""Check if there are pending jobs in the wait queue."""
return len(self) > 0
def wait(self, readable_timeout=WAIT_DEFAULT_TIMEOUT,
wait_cb=None, remove_cb=None, timeout_cb=None):
"""Wait for the jobs on Submitted and Running state."""
timeout = _convert_readable_timeout_to_seconds(readable_timeout)
endtime = None
# Negative value unset the timeout.
if timeout >= 0:
endtime = time.time() + timeout
while True:
for job in self[:]:
if job.status in ['Submitted', 'Running']:
# Call the wait function (if specified).
wait_cb and wait_cb(self, job)
else:
self.removejob(job, remove_cb)
# Break if no more jobs to wait for.
if not self.has_jobs():
break
# Exit with timeout of endtime.
if endtime and time.time() > endtime:
# Call the timeout function (if specified).
timeout_cb and timeout_cb(self, timeout)
break
# Sleep for 30 seconds before polling again.
time.sleep(30)
# Return the queue.
return self
def _update_exit_code(self, job):
"""This function collates the queue exit code to the worst error code"""
ec = job.exit_code
if ec < self._queue_exit_code:
self._queue_exit_code = ec
@property
def exit_code(self):
return self._queue_exit_code
def _convert_readable_timeout_to_seconds(timeout):
"""
Supported notations:
<timeout>h = hours
<timeout>m = minutes
<timeout>s = seconds (default if not specified)
"""
# 1 minute = 60 secs
minute = 60
hour = minute * minute
return \
timeout.endswith('h') and float(timeout[:-1]) * hour or \
timeout.endswith('m') and float(timeout[:-1]) * minute or \
timeout.endswith('s') and float(timeout[:-1]) or \
float(timeout)
|