import datetime import json import os import pandas import subprocess import sys import time import traceback from svviz import demo from svviz import testIssues from svviz import rendertest from svviz import testDemos from svviz import testCounts # USAGE = """ # python runTests.py run|reset [hg19.ref.fa] # run - run all svviz tests # reset - removes then regenerates all values stored for each test; # use only after verifying that svviz behavior has changed # and that the new behavior is correct # hg19.ref.fa - path to reference genome; must be defined here or using # the environmental variable SVVIZ_HG19_FASTA # """ # reset ... def reset(): print("resetting test values...") previousSummaryPath = "countsTest.previousSummary.txt" os.remove(previousSummaryPath) raise Exception("not yet implemented: reset for demos and for render test") # run ... def _runTest(fn, description): print("\n\n -- running {} --\n\n".format(description)) try: t0 = time.time() result = fn() t1 = time.time() result = [result[0], result[1], t1-t0] except Exception as e: print(" ** error running {}: {} **".format(description, e)) print(traceback.print_exc()) result = [False, str(e), -1] return result def getHG19Ref(path=None): if path is not None: os.environ["SVVIZ_HG19_FASTA"] = path return path path = os.environ.get("SVVIZ_HG19_FASTA", None) assert os.path.exists(path), "Can't find hg19 reference fasta at path '{}'".format(path) return path def getCountsData(): path = "svviz-examples/countsTest" if not os.path.exists(path): result = demo.downloadDemo("countsTest") if not result: raise Exception("Couldn't download the countsTest data.") def runTestCounts(): getCountsData() genome = getHG19Ref() vcfs = ["svviz-examples/countsTest/na12878_test_deletions.vcf"] bams = ["svviz-examples/countsTest/reads.sorted.bam"] previousSummaryPath = "countsTest.previousSummary.txt" return testCounts.run(genome, vcfs, bams, previousSummaryPath) def runTestIssues(): genome = getHG19Ref() return testIssues.run(genome) def saveTimingInfo(summary): timingsPath = "test_timings.csv" git_version = subprocess.check_output(["git", "describe"]).strip() new_row = summary[["timing"]].T new_row["date"] = [datetime.datetime.now()] new_row["version"] = git_version if os.path.exists(timingsPath): timings = pandas.read_csv(timingsPath, index_col=0) timings = pandas.concat([timings, new_row]) else: timings = new_row timings.to_csv(timingsPath) print(timings) def run(which): print("running all tests...") summary = pandas.DataFrame(columns=["pass", "info", "timing"]) # Test chromosome ends if len(which)==0 or "chrom_ends" in which: summary.loc["chrom_ends"] = _runTest(runTestIssues, "issues") # Run the demos if len(which)==0 or "demos" in which: summary.loc["demos"] = _runTest(testDemos.run, "demos") # Run regression testing on ref/alt/amb counts if len(which)==0 or "counts" in which: summary.loc["counts"] = _runTest(runTestCounts, "counts") # Run the render regression tests if len(which)==0 or "rendering" in which: summary.loc["rendering"] = _runTest(rendertest.run, "rendering") summary["timing"] = summary["timing"].apply(lambda x: "{}".format(datetime.timedelta(seconds=int(x)))) print(summary) saveTimingInfo(summary) def main(): # don't ask me why I rolled my own regression testing code instead of using one of the # gazillion existing frameworks... import argparse parser = argparse.ArgumentParser() parser.add_argument("-r", "--reference", help="path for hg19 reference fasta; must be defined here or " "using the environmental variable SVVIZ_HG19_FASTA") parser.add_argument("mode", help="run|reset") parser.add_argument("which", nargs="*", help="which analyses to run (default all)") args = parser.parse_args() print(args.which) # if len(sys.argv) < 2: # print USAGE # return if args.mode == "run": if getHG19Ref(args.reference) is None: parser.print_help() print("ERROR: Must provide path for hg19 reference fasta") sys.exit(1) run(args.which) elif args.mode == "reset": reset() else: parser.print_help() if __name__ == '__main__': main()