Commit ac1ea4e6 authored by Daniel Brown's avatar Daniel Brown
Browse files

added view of previous tests run and test rerun functionality, will reuse...

added view of previous tests run and test rerun functionality, will reuse Finesse build if available and just process the kats
parent 82f4c06f
......@@ -14,7 +14,7 @@ import time
import pickle
from datetime import datetime
from pykat.testing import utils
import sys
import sys, traceback
class RunException(Exception):
def __init__(self, returncode, args, err, out):
......@@ -53,11 +53,12 @@ class FinesseTestProcess(Thread):
running_kat = ""
running_suite = ""
cancelling = False
errorOccurred = None
def __init__(self, TEST_DIR, BASE_DIR, test_commit,
run_fast=False, suites=[], test_id="0",
git_bin="",emails="", nobuild=True,*args, **kqwargs):
Thread.__init__(self)
self.git_commit = test_commit
......@@ -224,12 +225,10 @@ class FinesseTestProcess(Thread):
run_times[suite] = {}
os.chdir(os.path.join(self.TEST_DIR,"kat_test",suite))
print suite
for files in os.listdir("."):
if files.endswith(".kat"):
self.total_kats += 1
print self.total_kats
for suite in self.suites:
self.cancelCheck()
......@@ -321,7 +320,7 @@ class FinesseTestProcess(Thread):
ix = np.where(rel_diff >= self.diff_rel_eps)[0][0]
output_differences[suite][out] = (ref_arr[ix], out_arr[ix], np.max(rel_diff))
os.chdir(BASE_DIR)
os.chdir(self.BASE_DIR)
if not os.path.exists("reports"):
os.mkdir("reports")
......@@ -385,9 +384,14 @@ class FinesseTestProcess(Thread):
def run(self):
try:
self.startFinesseTest()
except Exception as ex:
exc_type, exc_value, exc_traceback = sys.exc_info()
errorOccurred = dict(type=exc_type, value=exc_value, traceback=exc_traceback)
print "*** Exception for test_id = " + str(self.test_id)
traceback.print_exception(exc_type, exc_value, exc_traceback,
limit=5, file=sys.stdout)
finally:
finished_test = True
......
import subprocess as sub
import os
GIT_BIN = "/usr/bin/git"
try:
GIT_BIN = os.environ["GIT_BIN"]
except:
GIT_BIN = "/usr/bin/git"
print "GIT_BIN = " + GIT_BIN
class RunException(Exception):
def __init__(self, returncode, args, err, out):
self.returncode = returncode
......@@ -23,7 +28,7 @@ def git(args, git_bin=GIT_BIN):
print os.getcwd()
p = sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE,shell=True)
p = sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE)
out, err = p.communicate()
if p.returncode != 0:
......
<!DOCTYPE html>
<html>
<head>
<!--<link rel="stylesheet" type="text/css" href="/css/style.css"/>-->
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"/>
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css">
</head>
<body>
......@@ -35,35 +35,48 @@
</table>
</div>
<div class="new_test">
<h2>Start new test</h2>
<select id="branch_list" style="width: 100px;">
<option text="develop" value="develop"/>
</select>
<select id="commit_list" style="width: 300px;">
</select>
<input type="button" value="Refresh" id="btnGetLogs"/>
<div class="new_test">
<h2>Start new test</h2>
<select id="branch_list" style="width: 100px;">
<option text="develop" value="develop"/>
</select>
<select id="commit_list" style="width: 300px;">
</select>
<input type="button" value="Refresh" id="btnGetLogs"/>
<input type="button" value="Start new FINESSSE test" id="btnStartTest"/>
</div>
<input type="button" value="Start new FINESSSE test" id="btnStartTest"/>
<div class="prev_test">
<h2>Previous Tests</h2>
<input type="button" value="Refresh" id="btnGetPrevTests"/>
<div id="tblPrevTests" />
</div>
</div>
<script type="text/JavaScript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/JavaScript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
<script type="text/JavaScript">
$(document).ready(function(){
updateBranches();
getPreviousTests();
window.setInterval(function(){
updateQueuedTests();
updateProgress();
}, 1000);
});
$('#btnGetPrevTests').click(function(){
getPreviousTests();
});
$( "#current_test_progress" ).progressbar({
......@@ -94,6 +107,66 @@
updateProgress();
});
function getPreviousTests() {
$.ajax({
type: "POST",
url: "/finesse/get_100_prev_tests",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: buildPreviousTestTable,
error: function(o,a,err){
alert("Error getting previous tests : " + err);
}
});
}
function buildPreviousTestTable(data) {
var tbl = $('#tblPrevTests');
tbl.html('<table cellpadding="0" cellspacing="0" border="0" id="bTable" class="style1 datatable"></table>');
gtable = $('#bTable').dataTable({
"bPaginate": true,
"sPaginationType": "full_numbers",
"bAutoWidth": true,
"bLengthChange": true,
"aaData": data.tests,
"bJQueryUI": true,
"aoColumns": [
{
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
var a = $('<button type="button" style="margin: 0">View</button>').button().on('click', function () {
});
var b = $('<button type="button" style="margin: 0">Rerun</button>').button().on('click', function () {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/finesse/rerun_test_" + oData["test_id"],
success: function () {
updateQueuedTests();
updateProgress();
},
error: function(jqXHR, textStatus, err){
console.log('error: ' + err);
},
dataType: "json"
});
});
$(nTd).empty();
$(nTd).append(a);
$(nTd).append(b);
}, "mDataProp": "test_id", "sWidth": "30%", "bSearchable": false, "sTitle": "", "bSortable": false
},
{ "mDataProp": "test_id", "sTitle": "Test ID","bSearchable": true, "bVisible": true, "sClass": "center" },
{ "mDataProp": "git_commit", "sTitle": "Git Commit", "bSearchable": true, "bVisible": true, "sClass": "center" },
{ "mDataProp": "startTime", "sTitle": "Start Time", "bSearchable": false, "bVisible": true, "sClass": "center" },
{ "mDataProp": "endTime", "sTitle": "End Time", "bSearchable": false, "bVisible": true, "sClass": "center" }
]
});
}
function updateProgress(){
$.ajax({
......
......@@ -13,7 +13,12 @@ from pykat.testing import test as finesse_test
import shutil
from pykat.testing.web import app
import os
from CodernityDB.database_thread_safe import ThreadSafeDatabase
from CodernityDB.database import RecordNotFound
from hashlib import md5
from pykat.testing.web.database_indices import TestIDIndex
import os, sys
global current_test, scheduled_tests, schedule_lock
......@@ -23,8 +28,51 @@ scheduled_tests = []
schedule_lock = Lock()
watcher = None
print "Starting up database"
DB_PATH = os.path.join(app.instance_path,"db")
db = ThreadSafeDatabase(DB_PATH)
if db.exists():
db.open()
print db.get_db_details()
print "Reindexing..."
db.reindex()
print "Done reindexing"
# update the test_id from the previous tests that have been run
for a in db.all('testid'):
key = int(a['key'])
if key > test_id:
test_id = key
print "Current test_id: " + str(test_id)
else:
db.create()
db.add_index(TestIDIndex(db.path, 'testid'))
print "loading web interface"
# should be called with the correct locks already
# applied
def __run_new(test):
global current_test,watcher,scheduled_tests
# check if anything is running and if it
# isn't start this test off
if current_test is None:
print "running test"
current_test = test
# create watcher thread which will start the test
watcher = FinesseProcessWatcher()
watcher.setProcessToWatch(test)
watcher.start()
else:
print "queuing test"
scheduled_tests.append(test)
class FinesseProcessWatcher(Thread):
process_to_watch = None
......@@ -48,10 +96,20 @@ class FinesseProcessWatcher(Thread):
# raise Exception("Tried to watch something which wasn't a FinesseTestProcess")
print "Watcher is watching", self.process_to_watch
start = datetime.now()
self.process_to_watch.start()
self.process_to_watch.join()
print "Watcher is continuing"
doc = db.get('testid', self.process_to_watch.test_id,with_doc=True)["doc"]
doc["cancelled"] = self.process_to_watch.cancelling
doc["error"] = self.process_to_watch.errorOccurred
doc["startTime"] = str(start)
doc["endTime"] = str(datetime.now())
db.update(doc)
try:
# once done check if any other tests need to be ran
schedule_lock.acquire()
......@@ -82,11 +140,8 @@ def finesse_cancel_test(id):
# get lock here so that watcher doesn't interfere
# with removing/starting new tests
schedule_lock.acquire()
print current_test
if current_test is not None:
print "cid " + str(current_test.test_id)
if current_test.test_id == id:
current_test.cancelling = True
print "Cancelling Current Test"
......@@ -103,6 +158,7 @@ def finesse_cancel_test(id):
if remove > -1:
print "Cancelled queued test"
scheduled_tests[remove].cancelling = True
scheduled_tests.pop(remove)
return str(id)
......@@ -115,6 +171,49 @@ def finesse_cancel_test(id):
def home_page():
return render_template("finesse_test.html")
@app.route('/finesse/rerun_test_<id>', methods=["POST"])
def finesse_start_rerun(id):
id = int(id)
try:
schedule_lock.acquire()
test_prev_doc = db.get('testid', id, with_doc=True)["doc"]
if "rerun" in test_prev_doc:
test_prev_doc["rerun"] += 1
else:
test_prev_doc["rerun"] = 1
db.update(test_prev_doc)
TEST_OUTPUT_PATH = os.path.join(app.instance_path, "tests")
if not os.path.exists(TEST_OUTPUT_PATH):
raise Exception("Output path for rerun of test " + id + " does not exist")
TEST_RUN_PATH_OLD = os.path.join(TEST_OUTPUT_PATH, str(id))
TEST_RUN_PATH = os.path.join(TEST_OUTPUT_PATH, str(id) + "_rerun_" + str(test_prev_doc["rerun"]))
if not os.path.exists(TEST_RUN_PATH_OLD):
NOBUILD = True
shutil.copytree(os.path.join(TEST_RUN_PATH_OLD,"build"), os.path.join(TEST_RUN_PATH,"build"))
else:
NOBUILD = False
test = finesse_test.FinesseTestProcess(os.path.join(app.instance_path, "finesse_test"),
TEST_RUN_PATH,
test_prev_doc["git_commit"],
run_fast=True, suites=[], test_id=id,
emails="", nobuild=NOBUILD)
__run_new(test)
finally:
schedule_lock.release()
return "ok"
@app.route('/finesse/start_test', methods=["POST"])
def finesse_start_test():
global current_test, test_id
......@@ -125,15 +224,12 @@ def finesse_start_test():
test_id += 1
git_commit = request.json['git_commit']
print app.instance_path
TEST_OUTPUT_PATH = os.path.join(app.instance_path, "tests")
if not os.path.exists(TEST_OUTPUT_PATH):
os.mkdir(TEST_OUTPUT_PATH)
TEST_RUN_PATH = os.path.join(TEST_OUTPUT_PATH, str(test_id))
print TEST_RUN_PATH
if os.path.exists(TEST_RUN_PATH):
shutil.rmtree(TEST_RUN_PATH)
......@@ -143,21 +239,16 @@ def finesse_start_test():
test = finesse_test.FinesseTestProcess(os.path.join(app.instance_path, "finesse_test"),
TEST_RUN_PATH,
git_commit,
run_fast=False, suites=[], test_id=test_id,
run_fast=True, suites=[], test_id=test_id,
emails="", nobuild=False)
# check if anything is running and if it
# isn't start this test off
if current_test is None:
print "running test"
current_test = test
# create watcher thread which will start the test
watcher = FinesseProcessWatcher()
watcher.setProcessToWatch(test)
watcher.start()
else:
print "queuing test"
scheduled_tests.append(test)
db.insert(dict(t="test",
test_id=test.test_id,
git_commit=test.get_version(),
cancelled=test.cancelling,
error=test.errorOccurred))
__run_new(test)
finally:
schedule_lock.release()
......@@ -244,5 +335,51 @@ def finesse_get_log(count,branch):
return jsonify(logs=log2send)
\ No newline at end of file
@app.route('/finesse/get_<count>_prev_tests', methods=["POST"])
def finesse_get_prev_tests(count):
global test_id
rtn = list()
max = test_id
min = max - int(count)
if min < 0:
min = 0
if min > max:
min = max
try:
data = db.all('testid',with_doc=True)
#db.get_many('testid',start=min,end=max,limit=-1, with_doc=True)
for a in data:
i = a["doc"]
err = (not i['error'] is None)
if "startTime" in i:
startTime = i["startTime"]
else:
startTime = ""
if "endTime" in i:
endTime = i["endTime"]
else:
endTime = ""
obj = dict(test_id=i['test_id'],
git_commit=i['git_commit'],
error=err,
startTime=startTime,
endTime=endTime)
rtn.append(obj)
return jsonify(tests=rtn)
except RecordNotFound:
print "exception"
return jsonify(test=rtn)
\ No newline at end of file
import os
import sys
from flask import Flask
from pykat.testing import utils
from optparse import OptionParser
def start(instance_path,port=5000, debug=True, ip="0.0.0.0"):
global app
def start(instance_path,port=5000, debug=True, ip="0.0.0.0", git_bin="/usr/bin/git"):
os.environ["GIT_BIN"] = git_bin
# we import this now so that we can set the GIT_BIN env var
from pykat.testing import utils
print "starting web server..."
......@@ -42,36 +45,20 @@ def start(instance_path,port=5000, debug=True, ip="0.0.0.0"):
utils.git(["clone","git://gitmaster.atlas.aei.uni-hannover.de/finesse/test.git","finesse_test"])
app.secret_key = os.urandom(24)
app.run(debug=debug, port=int(port), host=ip)
app.run(debug=debug, port=int(port), host=ip,use_reloader=False)
if __name__ == "__main__":
n = len(sys.argv)
if n != 2 and n != 3:
print """
Command starts a Flask based website on which allows
users to manage the FINESSE test builds.
start_test_server usage:
python -m pykat.testing.web_server <server_path> <port>
Arguments:
server_path: Directory where website should be run from
port: TCP port which the server should run under
default is port 5000.
"""
exit()
instance_path = sys.argv[1]
parser = OptionParser()
if n == 3:
port = sys.argv[2]
else:
port = 5000
parser.add_option("-P","--path",type="string",dest="instance_path",help="")
parser.add_option("-p","--port",type="int",default=5000,dest="port",help="")
parser.add_option("-g","--git-bin",type="string",default="/usr/bin/git",dest="git_bin",help="")
start(instance_path, port=port)
options, args = parser.parse_args()
if options.instance_path is None:
print "Must specify a path for the web server"
exit()
start(options.instance_path, port=options.port, git_bin=options.git_bin )
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment