[FIX] Handle timeout in UI tests

bzr revid: ddm@openerp.com-20131223100003-h8qhzmk61dz9bzon
This commit is contained in:
ddm
2013-12-23 11:00:03 +01:00
parent cd0913cb6a
commit 726fd3f2bc
2 changed files with 85 additions and 21 deletions
+68 -21
View File
@@ -1,8 +1,10 @@
import json
import subprocess
import unittest
import subprocess
import os
import select
import time
import json
from openerp import tools
ROOT = os.path.join(os.path.dirname(__file__), 'ui_suite')
@@ -11,6 +13,26 @@ __all__ = ['load_tests', 'WebsiteUiSuite']
def _exc_info_to_string(err, test):
return err
class LineReader(object):
def __init__(self, fd):
self._fd = fd
self._buf = ''
def fileno(self):
return self._fd
def readlines(self):
data = os.read(self._fd, 4096)
if not data:
# EOF
return None
self._buf += data
if '\n' not in data:
return []
tmp = self._buf.split('\n')
lines, self._buf = tmp[:-1], tmp[-1]
return lines
class WebsiteUiTest(unittest.TestCase):
def __init__(self, name):
self.name = name
@@ -20,7 +42,8 @@ class WebsiteUiTest(unittest.TestCase):
return self.name
class WebsiteUiSuite(unittest.TestSuite):
def __init__(self, testfile, timeout=5000):
# timeout is in seconds
def __init__(self, testfile, timeout=5):
self.testfile = testfile
self.timeout = timeout
self._test = None
@@ -31,9 +54,12 @@ class WebsiteUiSuite(unittest.TestSuite):
def run(self, result):
# Test if phantom is correctly installed
try:
subprocess.call(['phantomjs', '-v'],
stdout=open(os.devnull, 'w'),
stderr=subprocess.STDOUT)
subprocess.call([
'phantomjs',
'-v'
],
stdout=open(os.devnull, 'w'),
stderr=subprocess.STDOUT)
except OSError:
test = WebsiteUiTest('UI Tests')
result.startTest(test)
@@ -48,24 +74,45 @@ class WebsiteUiSuite(unittest.TestSuite):
del result._exc_info_to_string
def _run(self, result):
self._test = WebsiteUiTest(self.testfile)
self.start_time = time.time()
phantomOptions = json.dumps({
'timeout': self.timeout,
'port': tools.config['xmlrpc_port']
})
phantom = subprocess.Popen([
'phantomjs',
os.path.join(ROOT, self.testfile),
json.dumps({ 'timeout': self.timeout })
], stdout=subprocess.PIPE)
phantomOptions
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
self._test = WebsiteUiTest(self.testfile)
proc_stdout = LineReader(phantom.stdout.fileno())
readable = [proc_stdout]
last_check_time = time.time()
try:
while True:
line = phantom.stdout.readline()
if line:
# the runner expects only one result per test
self.process(line, result)
result.stopTest(self._test)
break
else:
time.sleep(0.1)
while readable and last_check_time < self.start_time + self.timeout:
ready, _, _ = select.select(readable, [], [], 0)
if not ready:
last_check_time = time.time()
continue
for stream in ready:
lines = stream.readlines()
if lines is None:
# got EOF on this stream
readable.remove(stream)
break;
for line in lines:
# the runner expects only one output line
self.process(line, result)
break
if last_check_time >= (self.start_time + self.timeout):
result.addError(self._test, "Timeout after %s s" % (last_check_time - self.start_time ))
result.stopTest(self._test)
finally:
# kill phantomjs if phantom.exit() wasn't called in the test
if phantom.poll() is None:
@@ -81,12 +128,11 @@ class WebsiteUiSuite(unittest.TestSuite):
result.startTest(self._test)
try:
args = json.loads(line)
event = args.get('event')
message = args.get('message', "")
event = args.get('event', None)
if event == 'success':
result.addSuccess(self._test)
elif event == 'failure':
message = args.get('message', "")
result.addFailure(self._test, message)
else:
result.addError(self._test, "Unexpected message: %s" % line)
@@ -95,4 +141,5 @@ class WebsiteUiSuite(unittest.TestSuite):
def load_tests(loader, base, _):
base.addTest(WebsiteUiSuite('sample_test.js'))
base.addTest(WebsiteUiSuite('banner_tour.js'))
return base
@@ -0,0 +1,17 @@
var options = JSON.parse(phantom.args);
var page = require('webpage').create();
var url = 'http://localhost:'+options.port;
page.open(url, function (status) {
if (status !== 'success') {
console.log('{ "event": "failure", "message": "'+url+' failed to load"}');
phantom.exit();
} else {
page.evaluate(function() {
$(document).on("tour:ready", function () {
openerp.website.TestConsole.test('banner').run(true)
console.log('{ "event": "success" }');
phantom.exit();
});
});
}
});