diff --git a/pykat/testing/test.py b/pykat/testing/test.py index 851331ddb0e2f0d9495d51066adb78016a7e10ae..282b1ca1580685b821c3bfc4d275db67b161fd09 100644 --- a/pykat/testing/test.py +++ b/pykat/testing/test.py @@ -42,7 +42,7 @@ def runcmd(args): class FinesseTestProcess(Thread): queue_time = None - status = "Not started" + status = "" built = False total_kats = 0 done_kats = 0 @@ -55,6 +55,7 @@ class FinesseTestProcess(Thread): cancelling = False errorOccurred = None diffFound = False + diffing = False def __init__(self, TEST_DIR, BASE_DIR, test_commit, run_fast=False, suites=[], test_id="0", @@ -125,8 +126,10 @@ class FinesseTestProcess(Thread): return self.git_commit def get_progress(self): + if self.diffing: + return 'Diffing {0} out of {1} ({2} in {3})'.format(self.done_kats, self.total_kats, self.running_kat, self.running_suite) if self.built: - return '{0} out of {1} ({2} in {3})'.format(self.done_kats, self.total_kats,self.running_kat, self.running_suite) + return 'Running {0} out of {1} ({2} in {3})'.format(self.done_kats, self.total_kats, self.running_kat, self.running_suite) else: return 'Building FINESSE executable' @@ -231,6 +234,10 @@ class FinesseTestProcess(Thread): if files.endswith(".kat"): self.total_kats += 1 + # multiply as we include the diffining in the percentage + # done + self.total_kats *= 2 + for suite in self.suites: self.cancelCheck() print "Running suite: " + suite + "..." @@ -276,6 +283,7 @@ class FinesseTestProcess(Thread): else: print "No errors whilst running" + suite + self.diffing = True # Now we have generated the output files compare them to the references for suite in self.suites: @@ -322,7 +330,9 @@ class FinesseTestProcess(Thread): # store the rows which are different 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)) - + + self.done_kats += 1 + os.chdir(self.BASE_DIR) if not os.path.exists("reports"): diff --git a/pykat/testing/utils.py b/pykat/testing/utils.py index bbf13d249e44d2e40877f686f454fbe08c06bd16..a35b6cf4e83b2b6fc0297c9fca39c4d784687496 100644 --- a/pykat/testing/utils.py +++ b/pykat/testing/utils.py @@ -14,7 +14,18 @@ class RunException(Exception): self.args = args self.err = err self.out = out - + +def runcmd(args): + p = sub.Popen(args, stdout=sub.PIPE, stderr=sub.PIPE) + out, err = p.communicate() + + if p.returncode != 0: + print "STDERR: " + err + print "STDOUT: " + out + raise RunException(p.returncode, args, err, out) + + return [out,err] + def git(args, git_bin=GIT_BIN): cmd = "" diff --git a/pykat/testing/web/database_indices.py b/pykat/testing/web/database_indices.py index 943d5cf6460defbed5f6b97f249565d25cf0bb8b..8cb506f6455fd3a0346d02aa57993e92c6d7068f 100644 --- a/pykat/testing/web/database_indices.py +++ b/pykat/testing/web/database_indices.py @@ -22,11 +22,11 @@ class SrcCommitIndex(HashIndex): def __init__(self, *args, **kwargs): kwargs['key_format'] = '40s' - super(TestIDIndex, self).__init__(*args, **kwargs) + super(SrcCommitIndex, self).__init__(*args, **kwargs) def make_key_value(self, data): if data['t'] == 'test': - key = int(data['git_commit']) + key = str(data['git_commit']) return key, None else: return None diff --git a/pykat/testing/web/templates/finesse_test.html b/pykat/testing/web/templates/finesse_test.html index 3b9b540d34ac95003605ce45ef7fa921e425943e..beb34902fb4fccd15d3efd5f71779c6e77f37279 100644 --- a/pykat/testing/web/templates/finesse_test.html +++ b/pykat/testing/web/templates/finesse_test.html @@ -28,7 +28,7 @@ <col width="20%"> <tr> <td width="">Test ID</td> - <td>Start time</td> + <td>Queue time</td> <td>Git Commit</td> <td>Cancel Test</td> </tr> diff --git a/pykat/testing/web/templates/finesse_test_view.html b/pykat/testing/web/templates/finesse_test_view.html index 2f4106e52bb7f12badab6dad19ac6ac4065d8096..fad55711811ff2523d800dd5238e5915396cd5c4 100644 --- a/pykat/testing/web/templates/finesse_test_view.html +++ b/pykat/testing/web/templates/finesse_test_view.html @@ -10,6 +10,11 @@ <h1>FINESSE Test {{ view_test_id }} View</h1> <a href="/finesse/view/{{view_test_id}}/build.log">build.log</a> | <a href="/finesse/view/{{view_test_id}}/make.log">make.log</a> + + <h3>Test Exceptions:</h3> + <pre>{{ excp_message}}</pre> + <pre>{{ excp_traceback}}</pre> + </div> </body> </html> \ No newline at end of file diff --git a/pykat/testing/web/web_interface.py b/pykat/testing/web/web_interface.py index 8c7ca0880109e6cf57c95923417aeb09fcdaf9f5..20c5cdd7ea995712ad135817280fbb04aa9e1fcd 100644 --- a/pykat/testing/web/web_interface.py +++ b/pykat/testing/web/web_interface.py @@ -1,4 +1,4 @@ -from threading import Thread, Lock +from threading import Thread, Lock, Event from time import sleep from uuid import uuid4 from flask import Flask @@ -18,7 +18,7 @@ from CodernityDB.database import RecordNotFound from pykat.testing.web.database_indices import TestIDIndex, SrcCommitIndex -import os, sys +import os, sys, traceback global current_test, scheduled_tests, schedule_lock @@ -49,12 +49,19 @@ if db.exists(): print "Current test_id: " + str(test_id) + for a in db.all('srccommit'): + print a else: db.create() db.add_index(TestIDIndex(db.path, 'testid')) - db.add_index(SrcCommitIndex(db.path, 'src_commit')) - + db.add_index(SrcCommitIndex(db.path, 'srccommit')) + +SRC_GIT_PATH = os.path.join(app.instance_path, "finesse_src",".git") +# here we select a commit one back from HEAD to see if the +# commit checker is working correctly +latest_commit_id_tested = utils.git('--git-dir {0} log -2 --pretty=format:"%H"'.format(SRC_GIT_PATH))[0].split("\n")[1] + print "loading web interface" # should be called with the correct locks already @@ -220,16 +227,17 @@ def finesse_start_rerun(id): return "ok" @app.route('/finesse/start_test', methods=["POST"]) -def finesse_start_test(): +def finesse_start_test(git_commit): + return jsonify(__finesse_start_test(request.json["git_commit"])) + +def __finesse_start_test(git_commit): global current_test, test_id try: schedule_lock.acquire() test_id += 1 - - git_commit = request.json['git_commit'] - + TEST_OUTPUT_PATH = os.path.join(app.instance_path, "tests") if not os.path.exists(TEST_OUTPUT_PATH): os.mkdir(TEST_OUTPUT_PATH) @@ -259,7 +267,7 @@ def finesse_start_test(): finally: schedule_lock.release() - return jsonify({'id':test.test_id, 'queued': (current_test != test)}) + return {'id':test.test_id} @app.route('/finesse/get_tests', methods=["POST"]) def finesse_get_tests(): @@ -417,10 +425,20 @@ def finesse_view_make(view_test_id, log): if log == "build": log = os.path.join(TEST_PATH, "build", "build.log") - log_string = open(log).read() + + if not os.path.exists(log): + log_string = "No file found" + else: + log_string = open(log).read() elif log == "make": log = os.path.join(TEST_PATH, "build", "make.log") - log_string = open(log).read() + + if not os.path.exists(log): + log_string = "No file found" + else: + log_string = open(log).read() + else: + log_string = "No file found" response = make_response(log_string) response.headers["Content-type"] = "text/plain" @@ -429,16 +447,93 @@ def finesse_view_make(view_test_id, log): else: return "" + @app.route('/finesse/view/<view_test_id>/', methods=["GET"]) def finesse_view(view_test_id): - view_test_id = view_test_id + #try: + + view_test_id = int(view_test_id) + + doc = db.get('testid',view_test_id,with_doc=True) + + doc = doc["doc"] + + if "error" in doc and doc["error"] is not None: + traceback = doc["error"]["traceback"] + message = doc["error"]["value"] + else: + traceback = "" + message = "No test exceptions thrown" return render_template("finesse_test_view.html", - view_test_id = view_test_id) - + view_test_id = str(view_test_id), + excp_traceback=traceback, + excp_message=message) + #except RecordNotFound: + # pass - \ No newline at end of file + +print "Starting commit watch from most recent commit: " + latest_commit_id_tested + +def setInterval(interval): + def decorator(function): + def wrapper(*args, **kwargs): + stopped = Event() + + def loop(): # executed in another thread + while not stopped.wait(interval): # until stopped + function(*args, **kwargs) + + t = Thread(target=loop) + t.daemon = True # stop if the program exits + t.start() + return stopped + return wrapper + return decorator + +@setInterval(10) +def checkLatestCommits(): + global latest_commit_id_tested + out = utils.git(["--git-dir",SRC_GIT_PATH,"log",latest_commit_id_tested + "..HEAD",'--pretty=format:"%H"']) + + print "Checking latest commits..." + commits_not_tested = [] + + try: + done_all = True + commits = out[0].split("\n") + + for commit in commits: + commit.strip() + + if len(commit) == 40: + try: + db.get("srccommit",commit) + print "Commit already done: " + commit + except RecordNotFound: + print "Commit isn't done: " + commit + done_all = False + commits_not_tested.insert(0,commit) + + if done_all: + latest_commit_id_tested = commits[0] + else: + for commit in commits_not_tested: + print "Trying to test " + commit + __finesse_start_test(commit) + except Exception as ex: + + exc_type, exc_value, exc_traceback = sys.exc_info() + + print "*** Exception in commit checker" + traceback.print_exception(exc_type, exc_value, exc_traceback, + limit=5, file=sys.stdout) + + pass + +# start checker off +stop_checkLatestCommit = checkLatestCommits()