def checkPythonPxdHeader(src_path, bin_path, ignorefilename, pxds_out, print_pxd, output_format, generate_pxd): """ Checks a set of doxygen xml file against a set of pxd header files For each C++ class found in the doxygen XML files, it tries to identify the corresponding pxd file. If a pxd file exists, it checks whether i) all public functions, enums and attributes are wrapped in Python ii) all void return types are correct in Python (these are not checked at compile time) iii) all fields of an enum are accessible from Python If it finds a method missing, the script suggests an addition and if a whole class is missing, the script writes suggestion .pxd file to a specified location (pxds_out). The output format can either be in text form (human readable) or in xml form which will try to overwrite the cdash Test.xml file to proivide an output to cdash. Please only specify xml output if in your binary you have executed "ctest -D Nightly" or similar. TODO also look at ./doc/doxygen/doxygen-error.log ? Make sure to build the doxygen xmls first with $ make doc_xml """ xml_output_path = os.path.join(bin_path, "doc", "xml_output") xml_files = glob.glob(xml_output_path + "/*.xml") print "Found %s doxygen xml files" % (len(xml_files)) if len(xml_files) == 0: raise Exception("No doxygen files found in directory:\n%s,\n" % xml_output_path + \ "Please make sure you build the doxygen xmls (make doc_xml)\n" +\ "and that you specified the correct directory." ) print "Creating pxd file map" pxd_file_matching = create_pxd_file_map(src_path) print "Found %s matching pxd files" % len(pxd_file_matching) cnt = Counter() cnt.total = len(xml_files) ignorefile = IgnoreFile() if len(ignorefilename) > 0: ignorefile.load(ignorefilename) if len(generate_pxd) > 0: print "Will only consider class", generate_pxd def pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd): if print_pxd: print "" print pxd_text if len(pxds_out) > 0 and pxd_text is not None: fname = os.path.join(pxds_out, "%s.pxd" % comp_name.split("::")[-1]) with open(fname, "w") as f: f.write(pxd_text) testresults = TestResultHandler() # Iterate through all xml files generated by doxygen (these are all the # classes available in OpenMS) for class_cntr, f in enumerate(xml_files): # Only look out for one specific pxd file (see option --generate_pxd_for) if len(generate_pxd) > 0: if f.find(generate_pxd) == -1: continue # Try to parse the doxygen file dfile = DoxygenXMLFile(f) res = dfile.parse_doxygen() if dfile.parsing_error: # e.g. <computeroutput><bold></computeroutput> cnt.skipped_could_not_parse += 1 msg = "Skip:: No-parse :: could not parse file %s with error %s" % ( f, dfile.parsing_error_message) tres = TestResult(False, msg, name="%s_test" % f) testresults.append([tres]) continue elif os.path.basename(f) == "index.xml": # Skip the index file continue # Parse class and namespace # Skip certain namespaces or those without any namespace (we are only # interested in the OpenMS and OpenSwath namespace). compound = res.get_compounddef() comp_name = compound.get_compoundname() if len(comp_name.split("::")) == 1: # Not inside a namespace -> skip continue namespace = comp_name.split("::")[0] if namespace in ["std", "Ui", "xercesc", "seqan"]: # Namespace std, xerces, UI -> skip continue elif comp_name.startswith("ms::numpress"): # MS Numpress namespace continue elif not (comp_name.startswith("OpenMS") or comp_name.startswith("OpenSwath")): # Continue without checking or generating a testreport print "Unknown namespace", comp_name continue # Skip files which are listed in the "ignore" file if ignorefile.isNameIgnored(comp_name): msg = "Skip:: Ignored :: Class %s (file %s)" % (comp_name, f) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([tres]) cnt.skipped_ignored += 1 continue # Ignore private/protected classes if compound.prot != "public": msg = "Skip:: Protected :: Compound %s is not public, skip" % ( comp_name) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([tres]) cnt.skipped_protected += 1 continue # Get file location and skip empty files file_location = dfile.getCompoundFileLocation() if file_location is None: msg = "Skip:: No-data :: there is no source file for %s" % f tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([tres]) cnt.skipped_no_location += 1 continue # Skip empty classes openms_file = OpenMSSourceFile(file_location) maintainer = openms_file.getMaintainer() if dfile.isEmpty(True): msg = "Skip:: No-data :: File is empty (no section definitions found or only definitions found) in file %s" % f tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) tres.maintainer = maintainer testresults.append([tres]) cnt.skipped_no_sections += 1 continue # Retrieve all associated pxd files with this specific header file file_location_key = file_location if len(file_location.split("include/")) > 1: file_location_key = file_location.split("include/")[1] if file_location_key in pxd_file_matching: pxdfiles = pxd_file_matching[file_location_key] else: msg = "Skip:: No-pxd :: No pxd file exists for Class %s (File %s) %s" % ( comp_name, file_location, f) tres = TestResult(False, msg, name="Missing_%s_test" % comp_name) tres.maintainer = maintainer testresults.append([tres]) cnt.skipped_no_pxd_file += 1 pxd_text = dfile.get_pxd_from_class(dfile, file_location, xml_output_path) pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd) continue # Parse the pxd files corresponding to this doxygen XML file try: pxd_class = PXDFile.parse_multiple_files(pxdfiles, comp_name) pxdfile = pxd_class.pxdfile except PXDFileParseError as e: # TODO specific exception msg = "Skip:: No-pxd :: " + e.message + "for %s (in pxd file %s)" % ( comp_name, pxdfiles) tres = TestResult(False, msg, name="Missing_%s_test" % comp_name) tres.maintainer = maintainer testresults.append([tres]) cnt.skipped_no_pxd_match += 1 pxd_text = dfile.get_pxd_from_class(dfile, file_location, xml_output_path) pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd) continue # Count the current file cnt.parsed += 1 # Loop through all methods which are listed in the doxygen XML file and match them to the pxd file classtestresults = [] for method_cntr, mdef in enumerate(dfile.iterMemberDef()): if mdef.get_name() in ignorefile.getIgnoredMethods(comp_name): msg = "Ignore member function/attribute : %s %s %s " % ( mdef.kind, mdef.prot, mdef.name) tres = TestResult(True, msg, log_level=10) else: tres = handle_member_definition(mdef, pxd_class, cnt) testname = "%s_%s::%s" % (comp_name, method_cntr, mdef.name) testname = testname.replace("::", "_") testname = re.sub('[^a-zA-Z0-9_]+', '', testname) tres.comp_name = comp_name tres.file_location = file_location tres.pxdfile = pxdfile tres.maintainer = maintainer tres.name = testname classtestresults.append(tres) testresults.append(classtestresults) writeOutput(testresults, output_format, cnt, bin_path)
def checkPythonPxdHeader(src_path, bin_path, ignorefilename, pxds_out, print_pxd, output_format, generate_pxd): """ Checks a set of doxygen xml file against a set of pxd header files For each C++ class found in the doxygen XML files, it tries to identify the corresponding pxd file. If a pxd file exists, it checks whether i) all public functions, enums and attributes are wrapped in Python ii) all void return types are correct in Python (these are not checked at compile time) iii) all fields of an enum are accessible from Python If it finds a method missing, the script suggests an addition and if a whole class is missing, the script writes suggestion .pxd file to a specified location (pxds_out). The output format can either be in text form (human readable) or in xml form which will try to overwrite the cdash Test.xml file to proivide an output to cdash. Please only specify xml output if in your binary you have executed "ctest -D Nightly" or similar. TODO also look at ./doc/doxygen/doxygen-error.log ? Make sure to build the doxygen xmls first with $ make doc_xml """ xml_output_path = os.path.join(bin_path, "doc", "xml_output") xml_files = glob.glob(xml_output_path + "/*.xml") print "Found %s doxygen xml files" % (len(xml_files)) if len(xml_files) == 0: raise Exception("No doxygen files found in directory:\n%s,\n" % xml_output_path + \ "Please make sure you build the doxygen xmls (make dox_xml)\n" +\ "and that you specified the correct directory." ) print "Creating pxd file map" pxd_file_matching = create_pxd_file_map(src_path) cnt = Counter() cnt.total = len(xml_files) ignorefile = IgnoreFile() if len(ignorefilename) > 0: ignorefile.load(ignorefilename) def pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd): if print_pxd: print "" print pxd_text if len(pxds_out) > 0 and pxd_text is not None: fname = os.path.join(pxds_out, "%s.pxd" % comp_name.split("::")[-1] ) with open(fname, "w" ) as f: f.write(pxd_text) testresults = TestResultHandler() for class_cntr, f in enumerate(xml_files): if len(generate_pxd) > 0: if f.find(generate_pxd) == -1: continue dfile = DoxygenXMLFile(f) res = dfile.parse_doxygen() if dfile.parsing_error: # e.g. <computeroutput><bold></computeroutput> cnt.skipped_could_not_parse += 1 msg = "Skip:: No-parse :: could not parse file %s with error %s" % (f, dfile.parsing_error_message) tres = TestResult(False, msg, name="%s_test" % f ) testresults.append([ tres ]) continue elif os.path.basename(f) == "index.xml": # Skip the index continue compound = res.get_compounddef() comp_name = compound.get_compoundname() if not (comp_name.startswith("OpenMS") or comp_name.startswith("OpenSwath") ): # Continue without checking or generating a testreport continue if ignorefile.isNameIgnored(comp_name): msg = "Skip:: Ignored :: Class %s (file %s)" % (comp_name, f) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([ tres ]) cnt.skipped_ignored += 1 continue if compound.prot != "public": msg = "Skip:: Protected :: Compound %s is not public, skip" % (comp_name) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([ tres ]) cnt.skipped_protected += 1 continue file_location = dfile.getCompoundFileLocation() if file_location is None: msg = "Skip:: No-data :: there is no source file for %s" % f tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([ tres ]) cnt.skipped_no_location += 1 continue openms_file = OpenMSSourceFile(file_location) maintainer = openms_file.getMaintainer() if dfile.isEmpty(True): msg = "Skip:: No-data :: File is empty (no section definitions found or only definitions found) in file %s" % f tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) tres.maintainer = maintainer testresults.append([ tres ]) cnt.skipped_no_sections += 1 continue if file_location in pxd_file_matching: pxdfiles = pxd_file_matching[file_location] else: msg = "Skip:: No-pxd :: No pxd file exists for Class %s (File %s) %s" % (comp_name, file_location, f) tres = TestResult(False, msg, name="Missing_%s_test" % comp_name ) tres.maintainer = maintainer testresults.append([ tres ]) cnt.skipped_no_pxd_file += 1 pxd_text = dfile.get_pxd_from_class(dfile, file_location, xml_output_path) pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd) continue try: pxd_class = PXDFile.parse_multiple_files(pxdfiles, comp_name) pxdfile = pxd_class.pxdfile except PXDFileParseError as e: # TODO specific exception msg = "Skip:: No-pxd :: " + e.message + "for %s (in pxd file %s)" % (comp_name, pxdfiles) tres = TestResult(False, msg, name="Missing_%s_test" % comp_name ) tres.maintainer = maintainer testresults.append([ tres ]) cnt.skipped_no_pxd_match += 1 pxd_text = dfile.get_pxd_from_class(dfile, file_location, xml_output_path) pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd) continue cnt.parsed += 1 # Loop through all methods classtestresults = [] for method_cntr,mdef in enumerate(dfile.iterMemberDef()): if mdef.get_name() in ignorefile.getIgnoredMethods(comp_name): msg = "Ignore member function/attribute : %s %s %s " % (mdef.kind, mdef.prot, mdef.name) tres = TestResult(True, msg, log_level=10) else: tres = handle_member_definition(mdef, pxd_class, cnt) testname = "%s_%s::%s" % (comp_name, method_cntr, mdef.name) testname = testname.replace("::", "_") testname = re.sub('[^a-zA-Z0-9_]+', '', testname) tres.comp_name = comp_name tres.file_location = file_location tres.pxdfile = pxdfile tres.maintainer = maintainer tres.name = testname classtestresults.append(tres) testresults.append(classtestresults) ################################### # Output ################################### if output_format in ["text", "text-verbose", "text-quiet"]: for classtestresults in testresults: if len(classtestresults) > 1: t = classtestresults[0] lenfailed = len([t for t in classtestresults if not t.isPassed() ] ) if lenfailed > 0: print "== Test results for element %s - from Cpp file %s with maintainer %s and corresponding pxd file %s" % ( t.comp_name, t.file_location, t.maintainer, t.pxdfile) for tres in classtestresults: if not tres.isPassed(): print tres.message elif tres.log_level >= 10 and output_format in ["text", "text-verbose"]: print tres.message elif tres.log_level >= 0 and output_format in ["text-verbose"]: print tres.message elif output_format == "xml": # check if all files required to report in CDash are present tag_file = os.path.join(bin_path, "Testing", "TAG" ) try: # read the first line of tagfile (TAG) -> if it does not exist, # an IOError is thrown with open(tag_file) as f: ctestReportingPath = f.readline().strip() ctestReportingPath = os.path.join(bin_path, "Testing", ctestReportingPath) if not os.path.exists( ctestReportingPath ): raise Exception("Missing directory at %s" % ( ctestReportingPath ) ) except IOError: raise Exception("Missing nightly test information at %s" % (tag_file) ) template_path = os.path.join(ctestReportingPath, "Test.xml" ) testresults.to_cdash_xml(template_path, template_path) else: raise Exception("Unknown output format %s" % output_format) cnt.print_stats() cnt.print_skipping_reason()
def checkPythonPxdHeader(src_path, bin_path, ignorefilename, pxds_out, print_pxd, output_format, generate_pxd): """ Checks a set of doxygen xml file against a set of pxd header files For each C++ class found in the doxygen XML files, it tries to identify the corresponding pxd file. If a pxd file exists, it checks whether i) all public functions, enums and attributes are wrapped in Python ii) all void return types are correct in Python (these are not checked at compile time) iii) all fields of an enum are accessible from Python If it finds a method missing, the script suggests an addition and if a whole class is missing, the script writes suggestion .pxd file to a specified location (pxds_out). The output format can either be in text form (human readable) or in xml form which will try to overwrite the cdash Test.xml file to proivide an output to cdash. Please only specify xml output if in your binary you have executed "ctest -D Nightly" or similar. TODO also look at ./doc/doxygen/doxygen-error.log ? Make sure to build the doxygen xmls first with $ make doc_xml """ xml_output_path = os.path.join(bin_path, "doc", "xml_output") xml_files = glob.glob(xml_output_path + "/*.xml") print "Found %s doxygen xml files" % (len(xml_files)) if len(xml_files) == 0: raise Exception("No doxygen files found in directory:\n%s,\n" % xml_output_path + \ "Please make sure you build the doxygen xmls (make doc_xml)\n" +\ "and that you specified the correct directory." ) print "Creating pxd file map" pxd_file_matching = create_pxd_file_map(src_path) print "Found %s matching pxd files" % len(pxd_file_matching) cnt = Counter() cnt.total = len(xml_files) ignorefile = IgnoreFile() if len(ignorefilename) > 0: ignorefile.load(ignorefilename) if len(generate_pxd) > 0: print "Will only consider class", generate_pxd def pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd): if print_pxd: print "" print pxd_text if len(pxds_out) > 0 and pxd_text is not None: fname = os.path.join(pxds_out, "%s.pxd" % comp_name.split("::")[-1] ) with open(fname, "w" ) as f: f.write(pxd_text) testresults = TestResultHandler() # Iterate through all xml files generated by doxygen (these are all the # classes available in OpenMS) for class_cntr, f in enumerate(xml_files): # Only look out for one specific pxd file (see option --generate_pxd_for) if len(generate_pxd) > 0: if f.find(generate_pxd) == -1: continue # Try to parse the doxygen file dfile = DoxygenXMLFile(f) res = dfile.parse_doxygen() if dfile.parsing_error: # e.g. <computeroutput><bold></computeroutput> cnt.skipped_could_not_parse += 1 msg = "Skip:: No-parse :: could not parse file %s with error %s" % (f, dfile.parsing_error_message) tres = TestResult(False, msg, name="%s_test" % f ) testresults.append([ tres ]) continue elif os.path.basename(f) == "index.xml": # Skip the index file continue # Parse class and namespace # Skip certain namespaces or those without any namespace (we are only # interested in the OpenMS and OpenSwath namespace). compound = res.get_compounddef() comp_name = compound.get_compoundname() if len(comp_name.split("::") ) == 1: # Not inside a namespace -> skip continue namespace = comp_name.split("::")[0] if namespace in ["std", "Ui", "xercesc", "seqan"]: # Namespace std, xerces, UI -> skip continue elif comp_name.startswith("ms::numpress"): # MS Numpress namespace continue elif not (comp_name.startswith("OpenMS") or comp_name.startswith("OpenSwath") ): # Continue without checking or generating a testreport print "Unknown namespace", comp_name continue # Skip files which are listed in the "ignore" file if ignorefile.isNameIgnored(comp_name): msg = "Skip:: Ignored :: Class %s (file %s)" % (comp_name, f) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([ tres ]) cnt.skipped_ignored += 1 continue # Ignore private/protected classes if compound.prot != "public": msg = "Skip:: Protected :: Compound %s is not public, skip" % (comp_name) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([ tres ]) cnt.skipped_protected += 1 continue # Get file location and skip empty files file_location = dfile.getCompoundFileLocation() if file_location is None: msg = "Skip:: No-data :: there is no source file for %s" % f tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([ tres ]) cnt.skipped_no_location += 1 continue # Skip empty classes openms_file = OpenMSSourceFile(file_location) maintainer = openms_file.getMaintainer() if dfile.isEmpty(True): msg = "Skip:: No-data :: File is empty (no section definitions found or only definitions found) in file %s" % f tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) tres.maintainer = maintainer testresults.append([ tres ]) cnt.skipped_no_sections += 1 continue # Retrieve all associated pxd files with this specific header file file_location_key = file_location if len(file_location.split("include/")) > 1: file_location_key = file_location.split("include/")[1] if file_location_key in pxd_file_matching: pxdfiles = pxd_file_matching[file_location_key] else: msg = "Skip:: No-pxd :: No pxd file exists for Class %s (File %s) %s" % (comp_name, file_location, f) tres = TestResult(False, msg, name="Missing_%s_test" % comp_name ) tres.maintainer = maintainer testresults.append([ tres ]) cnt.skipped_no_pxd_file += 1 pxd_text = dfile.get_pxd_from_class(dfile, file_location, xml_output_path) pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd) continue # Parse the pxd files corresponding to this doxygen XML file try: pxd_class = PXDFile.parse_multiple_files(pxdfiles, comp_name) pxdfile = pxd_class.pxdfile except PXDFileParseError as e: # TODO specific exception msg = "Skip:: No-pxd :: " + e.message + "for %s (in pxd file %s)" % (comp_name, pxdfiles) tres = TestResult(False, msg, name="Missing_%s_test" % comp_name ) tres.maintainer = maintainer testresults.append([ tres ]) cnt.skipped_no_pxd_match += 1 pxd_text = dfile.get_pxd_from_class(dfile, file_location, xml_output_path) pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd) continue # Count the current file cnt.parsed += 1 # Loop through all methods which are listed in the doxygen XML file and match them to the pxd file classtestresults = [] for method_cntr,mdef in enumerate(dfile.iterMemberDef()): if mdef.get_name() in ignorefile.getIgnoredMethods(comp_name): msg = "Ignore member function/attribute : %s %s %s " % (mdef.kind, mdef.prot, mdef.name) tres = TestResult(True, msg, log_level=10) else: tres = handle_member_definition(mdef, pxd_class, cnt) testname = "%s_%s::%s" % (comp_name, method_cntr, mdef.name) testname = testname.replace("::", "_") testname = re.sub('[^a-zA-Z0-9_]+', '', testname) tres.comp_name = comp_name tres.file_location = file_location tres.pxdfile = pxdfile tres.maintainer = maintainer tres.name = testname classtestresults.append(tres) testresults.append(classtestresults) writeOutput(testresults, output_format, cnt, bin_path)
def checkPythonPxdHeader(src_path, bin_path, ignorefilename, pxds_out, print_pxd, output_format, generate_pxd): """ Checks a set of doxygen xml file against a set of pxd header files For each C++ class found in the doxygen XML files, it tries to identify the corresponding pxd file. If a pxd file exists, it checks whether i) all public functions, enums and attributes are wrapped in Python ii) all void return types are correct in Python (these are not checked at compile time) iii) all fields of an enum are accessible from Python If it finds a method missing, the script suggests an addition and if a whole class is missing, the script writes suggestion .pxd file to a specified location (pxds_out). The output format can either be in text form (human readable) or in xml form which will try to overwrite the cdash Test.xml file to proivide an output to cdash. Please only specify xml output if in your binary you have executed "ctest -D Nightly" or similar. TODO also look at ./doc/doxygen/doxygen-error.log ? Make sure to build the doxygen xmls first with $ make doc_xml """ xml_output_path = os.path.join(bin_path, "doc", "xml_output") xml_files = glob.glob(xml_output_path + "/*.xml") print "Found %s doxygen xml files" % (len(xml_files)) if len(xml_files) == 0: raise Exception( "No doxygen files found in directory:\n%s,\n" % xml_output_path + "Please make sure you build the doxygen xmls (make dox_xml)\n" + "and that you specified the correct directory." ) print "Creating pxd file map" pxd_file_matching = create_pxd_file_map(src_path) cnt = Counter() cnt.total = len(xml_files) ignorefile = IgnoreFile() if len(ignorefilename) > 0: ignorefile.load(ignorefilename) def pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd): if print_pxd: print "" print pxd_text if len(pxds_out) > 0 and pxd_text is not None: fname = os.path.join(pxds_out, "%s.pxd" % comp_name.split("::")[-1]) with open(fname, "w") as f: f.write(pxd_text) testresults = TestResultHandler() for class_cntr, f in enumerate(xml_files): if len(generate_pxd) > 0: if f.find(generate_pxd) == -1: continue dfile = DoxygenXMLFile(f) res = dfile.parse_doxygen() if dfile.parsing_error: # e.g. <computeroutput><bold></computeroutput> cnt.skipped_could_not_parse += 1 msg = "Skip:: No-parse :: could not parse file %s with error %s" % (f, dfile.parsing_error_message) tres = TestResult(False, msg, name="%s_test" % f) testresults.append([tres]) continue elif os.path.basename(f) == "index.xml": # Skip the index continue compound = res.get_compounddef() comp_name = compound.get_compoundname() if not (comp_name.startswith("OpenMS") or comp_name.startswith("OpenSwath")): # Continue without checking or generating a testreport continue if ignorefile.isNameIgnored(comp_name): msg = "Skip:: Ignored :: Class %s (file %s)" % (comp_name, f) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([tres]) cnt.skipped_ignored += 1 continue if compound.prot != "public": msg = "Skip:: Protected :: Compound %s is not public, skip" % (comp_name) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([tres]) cnt.skipped_protected += 1 continue file_location = dfile.getCompoundFileLocation() if file_location is None: msg = "Skip:: No-data :: there is no source file for %s" % f tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) testresults.append([tres]) cnt.skipped_no_location += 1 continue openms_file = OpenMSSourceFile(file_location) maintainer = openms_file.getMaintainer() if dfile.isEmpty(True): msg = ( "Skip:: No-data :: File is empty (no section definitions found or only definitions found) in file %s" % f ) tres = TestResult(True, msg, log_level=10, name="%s_test" % comp_name) tres.maintainer = maintainer testresults.append([tres]) cnt.skipped_no_sections += 1 continue if file_location in pxd_file_matching: pxdfiles = pxd_file_matching[file_location] else: msg = "Skip:: No-pxd :: No pxd file exists for Class %s (File %s) %s" % (comp_name, file_location, f) tres = TestResult(False, msg, name="Missing_%s_test" % comp_name) tres.maintainer = maintainer testresults.append([tres]) cnt.skipped_no_pxd_file += 1 pxd_text = dfile.get_pxd_from_class(dfile, file_location, xml_output_path) pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd) continue try: pxd_class = PXDFile.parse_multiple_files(pxdfiles, comp_name) pxdfile = pxd_class.pxdfile except PXDFileParseError as e: # TODO specific exception msg = "Skip:: No-pxd :: " + e.message + "for %s (in pxd file %s)" % (comp_name, pxdfiles) tres = TestResult(False, msg, name="Missing_%s_test" % comp_name) tres.maintainer = maintainer testresults.append([tres]) cnt.skipped_no_pxd_match += 1 pxd_text = dfile.get_pxd_from_class(dfile, file_location, xml_output_path) pxd_text_printout(pxd_text, pxds_out, comp_name, print_pxd) continue cnt.parsed += 1 # Loop through all methods classtestresults = [] for method_cntr, mdef in enumerate(dfile.iterMemberDef()): if mdef.get_name() in ignorefile.getIgnoredMethods(comp_name): msg = "Ignore member function/attribute : %s %s %s " % (mdef.kind, mdef.prot, mdef.name) tres = TestResult(True, msg, log_level=10) else: tres = handle_member_definition(mdef, pxd_class, cnt) testname = "%s_%s::%s" % (comp_name, method_cntr, mdef.name) testname = testname.replace("::", "_") testname = re.sub("[^a-zA-Z0-9_]+", "", testname) tres.comp_name = comp_name tres.file_location = file_location tres.pxdfile = pxdfile tres.maintainer = maintainer tres.name = testname classtestresults.append(tres) testresults.append(classtestresults) ################################### # Output ################################### if output_format in ["text", "text-verbose", "text-quiet"]: for classtestresults in testresults: if len(classtestresults) > 1: t = classtestresults[0] lenfailed = len([t for t in classtestresults if not t.isPassed()]) if lenfailed > 0: print "== Test results for element %s - from Cpp file %s with maintainer %s and corresponding pxd file %s" % ( t.comp_name, t.file_location, t.maintainer, t.pxdfile, ) for tres in classtestresults: if not tres.isPassed(): print tres.message elif tres.log_level >= 10 and output_format in ["text", "text-verbose"]: print tres.message elif tres.log_level >= 0 and output_format in ["text-verbose"]: print tres.message elif output_format == "xml": # check if all files required to report in CDash are present tag_file = os.path.join(bin_path, "Testing", "TAG") try: # read the first line of tagfile (TAG) -> if it does not exist, # an IOError is thrown with open(tag_file) as f: ctestReportingPath = f.readline().strip() ctestReportingPath = os.path.join(bin_path, "Testing", ctestReportingPath) if not os.path.exists(ctestReportingPath): raise Exception("Missing directory at %s" % (ctestReportingPath)) except IOError: raise Exception("Missing nightly test information at %s" % (tag_file)) template_path = os.path.join(ctestReportingPath, "Test.xml") testresults.to_cdash_xml(template_path, template_path) else: raise Exception("Unknown output format %s" % output_format) cnt.print_stats() cnt.print_skipping_reason()