def run(): print("LiSiCA initialiser program") if not os.path.isdir(os.path.join(HOME_DIRECTORY,"LiSiCA")): configure=Configuration() exe_filename=configure.exe_File() upgrader=Upgrader() jsonData=upgrader.findLatestVersion() url=jsonData['zipball_url'] installer_Object=Installer() installer_Object.downloadInstall(url) installer_Object.extractInstall() else : lisica_Folder=os.path.join(HOME_DIRECTORY,"LiSiCA") import FileStructure file_StructureObj=FileStructure.Directory_Structure(lisica_Folder) if file_StructureObj.check()==True: pass else: tkMessageBox.showerror("Missing Files", """LiSiCA Directory is corrupted. Missing files or folders. Try reinstalling the plugin """) #modify this exe_path="so" import License if License.checkLicenseStatus()==None: License.activate(exe_path) else: import Plugin_GUI Plugin_GUI.main()
def upgrade(self): print "upgrading lisicagui to the latest version = ", self.latestVersionGUI self.downloadInstall() self.extractInstall() sys.path.append(os.path.normpath(os.path.join(LISICA_DIRECTORY,"modules"))) import License License.writeToInsilabTxt(self.latestVersionGUI) print "Upgrade finished successfully!"
def findCurrentVersion(self): import License #for GUI license_details=License.checkVersionGUI() self.licenseCodeGUI = license_details['Key'] self.currentVersionGUI = license_details['Version'] #for lisica program license_details=License.checkLicenseStatus() self.licenseCodeLisica = license_details['Key'] self.currentVersionLisica = license_details['Version']
def run(): print("Initialising LiSiCA...") try: sys.path.remove('') except: pass upgraderObj = UpgraderGitlab() if upgraderObj.firstUpgrade(): upgraderObj.findLatestVersionGUI() upgraderObj.upgrade() sys.path.append(os.path.normpath(os.path.join(LISICA_DIRECTORY,"modules"))) import License if License.checkVersionGUI()==None: upgraderObj.findLatestVersionGUI() upgraderObj.upgrade() del upgraderObj configure=Configuration() exe_filename=configure.exe_File() exe_path=os.path.normpath(os.path.join(LISICA_DIRECTORY,"bin",exe_filename)) st = os.stat(exe_path) os.chmod(exe_path, st.st_mode | stat.S_IEXEC) import LisicaGUI LisicaGUI.main()
def findCurrentVersion(self): import License #for GUI self.currentVersionGUI = License.checkVersionGUI()['Version']
def main(argv): print """ __ _ __ __ __ ____ _ / / (_)/ /_ / /_ / /___ / __ \ ____ _ _____ _ __ (_)____ / / / // __// __// // _ \ / / / // __ `// ___/| | /| / // // __ \\ / /___ / // /_ / /_ / // __// /_/ // /_/ // / | |/ |/ // // / / / /_____//_/ \__/ \__//_/ \___//_____/ \__,_//_/ |__/|__//_//_/ /_/ _ _ ___ /_| /|/| _/__/' /_| _ / _ ' _ (_ _ _ _ _ _ / ( | / |(//(///()/) ( |/)(/((/_) /_) / / (///)(-((/()/ /( / LittleDarwin version %s Copyright (C) 2014 Ali Parsai LittleDarwin comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; run LittleDarwin --license for details. """ % littleDarwinVersion # let's caution the user that we are using the alternative method. # if not timeoutSupport: # print "!!! CAUTION !!!\nmodule subprocess32 not found. using alternative method. build procedure may hang in an infinite loop.\n\n" # parsing input options optionParser = OptionParser() optionParser.add_option("-m", "--mutate", action="store_true", dest="isMutationActive", default=False, help="Activate the mutation phase.") optionParser.add_option("-b", "--build", action="store_true", dest="isBuildActive", default=False, help="Activate the build phase.") optionParser.add_option("-v", "--verbose", action="store_true", dest="isVerboseActive", default=False, help="Verbose output.") optionParser.add_option("-p", "--path", action="store", dest="sourcePath", default=os.path.dirname(os.path.realpath(__file__)), help="Path to source files.") optionParser.add_option("-t", "--build-path", action="store", dest="buildPath", default=os.path.dirname(os.path.realpath(__file__)), help="Path to build system working directory.") optionParser.add_option("-c", "--build-command", action="store", dest="buildCommand", default="mvn,test", help="Command to run the build system. If it includes more than a single argument, they should be seperated by comma. For example: mvn,install") optionParser.add_option("--test-path", action="store", dest="testPath", default="***dummy***", help="path to test project build system working directory") optionParser.add_option("--test-command", action="store", dest="testCommand", default="***dummy***", help="Command to run the test-suite. If it includes more than a single argument, they should be seperated by comma. For example: mvn,test") optionParser.add_option("--initial-build-command", action="store", dest="initialBuildCommand", default="***dummy***", help="Command to run the initial build.") optionParser.add_option("--timeout", type="int", action="store", dest="timeout", default=60, help="Timeout value for the build process.") optionParser.add_option("--cleanup", action="store", dest="cleanUp", default="***dummy***", help="Commands to run after each build.") optionParser.add_option("--use-alternate-database", action="store", dest="alternateDb", default="***dummy***", help="Path to alternative database.") optionParser.add_option("--license", action="store_true", dest="isLicenseActive", default=False, help="Output the license and exit.") optionParser.add_option("--higher-order", type="int", action="store", dest="higherOrder", default=1, help="Define order of mutation. Use -1 to dynamically adjust per class.") optionParser.add_option("--null-check", action="store_true", dest="isNullCheck", default=False, help="Use null check mutation operators.") optionParser.add_option("--all", action="store_true", dest="isAll", default=False, help="Use all mutation operators.") (options, args) = optionParser.parse_args() if options.isLicenseActive: License.outputLicense() sys.exit(0) if options.higherOrder <= 1 and options.higherOrder != -1: higherOrder = 1 else: higherOrder = options.higherOrder # there is an upside in not running two phases together. we may include the ability to edit some mutants later. if options.isBuildActive and options.isMutationActive: print "it is strongly recommended to do the analysis in two different phases.\n\n" #***************************************************************************************************************** #---------------------------------------- mutant generation phase ------------------------------------------------ #***************************************************************************************************************** if options.isMutationActive: assert options.isVerboseActive is not None # creating our module objects. javaRead = JavaRead(options.isVerboseActive) javaParse = JavaParse(options.isVerboseActive) javaMutate = JavaMutate(javaParse, options.isVerboseActive) totalMutantCount = 0 try: assert os.path.isdir(options.sourcePath) except AssertionError as exception: print "source path must be a directory." sys.exit(1) # getting the list of files. javaRead.listFiles(os.path.abspath(options.sourcePath)) fileCounter = 0 fileCount = len(javaRead.fileList) # creating a database for generated mutants. the format of this database is different on different platforms, # so it cannot be simply copied from a platform to another. databasePath = os.path.join(javaRead.targetDirectory, "mutationdatabase") print "source dir: ", javaRead.sourceDirectory print "target dir: ", javaRead.targetDirectory print "creating mutation database: ", databasePath mutationDatabase = shelve.open(databasePath, "c") mutantTypeDatabase = dict() # go through each file, parse it, calculate all mutations, and generate files accordingly. for srcFile in javaRead.fileList: print "(" + str(fileCounter + 1) + "/" + str(fileCount) + ") source file: ", srcFile targetList = list() try: # parsing the source file into a tree. tree = javaParse.parse(javaRead.getFileContent(srcFile)) # assigning a number to each node to be able to identify it uniquely. javaParse.numerify(tree) # javaParse.tree2DOT(tree) except Exception as e: # Java 8 problem print "Error in parsing, skipping the file." sys.stderr.write(e.message) continue fileCounter += 1 if options.isAll: enabledMutators = "all" elif options.isNullCheck: enabledMutators = "null-check" else: enabledMutators = "classical" # apply mutations on the tree and receive the resulting mutants as a list of strings, and a detailed # list of which operators created how many mutants. mutated, mutantTypes = javaMutate.applyMutators(tree, higherOrder, enabledMutators) print "--> mutations found: ", len(mutated) # go through all mutant types, and add them in total. also output the info to the user. for mutantType in mutantTypes.keys(): if mutantTypes[mutantType] > 0: print "---->", mutantType, ":", mutantTypes[mutantType] mutantTypeDatabase[mutantType] = mutantTypes[mutantType] + mutantTypeDatabase.get(mutantType, 0) totalMutantCount += len(mutated) # for each mutant, generate the file, and add it to the list. for mutatedFile in mutated: targetList.append(javaRead.generateNewFile(srcFile, mutatedFile)) # if the list is not empty (some mutants were found), put the data in the database. if len(targetList) != 0: mutationDatabase[os.path.relpath(srcFile, javaRead.sourceDirectory)] = targetList mutationDatabase.close() print "total mutations found: ", totalMutantCount for mutantType in mutantTypeDatabase.keys(): if mutantTypeDatabase[mutantType] > 0: print "-->", mutantType, ":", mutantTypeDatabase[mutantType] #***************************************************************************************************************** #---------------------------------------- test suite running phase ----------------------------------------------- #***************************************************************************************************************** if options.isBuildActive: # let's tell the user upfront that this may corrupt the source code. print "\n\n!!! CAUTION !!!" print "code can be changed accidentally. use a backup version.\n" reportGenerator = ReportGenerator() if options.alternateDb == "***dummy***": databasePath = os.path.abspath(os.path.join(options.sourcePath, os.path.pardir, "mutated", "mutationdatabase")) else: databasePath = options.alternateDb resultsDatabasePath = databasePath + "-results" reportGenerator.initiateDatabase(resultsDatabasePath) try: if os.path.basename(options.buildPath) == "pom.xml": assert os.path.isfile(options.buildPath) buildDir = os.path.abspath(os.path.dirname(options.buildPath)) else: assert os.path.isdir(options.buildPath) buildDir = os.path.abspath(options.buildPath) except AssertionError as exception: print "build system working directory should be a directory." # check if we have separate test-suite if options.testCommand != "***dummy***": separateTestSuite = True if options.testPath == "***dummy***": testDir = buildDir else: try: if os.path.basename(options.buildPath) == "pom.xml": assert os.path.isfile(options.buildPath) testDir = os.path.abspath(os.path.dirname(options.testPath)) else: assert os.path.isdir(options.buildPath) testDir = os.path.abspath(options.testPath) except AssertionError as exception: print "test project build system working directory should be a directory." else: separateTestSuite = False # try to open the database. if it can't be opened, it means that it does not exist or it is corrupt. try: mutationDatabase = shelve.open(databasePath, "r") except: print "cannot open mutation database. it may be corrupted or unavailable. delete all generated files and run the mutant generation phase again." sys.exit(1) databaseKeys = mutationDatabase.keys() assert isinstance(databaseKeys, list) # let's sort the mutants by name to create the possibility of following the flow of the process by user. databaseKeys.sort() # only here for debugging purposes # for desired in databaseKeys: # if "PluginMap.java" in desired: # desiredIndex = databaseKeys.index(desired) # break # # databaseKeys.insert(0, databaseKeys.pop(desiredIndex)) # mutationDatabaseLength = len(databaseKeys) textReportData = list() htmlReportData = list() fileCounter = 0 # initial build check to avoid false results. the system must be able to build cleanly without errors. # use build command for the initial build unless it is explicitly provided. if options.initialBuildCommand == "***dummy***": commandString = options.buildCommand.split(',') else: commandString = options.initialBuildCommand.split(',') print "Initial build... ", try: processKilled, processExitCode, initialOutput = timeoutAlternative(commandString, workingDirectory=buildDir, timeout=int(options.timeout)) # initialOutput = subprocess.check_output(commandString, stderr=subprocess.STDOUT, cwd=buildDir) # workaround for older python versions if processKilled or processExitCode: raise subprocess.CalledProcessError(1 if processKilled else processExitCode, commandString, initialOutput) with open(os.path.abspath(os.path.join(options.sourcePath, os.path.pardir, "mutated", "initialbuild.txt")), 'w') as content_file: content_file.write(initialOutput) print "done.\n\n" except subprocess.CalledProcessError as exception: initialOutput = exception.output with open(os.path.abspath(os.path.join(options.sourcePath, os.path.pardir, "mutated", "initialbuild.txt")), 'w') as content_file: content_file.write(initialOutput) print "failed.\n\nInitial build failed. Try building the system manually first to make sure it can be built." sys.exit(1) totalMutantCount = 0 totalMutantCounter = 0 for key in databaseKeys: totalMutantCount += len(mutationDatabase[key]) startTime = time.time() # running the build system for each mutant. for key in databaseKeys: fileCounter += 1 print "(" + str(fileCounter) + "/" + str(mutationDatabaseLength) + ") collecting results for ", key mutantCount = len(mutationDatabase[key]) mutantCounter = 0 successList = list() failureList = list() # for each mutant, replace the original file, run the build, store the results for replacementFileRel in mutationDatabase[key]: replacementFile = os.path.join(options.sourcePath, os.path.pardir, "mutated", replacementFileRel) mutantCounter += 1 totalMutantCounter += 1 # let's make sure that runOutput is empty, and not None to begin with. runOutput = "" runOutputTest = "" # replace the original file with the mutant shutil.copyfile(replacementFile, os.path.join(options.sourcePath, key)) commandString = options.buildCommand.split(',') if separateTestSuite: testCommandString = options.testCommand.split(',') try: # if we have timeout support, simply run the command with timeout support from subprocess32 # if timeoutSupport: # runOutput = subprocess.check_output(commandString, stderr=subprocess.STDOUT, cwd=buildDir, # timeout=int(options.timeout)) # if separateTestSuite: # runOutput += subprocess.check_output(testCommandString, stderr=subprocess.STDOUT, cwd=testDir, # timeout=int(options.timeout)) # else, run our alternative method # else: processKilled, processExitCode, runOutput = timeoutAlternative(commandString, workingDirectory=buildDir, timeout=int(options.timeout)) # raise the same exception as the original check_output. if processKilled or processExitCode: raise subprocess.CalledProcessError(1 if processKilled else processExitCode, commandString, runOutput) if separateTestSuite: processKilled, processExitCode, runOutputTest = timeoutAlternative(testCommandString, workingDirectory=testDir, timeout=int(options.timeout)) # raise the same exception as the original check_output. if processKilled or processExitCode: raise subprocess.CalledProcessError(1 if processKilled else processExitCode, commandString, "\n".join([runOutput, runOutputTest])) # if we are here, it means no exceptions happened, so lets add this to our success list. runOutput += "\n" + runOutputTest successList.append(os.path.basename(replacementFile)) # putting two exceptions in one except clause, specially when one of them is not defined on some # platforms does not look like a good idea; even though both of them do exactly the same thing. except subprocess.CalledProcessError as exception: runOutput = exception.output # oops, error. let's add this to failure list. failureList.append(os.path.basename(replacementFile)) # except subprocess.TimeoutExpired as exception: # runOutput = exception.output # failureList.append(os.path.basename(replacementFile)) targetTextOutputFile = os.path.splitext(replacementFile)[0] + ".txt" # we can't use print, since we like to write on the same line again. sys.stdout.write( "elapsed: " + str(datetime.timedelta(seconds=int(time.time() - startTime))) + " remaining: " + str( datetime.timedelta(seconds=int((float(time.time() - startTime) / totalMutantCounter) * float( totalMutantCount - totalMutantCounter)))) + " total: " + str( totalMutantCounter) + "/" + str(totalMutantCount) + " current: " + str( mutantCounter) + "/" + str(mutantCount) + " *** survived: " + str( len(successList)) + " - killed: " + str(len(failureList)) + " \r") sys.stdout.flush() # writing the build output to disk. with open(targetTextOutputFile, 'w') as content_file: content_file.write(runOutput) # if there's a cleanup option, execute it. the results will be ignored because we don't want our process # to be interrupted if there's nothing to clean up. if options.cleanUp != "***dummy***": subprocess.call(options.cleanUp.split(","), cwd=buildDir) if separateTestSuite: subprocess.call(options.cleanUp.split(","), cwd=testDir) #workaround: #shutil.rmtree(os.path.join(testDir,"VolumetryLoggerTest"),ignore_errors=True) # all mutants must be checked by now, so we should have a complete divide between success and failure. assert len(successList) + len(failureList) == mutantCount # append the information for this file to the reports. textReportData.append(key + ": survived (" + str(len(successList)) + "/" + str(mutantCount) + ") -> " + str( successList) + " - killed (" + str(len(failureList)) + "/" + str(mutantCount) + ") -> " + str( failureList) + "\r\n") htmlReportData.append([key, len(successList), mutantCount]) # we are done with the file. let's return it to the original state. shutil.copyfile(os.path.join(os.path.dirname(replacementFile), "original.java"), os.path.join(options.sourcePath, key)) # generate an HTML report for the file. targetHTMLOutputFile = os.path.join(os.path.dirname(replacementFile), "results.html") with open(targetHTMLOutputFile, 'w') as content_file: content_file.write( reportGenerator.generateHTMLReportPerFile(key, targetHTMLOutputFile, successList, failureList)) print "\n\n" # write final text report. with open(os.path.abspath(os.path.join(options.sourcePath, os.path.pardir, "mutated", "report.txt")), 'w') as textReportFile: textReportFile.writelines(textReportData) # write final HTML report. targetHTMLReportFile = os.path.abspath( os.path.join(options.sourcePath, os.path.pardir, "mutated", "report.html")) with open(targetHTMLReportFile, 'w') as htmlReportFile: htmlReportFile.writelines(reportGenerator.generateHTMLFinalReport(htmlReportData, targetHTMLReportFile)) # if neither build nor mutation phase is active, let's help the user. if not (options.isBuildActive or options.isMutationActive): optionParser.print_help()
def _compile_tags (self): # Versions & Source version_of = None version = self._db.get('version', None) versions = [x['id'] for x in self._versions if x['id']!=self['id']] source = self._parent_id if self['version'] != 1: version_of = self._replacements.get('replaces') # Formats has_formats = None is_format_of = None if self._formats: format_list =[x['format'] for x in self._formats if x['id']!=self['id']] has_formats = dict.fromkeys(format_list).keys() for f in self._formats: if f['source'] == None and f['id'] != self['id']: is_format_of = f['id'] self._tags = { 'Creator': self._db.get('creator_id'), 'Date': max(self._db.get('date_modified'), self._db.get('date_edited'), self._db.get('date_created')), 'Date Created': self._db.get('date_created'), 'Date (Modified)': self._db.get('date_modified'), 'Date Available': self._db.get('date_available'), 'Description': self._db.get('description'), 'Extent': self._file.get('extent'), 'Format': self._file.get('formats_id'), 'Has Format': has_formats, 'Has Part': self._parts.get('has_parts_of'), 'Has Version': versions, 'Identifier': self._db.get('id'), 'Is Format Of': is_format_of, 'Is Part Of': self._parts.get('is_part_of'), 'Is Referenced By': self._db.get('collections_id'), 'Is Replaced By': self._replacements.get('replaced_by'), 'Is Version Of': version_of, 'Language': self._db.get('language'), 'Publisher': self._db.get('publisher_id'), 'Relation': self._collection, 'Replaces': self._replacements.get('replaces'), 'Source': source, 'Subject': self._db.get('subject'), 'Title': self._db.get('title'), 'Type': self._db.get('asset_types_id'), 'Rights': self._db.get('licenses_id'), } if self['Creator']: self._tags['Creator'] = Auth.get_user_name (self['tags']['Creator']) if self['Publisher']: self._tags['Publisher'] = Auth.get_user_name (self['tags']['Publisher']) if self['Rights']: self._tags['Rights'] = License.get_license_name(self['tags']['Rights']) if self['Format']: self._tags['Format'] = Format.get_format_name (self['tags']['Format']) if self['Type']: self._tags['Type'] = Type.get_type_name (self['tags']['Type']) for key in self._tags.keys(): if key.startswith('Date') and self._tags[key] == '0000-00-00 00:00:00': self._tags[key] = None
def main(argv): print """ __ _ __ __ __ ____ _ / / (_)/ /_ / /_ / /___ / __ \ ____ _ _____ _ __ (_)____ / / / // __// __// // _ \ / / / // __ `// ___/| | /| / // // __ \\ / /___ / // /_ / /_ / // __// /_/ // /_/ // / | |/ |/ // // / / / /_____//_/ \__/ \__//_/ \___//_____/ \__,_//_/ |__/|__//_//_/ /_/ _ _ ___ /_| /|/| _/__/' /_| _ / _ ' _ (_ _ _ _ _ _ / ( | / |(//(///()/) ( |/)(/((/_) /_) / / (///)(-((/()/ /( / LittleDarwin version %s Copyright (C) 2014 Ali Parsai LittleDarwin comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; run LittleDarwin --license for details. """ % littleDarwinVersion # let's caution the user that we are using the alternative method. # if not timeoutSupport: # print "!!! CAUTION !!!\nmodule subprocess32 not found. using alternative method. build procedure may hang in an infinite loop.\n\n" # parsing input options optionParser = OptionParser() optionParser.add_option("-m", "--mutate", action="store_true", dest="isMutationActive", default=False, help="Activate the mutation phase.") optionParser.add_option("-b", "--build", action="store_true", dest="isBuildActive", default=False, help="Activate the build phase.") optionParser.add_option("-v", "--verbose", action="store_true", dest="isVerboseActive", default=False, help="Verbose output.") optionParser.add_option("-p", "--path", action="store", dest="sourcePath", default=os.path.dirname( os.path.realpath(__file__)), help="Path to source files.") optionParser.add_option("-t", "--build-path", action="store", dest="buildPath", default=os.path.dirname( os.path.realpath(__file__)), help="Path to build system working directory.") optionParser.add_option( "-c", "--build-command", action="store", dest="buildCommand", default="mvn,test", help= "Command to run the build system. If it includes more than a single argument, they should be seperated by comma. For example: mvn,install" ) optionParser.add_option( "--test-path", action="store", dest="testPath", default="***dummy***", help="path to test project build system working directory") optionParser.add_option( "--test-command", action="store", dest="testCommand", default="***dummy***", help= "Command to run the test-suite. If it includes more than a single argument, they should be seperated by comma. For example: mvn,test" ) optionParser.add_option("--initial-build-command", action="store", dest="initialBuildCommand", default="***dummy***", help="Command to run the initial build.") optionParser.add_option("--timeout", type="int", action="store", dest="timeout", default=60, help="Timeout value for the build process.") optionParser.add_option("--cleanup", action="store", dest="cleanUp", default="***dummy***", help="Commands to run after each build.") optionParser.add_option("--use-alternate-database", action="store", dest="alternateDb", default="***dummy***", help="Path to alternative database.") optionParser.add_option("--license", action="store_true", dest="isLicenseActive", default=False, help="Output the license and exit.") optionParser.add_option( "--higher-order", type="int", action="store", dest="higherOrder", default=1, help="Define order of mutation. Use -1 to dynamically adjust per class." ) optionParser.add_option("--null-check", action="store_true", dest="isNullCheck", default=False, help="Use null check mutation operators.") optionParser.add_option("--all", action="store_true", dest="isAll", default=False, help="Use all mutation operators.") (options, args) = optionParser.parse_args() if options.isLicenseActive: License.outputLicense() sys.exit(0) if options.higherOrder <= 1 and options.higherOrder != -1: higherOrder = 1 else: higherOrder = options.higherOrder # there is an upside in not running two phases together. we may include the ability to edit some mutants later. if options.isBuildActive and options.isMutationActive: print "it is strongly recommended to do the analysis in two different phases.\n\n" #***************************************************************************************************************** #---------------------------------------- mutant generation phase ------------------------------------------------ #***************************************************************************************************************** if options.isMutationActive: assert options.isVerboseActive is not None # creating our module objects. javaRead = JavaRead(options.isVerboseActive) javaParse = JavaParse(options.isVerboseActive) javaMutate = JavaMutate(javaParse, options.isVerboseActive) totalMutantCount = 0 try: assert os.path.isdir(options.sourcePath) except AssertionError as exception: print "source path must be a directory." sys.exit(1) # getting the list of files. javaRead.listFiles(os.path.abspath(options.sourcePath)) fileCounter = 0 fileCount = len(javaRead.fileList) # creating a database for generated mutants. the format of this database is different on different platforms, # so it cannot be simply copied from a platform to another. databasePath = os.path.join(javaRead.targetDirectory, "mutationdatabase") print "source dir: ", javaRead.sourceDirectory print "target dir: ", javaRead.targetDirectory print "creating mutation database: ", databasePath mutationDatabase = shelve.open(databasePath, "c") mutantTypeDatabase = dict() # go through each file, parse it, calculate all mutations, and generate files accordingly. for srcFile in javaRead.fileList: print "(" + str(fileCounter + 1) + "/" + str( fileCount) + ") source file: ", srcFile targetList = list() try: # parsing the source file into a tree. tree = javaParse.parse(javaRead.getFileContent(srcFile)) # assigning a number to each node to be able to identify it uniquely. javaParse.numerify(tree) # javaParse.tree2DOT(tree) except Exception as e: # Java 8 problem print "Error in parsing, skipping the file." sys.stderr.write(e.message) continue fileCounter += 1 if options.isAll: enabledMutators = "all" elif options.isNullCheck: enabledMutators = "null-check" else: enabledMutators = "classical" # apply mutations on the tree and receive the resulting mutants as a list of strings, and a detailed # list of which operators created how many mutants. mutated, mutantTypes = javaMutate.applyMutators( tree, higherOrder, enabledMutators) print "--> mutations found: ", len(mutated) # go through all mutant types, and add them in total. also output the info to the user. for mutantType in mutantTypes.keys(): if mutantTypes[mutantType] > 0: print "---->", mutantType, ":", mutantTypes[mutantType] mutantTypeDatabase[mutantType] = mutantTypes[ mutantType] + mutantTypeDatabase.get(mutantType, 0) totalMutantCount += len(mutated) # for each mutant, generate the file, and add it to the list. for mutatedFile in mutated: targetList.append( javaRead.generateNewFile(srcFile, mutatedFile)) # if the list is not empty (some mutants were found), put the data in the database. if len(targetList) != 0: mutationDatabase[os.path.relpath( srcFile, javaRead.sourceDirectory)] = targetList mutationDatabase.close() print "total mutations found: ", totalMutantCount for mutantType in mutantTypeDatabase.keys(): if mutantTypeDatabase[mutantType] > 0: print "-->", mutantType, ":", mutantTypeDatabase[mutantType] #***************************************************************************************************************** #---------------------------------------- test suite running phase ----------------------------------------------- #***************************************************************************************************************** if options.isBuildActive: # let's tell the user upfront that this may corrupt the source code. print "\n\n!!! CAUTION !!!" print "code can be changed accidentally. use a backup version.\n" reportGenerator = ReportGenerator() if options.alternateDb == "***dummy***": databasePath = os.path.abspath( os.path.join(options.sourcePath, os.path.pardir, "mutated", "mutationdatabase")) else: databasePath = options.alternateDb resultsDatabasePath = databasePath + "-results" reportGenerator.initiateDatabase(resultsDatabasePath) try: if os.path.basename(options.buildPath) == "pom.xml": assert os.path.isfile(options.buildPath) buildDir = os.path.abspath(os.path.dirname(options.buildPath)) else: assert os.path.isdir(options.buildPath) buildDir = os.path.abspath(options.buildPath) except AssertionError as exception: print "build system working directory should be a directory." # check if we have separate test-suite if options.testCommand != "***dummy***": separateTestSuite = True if options.testPath == "***dummy***": testDir = buildDir else: try: if os.path.basename(options.buildPath) == "pom.xml": assert os.path.isfile(options.buildPath) testDir = os.path.abspath( os.path.dirname(options.testPath)) else: assert os.path.isdir(options.buildPath) testDir = os.path.abspath(options.testPath) except AssertionError as exception: print "test project build system working directory should be a directory." else: separateTestSuite = False # try to open the database. if it can't be opened, it means that it does not exist or it is corrupt. try: mutationDatabase = shelve.open(databasePath, "r") except: print "cannot open mutation database. it may be corrupted or unavailable. delete all generated files and run the mutant generation phase again." sys.exit(1) databaseKeys = mutationDatabase.keys() assert isinstance(databaseKeys, list) # let's sort the mutants by name to create the possibility of following the flow of the process by user. databaseKeys.sort() # only here for debugging purposes # for desired in databaseKeys: # if "PluginMap.java" in desired: # desiredIndex = databaseKeys.index(desired) # break # # databaseKeys.insert(0, databaseKeys.pop(desiredIndex)) # mutationDatabaseLength = len(databaseKeys) textReportData = list() htmlReportData = list() fileCounter = 0 # initial build check to avoid false results. the system must be able to build cleanly without errors. # use build command for the initial build unless it is explicitly provided. if options.initialBuildCommand == "***dummy***": commandString = options.buildCommand.split(',') else: commandString = options.initialBuildCommand.split(',') print "Initial build... ", try: processKilled, processExitCode, initialOutput = timeoutAlternative( commandString, workingDirectory=buildDir, timeout=int(options.timeout)) # initialOutput = subprocess.check_output(commandString, stderr=subprocess.STDOUT, cwd=buildDir) # workaround for older python versions if processKilled or processExitCode: raise subprocess.CalledProcessError( 1 if processKilled else processExitCode, commandString, initialOutput) with open( os.path.abspath( os.path.join(options.sourcePath, os.path.pardir, "mutated", "initialbuild.txt")), 'w') as content_file: content_file.write(initialOutput) print "done.\n\n" except subprocess.CalledProcessError as exception: initialOutput = exception.output with open( os.path.abspath( os.path.join(options.sourcePath, os.path.pardir, "mutated", "initialbuild.txt")), 'w') as content_file: content_file.write(initialOutput) print "failed.\n\nInitial build failed. Try building the system manually first to make sure it can be built." sys.exit(1) totalMutantCount = 0 totalMutantCounter = 0 for key in databaseKeys: totalMutantCount += len(mutationDatabase[key]) startTime = time.time() # running the build system for each mutant. for key in databaseKeys: fileCounter += 1 print "(" + str(fileCounter) + "/" + str( mutationDatabaseLength) + ") collecting results for ", key mutantCount = len(mutationDatabase[key]) mutantCounter = 0 successList = list() failureList = list() # for each mutant, replace the original file, run the build, store the results for replacementFileRel in mutationDatabase[key]: replacementFile = os.path.join(options.sourcePath, os.path.pardir, "mutated", replacementFileRel) mutantCounter += 1 totalMutantCounter += 1 # let's make sure that runOutput is empty, and not None to begin with. runOutput = "" runOutputTest = "" # replace the original file with the mutant shutil.copyfile(replacementFile, os.path.join(options.sourcePath, key)) commandString = options.buildCommand.split(',') if separateTestSuite: testCommandString = options.testCommand.split(',') try: # if we have timeout support, simply run the command with timeout support from subprocess32 # if timeoutSupport: # runOutput = subprocess.check_output(commandString, stderr=subprocess.STDOUT, cwd=buildDir, # timeout=int(options.timeout)) # if separateTestSuite: # runOutput += subprocess.check_output(testCommandString, stderr=subprocess.STDOUT, cwd=testDir, # timeout=int(options.timeout)) # else, run our alternative method # else: processKilled, processExitCode, runOutput = timeoutAlternative( commandString, workingDirectory=buildDir, timeout=int(options.timeout)) # raise the same exception as the original check_output. if processKilled or processExitCode: raise subprocess.CalledProcessError( 1 if processKilled else processExitCode, commandString, runOutput) if separateTestSuite: processKilled, processExitCode, runOutputTest = timeoutAlternative( testCommandString, workingDirectory=testDir, timeout=int(options.timeout)) # raise the same exception as the original check_output. if processKilled or processExitCode: raise subprocess.CalledProcessError( 1 if processKilled else processExitCode, commandString, "\n".join([runOutput, runOutputTest])) # if we are here, it means no exceptions happened, so lets add this to our success list. runOutput += "\n" + runOutputTest successList.append(os.path.basename(replacementFile)) # putting two exceptions in one except clause, specially when one of them is not defined on some # platforms does not look like a good idea; even though both of them do exactly the same thing. except subprocess.CalledProcessError as exception: runOutput = exception.output # oops, error. let's add this to failure list. failureList.append(os.path.basename(replacementFile)) # except subprocess.TimeoutExpired as exception: # runOutput = exception.output # failureList.append(os.path.basename(replacementFile)) targetTextOutputFile = os.path.splitext( replacementFile)[0] + ".txt" # we can't use print, since we like to write on the same line again. sys.stdout.write("elapsed: " + str( datetime.timedelta(seconds=int(time.time() - startTime)) ) + " remaining: " + str( datetime.timedelta(seconds=int( (float(time.time() - startTime) / totalMutantCounter) * float(totalMutantCount - totalMutantCounter)))) + " total: " + str(totalMutantCounter) + "/" + str(totalMutantCount) + " current: " + str(mutantCounter) + "/" + str(mutantCount) + " *** survived: " + str(len(successList)) + " - killed: " + str(len(failureList)) + " \r") sys.stdout.flush() # writing the build output to disk. with open(targetTextOutputFile, 'w') as content_file: content_file.write(runOutput) # if there's a cleanup option, execute it. the results will be ignored because we don't want our process # to be interrupted if there's nothing to clean up. if options.cleanUp != "***dummy***": subprocess.call(options.cleanUp.split(","), cwd=buildDir) if separateTestSuite: subprocess.call(options.cleanUp.split(","), cwd=testDir) #workaround: #shutil.rmtree(os.path.join(testDir,"VolumetryLoggerTest"),ignore_errors=True) # all mutants must be checked by now, so we should have a complete divide between success and failure. assert len(successList) + len(failureList) == mutantCount # append the information for this file to the reports. textReportData.append(key + ": survived (" + str(len(successList)) + "/" + str(mutantCount) + ") -> " + str(successList) + " - killed (" + str(len(failureList)) + "/" + str(mutantCount) + ") -> " + str(failureList) + "\r\n") htmlReportData.append([key, len(successList), mutantCount]) # we are done with the file. let's return it to the original state. shutil.copyfile( os.path.join(os.path.dirname(replacementFile), "original.java"), os.path.join(options.sourcePath, key)) # generate an HTML report for the file. targetHTMLOutputFile = os.path.join( os.path.dirname(replacementFile), "results.html") with open(targetHTMLOutputFile, 'w') as content_file: content_file.write( reportGenerator.generateHTMLReportPerFile( key, targetHTMLOutputFile, successList, failureList)) print "\n\n" # write final text report. with open( os.path.abspath( os.path.join(options.sourcePath, os.path.pardir, "mutated", "report.txt")), 'w') as textReportFile: textReportFile.writelines(textReportData) # write final HTML report. targetHTMLReportFile = os.path.abspath( os.path.join(options.sourcePath, os.path.pardir, "mutated", "report.html")) with open(targetHTMLReportFile, 'w') as htmlReportFile: htmlReportFile.writelines( reportGenerator.generateHTMLFinalReport( htmlReportData, targetHTMLReportFile)) # if neither build nor mutation phase is active, let's help the user. if not (options.isBuildActive or options.isMutationActive): optionParser.print_help()