[FIX] Handle timeout in UI tests
bzr revid: ddm@openerp.com-20131223100003-h8qhzmk61dz9bzon
This commit is contained in:
@@ -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();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user