From 00ab9eed8d19142f4e67d2bf24473ea84931a4de Mon Sep 17 00:00:00 2001 From: Chris Fischer Date: Fri, 31 Mar 2017 15:35:41 -0600 Subject: [PATCH 1/6] Rewrite testreporter into python. The perl version was having issues handling web posts differently on different systems. Fix issue where testreport failed to be copied to testing directory. Test suite: scripts_regression_tests.py. Populated testdata base for alpha06g on cheyenne and hobart Test baseline: Test namelist changes: Test status: bit for bit Fixes #1292 User interface changes?: Code review: --- scripts/Tools/testreporter.py | 240 +++++++++++++++++++++++++++++ scripts/lib/CIME/test_scheduler.py | 15 +- 2 files changed, 250 insertions(+), 5 deletions(-) create mode 100755 scripts/Tools/testreporter.py diff --git a/scripts/Tools/testreporter.py b/scripts/Tools/testreporter.py new file mode 100755 index 00000000000..d7e136d172f --- /dev/null +++ b/scripts/Tools/testreporter.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python + +""" + +Simple script to populate CESM test database with test results. This can be +run with out any knowledge of CIME. + +""" + +import os +import glob +import xml.etree.ElementTree as ET +from xml.dom import minidom +import HTMLParser +import urllib +import argparse + + + +# Parse command line options + +parser = argparse.ArgumentParser(description='Arguements for testreporter') +parser.add_argument("--tagname", + help="Name of the tag being tested.") +parser.add_argument("--testid", + help="Test id, ie c2_0_a6g,c2_0_b6g.") +parser.add_argument("--testroot", + help="Root directory for tests to populate the database.") +parser.add_argument("--testtype", + help="Type of test, prealpha or prebeta.") +parser.add_argument("--dryrun",action="store_true", + help="Do a dry run, database will not be populated.") +parser.add_argument("--dumpxml",action="store_true", + help="Dump XML test results to sceen.") +args = parser.parse_args() + +# Fill in values needed from xml files (COMPILER, MPILIB, MACH, BASELINE_NAME_CMP. + +os.chdir(args.testroot) + +xml_file=glob.glob("*"+args.testid+"/env_build.xml") +root = ET.parse(xml_file[0]).getroot() +for child in root.iter('group'): + for entry in child.iter('entry'): + id = entry.get('id') + value = entry.get('value') + if id == "COMPILER": + compiler=value + if id == "MPILIB": + mpilib = value + +xml_file=glob.glob("*"+args.testid+"/env_case.xml") +root = ET.parse(xml_file[0]).getroot() +for child in root.iter('group'): + for entry in child.iter('entry'): + id = entry.get('id') + value = entry.get('value') + if id == "MACH": + machine=value + +xml_file=glob.glob("*"+args.testid+"/env_test.xml") +root = ET.parse(xml_file[0]).getroot() +for child in root.iter('group'): + for entry in child.iter('entry'): + id = entry.get('id') + value = entry.get('value') + if id == "BASELINE_NAME_CMP": + baseline=value + + +# +# Create XML +# + +testrecord = ET.Element("testrecord") +tag_name = ET.SubElement(testrecord,'tag_name').text=args.tagname +mach = ET.SubElement(testrecord,'mach').text=machine +compiler = ET.SubElement(testrecord,'compiler',attrib={"version":""}).text=compiler +mpilib = ET.SubElement(testrecord,'mpilib',attrib={"version":""}).text=mpilib +testroot = ET.SubElement(testrecord,'testroot').text=args.testroot +testtype = ET.SubElement(testrecord,'testtype').text=args.testtype +baselinetag = ET.SubElement(testrecord,'baselinetag').text= baseline +# +# Create lists on tests based on the testid in the testroot directory. +# +test_names=glob.glob("*"+args.testid) +# +# Loop over all tests and parse the test results +# +test_status={} +for test_name in test_names: + if test_name == "cs.status."+args.testid: + continue + test_status[test_name,'COMMENT']="" + test_status[test_name,'BASELINE']='----' + test_status[test_name,'MEMCOMP']='----' + test_status[test_name,'MEMLEAK']='----' + test_status[test_name,'NLCOMP']='----' + test_status[test_name,'STATUS']='----' + test_status[test_name,'TPUTCOMP']='----' + # + # Check to see if TestStatus is present, if not then continue + # I might want to set the status to fail + # + try: + lines = [line.rstrip('\n') for line in open(test_name+"/TestStatus")] + except: + test_status[test_name,'STATUS']="FAIL" + test_status[test_name,'COMMENT']="TestStatus missing. " + continue + # + # Loop over each line of TestStatus, and check for different types of failures. + # + for line in lines: + if "NLCOMP" in line: + test_status[test_name,'NLCOMP']=line[0:4] + if "MEMLEAK" in line: + test_status[test_name,'MEMLEAK']=line[0:4] + if "MEMCOMP" in line: + test_status[test_name,'MEMCOMP']=line[0:4] + if "BASELINE" in line: + test_status[test_name,'BASELINE']=line[0:4] + if "TPUTCOMP" in line: + test_status[test_name,'TPUTCOMP']=line[0:4] + if "INIT" in line: + test_status[test_name,'INIT']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="SFAIL" + test_status[test_name,'COMMENT']+="INIT fail! " + break + if "CREATE_NEWCASE" in line: + test_status[test_name,'CREATE_NEWCASE']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="SFAIL" + test_status[test_name,'COMMENT']+="CREATE_NEWCASE fail! " + break + if "XML" in line: + test_status[test_name,'XML']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="SFAIL" + test_status[test_name,'COMMENT']+="XML fail! " + break + if "SETUP" in line: + test_status[test_name,'SETUP']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="SFAIL" + test_status[test_name,'COMMENT']+="SETUP fail! " + break + if "SHAREDLIB_BUILD" in line: + test_status[test_name,'SHAREDLIB_BUILD']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="CFAIL" + test_status[test_name,'COMMENT']+="SHAREDLIB_BUILD fail! " + break + if "MODEL_BUILD" in line: + test_status[test_name,'MODEL_BUILD']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="CFAIL" + test_status[test_name,'COMMENT']+="MODEL_BUILD fail! " + break + if "SUBMIT" in line: + test_status[test_name,'STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'COMMENT']+="SUBMIT fail! " + break + if "RUN" in line: + test_status[test_name,'STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'COMMENT']+="RUN fail! " + break + if "COMPARE_base_rest" in line: + test_status[test_name,'STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'COMMENT']+="Restart fail! " + break + if "COMPARE_base_hybrid" in line: + test_status[test_name,'STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'COMMENT']+="Hybrid fail! " + break + + # + # Do not include time comments. Just a preference to have cleaner comments in the test database + # + try: + if 'time=' not in line: + test_status[test_name,'COMMENT']+=line.split(' ',3)[3]+' ' + except: + pass + + # + # File in the xml with the test results + # + tests = ET.Element('tests',attrib={"testname":test_name}) + testrecord.append(tests) + category=ET.SubElement(tests,'category',attrib={"name":"casestatus"}) + category=ET.SubElement(tests,'category',attrib={"name":"comment"}).text= test_status[test_name,'COMMENT'] + category=ET.SubElement(tests,'category',attrib={"name":"compare"}).text= test_status[test_name,'BASELINE'] + category=ET.SubElement(tests,'category',attrib={"name":"memcomp"}).text= test_status[test_name,'MEMCOMP'] + category=ET.SubElement(tests,'category',attrib={"name":"memleak"}).text=test_status[test_name,'MEMLEAK'] + category=ET.SubElement(tests,'category',attrib={"name":"nlcomp"}).text= test_status[test_name,'NLCOMP'] + category=ET.SubElement(tests,'category',attrib={"name":"status"}).text= test_status[test_name,'STATUS'] + category=ET.SubElement(tests,'category',attrib={"name":"tputcomp"}).text= test_status[test_name,'TPUTCOMP'] + + +# +# Convert XML to a string +# +xmlstr = ET.tostring(testrecord,method="xml",encoding="UTF-8") + +# +# Make the XML string human readable and print it out +# +xml=minidom.parseString(xmlstr) +testXML = xml.toprettyxml(encoding="UTF-8") +# +# Dump xml to the screen. +# +if args.dumpxml: + print testXML + +# +# Prompt for username and password, then post the XML string to the test database website +# +if not args.dryrun: + username=raw_input("Username:") + os.system("stty -echo") + password=raw_input("Password:") + os.system("stty echo") + params={'username':username,'password':password,'testXML':testXML} + url="https://csegweb.cgd.ucar.edu/testdb/cgi-bin/processXMLtest.cgi" + params = urllib.urlencode(params) + f = urllib.urlopen(url, params) + # + # Print any messages from the post command + # + print f.read() + print f.code + + diff --git a/scripts/lib/CIME/test_scheduler.py b/scripts/lib/CIME/test_scheduler.py index dd97d93d301..9d4a1f24d2f 100644 --- a/scripts/lib/CIME/test_scheduler.py +++ b/scripts/lib/CIME/test_scheduler.py @@ -774,11 +774,16 @@ def _setup_cs_files(self): os.chmod(cs_submit_file, os.stat(cs_submit_file).st_mode | stat.S_IXUSR | stat.S_IXGRP) - if get_model == "cesm": - testreporter = os.path.join(self._test_root,"testreporter.pl") - shutil.copy(os.path.join(self._cime_root,"scripts","Testing","testreporter.pl"), - testreporter) - os.chmod(testreporter, os.stat(testreporter).st_mode | stat.S_IXUSR | stat.S_IXGRP) + if get_model() == "cesm": + template_file = os.path.join(python_libs_root, "testreporter.template") + template = open(template_file, "r").read() + template = template.replace("", + os.path.join(self._cime_root, "scripts", "Tools")) + testreporter_file = os.path.join(self._test_root, "testreporter") + with open(testreporter_file, "w") as fd: + fd.write(template) + os.chmod(testreporter_file, os.stat(testreporter_file).st_mode + | stat.S_IXUSR | stat.S_IXGRP) except Exception as e: logger.warning("FAILED to set up cs files: %s" % str(e)) From 01fd3f7311157c80df113d81113054dc4e83dce1 Mon Sep 17 00:00:00 2001 From: Chris Fischer Date: Mon, 3 Apr 2017 13:24:17 -0600 Subject: [PATCH 2/6] Update indenting for testreporter.py Test suite: Test baseline: Test namelist changes: Test status: [bit for bit, roundoff, climate changing] Fixes [CIME Github issue #] User interface changes?: Code review: --- scripts/Tools/testreporter.py | 140 +++++++++++++++++----------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/scripts/Tools/testreporter.py b/scripts/Tools/testreporter.py index d7e136d172f..74735fe5687 100755 --- a/scripts/Tools/testreporter.py +++ b/scripts/Tools/testreporter.py @@ -41,30 +41,30 @@ xml_file=glob.glob("*"+args.testid+"/env_build.xml") root = ET.parse(xml_file[0]).getroot() for child in root.iter('group'): - for entry in child.iter('entry'): - id = entry.get('id') - value = entry.get('value') - if id == "COMPILER": - compiler=value - if id == "MPILIB": - mpilib = value + for entry in child.iter('entry'): + test_id = entry.get('id') + value = entry.get('value') + if test_id == "COMPILER": + compiler=value + if test_id == "MPILIB": + mpilib = value xml_file=glob.glob("*"+args.testid+"/env_case.xml") root = ET.parse(xml_file[0]).getroot() for child in root.iter('group'): - for entry in child.iter('entry'): - id = entry.get('id') - value = entry.get('value') - if id == "MACH": + for entry in child.iter('entry'): + test_id = entry.get('id') + value = entry.get('value') + if test_id == "MACH": machine=value xml_file=glob.glob("*"+args.testid+"/env_test.xml") root = ET.parse(xml_file[0]).getroot() for child in root.iter('group'): - for entry in child.iter('entry'): - id = entry.get('id') - value = entry.get('value') - if id == "BASELINE_NAME_CMP": + for entry in child.iter('entry'): + test_id = entry.get('id') + value = entry.get('value') + if test_id == "BASELINE_NAME_CMP": baseline=value @@ -113,80 +113,80 @@ # for line in lines: if "NLCOMP" in line: - test_status[test_name,'NLCOMP']=line[0:4] + test_status[test_name,'NLCOMP']=line[0:4] if "MEMLEAK" in line: - test_status[test_name,'MEMLEAK']=line[0:4] + test_status[test_name,'MEMLEAK']=line[0:4] if "MEMCOMP" in line: - test_status[test_name,'MEMCOMP']=line[0:4] + test_status[test_name,'MEMCOMP']=line[0:4] if "BASELINE" in line: - test_status[test_name,'BASELINE']=line[0:4] + test_status[test_name,'BASELINE']=line[0:4] if "TPUTCOMP" in line: - test_status[test_name,'TPUTCOMP']=line[0:4] + test_status[test_name,'TPUTCOMP']=line[0:4] if "INIT" in line: - test_status[test_name,'INIT']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="SFAIL" - test_status[test_name,'COMMENT']+="INIT fail! " - break + test_status[test_name,'INIT']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="SFAIL" + test_status[test_name,'COMMENT']+="INIT fail! " + break if "CREATE_NEWCASE" in line: - test_status[test_name,'CREATE_NEWCASE']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="SFAIL" - test_status[test_name,'COMMENT']+="CREATE_NEWCASE fail! " - break + test_status[test_name,'CREATE_NEWCASE']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="SFAIL" + test_status[test_name,'COMMENT']+="CREATE_NEWCASE fail! " + break if "XML" in line: - test_status[test_name,'XML']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="SFAIL" - test_status[test_name,'COMMENT']+="XML fail! " - break + test_status[test_name,'XML']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="SFAIL" + test_status[test_name,'COMMENT']+="XML fail! " + break if "SETUP" in line: - test_status[test_name,'SETUP']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="SFAIL" - test_status[test_name,'COMMENT']+="SETUP fail! " - break + test_status[test_name,'SETUP']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="SFAIL" + test_status[test_name,'COMMENT']+="SETUP fail! " + break if "SHAREDLIB_BUILD" in line: - test_status[test_name,'SHAREDLIB_BUILD']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="CFAIL" - test_status[test_name,'COMMENT']+="SHAREDLIB_BUILD fail! " - break + test_status[test_name,'SHAREDLIB_BUILD']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="CFAIL" + test_status[test_name,'COMMENT']+="SHAREDLIB_BUILD fail! " + break if "MODEL_BUILD" in line: - test_status[test_name,'MODEL_BUILD']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="CFAIL" - test_status[test_name,'COMMENT']+="MODEL_BUILD fail! " - break + test_status[test_name,'MODEL_BUILD']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'STATUS']="CFAIL" + test_status[test_name,'COMMENT']+="MODEL_BUILD fail! " + break if "SUBMIT" in line: - test_status[test_name,'STATUS']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'COMMENT']+="SUBMIT fail! " - break + test_status[test_name,'STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'COMMENT']+="SUBMIT fail! " + break if "RUN" in line: - test_status[test_name,'STATUS']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'COMMENT']+="RUN fail! " - break + test_status[test_name,'STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'COMMENT']+="RUN fail! " + break if "COMPARE_base_rest" in line: - test_status[test_name,'STATUS']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'COMMENT']+="Restart fail! " - break + test_status[test_name,'STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'COMMENT']+="Restart fail! " + break if "COMPARE_base_hybrid" in line: - test_status[test_name,'STATUS']=line[0:4] - if line[0:4] == "FAIL": - test_status[test_name,'COMMENT']+="Hybrid fail! " - break + test_status[test_name,'STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status[test_name,'COMMENT']+="Hybrid fail! " + break # # Do not include time comments. Just a preference to have cleaner comments in the test database # try: - if 'time=' not in line: - test_status[test_name,'COMMENT']+=line.split(' ',3)[3]+' ' + if 'time=' not in line: + test_status[test_name,'COMMENT']+=line.split(' ',3)[3]+' ' except: - pass + pass # # File in the xml with the test results @@ -217,7 +217,7 @@ # Dump xml to the screen. # if args.dumpxml: - print testXML + print testXML # # Prompt for username and password, then post the XML string to the test database website From 8abef1c5714b5c9efb9648d0d78a2229c1255a3d Mon Sep 17 00:00:00 2001 From: Chris Fischer Date: Mon, 17 Apr 2017 15:25:07 -0600 Subject: [PATCH 3/6] Merge in esmci/master Test suite: Test baseline: Test namelist changes: Test status: [bit for bit, roundoff, climate changing] Fixes [CIME Github issue #] User interface changes?: Code review: --- scripts/Tools/testreporter.py | 9 +- scripts/lib/CIME/XML/test_reporter.py | 120 ++++++++++++++++++++++++++ scripts/lib/CIME/test_scheduler.py | 2 +- 3 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 scripts/lib/CIME/XML/test_reporter.py diff --git a/scripts/Tools/testreporter.py b/scripts/Tools/testreporter.py index 74735fe5687..5ff6546f187 100755 --- a/scripts/Tools/testreporter.py +++ b/scripts/Tools/testreporter.py @@ -11,7 +11,6 @@ import glob import xml.etree.ElementTree as ET from xml.dom import minidom -import HTMLParser import urllib import argparse @@ -55,8 +54,8 @@ for entry in child.iter('entry'): test_id = entry.get('id') value = entry.get('value') - if test_id == "MACH": - machine=value + if test_id == "MACH": + machine=value xml_file=glob.glob("*"+args.testid+"/env_test.xml") root = ET.parse(xml_file[0]).getroot() @@ -64,8 +63,8 @@ for entry in child.iter('entry'): test_id = entry.get('id') value = entry.get('value') - if test_id == "BASELINE_NAME_CMP": - baseline=value + if test_id == "BASELINE_NAME_CMP": + baseline=value # diff --git a/scripts/lib/CIME/XML/test_reporter.py b/scripts/lib/CIME/XML/test_reporter.py new file mode 100644 index 00000000000..edbdc666495 --- /dev/null +++ b/scripts/lib/CIME/XML/test_reporter.py @@ -0,0 +1,120 @@ +""" +Interface to the archive.xml file. This class inherits from GenericXML.py + +""" + +from CIME.XML.standard_module_setup import * +from CIME.XML.generic_xml import GenericXML +from CIME.utils import expect,get_model + +import urllib + + + +class TestReporter(GenericXML): + + def __init__(self): + """ + initialize an object + """ + + expect(get_model() == 'cesm', "testreport is only meant to populate the CESM test database." ) + self.root = None + + GenericXML.__init__(self) + + def setup_header(self, tagname,machine,compiler,mpilib,testroot,testtype,baseline): + # + # Create the XML header that the testdb is expecting to recieve + # + tlelem = ET.Element("testrecord") + elem = ET.Element('tag_name') + elem.text = tagname + tlelem.append(elem) + elem = ET.Element('mach') + elem.text = machine + tlelem.append(elem) + elem = ET.Element('compiler',attrib={"version":""}) + elem.text = compiler + tlelem.append(elem) + elem = ET.Element('mpilib',attrib={"version":""}) + elem.text = mpilib + tlelem.append(elem) + elem = ET.Element('testroot') + elem.text = testroot + tlelem.append(elem) + elem = ET.Element('testtype') + elem.text = testtype + tlelem.append(elem) + elem = ET.Element('baselinetag') + elem.text = baseline + tlelem.append(elem) + + self.root=tlelem + + + + def dumpxml(self): + # + # Print testreport XML string to screen + # + GenericXML.write(self,outfile="TestRecord.xml") + + def add_result(self,test_name,test_status): + # + # Add a test result to the XML structure. + # + tlelem = ET.Element('tests',attrib={"testname":test_name}) + elem=ET.Element('category',attrib={"name":"casestatus"}) + tlelem.append(elem) + elem=ET.Element('category',attrib={"name":"comment"}) + elem.text= test_status['COMMENT'] + tlelem.append(elem) + + elem=ET.Element('category',attrib={"name":"compare"}) + elem.text= test_status['BASELINE'] + tlelem.append(elem) + + elem=ET.Element('category',attrib={"name":"memcomp"}) + elem.text= test_status['MEMCOMP'] + tlelem.append(elem) + + elem=ET.Element('category',attrib={"name":"memleak"}) + elem.text= test_status['MEMLEAK'] + tlelem.append(elem) + + elem=ET.Element('category',attrib={"name":"nlcomp"}) + elem.text= test_status['NLCOMP'] + tlelem.append(elem) + + elem=ET.Element('category',attrib={"name":"status"}) + elem.text= test_status['STATUS'] + tlelem.append(elem) + + elem=ET.Element('category',attrib={"name":"tputcomp"}) + elem.text= test_status['TPUTCOMP'] + tlelem.append(elem) + + self.root.append(tlelem) + + + + def push2testdb(self): + # + # Post test result XML to CESM test database + # + xmlstr = ET.tostring(self.root,method="xml",encoding="UTF-8") + username=raw_input("Username:") + os.system("stty -echo") + password=raw_input("Password:") + os.system("stty echo") + params={'username':username,'password':password,'testXML':xmlstr} + url="https://csegweb.cgd.ucar.edu/testdb/cgi-bin/processXMLtest.cgi" + params = urllib.urlencode(params) + f = urllib.urlopen(url, params) + # + # Print any messages from the post command + # + print f.read() + print f.code + diff --git a/scripts/lib/CIME/test_scheduler.py b/scripts/lib/CIME/test_scheduler.py index 9d4a1f24d2f..deaf0f0a67c 100644 --- a/scripts/lib/CIME/test_scheduler.py +++ b/scripts/lib/CIME/test_scheduler.py @@ -8,7 +8,7 @@ they can be run outside the context of TestScheduler. """ -import shutil, traceback, stat, threading, time, glob +import traceback, stat, threading, time, glob from CIME.XML.standard_module_setup import * import CIME.compare_namelists import CIME.utils From 55b660d915e7976983bad885fea331a1893dd7f9 Mon Sep 17 00:00:00 2001 From: Chris Fischer Date: Thu, 20 Apr 2017 14:03:16 -0600 Subject: [PATCH 4/6] Update python version of testreport to apply requested changes from the PR. Test suite: Test baseline: Test namelist changes: Test status: [bit for bit, roundoff, climate changing] Fixes [CIME Github issue #] User interface changes?: Code review: --- scripts/Tools/testreporter.py | 196 ++++++++++++++-------------------- 1 file changed, 80 insertions(+), 116 deletions(-) diff --git a/scripts/Tools/testreporter.py b/scripts/Tools/testreporter.py index 5ff6546f187..4ca00fb8ffa 100755 --- a/scripts/Tools/testreporter.py +++ b/scripts/Tools/testreporter.py @@ -2,17 +2,22 @@ """ -Simple script to populate CESM test database with test results. This can be -run with out any knowledge of CIME. +Simple script to populate CESM test database with test results. """ -import os +from standard_script_setup import * + +from CIME.XML.env_build import EnvBuild +from CIME.XML.env_case import EnvCase +from CIME.XML.env_test import EnvTest +from CIME.XML.test_reporter import TestReporter +from CIME.utils import expect + + import glob -import xml.etree.ElementTree as ET -from xml.dom import minidom -import urllib -import argparse + + @@ -37,48 +42,38 @@ os.chdir(args.testroot) +# +# Retrieve compiler name and mpi library +# xml_file=glob.glob("*"+args.testid+"/env_build.xml") -root = ET.parse(xml_file[0]).getroot() -for child in root.iter('group'): - for entry in child.iter('entry'): - test_id = entry.get('id') - value = entry.get('value') - if test_id == "COMPILER": - compiler=value - if test_id == "MPILIB": - mpilib = value +expect(len(xml_file) > 0, "Tests not found. It's possible your testid, %s is wrong." %args.testid ) +print len(xml_file) +envxml=(EnvBuild(".",infile=xml_file[0])) +compiler=envxml.get_value("COMPILER") +mpilib=envxml.get_value("MPILIB") +# +# Retrieve machine name +# xml_file=glob.glob("*"+args.testid+"/env_case.xml") -root = ET.parse(xml_file[0]).getroot() -for child in root.iter('group'): - for entry in child.iter('entry'): - test_id = entry.get('id') - value = entry.get('value') - if test_id == "MACH": - machine=value +envxml=(EnvCase(".",infile=xml_file[0])) +machine=envxml.get_value("MACH") +# +# Retrieve baseline tag to compare to +# xml_file=glob.glob("*"+args.testid+"/env_test.xml") -root = ET.parse(xml_file[0]).getroot() -for child in root.iter('group'): - for entry in child.iter('entry'): - test_id = entry.get('id') - value = entry.get('value') - if test_id == "BASELINE_NAME_CMP": - baseline=value - +envxml=(EnvTest(".",infile=xml_file[0])) +baseline = envxml.get_value("BASELINE_NAME_CMP") # -# Create XML +# Create XML header # -testrecord = ET.Element("testrecord") -tag_name = ET.SubElement(testrecord,'tag_name').text=args.tagname -mach = ET.SubElement(testrecord,'mach').text=machine -compiler = ET.SubElement(testrecord,'compiler',attrib={"version":""}).text=compiler -mpilib = ET.SubElement(testrecord,'mpilib',attrib={"version":""}).text=mpilib -testroot = ET.SubElement(testrecord,'testroot').text=args.testroot -testtype = ET.SubElement(testrecord,'testtype').text=args.testtype -baselinetag = ET.SubElement(testrecord,'baselinetag').text= baseline +testxml=TestReporter() +testrecord=None +testxml.setup_header(args.tagname,machine,compiler,mpilib,args.testroot,args.testtype,baseline) + # # Create lists on tests based on the testid in the testroot directory. # @@ -90,13 +85,13 @@ for test_name in test_names: if test_name == "cs.status."+args.testid: continue - test_status[test_name,'COMMENT']="" - test_status[test_name,'BASELINE']='----' - test_status[test_name,'MEMCOMP']='----' - test_status[test_name,'MEMLEAK']='----' - test_status[test_name,'NLCOMP']='----' - test_status[test_name,'STATUS']='----' - test_status[test_name,'TPUTCOMP']='----' + test_status['COMMENT']="" + test_status['BASELINE']='----' + test_status['MEMCOMP']='----' + test_status['MEMLEAK']='----' + test_status['NLCOMP']='----' + test_status['STATUS']='----' + test_status['TPUTCOMP']='----' # # Check to see if TestStatus is present, if not then continue # I might want to set the status to fail @@ -104,78 +99,78 @@ try: lines = [line.rstrip('\n') for line in open(test_name+"/TestStatus")] except: - test_status[test_name,'STATUS']="FAIL" - test_status[test_name,'COMMENT']="TestStatus missing. " + test_status['STATUS']="FAIL" + test_status['COMMENT']="TestStatus missing. " continue # # Loop over each line of TestStatus, and check for different types of failures. # for line in lines: if "NLCOMP" in line: - test_status[test_name,'NLCOMP']=line[0:4] + test_status['NLCOMP']=line[0:4] if "MEMLEAK" in line: - test_status[test_name,'MEMLEAK']=line[0:4] + test_status['MEMLEAK']=line[0:4] if "MEMCOMP" in line: - test_status[test_name,'MEMCOMP']=line[0:4] + test_status['MEMCOMP']=line[0:4] if "BASELINE" in line: - test_status[test_name,'BASELINE']=line[0:4] + test_status['BASELINE']=line[0:4] if "TPUTCOMP" in line: - test_status[test_name,'TPUTCOMP']=line[0:4] + test_status['TPUTCOMP']=line[0:4] if "INIT" in line: - test_status[test_name,'INIT']=line[0:4] + test_status['INIT']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="SFAIL" - test_status[test_name,'COMMENT']+="INIT fail! " + test_status['STATUS']="SFAIL" + test_status['COMMENT']+="INIT fail! " break if "CREATE_NEWCASE" in line: - test_status[test_name,'CREATE_NEWCASE']=line[0:4] + test_status['CREATE_NEWCASE']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="SFAIL" - test_status[test_name,'COMMENT']+="CREATE_NEWCASE fail! " + test_status['STATUS']="SFAIL" + test_status['COMMENT']+="CREATE_NEWCASE fail! " break if "XML" in line: - test_status[test_name,'XML']=line[0:4] + test_status['XML']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="SFAIL" - test_status[test_name,'COMMENT']+="XML fail! " + test_status['STATUS']="SFAIL" + test_status['COMMENT']+="XML fail! " break if "SETUP" in line: - test_status[test_name,'SETUP']=line[0:4] + test_status['SETUP']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="SFAIL" - test_status[test_name,'COMMENT']+="SETUP fail! " + test_status['STATUS']="SFAIL" + test_status['COMMENT']+="SETUP fail! " break if "SHAREDLIB_BUILD" in line: - test_status[test_name,'SHAREDLIB_BUILD']=line[0:4] + test_status['SHAREDLIB_BUILD']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="CFAIL" - test_status[test_name,'COMMENT']+="SHAREDLIB_BUILD fail! " + test_status['STATUS']="CFAIL" + test_status['COMMENT']+="SHAREDLIB_BUILD fail! " break if "MODEL_BUILD" in line: - test_status[test_name,'MODEL_BUILD']=line[0:4] + test_status['MODEL_BUILD']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'STATUS']="CFAIL" - test_status[test_name,'COMMENT']+="MODEL_BUILD fail! " + test_status['STATUS']="CFAIL" + test_status['COMMENT']+="MODEL_BUILD fail! " break if "SUBMIT" in line: - test_status[test_name,'STATUS']=line[0:4] + test_status['STATUS']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'COMMENT']+="SUBMIT fail! " + test_status['COMMENT']+="SUBMIT fail! " break if "RUN" in line: - test_status[test_name,'STATUS']=line[0:4] + test_status['STATUS']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'COMMENT']+="RUN fail! " + test_status['COMMENT']+="RUN fail! " break if "COMPARE_base_rest" in line: - test_status[test_name,'STATUS']=line[0:4] + test_status['STATUS']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'COMMENT']+="Restart fail! " + test_status['COMMENT']+="Restart fail! " break if "COMPARE_base_hybrid" in line: - test_status[test_name,'STATUS']=line[0:4] + test_status['STATUS']=line[0:4] if line[0:4] == "FAIL": - test_status[test_name,'COMMENT']+="Hybrid fail! " + test_status['COMMENT']+="Hybrid fail! " break # @@ -183,57 +178,26 @@ # try: if 'time=' not in line: - test_status[test_name,'COMMENT']+=line.split(' ',3)[3]+' ' + test_status['COMMENT']+=line.split(' ',3)[3]+' ' except: pass # - # File in the xml with the test results + # Fill in the xml with the test results # - tests = ET.Element('tests',attrib={"testname":test_name}) - testrecord.append(tests) - category=ET.SubElement(tests,'category',attrib={"name":"casestatus"}) - category=ET.SubElement(tests,'category',attrib={"name":"comment"}).text= test_status[test_name,'COMMENT'] - category=ET.SubElement(tests,'category',attrib={"name":"compare"}).text= test_status[test_name,'BASELINE'] - category=ET.SubElement(tests,'category',attrib={"name":"memcomp"}).text= test_status[test_name,'MEMCOMP'] - category=ET.SubElement(tests,'category',attrib={"name":"memleak"}).text=test_status[test_name,'MEMLEAK'] - category=ET.SubElement(tests,'category',attrib={"name":"nlcomp"}).text= test_status[test_name,'NLCOMP'] - category=ET.SubElement(tests,'category',attrib={"name":"status"}).text= test_status[test_name,'STATUS'] - category=ET.SubElement(tests,'category',attrib={"name":"tputcomp"}).text= test_status[test_name,'TPUTCOMP'] + testxml.add_result(test_name,test_status) -# -# Convert XML to a string -# -xmlstr = ET.tostring(testrecord,method="xml",encoding="UTF-8") - -# -# Make the XML string human readable and print it out -# -xml=minidom.parseString(xmlstr) -testXML = xml.toprettyxml(encoding="UTF-8") # # Dump xml to the screen. # if args.dumpxml: - print testXML + testxml.dumpxml() # # Prompt for username and password, then post the XML string to the test database website # if not args.dryrun: - username=raw_input("Username:") - os.system("stty -echo") - password=raw_input("Password:") - os.system("stty echo") - params={'username':username,'password':password,'testXML':testXML} - url="https://csegweb.cgd.ucar.edu/testdb/cgi-bin/processXMLtest.cgi" - params = urllib.urlencode(params) - f = urllib.urlopen(url, params) - # - # Print any messages from the post command - # - print f.read() - print f.code + testxml.push2testdb() From 08f53ec59309b47d850febbba04715f9ed317523 Mon Sep 17 00:00:00 2001 From: Chris Fischer Date: Fri, 21 Apr 2017 11:03:24 -0600 Subject: [PATCH 5/6] Add testreporter.template. Fix comment in test_reporter.py Test suite: Test baseline: Test namelist changes: Test status: [bit for bit, roundoff, climate changing] Fixes [CIME Github issue #] User interface changes?: Code review: --- scripts/lib/CIME/XML/test_reporter.py | 2 +- scripts/lib/testreporter.template | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 scripts/lib/testreporter.template diff --git a/scripts/lib/CIME/XML/test_reporter.py b/scripts/lib/CIME/XML/test_reporter.py index edbdc666495..5b950557b9e 100644 --- a/scripts/lib/CIME/XML/test_reporter.py +++ b/scripts/lib/CIME/XML/test_reporter.py @@ -1,5 +1,5 @@ """ -Interface to the archive.xml file. This class inherits from GenericXML.py +Interface to the testreporter xml. This class inherits from GenericXML.py """ diff --git a/scripts/lib/testreporter.template b/scripts/lib/testreporter.template new file mode 100644 index 00000000000..c8bfa79405a --- /dev/null +++ b/scripts/lib/testreporter.template @@ -0,0 +1,3 @@ +#! /bin/bash + +/testreporter.py "$@" From 34db2f2da5d41b6c0997333c1f5a0c9b47a879ef Mon Sep 17 00:00:00 2001 From: Chris Fischer Date: Fri, 21 Apr 2017 15:48:00 -0600 Subject: [PATCH 6/6] More changes for testreport from code review. Test suite: Test baseline: Test namelist changes: Test status: [bit for bit, roundoff, climate changing] Fixes [CIME Github issue #] User interface changes?: Code review: --- scripts/Tools/testreporter.py | 347 ++++++++++++++------------ scripts/lib/CIME/XML/test_reporter.py | 7 - 2 files changed, 186 insertions(+), 168 deletions(-) diff --git a/scripts/Tools/testreporter.py b/scripts/Tools/testreporter.py index 4ca00fb8ffa..4ea6666dc24 100755 --- a/scripts/Tools/testreporter.py +++ b/scripts/Tools/testreporter.py @@ -13,191 +13,216 @@ from CIME.XML.env_test import EnvTest from CIME.XML.test_reporter import TestReporter from CIME.utils import expect +from CIME.XML.generic_xml import GenericXML import glob +############################################################################### +def parse_command_line(args): +############################################################################### + parser = argparse.ArgumentParser() + CIME.utils.setup_standard_logging_options(parser) -# Parse command line options + # Parse command line options -parser = argparse.ArgumentParser(description='Arguements for testreporter') -parser.add_argument("--tagname", +# parser = argparse.ArgumentParser(description='Arguements for testreporter') + parser.add_argument("--tagname", help="Name of the tag being tested.") -parser.add_argument("--testid", - help="Test id, ie c2_0_a6g,c2_0_b6g.") -parser.add_argument("--testroot", + parser.add_argument("--testid", + help="Test id, ie c2_0_a6g_ing,c2_0_b6g_gnu.") + parser.add_argument("--testroot", help="Root directory for tests to populate the database.") -parser.add_argument("--testtype", + parser.add_argument("--testtype", help="Type of test, prealpha or prebeta.") -parser.add_argument("--dryrun",action="store_true", + parser.add_argument("--dryrun",action="store_true", help="Do a dry run, database will not be populated.") -parser.add_argument("--dumpxml",action="store_true", + parser.add_argument("--dumpxml",action="store_true", help="Dump XML test results to sceen.") -args = parser.parse_args() - -# Fill in values needed from xml files (COMPILER, MPILIB, MACH, BASELINE_NAME_CMP. - -os.chdir(args.testroot) - -# -# Retrieve compiler name and mpi library -# -xml_file=glob.glob("*"+args.testid+"/env_build.xml") -expect(len(xml_file) > 0, "Tests not found. It's possible your testid, %s is wrong." %args.testid ) -print len(xml_file) -envxml=(EnvBuild(".",infile=xml_file[0])) -compiler=envxml.get_value("COMPILER") -mpilib=envxml.get_value("MPILIB") - -# -# Retrieve machine name -# -xml_file=glob.glob("*"+args.testid+"/env_case.xml") -envxml=(EnvCase(".",infile=xml_file[0])) -machine=envxml.get_value("MACH") - -# -# Retrieve baseline tag to compare to -# -xml_file=glob.glob("*"+args.testid+"/env_test.xml") -envxml=(EnvTest(".",infile=xml_file[0])) -baseline = envxml.get_value("BASELINE_NAME_CMP") - -# -# Create XML header -# - -testxml=TestReporter() -testrecord=None -testxml.setup_header(args.tagname,machine,compiler,mpilib,args.testroot,args.testtype,baseline) - -# -# Create lists on tests based on the testid in the testroot directory. -# -test_names=glob.glob("*"+args.testid) -# -# Loop over all tests and parse the test results -# -test_status={} -for test_name in test_names: - if test_name == "cs.status."+args.testid: - continue - test_status['COMMENT']="" - test_status['BASELINE']='----' - test_status['MEMCOMP']='----' - test_status['MEMLEAK']='----' - test_status['NLCOMP']='----' - test_status['STATUS']='----' - test_status['TPUTCOMP']='----' - # - # Check to see if TestStatus is present, if not then continue - # I might want to set the status to fail - # - try: - lines = [line.rstrip('\n') for line in open(test_name+"/TestStatus")] - except: - test_status['STATUS']="FAIL" - test_status['COMMENT']="TestStatus missing. " - continue - # - # Loop over each line of TestStatus, and check for different types of failures. - # - for line in lines: - if "NLCOMP" in line: - test_status['NLCOMP']=line[0:4] - if "MEMLEAK" in line: - test_status['MEMLEAK']=line[0:4] - if "MEMCOMP" in line: - test_status['MEMCOMP']=line[0:4] - if "BASELINE" in line: - test_status['BASELINE']=line[0:4] - if "TPUTCOMP" in line: - test_status['TPUTCOMP']=line[0:4] - if "INIT" in line: - test_status['INIT']=line[0:4] - if line[0:4] == "FAIL": - test_status['STATUS']="SFAIL" - test_status['COMMENT']+="INIT fail! " - break - if "CREATE_NEWCASE" in line: - test_status['CREATE_NEWCASE']=line[0:4] - if line[0:4] == "FAIL": - test_status['STATUS']="SFAIL" - test_status['COMMENT']+="CREATE_NEWCASE fail! " - break - if "XML" in line: - test_status['XML']=line[0:4] - if line[0:4] == "FAIL": - test_status['STATUS']="SFAIL" - test_status['COMMENT']+="XML fail! " - break - if "SETUP" in line: - test_status['SETUP']=line[0:4] - if line[0:4] == "FAIL": - test_status['STATUS']="SFAIL" - test_status['COMMENT']+="SETUP fail! " - break - if "SHAREDLIB_BUILD" in line: - test_status['SHAREDLIB_BUILD']=line[0:4] - if line[0:4] == "FAIL": - test_status['STATUS']="CFAIL" - test_status['COMMENT']+="SHAREDLIB_BUILD fail! " - break - if "MODEL_BUILD" in line: - test_status['MODEL_BUILD']=line[0:4] - if line[0:4] == "FAIL": - test_status['STATUS']="CFAIL" - test_status['COMMENT']+="MODEL_BUILD fail! " - break - if "SUBMIT" in line: - test_status['STATUS']=line[0:4] - if line[0:4] == "FAIL": - test_status['COMMENT']+="SUBMIT fail! " - break - if "RUN" in line: - test_status['STATUS']=line[0:4] - if line[0:4] == "FAIL": - test_status['COMMENT']+="RUN fail! " - break - if "COMPARE_base_rest" in line: - test_status['STATUS']=line[0:4] - if line[0:4] == "FAIL": - test_status['COMMENT']+="Restart fail! " - break - if "COMPARE_base_hybrid" in line: - test_status['STATUS']=line[0:4] - if line[0:4] == "FAIL": - test_status['COMMENT']+="Hybrid fail! " - break + args = parser.parse_args() + CIME.utils.handle_standard_logging_options(args) + + return args.testroot, args.testid, args.tagname, args.testtype, args.dryrun, args.dumpxml + +############################################################################### +def get_testreporter_xml(testroot, testid, tagname, testtype): +############################################################################### + os.chdir(testroot) + + # + # Retrieve compiler name and mpi library + # + xml_file=glob.glob("*"+testid+"/env_build.xml") + expect(len(xml_file) > 0, "Tests not found. It's possible your testid, %s is wrong." %testid ) + envxml=(EnvBuild(".",infile=xml_file[0])) + compiler=envxml.get_value("COMPILER") + mpilib=envxml.get_value("MPILIB") + + # + # Retrieve machine name + # + xml_file=glob.glob("*"+testid+"/env_case.xml") + envxml=(EnvCase(".",infile=xml_file[0])) + machine=envxml.get_value("MACH") + + # + # Retrieve baseline tag to compare to + # + xml_file=glob.glob("*"+testid+"/env_test.xml") + envxml=(EnvTest(".",infile=xml_file[0])) + baseline = envxml.get_value("BASELINE_NAME_CMP") + + # + # Create XML header + # + + testxml=TestReporter() + testxml.setup_header(tagname,machine,compiler,mpilib,testroot,testtype,baseline) + + # + # Create lists on tests based on the testid in the testroot directory. + # + test_names=glob.glob("*"+testid) + # + # Loop over all tests and parse the test results + # + test_status={} + for test_name in test_names: + if not os.path.isfile(test_name+"/TestStatus"): + continue + test_status['COMMENT']="" + test_status['BASELINE']='----' + test_status['MEMCOMP']='----' + test_status['MEMLEAK']='----' + test_status['NLCOMP']='----' + test_status['STATUS']='----' + test_status['TPUTCOMP']='----' # - # Do not include time comments. Just a preference to have cleaner comments in the test database + # Check to see if TestStatus is present, if not then continue + # I might want to set the status to fail # try: - if 'time=' not in line: - test_status['COMMENT']+=line.split(' ',3)[3]+' ' + lines = [line.rstrip('\n') for line in open(test_name+"/TestStatus")] except: - pass + test_status['STATUS']="FAIL" + test_status['COMMENT']="TestStatus missing. " + continue + # + # Loop over each line of TestStatus, and check for different types of failures. + # + for line in lines: + if "NLCOMP" in line: + test_status['NLCOMP']=line[0:4] + if "MEMLEAK" in line: + test_status['MEMLEAK']=line[0:4] + if "MEMCOMP" in line: + test_status['MEMCOMP']=line[0:4] + if "BASELINE" in line: + test_status['BASELINE']=line[0:4] + if "TPUTCOMP" in line: + test_status['TPUTCOMP']=line[0:4] + if "INIT" in line: + test_status['INIT']=line[0:4] + if line[0:4] == "FAIL": + test_status['STATUS']="SFAIL" + test_status['COMMENT']+="INIT fail! " + break + if "CREATE_NEWCASE" in line: + test_status['CREATE_NEWCASE']=line[0:4] + if line[0:4] == "FAIL": + test_status['STATUS']="SFAIL" + test_status['COMMENT']+="CREATE_NEWCASE fail! " + break + if "XML" in line: + test_status['XML']=line[0:4] + if line[0:4] == "FAIL": + test_status['STATUS']="SFAIL" + test_status['COMMENT']+="XML fail! " + break + if "SETUP" in line: + test_status['SETUP']=line[0:4] + if line[0:4] == "FAIL": + test_status['STATUS']="SFAIL" + test_status['COMMENT']+="SETUP fail! " + break + if "SHAREDLIB_BUILD" in line: + test_status['SHAREDLIB_BUILD']=line[0:4] + if line[0:4] == "FAIL": + test_status['STATUS']="CFAIL" + test_status['COMMENT']+="SHAREDLIB_BUILD fail! " + break + if "MODEL_BUILD" in line: + test_status['MODEL_BUILD']=line[0:4] + if line[0:4] == "FAIL": + test_status['STATUS']="CFAIL" + test_status['COMMENT']+="MODEL_BUILD fail! " + break + if "SUBMIT" in line: + test_status['STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status['COMMENT']+="SUBMIT fail! " + break + if "RUN" in line: + test_status['STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status['COMMENT']+="RUN fail! " + break + if "COMPARE_base_rest" in line: + test_status['STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status['COMMENT']+="Restart fail! " + break + if "COMPARE_base_hybrid" in line: + test_status['STATUS']=line[0:4] + if line[0:4] == "FAIL": + test_status['COMMENT']+="Hybrid fail! " + break + + # + # Do not include time comments. Just a preference to have cleaner comments in the test database + # + try: + if 'time=' not in line: + test_status['COMMENT']+=line.split(' ',3)[3]+' ' + except: + pass + + # + # Fill in the xml with the test results + # + testxml.add_result(test_name,test_status) + + return testxml + + +############################################################################## +def _main_func(): +############################################################################### + + testroot, testid, tagname, testtype, dryrun, dumpxml = parse_command_line(sys.argv) + + testxml = get_testreporter_xml(testroot, testid, tagname, testtype) # - # Fill in the xml with the test results + # Dump xml to a file. # - testxml.add_result(test_name,test_status) + if dumpxml: + GenericXML.write(testxml,outfile="TestRecord.xml") + + # + # Prompt for username and password, then post the XML string to the test database website + # + if not dryrun: + testxml.push2testdb() -# -# Dump xml to the screen. -# -if args.dumpxml: - testxml.dumpxml() +############################################################################### -# -# Prompt for username and password, then post the XML string to the test database website -# -if not args.dryrun: - testxml.push2testdb() +if __name__ == "__main__": + _main_func() diff --git a/scripts/lib/CIME/XML/test_reporter.py b/scripts/lib/CIME/XML/test_reporter.py index 5b950557b9e..261a13a9d14 100644 --- a/scripts/lib/CIME/XML/test_reporter.py +++ b/scripts/lib/CIME/XML/test_reporter.py @@ -52,13 +52,6 @@ def setup_header(self, tagname,machine,compiler,mpilib,testroot,testtype,baselin self.root=tlelem - - - def dumpxml(self): - # - # Print testreport XML string to screen - # - GenericXML.write(self,outfile="TestRecord.xml") def add_result(self,test_name,test_status): #