def save_application_output(self, application, testClassName, testRunName): """" saves the output of an application to a file This method can only be called if application was stopped before. """ if not application.started: resultDirForTest = self.resultDir + '/' + testClassName + "/" + testRunName if application.nameExtension: fileName = "{0}_{1}_{2}".format(application.name, application.nameExtension, self.name) else: fileName = "{0}_{1}".format(application.name, self.name) stdoutOutputList = application.get_stdout_data() if stdoutOutputList: helper.save_text_file( resultDirForTest + "/" + fileName + ".txt", "".join(stdoutOutputList)) stderrOutputList = application.get_stderr_data() if stderrOutputList: helper.save_text_file( resultDirForTest + "/" + fileName + "_STDERR.txt", "".join(stderrOutputList)) else: log.error( "application output can only be saved if application was stopped before" )
def start_application(self, applicationName, args="", binaryDirectoryOnTarget=None, nameExtension="", env={}, dltAppID=None): #ensure binary is there if binaryDirectoryOnTarget: binaryPathOnTarget = binaryDirectoryOnTarget + '/' + applicationName else: binaryPathOnTarget = applicationName (_, _, resultTest) = self.execute_on_target("type " + binaryPathOnTarget) #test -e cannot be used as it does not work for applications in system path if resultTest != 0: log.error("Error: executable '{0}' could not be found (path: '{1}')".format(applicationName, binaryPathOnTarget)) return Application(None, None, None, applicationName, binaryDirectoryOnTarget, nameExtension) prefix = helper.get_env_var_setting_string(self._get_merged_env(env)) #execute application if binaryDirectoryOnTarget: command = "cd {}; {} ./{} {}".format(binaryDirectoryOnTarget, prefix, applicationName, args) else: command = "{} {} {}".format(prefix, applicationName, args) log.info("start_application command: '{}'".format(command)) try: stdin, stdout, stderr = self.sshClient.exec_command(command) except Exception as e: log.error("Error: {0} could not be started (error message: {1})".format(applicationName, e.message)) return Application(None, None, None, applicationName, binaryDirectoryOnTarget, nameExtension) application = Application(stdin, stdout, stderr, applicationName, binaryDirectoryOnTarget, nameExtension) application.started = True return application
def _connect(self): self.sshClient = paramiko.SSHClient() self.sshClient.set_missing_host_key_policy(paramiko.AutoAddPolicy()) log.info("connecting to "+self.name+" hostname: "+self.hostname+" user: "******"Trying to connect to {} port {} for the {} time.".format(self.hostname, self.sshPort, nrAttempts)) self.sshClient.connect(self.hostname, port=self.sshPort, username=self.username, password=self.password, pkey=rsa_key, timeout=self.sshConnectionTimeoutPerAttempt, allow_agent=False, look_for_keys=False, banner_timeout=45) transport = self.sshClient.get_transport() transport.set_keepalive(5) except (socket.error, SSHException) as e: log.warning("Connection could not be established, maybe not ready yet: {0}".format(e)) time.sleep(self.sshConnectionSleepPerAttempt) # server not yet ready except (BadHostKeyException, AuthenticationException) as e: log.error("Connection error: {0}".format(e)) break else: self.isConnected = True if not self.isConnected: log.error("Connection to {0} could not be established".format(self.name)) return log.info("Connection to {0} successfully established".format(self.name))
def run(self): while True: self.startedLock.acquire() doStop = (self.started is False) self.startedLock.release() if doStop: if (self.abortTime is not None) and (time.time() >= self.abortTime): log.error( "Timeout while trying to read remaining contents of pipe ({}). Current buffer content\n----------------\n{}\n----------------" .format(self._name, self._buffer.get_all_data())) return line = self._pipe.readline() if not isinstance(line, str): # ignore ascii->utf-8 errors without failing line = line.decode( 'utf-8', 'replace' ) # TODO(tobias) check if some targets (VDT, others?) send valid utf-8 already if line == "": if doStop: return # pipe is empty, we can stop reader immediately else: time.sleep(0.1) # pipe currently empty, wait for new data else: self._buffer.append(line)
def _expand_test(self, test, expandedSuite): if isinstance(test, test_classes.OnAllDefaultTargetsTest): for target in self.defaultTestTargets: if target.isConnected: #create a copy of test for each target testForOneTarget = copy.deepcopy(test) testForOneTarget.set_target(target) expandedSuite.addTest(testForOneTarget) elif isinstance(test, test_classes.MultipleConnectionsTest) or isinstance(test, test_classes.OnSelectedTargetsTest): if type(test).__name__ in self.config.testToTargetConfig: for targetInfoSet in self.config.testToTargetConfig[type(test).__name__]: targetSet = [self.targets[i] for i in targetInfoSet] if self._checkIfAllTargetsReady(targetSet) and self._checkIfValidConfig(test, targetSet): # create a copy of test for each target set testForOneTargetSet = copy.deepcopy(test) for target in targetSet: if isinstance(test, test_classes.MultipleConnectionsTest): testForOneTargetSet.add_target(target) else: testForOneTargetSet.set_target(target) expandedSuite.addTest(testForOneTargetSet) else: log.error("test '{0}' could not be added to the active tests due to missing target connection or " "invalid src.".format(test.id())) else: log.warning("Missing testToTargetConfig for test {0}".format(test.id())) else: # other kinds of unit tests are executed as usual expandedSuite.addTest(test)
def save_application_output(self, application, testClassName, testRunName, nr=None): """" saves the output of an application to a file This method can only be called if application was stopped before. If multiple instances of one application are started on one target the nr parameter can be used to generate unique filenames """ if not application.started: resultDirForTest = self.resultDir + '/' + testClassName + "/" + testRunName if nr is None: fileName = "{0}_{1}".format(application.name, self.name) else: fileName = "{0}{1}_{2}".format(application.name, nr, self.name) stdoutOutputList = application.get_stdout_data() if stdoutOutputList: helper.save_text_file( resultDirForTest + "/" + fileName + ".txt", "".join(stdoutOutputList)) stderrOutputList = application.get_stderr_data() if stderrOutputList: helper.save_text_file( resultDirForTest + "/" + fileName + "_STDERR.txt", "".join(stderrOutputList)) else: log.error( "application output can only be saved if application was stopped before" )
def _checkIfAllTargetsReady(self, targetSet): for target in targetSet: if not target.isConnected: log.error("target '{0}' is not ready".format(target.name)) return False return True
def compareUnequal(image1, image2, numberOfRequiredUnequalPixels, percentageOfRGBDifferenceRequiredPerPixel): log.info("Requiring {}% difference on RGBA value per pixel, and require {} really distinct pixels".format(percentageOfRGBDifferenceRequiredPerPixel*100, numberOfRequiredUnequalPixels)) if not _checkImageSizeEqual(image1, image2): return False nrEqualPixels = 0 nrTooSimilarPixels = 0 totalNumberOfPixels = image1.width * image1.height # PIL image comparison is well optimized -> early out if images are identical if image1 == image2: nrEqualPixels = totalNumberOfPixels nrTooSimilarPixels = totalNumberOfPixels else: imageDiff = ImageChops.difference(image1.convert("RGBA"), image2.convert("RGBA")) imageData = imageDiff.getdata() percentageOfRGBDifferenceRequiredPerPixelScaled = int(percentageOfRGBDifferenceRequiredPerPixel*255) for i in range(0, image1.width * image1.height): chMax = max(imageData[i]) if chMax < percentageOfRGBDifferenceRequiredPerPixelScaled: nrTooSimilarPixels += 1 if chMax == 0: nrEqualPixels += 1 log.important_info("Comparison stats: Percentage of too similar pixels: {}% ({})".format(float(nrTooSimilarPixels) / totalNumberOfPixels*100, nrTooSimilarPixels)) log.important_info("Comparison stats: Percentage of exactly equal pixels: {}% ({})".format(float(nrEqualPixels) / totalNumberOfPixels*100, nrEqualPixels)) if totalNumberOfPixels - nrTooSimilarPixels < numberOfRequiredUnequalPixels: log.error("compareUnequal: Not enough unequal pixels, aborting...") return False return True
def compareEqual(image1, image2, percentageOfWrongPixelsAllowed, percentageOfRGBDifferenceAllowedPerPixel): log.info("Allowing {}% tolerance on RGBA value per pixel, and {}% wrong pixels".format(percentageOfRGBDifferenceAllowedPerPixel*100, percentageOfWrongPixelsAllowed*100)) if not _checkImageSizeEqual(image1, image2): return False nrWrongPixels = 0 nrDifferentPixels = 0 # PIL image comparison is well optimized -> early out if images are identical if image1 != image2: imageDiff = ImageChops.difference(image1.convert("RGBA"), image2.convert("RGBA")) imageData = imageDiff.getdata() percentageOfRGBDifferenceAllowedPerPixelScaled = int(percentageOfRGBDifferenceAllowedPerPixel*255) for i in range(0, image1.width * image1.height): chMax = max(imageData[i]) if chMax > 0: nrDifferentPixels += 1 if chMax > percentageOfRGBDifferenceAllowedPerPixelScaled: nrWrongPixels += 1 totalNumberOfPixels = image1.width * image1.height log.important_info("Comparison stats: Percentage of wrong pixels: {0}%".format(float(nrWrongPixels) / totalNumberOfPixels*100)) log.important_info("Comparison stats: Percentage of different, but accepted pixels: {0}%".format(float(nrDifferentPixels-nrWrongPixels) / totalNumberOfPixels*100)) if ((float(nrWrongPixels) / totalNumberOfPixels) > percentageOfWrongPixelsAllowed): log.error("compareEqual: Too many wrong pixels, aborting...") return False return True
def setup(self, transfer_binaries=True): self.defaultPlatform = "windows-wgl-es-3-0" self.defaultEnvironment = { "PATH": "${HOME}/" + self.ramsesInstallDir + "/bin:${PATH}" } # base implementation that includes setup of connection and transfer of binaries baseSetupSuccessful = RemoteTarget.setup(self, transfer_binaries) if not baseSetupSuccessful: return False # must set dll executable to prevent error when running executables using these dlls. cmake/cpack # is not able to do this on windows. without you get following errors: # return code 127 (file not found) on cygwin. error code 0xc000022 in gui mode self.execute_on_target("cd '" + self.ramsesInstallDir + "/bin/'; chmod +x *.dll") # Path conversion to windows-style (/c/folder -> C:/folder) # Conversion is needed because screenshopts in RAMSES use Windows APIs directly # and require windows-style paths stdout, stderr, returncode = self.execute_on_target( "cygpath -am ${HOME}") if returncode == 0: self.tmpDir = stdout[0].strip() else: log.error( "Error getting tmp directory: returncode {} stdout: {} stderr: {}" .format(returncode, stdout, stderr)) return True
def _checkIfValidConfig(self, test, targetSet): if test.get_nr_targets() != len(targetSet): log.error( "Invalid configuration, number of connections defined in testToTargetConfig does not match with \ with number of connections expected in test (test: {0})". format(type(test).__name__)) return False return True
def _checkImageSizeEqual(image1, image2): if (image1.size[0] != image2.size[0]) or (image1.size[1] != image2.size[1]): log.error( "images sizes do not match, cannot compare {}*{} vs {}*{}".format( image1.size[0], image1.size[1], image2.size[0], image2.size[1])) return False return True
def kill_application(self, application): if application.started: if platform.system() == "Windows": self.execute_on_target("Taskkill /F /T /IM {}.exe".format(application.name)) elif platform.system() == "Linux": self.execute_on_target("killall -9 {}".format(application.name)) else: log.error("Unknown system {}: Application cannot be killed".format(platform.system())) application.started = False application.stop_readers()
def send_ramsh_command(self, command, response_message=None, timeout=DEFAULT_WAIT_FOR_MESSAGE_TIMEOUT, waitForRendererConfirmation=False, confirmationDisplay=0): """optional arguments: response_message -- waits after sending command until response_message(string) appears in application stdout Cannot be used in combination with waitForRendererConfirmation response_message is interpreted as regular expression timeout -- maximum time (in seconds) to wait for response message. If set to None method will block waitForRendererConfirmation: adds a second command in command queue of renderer to confirm that given command was executed. Can only be used with renderer executables and cannot be used in combination with response_message until response message is received without timeout @:return True if requested response_message or renderer confirmation have been received (or none of them was set) """ if response_message and waitForRendererConfirmation: log.error( "response_message and waitForRendererConfirmation cannot be used in combination" ) return False if self.started and self.is_initialised( Application.DEFAULT_WAIT_FOR_MESSAGE_TIMEOUT): if response_message or waitForRendererConfirmation: watchId = self.start_watch_stdout() else: watchId = None self._internal_send_ramsh_command(command) if waitForRendererConfirmation: self.rendererConfirmationNr += 1 self._internal_send_ramsh_command("confirm {0} {1}".format( confirmationDisplay, self.rendererConfirmationNr)) if response_message: return self.wait_for_msg_in_stdout(watchId, response_message, timeout) elif waitForRendererConfirmation: log.info("waiting for renderer confirmation number {}".format( self.rendererConfirmationNr)) return self.wait_for_msg_in_stdout( watchId, "confirmation: {}".format(self.rendererConfirmationNr), timeout) else: return True else: log.error( "command cannot be executed, as application was not started correctly" ) return False
def _get_full_process_list(self): retCode = 0 if platform.system() == "Windows": (out, _, retCode) = self.execute_on_target("tasklist") elif platform.system() == "Linux": (out, _, retCode) = self.execute_on_target("ps aux") else: log.error("Unknown system {}: Process list cannot be retrieved".format(platform.system())) out = [] assert retCode == 0, "_get_full_process_list failed" return out
def createTelnetConnection(self): log.info("Connecting to power device {0} user: {1}".format( self.url, self.username)) #create telnet connection to power outlet try: telnet_conn = telnetlib.Telnet(self.url, 1234) return telnet_conn except: log.error( "Connection to power device {0} could not be established". format(self.url)) return None
def start_application(self, applicationName, args="", binaryDirectoryOnTarget=None, nameExtension="", env={}, dltAppID=None, prepend_unbuffer=False): #ensure binary is there if binaryDirectoryOnTarget: binaryPathOnTarget = binaryDirectoryOnTarget + '/' + applicationName else: binaryPathOnTarget = applicationName if not self._executable_exists_on_target(binaryPathOnTarget): log.error( "Error: executable '{0}' could not be found (path: '{1}')". format(applicationName, binaryPathOnTarget)) return Application(None, None, None, applicationName, binaryDirectoryOnTarget, nameExtension) prefix = helper.get_env_var_setting_string(self._get_merged_env(env)) if prepend_unbuffer: if self.supportsUnbuffer: prefix += " unbuffer" else: log.warn( "Unbuffer is not supported on this target! Will be ignored." ) #execute application if binaryDirectoryOnTarget: command = "cd {}; {} ./{} {}".format(binaryDirectoryOnTarget, prefix, applicationName, args) else: command = "{} {} {}".format(prefix, applicationName, args) log.info("start_application command: '{}'".format(command)) try: stdin, stdout, stderr = self.sshClient.exec_command(command) except Exception as e: log.error( "Error: {0} could not be started (error message: {1})".format( applicationName, e.message)) return Application(None, None, None, applicationName, binaryDirectoryOnTarget, nameExtension) application = Application(stdin, stdout, stderr, applicationName, binaryDirectoryOnTarget, nameExtension) application.started = True return application
def start_application(self, applicationName, args="", binaryDirectoryOnTarget=None, nameExtension="", env={}, dltAppID=None, prepend_unbuffer=False): if prepend_unbuffer: log.warn( "Unbuffer is not supported on this target! Will be ignored.") if binaryDirectoryOnTarget: applicationDirectory = os.path.normcase(binaryDirectoryOnTarget) applicationPath = os.path.normcase(applicationDirectory + "/" + applicationName) else: applicationDirectory = None applicationPath = applicationName if not spawn.find_executable(applicationPath): log.error( "executable '{0}' could not be found (path: '{1}')".format( applicationName, applicationPath)) return LocalApplication(None, applicationName, binaryDirectoryOnTarget) command = "{} {}".format(applicationPath, args) my_env = dict(os.environ) my_env.update(self.defaultEnvironment) my_env.update(env) log.info('Execute: ' + command) popenApp = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=applicationDirectory, shell=True, env=my_env) application = LocalApplication(popenApp, applicationName, applicationDirectory, nameExtension=nameExtension) application.started = True return application
def compareUnequal(image1, image2, numberOfRequiredUnequalPixels, percentageOfRGBDifferenceRequiredPerPixel): log.info("compareUnequal: Bitmap compare of {0} with {1}".format( image1.filename, image2.filename)) log.info( "Requiring {}% difference on RGB value per pixel, and require {} really distinct pixels" .format(percentageOfRGBDifferenceRequiredPerPixel * 100, numberOfRequiredUnequalPixels)) if not _checkImageSizeEqual(image1, image2): return False # work around crappy nested function variable access rules nrEqualPixels = [0] nrTooSimilarPixels = [0] def compare(x, y, c1, c2, diff): if all(e < percentageOfRGBDifferenceRequiredPerPixel for e in diff): if nrTooSimilarPixels[0] == 0: log.info( "First wrong Pixel {}/{} (source pixel {} / otherPixel {})" .format(x, y, c1, c2)) nrTooSimilarPixels[0] += 1 if all(e == 0 for e in diff): nrEqualPixels[0] += 1 _forAllPixels(image1, image2, compare) totalNumberOfPixels = image1.size[0] * image1.size[1] log.important_info( "Comparison stats: Percentage of too similar pixels: {}% ({})".format( float(nrTooSimilarPixels[0]) / totalNumberOfPixels * 100, nrTooSimilarPixels[0])) log.important_info( "Comparison stats: Percentage of exactly equal pixels: {}% ({})". format( float(nrEqualPixels[0]) / totalNumberOfPixels * 100, nrEqualPixels[0])) if totalNumberOfPixels - nrTooSimilarPixels[ 0] < numberOfRequiredUnequalPixels: log.error("compareUnequal: Not enough unequal pixels, aborting...") return False return True
def compareEqual(image1, image2, percentageOfWrongPixelsAllowed, percentageOfRGBDifferenceAllowedPerPixel): log.info("compareEqual: Bitmap compare of {0} with {1}".format( image1.filename, image2.filename)) log.info( "Allowing {}% tolerance on RGB value per pixel, and {}% wrong pixels". format(percentageOfRGBDifferenceAllowedPerPixel * 100, percentageOfWrongPixelsAllowed * 100)) if not _checkImageSizeEqual(image1, image2): return False # work around nested function variable access rules nrWrongPixels = [0] nrDifferentPixels = [0] def compare(x, y, c1, c2, diff): if any(e > 0 for e in diff): nrDifferentPixels[0] += 1 if any(e > percentageOfRGBDifferenceAllowedPerPixel for e in diff): if nrWrongPixels[0] == 0: log.info( "First wrong Pixel {}/{} (source pixel {} / otherPixel {})" .format(x, y, c1, c2)) nrWrongPixels[0] += 1 _forAllPixels(image1, image2, compare) totalNumberOfPixels = image1.size[0] * image1.size[1] log.important_info( "Comparison stats: Percentage of wrong pixels: {0}%".format( float(nrWrongPixels[0]) / totalNumberOfPixels * 100)) log.important_info( "Comparison stats: Percentage of different, but accepted pixels: {0}%". format( float(nrDifferentPixels[0] - nrWrongPixels[0]) / totalNumberOfPixels * 100)) if ((float(nrWrongPixels[0]) / totalNumberOfPixels) > percentageOfWrongPixelsAllowed): log.error("compareEqual: Too many wrong pixels, aborting...") return False return True
def compareUnequal(image1, image2, numberOfRequiredUnequalPixels, percentageOfRGBDifferenceRequiredPerPixel): log.info( "Requiring {}% difference on RGB value per pixel, and require {} really distinct pixels" .format(percentageOfRGBDifferenceRequiredPerPixel * 100, numberOfRequiredUnequalPixels)) if not _checkImageSizeEqual(image1, image2): return False # work around crappy nested function variable access rules nrEqualPixels = [0] nrTooSimilarPixels = [0] def compare(c1, c2, diff): if all(e < percentageOfRGBDifferenceRequiredPerPixel for e in diff): nrTooSimilarPixels[0] += 1 if all(e == 0 for e in diff): nrEqualPixels[0] += 1 totalNumberOfPixels = image1.width * image1.height if image1 == image2: # PIL image comparison is well optimized -> early out if images are identical nrEqualPixels = totalNumberOfPixels nrTooSimilarPixels = totalNumberOfPixels else: _forAllPixels(image1, image2, compare) log.important_info( "Comparison stats: Percentage of too similar pixels: {}% ({})".format( float(nrTooSimilarPixels[0]) / totalNumberOfPixels * 100, nrTooSimilarPixels[0])) log.important_info( "Comparison stats: Percentage of exactly equal pixels: {}% ({})". format( float(nrEqualPixels[0]) / totalNumberOfPixels * 100, nrEqualPixels[0])) if totalNumberOfPixels - nrTooSimilarPixels[ 0] < numberOfRequiredUnequalPixels: log.error("compareUnequal: Not enough unequal pixels, aborting...") return False return True
def flush(self): if len(self.command_buffer) > 0: cmd = " . ".join(self.command_buffer) self.command_buffer = [] (stdout, stderr, returnCode) = self.callIVIControl(cmd) if returnCode != 0: log.error( "Failed to execute ivi control commands. Return code: {}". format(returnCode)) log.error("Stdout: '{}'".format(stdout)) log.error("Stderr: '{}'".format(stderr)) log.error("Expect further failing tests!")
def run(self): while True: self.startedLock.acquire() doStop = (self.started is False) self.startedLock.release() if doStop: if (self.abortTime is not None) and (time.time() >= self.abortTime): log.error("Timeout while trying to read remaining contents of pipe ({}). Current buffer content\n----------------\n{}\n----------------".format(self._name, self._buffer.get_all_data())) return line = self._pipe.readline() if line == "": if doStop: return #pipe is empty, we can stop reader immediately else: time.sleep(0.1) #pipe currently empty, wait for new data else: self._buffer.append(line)
def setup(self, transfer_binaries=True): self.defaultPlatform = "windows-wgl-es-3-0" self.defaultEnvironment = {"PATH" : "${PATH}:${HOME}/" + self.ramsesInstallDir + "/lib", "TMP" : "/tmp"} # base implementation that includes setup of connection and transfer of binaries baseSetupSuccessful = RemoteTarget.setup(self, transfer_binaries) if not baseSetupSuccessful: return False # must set dll executable to prevent error when running executables using these dlls. cmake/cpack # is not able to do this on windows. without you get following errors: # return code 127 (file not found) on cygwin. error code 0xc000022 in gui mode self.execute_on_target("cd '" + self.ramsesInstallDir + "/lib/'; chmod +x *.dll") stdout, stderr, returncode = self.execute_on_target("cygpath -am {}".format(self.defaultEnvironment["TMP"])) if returncode == 0: self.tmpDir = stdout[0].strip() else: log.error("Error getting tmp directory: returncode {} stdout: {} stderr: {}".format(returncode, stdout, stderr)) return True
def compareEqual(image1, image2, percentageOfWrongPixelsAllowed, percentageOfRGBDifferenceAllowedPerPixel): log.info( "Allowing {}% tolerance on RGB value per pixel, and {}% wrong pixels". format(percentageOfRGBDifferenceAllowedPerPixel * 100, percentageOfWrongPixelsAllowed * 100)) if not _checkImageSizeEqual(image1, image2): return False # work around nested function variable access rules nrWrongPixels = [0] nrDifferentPixels = [0] def compare(c1, c2, diff): if any(e > 0 for e in diff): nrDifferentPixels[0] += 1 if any(e > percentageOfRGBDifferenceAllowedPerPixel for e in diff): nrWrongPixels[0] += 1 if image1 != image2: # PIL image comparison is well optimized -> early out if images are identical _forAllPixels(image1, image2, compare) totalNumberOfPixels = image1.width * image1.height log.important_info( "Comparison stats: Percentage of wrong pixels: {0}%".format( float(nrWrongPixels[0]) / totalNumberOfPixels * 100)) log.important_info( "Comparison stats: Percentage of different, but accepted pixels: {0}%". format( float(nrDifferentPixels[0] - nrWrongPixels[0]) / totalNumberOfPixels * 100)) if ((float(nrWrongPixels[0]) / totalNumberOfPixels) > percentageOfWrongPixelsAllowed): log.error("compareEqual: Too many wrong pixels, aborting...") return False return True
def switch(self, outletNr, on): log.info("Connecting to power device {0} user: {1}".format( self.url, self.username)) #create telnet connection to power outlet try: tn = telnetlib.Telnet(self.url, 1234) except: log.error( "Connection to power device {0} could not be established". format(self.url)) else: #tn.read_until("100 HELLO 00000000 - KSHELL V1.5") tn.write("login {0} {1}\n".format(self.username, self.password)) #turn power outlet on or off status = 0 if on: status = 1 tn.write("port {0} {1}\n".format(outletNr, status)) tn.write("quit\n") time.sleep(1) log.info(tn.read_eager())
def download_tar_from_ci_cache(hash, buildJobName, ciCacheUrl, destFolder): chunksize = 32 * 1024 filter_re = re.compile( "{}-(.*)-(.*)-{}\.tar\.gz".format(buildJobName, hash), re.IGNORECASE) for f in os.listdir(destFolder): match = re.match(filter_re, f) if match: log.info( "File already exist in destFolder, using existing file {}". format(f)) return True, match.group(1), match.group(2) try: page_url = "{}/{}-{}/".format(ciCacheUrl, buildJobName, hash) page_response = urlopen(page_url) content = page_response.read() except HTTPError: log.error("Could not open url {}".format(page_url)) return False, "", "" match = re.search(filter_re, content) if match is None: log.error("Could not find tar on page") print(content) return False, "", "" tarfilename = match.group(0) version = match.group(1) commitNr = match.group(2) log.info("downloading: {}".format(tarfilename)) file_response = urlopen("{}/{}-{}/{}".format(ciCacheUrl, buildJobName, hash, tarfilename)) meta = file_response.info() content_length = int(meta.getheaders("Content-Length")[0]) progress_messages_step_size = content_length / 10 bytes = 0 bytes_since_last_message = 0 with open(os.path.join(destFolder, tarfilename), "wb") as f: while True: chunk = file_response.read(chunksize) if not chunk: break f.write(chunk) bytes += len(chunk) bytes_since_last_message += len(chunk) if bytes_since_last_message >= progress_messages_step_size or bytes == content_length: log.info("downloaded {} of {} bytes".format( bytes, content_length)) bytes_since_last_message = 0 if bytes == content_length: return True, version, commitNr else: log.error("Download incomplete") return False, "", ""
def _transfer_binaries(self): packageBaseName = self.buildJobName+'-'+self.ramsesVersion+'-'+self.gitCommitCount\ +'-'+self.gitCommitHash # package name without extension # glob to support any filters set by the user resultList = glob.glob("{0}/{1}".format(self.basePath, packageBaseName)) if not resultList: log.error("no package found for filter \"{}.tar.gz\"".format(packageBaseName)) return False packagePathOnBuildServer = "{0}/{1}".format(self.basePath, os.path.basename(resultList[0])) packagePathOnTarget = "{0}/{1}".format(self.ramsesInstallDir, os.path.basename(resultList[0])) #check that package is available if not os.path.exists(packagePathOnBuildServer): log.error("package \"{}\" could not be found".format(packagePathOnBuildServer)) return False # transfer package returnCode = self._scp(packagePathOnBuildServer, False, self.ramsesInstallDir, True) if returnCode != 0: log.error("scp call for binary transfer not successful, return code {}".format(returnCode)) return False #extract package stdout, stderr, returnCode = self.execute_on_target( "tar mxf {0} -C {1}".format(packagePathOnTarget, self.ramsesInstallDir), block=True) if returnCode != 0: log.error("tar extraction not successful, return code: {}, stdout: {}, stderr: {}". format(returnCode, "".join(stdout), "".join(stderr))) return False #remove tar self.execute_on_target("rm {0}".format(packagePathOnTarget)) #move contents from subfolder directly to install dir self.execute_on_target( "mv {0}/{1}/* {0}".format(self.ramsesInstallDir, packageBaseName), block=True) return True
def _transfer_binaries(self): packageBaseName = self.buildJobName + '-*' # glob to get single expected archive for target, otherwise fail resultList = glob.glob("{0}/{1}".format(self.basePath, packageBaseName)) if not resultList: log.error( "no package found for filter \"{}\"".format(packageBaseName)) return False elif len(resultList) > 1: log.error("too many packages found for filter \"{}\": {}".format( packageBaseName, resultList)) return False packagePathOnBuildServer = "{0}/{1}".format( self.basePath, os.path.basename(resultList[0])) packagePathOnTarget = "{0}/{1}".format(self.ramsesInstallDir, os.path.basename(resultList[0])) # transfer package self._scp(packagePathOnBuildServer, False, self.ramsesInstallDir, True) #extract package stdout, stderr, returnCode = self.execute_on_target( "tar mxf {0} -C {1}".format(packagePathOnTarget, self.ramsesInstallDir), block=True) if returnCode != 0: log.error( "tar extraction not successful, return code: {}, stdout: {}, stderr: {}" .format(returnCode, "".join(stdout), "".join(stderr))) return False #remove tar self.execute_on_target("rm {0}".format(packagePathOnTarget)) #move contents from subfolder directly to install dir self.execute_on_target("mv {0}/{1}/* {0}".format( self.ramsesInstallDir, packageBaseName), block=True) return True
def wait_for_msg(self, watch_id, msg, timeout=None): """ Blocks until msg found or timeout :return: True if msg found during watch, False otherwise """ # don't wait if no watch_id if watch_id is None: log.error("Cannot wait! No watch_id given!") return False # don't wait if watch not active if not self.is_active(watch_id): log.error( "Cannot wait! Reader has no active watch with given id: {}!". format(watch_id)) return False timer = None if timeout: timer = threading.Timer(timeout, self.remove_watch, [watch_id]) timer.start() if msg is None: log.warning("Msg not given! Will block until timeout") timer.join() return False elif msg: log.warning( "Timeout not given! Will block until message received.\n" "(Note: if msg not found, will block forever.)") else: # don't wait if not timer and no msg given log.error("Cannot wait! Nor timeout or msg given.") return False # check data in buffer that is available until now nextLinePos = self.buffer.get_length() for i in range(self.watchStartPositions[watch_id], nextLinePos): if not self.is_active(watch_id): log.warning( "Timeout ({} seconds) waiting for msg:\'{}\' in reader: {}." .format(str(timeout), msg, self.name)) return False line = self.buffer.get_line(i) if re.search(msg, line): self.remove_watch(watch_id) if timer: timer.cancel() return True # wait for new data while self.is_active(watch_id): bufferSize = self.buffer.get_length() if nextLinePos >= bufferSize: time.sleep(0.1) else: line = self.buffer.get_line(nextLinePos) if re.search(msg, line): self.remove_watch(watch_id) if timer: timer.cancel() return True else: nextLinePos += 1 log.warning("Timeout ({} seconds) waiting for msg:\'{}\'".format( str(timeout), msg)) return False