Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

266 lines
9.8 KiB

import os
import sys
import pprint
import CDashQueryAnalyzeReport as CDQAR
import cdash_build_testing_date as CDBTD
from Python2and3 import dictItems
g_pp = pprint.PrettyPrinter(indent=2)
# Class that is used to create issue trackers for nonpassing tests downloaded
# from a CDash queryTests.php query.
#
# To make this general, the user has to create a class object that is passed
# in as the argument 'issueTrackerFormatter' in this class that supports
# the following functions:
#
# issueTrackerFormatter.createFormattedIssueTracker((issueTrackerData):
#
# This function is expected to return the created text for the issue tracker
# given the data provided by the argument 'issueTrackerData' of type
# 'IssueTrackerData'. The format of this text can be anything such as
# Markdown, RestructredText, JIRA Issue Markup, etc. The only assumption
# about formatting is in the HTML table passed in the argument
# 'issueTrackerData.testHistoryHtmlTableText'.
#
# The object 'issueTrackerFormatter' can format the issue tracker text anyway
# it wants. The object 'issueTrackerFormatter' is stateless w.r.t. this class
# CreateIssueTrackerFromCDashQueryDriver.
#
class CreateIssueTrackerFromCDashQueryDriver:
def __init__(self, issueTrackerFormatter, cdashProjectStartTimeUtc=None,
usageHelp="", issueTrackerUrlTemplate="", issueTrackerTemplate="",
):
self.issueTrackerFormatter = issueTrackerFormatter
self.cdashProjectStartTimeUtc = cdashProjectStartTimeUtc
self.usageHelp = usageHelp
self.issueTrackerUrlTemplate = issueTrackerUrlTemplate
self.issueTrackerTemplate = issueTrackerTemplate
self.options = None
def runDriver(self):
print("\n***")
print("*** Getting data to create a new issue tracker")
print("***\n")
self.getCmndLineOptions()
print("Downloading full list of nonpassing tests from CDash URL:\n")
print(" "+self.options.nonpassingTestsUrl+"\n")
nonpassingTestsLOD = self.downloadNonpassingTestsData()
print("\nTotal number of nonpassing tests over all days = "\
+str(len(nonpassingTestsLOD)))
uniqNonpassingTestsLOD = getUniqueTestsListOfDicts(nonpassingTestsLOD)
print("\nTotal number of unique nonpassing test/build pairs over all days = "\
+str(len(uniqNonpassingTestsLOD)))
(testnameList, buildnameList) = getTestnameAndBuildnameLists(uniqNonpassingTestsLOD)
print("\nNumber of test names = "+str(len(testnameList)))
print("\nNumber of build names = "+str(len(buildnameList)))
testingDayStartNonpassingDate = getTestingDayStartNonpassingDate(
nonpassingTestsLOD, self.options.cdashProjectStartTimeUtc)
#print("testingDayStartNonpassingDate = "+testingDayStartNonpassingDate)
testHistoryHtmlTableText = "" # ToDo: Implement!
issueTrackerText = self.issueTrackerFormatter.createFormattedIssueTracker(
IssueTrackerData(
summaryLine=self.options.summaryLine,
testingDayStartNonpassingDate=testingDayStartNonpassingDate,
nonpassingTestsUrl=self.options.nonpassingTestsUrl,
uniqNonpassingTestsLOD=uniqNonpassingTestsLOD,
buildnameList=buildnameList,
testnameList=testnameList,
testHistoryHtmlTableText=testHistoryHtmlTableText,
)
)
self.writeNewIssueTrackerFile(issueTrackerText)
self.writeNewTestsWithIssueTrackersFile(uniqNonpassingTestsLOD)
def injectExtraCmndLineOptions(self, clp):
clp.add_argument(
"--nonpassing-tests-url", "-u", dest="nonpassingTestsUrl", default="",
help="Full CDash queryTest.php URL for the list of nonpassing tests over a"\
+" time range given as 'begin' and 'end' fields [Required]." )
clp.add_argument(
"--cdash-project-start-time", dest="cdashProjectStartTimeUtc", default="",
help="Starting time for the CDash testing day in 'hh:mm' in UTC."\
+ " Check the CDash project settings for the testing day start time." )
clp.add_argument(
"--summary-line", "-s", dest="summaryLine", default="<summary-line>",
help="The summary line text for the issue tracker [Default '<summary-line>']." )
clp.add_argument(
"--new-issue-tracker-file", "-i", dest="newIssueTrackerFile", default="",
help="File created with the new issue tracker text if"\
+" specified [Default empty '']." )
clp.add_argument(
"--new-tests-with-issue-trackers-file", "-t", dest="newTestsWithIssueTrackersFile",
default="",
help="CSV file created with entries for the list of nonpassing tests "\
+" if specified [Default empty '']." )
def getCmndLineOptions(self):
from argparse import ArgumentParser, RawDescriptionHelpFormatter
clp = ArgumentParser(
description=self.usageHelp,
formatter_class=RawDescriptionHelpFormatter)
self.injectExtraCmndLineOptions(clp)
self.options = clp.parse_args(sys.argv[1:])
self.postReadFixupCommandlineOptions()
self.validateCommandLineOptions()
def postReadFixupCommandlineOptions(self):
if (self.options.cdashProjectStartTimeUtc == "") \
and self.cdashProjectStartTimeUtc \
:
self.options.cdashProjectStartTimeUtc = self.cdashProjectStartTimeUtc
def validateCommandLineOptions(self):
if self.options.nonpassingTestsUrl == "":
print("Error, the argument --nopassing-tests-url is required (see --help)")
sys.exit(1)
if self.options.cdashProjectStartTimeUtc == "":
print("Error, the argument --cdash-project-start-time is required (see --help)")
sys.exit(1)
def downloadNonpassingTestsData(self):
apiQueryTestsUrl = self.options.nonpassingTestsUrl.replace(
"/queryTests.php", "/api/v1/queryTests.php")
cdashDownloadFileForTesting = \
os.environ.get('CREATE_ISSUE_TRACKER_FROM_CDASH_QUERY_FILE_FOR_UNIT_TESTING',
'' )
nonpassingTestsLOD = \
CDQAR.downloadTestsOffCDashQueryTestsAndFlatten(apiQueryTestsUrl,
fullCDashQueryTestsJsonCacheFile=cdashDownloadFileForTesting,
alwaysUseCacheFileIfExists=True )
return nonpassingTestsLOD
def writeNewIssueTrackerFile(self, issueTrackerText):
if self.options.newIssueTrackerFile:
print("\nWriting out new issue tracker text to '"\
+self.options.newIssueTrackerFile+"'")
with open(self.options.newIssueTrackerFile, 'w') as fileHandle:
fileHandle.write(issueTrackerText)
def writeNewTestsWithIssueTrackersFile(self, uniqNonpassingTestsLOD):
if self.options.newTestsWithIssueTrackersFile:
print("\nWriting out list of test/biuld pairs for CSV file '"\
+self.options.newTestsWithIssueTrackersFile+"'")
csvFileStruct = CDQAR.writeTestsListOfDictsToCsvFileStructure(uniqNonpassingTestsLOD,
self.issueTrackerUrlTemplate, self.issueTrackerTemplate )
with open(self.options.newTestsWithIssueTrackersFile, 'w') as csvFile:
csvFile.write(CDQAR.writeCsvFileStructureToStr(csvFileStruct))
# Class object for issue tracker data
#
class IssueTrackerData:
def __init__(self,
summaryLine=None,
testingDayStartNonpassingDate=None,
nonpassingTestsUrl=None,
uniqNonpassingTestsLOD=None,
buildnameList=None,
testnameList=None,
testHistoryHtmlTableText=None,
):
self.summaryLine = summaryLine
self.testingDayStartNonpassingDate = testingDayStartNonpassingDate
self.nonpassingTestsUrl = nonpassingTestsUrl
self.uniqNonpassingTestsLOD = uniqNonpassingTestsLOD
self.buildnameList = buildnameList
self.testnameList = testnameList
self.testHistoryHtmlTableText = testHistoryHtmlTableText
#
# Nonmember functions
#
def getUniqueTestsListOfDicts(cdashTestsLOD): #LOD == "List of Dicts"
# Get a dict that has just unique keys 'site', 'buildName' and 'testname' values
uniqTestDict = {}
for testDict in cdashTestsLOD:
site = testDict.get('site')
buildName = testDict.get('buildName')
testname = testDict.get('testname')
uniqTestDict.update( {
site+"_"+buildName+"_"+testname :
{'site':site, 'buildName':buildName, 'testname':testname}
} )
# Get a flat list of test dicts
uniqNonpassingTestsLOD= []
for key, value in dictItems(uniqTestDict):
uniqNonpassingTestsLOD.append(value)
uniqNonpassingTestsLOD = CDQAR.sortAndLimitListOfDicts(uniqNonpassingTestsLOD,
CDQAR.getDefaultTestDictsSortKeyList())
return uniqNonpassingTestsLOD
def getTestnameAndBuildnameLists(uniqNonpassingTestsLOD):
testnameSet = set()
buildnameSet = set()
for testDict in uniqNonpassingTestsLOD:
testnameSet.add(testDict.get('testname'))
buildnameSet.add(testDict.get('buildName'))
testnameList = extractListAndSort(testnameSet)
buildnameList = extractListAndSort(buildnameSet)
return (testnameList, buildnameList)
def extractListAndSort(setIn):
listOut = []
for item in setIn: listOut.append(item)
listOut.sort()
return listOut
def getTestingDayStartNonpassingDate(nonpassingTestsLOD, cdashProjectStartTimeUtcStr):
cdashProjectStartTimeUtcStrTD = CDBTD.getProjectTestingDayStartTimeDeltaFromStr(
cdashProjectStartTimeUtcStr)
testingDayStartNonpassingDate = None
for testDict in nonpassingTestsLOD:
#print("")
#g_pp.pprint(testDict)
buildStartTime = testDict.get('buildstarttime')
#print("buildStartTime = "+str(buildStartTime))
testingDate = CDBTD.getTestingDayDateFromBuildStartTimeStr(buildStartTime,
cdashProjectStartTimeUtcStrTD)
if (testingDayStartNonpassingDate==None) \
or (testingDate < testingDayStartNonpassingDate) \
:
testingDayStartNonpassingDate = testingDate
#print("testingDayStartNonpassingDate = "+str(testingDayStartNonpassingDate))
return testingDayStartNonpassingDate
#
# Helper functions to be used in concrete drivers
#
def getMarkdownListStr(inputList, formatChars):
markdownText = ""
for item in inputList:
markdownText += "* "+formatChars+item+formatChars+"\n"
return markdownText