def run(self, context): """ Runs the test step :type context: TestStepContext :param context: test case context """ TestStepBase.run(self, context) self._http_downloader_obj = HttpDownloaderUtil( url=self._pars.url, destination=self._pars.destination, proxy=self._pars.http_proxy, creds=self._pars.credential, http_timeout=self._pars.http_timeout, override=self._pars.override_file, download_timeout=self._pars.transfer_timeout, logger=self._logger) try: response = self._http_downloader_obj.init() except AcsConfigException: raise if not response: error_msg = "Cannot get response from server" raise AcsToolException(AcsToolException.OPERATION_FAILED, error_msg) verdict, output, _ = self._http_downloader_obj.download(response) if verdict != Global.SUCCESS: raise AcsToolException(AcsToolException.OPERATION_FAILED, output) else: self.ts_verdict_msg = output
def _download_file(self, url): """ Download a file from http server :type url: str :param url: url to the file to download :rtype: tuple :return: ACS verdict and local path to downloaded file """ result = Global.FAILURE file_name = os.path.join(gettempdir(), url.rstrip('/').split('/')[-1]) http_downloader = HttpDownloaderUtil(url=url, destination=file_name, override=True, download_timeout=self._test_timeout, logger=self._logger) try: # check args response = http_downloader.init() # then, process download result, _, file_name = http_downloader.download(response) except (SysErrors, AcsConfigException): msg = ("Exception occurred while Downloading {0}" "Detailed exception below:\n{1}".format(url, traceback.format_exc())) file_name = "" result = Global.FAILURE self._logger.error(msg) return result, file_name
def test_http_downloader_check_url_arg_ok_https_url(self, mock_check_url): mock_logger = Mock() mock_check_url.return_value = fake_request_response() # empty url http_downloader_obj = HttpDownloaderUtil(url="https://www.google.com", destination="", logger=mock_logger) http_downloader_obj.check_url_arg()
def test_http_downloader_check_url_ok(self, mock_get): mock_logger = Mock() http_downloader_obj = HttpDownloaderUtil(url="", destination="", logger=mock_logger) fake_response = fake_request_response() fake_response.status_code = 200 mock_get.return_value = fake_response self.assertTrue(http_downloader_obj.check_url())
def test_http_downloader_check_destination_arg_ok_unexisting_file_but_existing_dir_as_dest(self): mock_logger = Mock() # good url is according to method comment # existing dir, unexisting file dest_file = os.path.join(os.path.dirname(__file__), "doesnotexistfile") http_downloader_obj = HttpDownloaderUtil(url="http://test/my_file", destination=dest_file, logger=mock_logger) http_downloader_obj.check_destination_arg() self.assertEqual(http_downloader_obj._destination, dest_file)
def test_http_downloader_check_destination_arg_ok_file_as_dest(self): mock_logger = Mock() # good url is according to method comment # existing file destination dest_file = __file__ http_downloader_obj = HttpDownloaderUtil(url="http://test/my_file", destination=dest_file, logger=mock_logger) http_downloader_obj.check_destination_arg() self.assertEqual(http_downloader_obj._destination, dest_file)
def test_http_downloader_check_destination_arg_ok_dir_as_dest(self): mock_logger = Mock() # good url is according to method comment # existing dir destination dest_dir = os.path.dirname(__file__) expected_dest = os.path.join(dest_dir, "my_file") http_downloader_obj = HttpDownloaderUtil(url="http://test/my_file", destination=dest_dir, logger=mock_logger) http_downloader_obj.check_destination_arg() self.assertEqual(http_downloader_obj._destination, expected_dest)
def test_http_downloader_download_ko_bad_header(self, mock_get): mock_logger = Mock() # empty header http_downloader_obj = HttpDownloaderUtil(url="", destination="", logger=mock_logger) fake_response = fake_request_response() fake_response.headers = dict() mock_get.return_value = fake_response return_value = http_downloader_obj.download() self.assertNotEqual(return_value[0], 0) self.assertEqual(return_value[2], "")
def test_http_downloader_download_no_md5_check(self, mock_get): patch("acs_test_scripts.Utilities.HttpDownloaderUtil.hashlib.md5") mock_logger = Mock() # empty header http_downloader_obj = HttpDownloaderUtil(url="", destination=os.path.dirname(__file__), download_timeout=1, logger=mock_logger) fake_response = fake_request_response() fake_response.headers = {'content-length': '10'} mock_get.return_value = fake_response return_value = http_downloader_obj.download() self.assertEqual(return_value[0], 0) self.assertNotEqual(return_value[2], "")
def _compute_remote_uri(artifact_name, artifact_root_uri): """ Generates the full artifact uri according to artifact name as:: * Http URL * Local file system path :param artifact_name: the name of artifact :type artifact_name: str :param artifact_root_uri: the uri of artifact source :type artifact_root_uri: str :return: uri to the artifact to process :rtype: str """ if HttpDownloaderUtil.is_http_uri(artifact_root_uri): if not artifact_root_uri.endswith('/'): artifact_root_uri += '/' artifact_to_process = urljoin(artifact_root_uri, artifact_name) else: error_msg = "Mal-Formed URI {0} for artifact {1}".format( artifact_root_uri, artifact_name) raise AcsConfigException(AcsConfigException.INVALID_PARAMETER, error_msg) return artifact_to_process
def test_http_downloader_download_timeout_md5_check_ko(self, mock_get, mock_md5): mock_logger = Mock() # empty header http_downloader_obj = HttpDownloaderUtil(url="", destination=os.path.dirname(__file__), download_timeout=1, logger=mock_logger) fake_response = fake_request_response() fake_response.headers = {'content-length': '10', 'X-Checksum-Md5': '123456789abc'} my_md5 = mock_md5() my_md5.hexdigest.return_value = '123456789abcNotTheSame' mock_get.return_value = fake_response return_value = http_downloader_obj.download() self.assertNotEqual(return_value[0], 0) self.assertEqual(return_value[2], "")
def test_http_downloader_check_destination_arg_ko_empty_destination(self): mock_logger = Mock() # good url is according to method comment # empty destination http_downloader_obj = HttpDownloaderUtil(url="http://test/my_file", destination="", logger=mock_logger) self.assertRaises(AcsConfigException, http_downloader_obj.check_destination_arg)
def test_http_downloader_download_override_parameter(self): # to avoid removing file if unit teest is ko mock_logger = Mock() # empty header http_downloader_obj = HttpDownloaderUtil(url="", destination=__file__, override=False, logger=mock_logger) self.assertRaises(AcsConfigException, http_downloader_obj.download)
def test_http_downloader_check_url_arg_ko_url_could_not_be_reached(self, mock_check_url): mock_logger = Mock() mock_check_url.return_value = None # good url but not cound not be reached http_downloader_obj = HttpDownloaderUtil(url="http://ggoggle.com", destination="", logger=mock_logger) self.assertRaises(AcsConfigException, http_downloader_obj.check_url_arg) self.assertTrue(mock_check_url.called)
def test_http_downloader_check_url_arg_ko_url_empty(self, mock_check_url): mock_logger = Mock() mock_check_url.return_value = None # empty url http_downloader_obj = HttpDownloaderUtil(url="", destination="", logger=mock_logger) self.assertRaises(AcsConfigException, http_downloader_obj.check_url_arg)
def test_http_downloader_check_destination_arg_ko_destination_does_not_exist(self): mock_logger = Mock() # good url is according to method comment # destination does not exist http_downloader_obj = HttpDownloaderUtil(url="http://test/my_file", destination="doestNotExist/at/all/", logger=mock_logger) self.assertRaises(AcsConfigException, http_downloader_obj.check_destination_arg)
def test_http_downloader_download_timeout_ko(self, mock_get): mock_logger = Mock() # empty header http_downloader_obj = HttpDownloaderUtil(url="", destination="", download_timeout=0, logger=mock_logger) fake_response = fake_request_response() mock_get.return_value = fake_response self.assertRaises(AcsToolException, http_downloader_obj.download)
def _push_cts_medias(self): """ Push videos needed by CTS tests - retrieve cts media files if specified by the user - push them on the phone :rtype: tuple :return: ACS verdict and msg output """ verdict = Global.SUCCESS error_msg = "" if not self._cts_media_path: self._logger.warning("No media specified, some CTS packages require such files and may be failed") verdict = Global.SUCCESS error_msg = "Nothing to do, no media specified" else: self._logger.info("Retrieve cts media from %s" % self._cts_media_path) if HttpDownloaderUtil.is_http_uri(self._cts_media_path): # Test is available thru URL => download it localy result, full_path = self._download_file(self._cts_media_path) else: result, full_path = self._get_file_path(self._cts_media_path) if result != Global.SUCCESS: verdict, error_msg = result, "Cannot find %s" % self._cts_media_path else: self._cts_media_path = full_path if verdict == Global.SUCCESS: # Set cts directory path # can be a path to a dir or a zip file # in both case, resulting filename will be a directory fileName, fileExtension = os.path.splitext(self._cts_media_path) if fileExtension.lower() == ".zip": zip_file = zipfile.ZipFile(self._cts_media_path, "r") zip_file.extractall(fileName) zip_file.close() # cts path should be a dir. if os.path.isdir(fileName): self._cts_media_path = fileName # Get path to multimedia files # CTS expects video files in /sdcard/test dir # mmPath = self._device.multimedia_path mmPath = "/sdcard/test" (error_code, _error_msg) = self._device.run_cmd("adb shell mkdir %s" % mmPath, 30) push_cmd = "adb push \"%s\" \"%s\"" % (self._cts_media_path, mmPath) (error_code, _error_msg) = self._device.run_cmd(push_cmd, self._test_timeout) if not error_code == Global.SUCCESS: verdict, error_msg = Global.FAILURE, "Cannot push %s on %s" % (self._cts_media_path, mmPath) else: verdict, error_msg = Global.SUCCESS, "CTS Medias pushed properly" else: verdict, error_msg = Global.FAILURE, "Cannot find CTS media" return verdict, error_msg
def test_http_downloader_check_url_arg_ko_url_bad_pattern(self, mock_check_url): mock_logger = Mock() mock_check_url.return_value = None # wrong http pattern http_downloader_obj = HttpDownloaderUtil(url="http:/does_not_exist.com", destination="", logger=mock_logger) # wrong url format self.assertRaises(AcsConfigException, http_downloader_obj.check_url_arg) # error raised without any call of check_url self.assertFalse(mock_check_url.called)
def test_http_downloader_check_wrong_creds_format(self): mock_logger = Mock() # empty creds http_downloader_obj = HttpDownloaderUtil(url="", destination="", logger=mock_logger, creds="") self.assertRaises(AcsConfigException, http_downloader_obj.check_creds) # wrong creds format http_downloader_obj.set_creds("mylogin-mdp") self.assertRaises(AcsConfigException, http_downloader_obj.check_creds) # missing password http_downloader_obj.set_creds("mylogin:"******":mypassword") self.assertRaises(AcsConfigException, http_downloader_obj.check_creds)
def test_http_downloader_check_creds_good_format(self): mock_logger = Mock() # empty creds http_downloader_obj = HttpDownloaderUtil(url="", destination="", logger=mock_logger, creds="mylogin:password") http_downloader_obj.check_creds() encoded_creds = http_downloader_obj._encoded_creds self.assertNotEqual(encoded_creds, "") # anonymous http_downloader_obj.set_creds("anonymous") no_encoded_creds = http_downloader_obj._encoded_creds self.assertNotEqual(encoded_creds, no_encoded_creds)
def get_artifact(self, artifact_name, artifact_root_uri="", transfer_timeout=60 * 10): """ Retrieve an artifact on the local host :param artifact_name: the name of artifact (eg. its path, relative to root uri) :type artifact_name: str :param artifact_root_uri: the uri of artifact source. Use it to override URI from bench param. :type artifact_root_uri: str :param transfer_timeout: timeout to transfer the artifact on local host :type transfer_timeout: int :return: path to the downloaded artifact :rtype: str """ if not artifact_root_uri: artifact_root_uri = self.__artifact_root_uri is_local = not HttpDownloaderUtil.is_http_uri(artifact_root_uri) logical_art_path = path.join(self.__cache_artifacts_path, path.normpath(artifact_name)) if not path.exists(path.dirname(logical_art_path)): os.makedirs(path.dirname(logical_art_path)) if is_local: artifact = self._get_artifact_from_local_host( artifact_name, artifact_root_uri) else: artifact = self._get_artifact_from_http_server( artifact_name, artifact_root_uri, transfer_timeout) return artifact.value
def test_http_downloader_check_url_ko(self, mock_get): mock_logger = Mock() http_downloader_obj = HttpDownloaderUtil(url="", destination="", logger=mock_logger) fake_response = fake_request_response() fake_response.status_code = None mock_get.return_value = fake_response self.assertFalse(http_downloader_obj.check_url()) mock_get.reset_mock() fake_response.status_code = 403 mock_get.return_value = fake_response self.assertFalse(http_downloader_obj.check_url()) mock_get.reset_mock() fake_response.status_code = 401 mock_get.return_value = fake_response self.assertFalse(http_downloader_obj.check_url()) mock_get.reset_mock() fake_response.status_code = 404 mock_get.return_value = fake_response self.assertFalse(http_downloader_obj.check_url())
def _get_artifact_from_http_server(self, artifact_name, artifact_uri, transfer_timeout): """ Download an artifact from http server. :param artifact_uri: uri to the artifact to retrieved :type artifact_uri: str :param artifact_name: the name of artifact :type artifact_name: str :param transfer_timeout: timeout to download the artifact :type transfer_timeout: int :return: path to the artifact :rtype: str :raise: AcsConfigException.FILE_NOT_FOUND if artifact could not be found """ dest_file = os.path.join(self.__cache_artifacts_path, os.path.normpath(artifact_name)) if not os.path.exists(os.path.dirname(dest_file)): os.makedirs(os.path.dirname(dest_file)) artifact = self.cache_engine.get(artifact_name) url = self._compute_remote_uri(artifact_name, artifact_uri) self.__http_downloader = http_downloader = HttpDownloaderUtil( url=url, destination=dest_file, override=True, download_timeout=transfer_timeout, logger=self.logger, **self.__http_config) # check args response = http_downloader.init() # We 've got a local artifact if artifact: # We got response from the remote host? if response: remote_md5 = http_downloader.get_md5(response) # We've got same file version ? if remote_md5 != artifact.hash: # We must update file artifact = self._download2cache(response, artifact_name) artifact.update(hash=remote_md5) else: self.logger.info( 'Artifact {0} is already available in cache: ' '{1} | md5 {2}'.format(artifact.key, artifact.value, artifact.hash)) else: # We could not fetch remote host, but we've got a local artifact self.logger.warning( 'Remote Artifactory could not be fetched!\n' 'However, Artifact ``{0}`` is present in Cache\n' 'BE AWARE: Use of this Artifact might cause ' 'unexpected results'.format(artifact.value)) else: # We do not have a local artifact, we need to download it and add it to cache # We got response from the remote host? if response: artifact = self._download2cache(response, artifact_name) else: raise AcsConfigException( AcsConfigException.FILE_NOT_FOUND, 'Artifact: ``{0}`` is ' 'neither reachable from remote host, ' 'nor from Cache!'.format(artifact_name)) return artifact
def set_up(self): """ Initialize the test :rtype: tuple :return: ACS verdict and msg output """ verdict = Global.SUCCESS msg = "" LiveWifiBase.set_up(self) if self._test_timeout is None: return (Global.FAILURE, "You need to specify a " "TESTS_TIMEOUT value.") if self._cts_path is None: return (Global.FAILURE, "You need to specify a " "CTS_PATH value.") if self._test_cmd_lines is None: return (Global.FAILURE, "You need to specify a " "TEST_PACKAGES_NAMES value.") if self._cts_media_path is None: self._logger.info("No media specified for CTS tests") if self._cts_result_comparison is None: self._logger.info("No comparison will be done with previous CTS run") full_path = "" if HttpDownloaderUtil.is_http_uri(self._cts_path): # Test is available thru URL => download it localy result, full_path = self._download_file(self._cts_path) else: result, full_path = self._get_file_path(self._cts_path) if result != Global.SUCCESS: verdict = result msg = "Cannot get the cts version from %s" % self._cts_path else: self._cts_path = full_path # Set cts directory path # can be a path to a dir or a zip file # in both case, resulting filename will be a directory cts_exec_found = False fileName, fileExtension = os.path.splitext(self._cts_path) if fileExtension.lower() == ".zip": zip_file = zipfile.ZipFile(self._cts_path, "r") zip_file.extractall(fileName) zip_file.close() else: fileName = self._cts_path # cts path should be a dir if os.path.isdir(fileName): self._cts_path = fileName for root, _, file_names in os.walk(self._cts_path): for file_ in file_names: if file_ == CTS_EXEC_FILENAME: self._cts_exec_path = os.path.join(root, file_) os.chmod(self._cts_exec_path, stat.S_IRWXU) cts_exec_found = True if not cts_exec_found: verdict, msg = Global.FAILURE, "Cannot find the CTS executable binary" else: # clean up old previous results for root, _, file_names in os.walk(self._cts_path): for file_ in file_names: if CTS_RESULT_FILENAME in file_: shutil.rmtree(root) # Initialize UI api self._ui_api.init() # setup the board if it has not been done previously verdict, msg = self._setup_device_for_cts() return verdict, msg
def _extract_cts_results_from_cts_report(self, path_to_cts_report, previous_cts_results=None, publishInExternalReport=False): """ Extract in a list the cts tests results from cts xml file return structure will be like this: { package1: { test1: { "NOT_EXECUTED": ["test7", "test8"], "PASS": ["test4", "test6"], "FAIL": ["test1", "test2"], test2: ... ... } package2: ... } :type path_to_cts_report: str :param path_to_cts_report: path to CTS report where result will be extracted :type previous_cts_results: str :param previous_cts_results: path to a PREVIOUS CTS report in order to compare results :type publishInExternalReport: str :param publishInExternalReport: do we add result in external report :rtype: dict :return: full cts result by package """ cts_results = None self._logger.debug("CTS - _extract_cts_results_from_cts_report starts...") if not isinstance(previous_cts_results, dict): previous_cts_results = {} cts_report_path = "" if HttpDownloaderUtil.is_http_uri(path_to_cts_report): # Test is available thru URL => download it localy result, full_path = self._download_file(path_to_cts_report) else: result, full_path = self._get_file_path(path_to_cts_report) if result != Global.SUCCESS: self._logger.error("Cannot find %s" % path_to_cts_report) else: self._logger.debug("CTS - _extract_cts_results_from_cts_report - CTS report Download OK") cts_report_path = full_path try: cts_parsed_result = et.parse(cts_report_path) self._logger.debug("CTS - _extract_cts_results_from_cts_report - Parsing of the CTS report completed") except et.XMLSyntaxError: error_msg = "CTS report file " + str( cts_report_path) + "- parsing-reading issue (exception= " + str(format_exception_info()) + ")" raise AcsToolException(AcsToolException.XML_PARSING_ERROR, error_msg) xpath_request_pck = "//TestPackage" package_list = cts_parsed_result.getroot().xpath(xpath_request_pck) cts_results = previous_cts_results results_tc = {} for package in package_list: self._logger.debug("CTS - _extract_cts_results_from_cts_report - Packages results processing") package_name = package.get('appPackageName') if package_name is not None: xpath_request_tc = ".//TestCase" tcs = package.xpath(xpath_request_tc) cts_results[package_name] = {} for tc_node in tcs: tc_name = tc_node.get('name') if tc_name is not None: default_value = {"PASS": [], "FAIL": [], "NOT_EXECUTED": []} results_tc = cts_results[package_name].get(tc_name, default_value) xpath_request_test = ".//Test" tests = tc_node.xpath(xpath_request_test) for test_node in tests: test_name = test_node.get('name') if test_name is not None: test_result = test_node.get("result") if test_result is not None: test_result = test_result.lower() if test_result == "fail": if publishInExternalReport: self.__tc_report.add_result(test_name, self.__tc_report.verdict.FAIL, "cts test is FAIL", self.get_name(), self.tc_order) results_tc["FAIL"].append(test_name) elif test_result == "pass": if publishInExternalReport: self.__tc_report.add_result(test_name, self.__tc_report.verdict.PASS, "cts test is PASS", self.get_name(), self.tc_order) results_tc["PASS"].append(test_name) else: if publishInExternalReport: self.__tc_report.add_result(test_name, self.__tc_report.verdict.BLOCKED, "cts test has not been executed", self.get_name( ), self.tc_order) results_tc["NOT_EXECUTED"].append(test_name) cts_results[package_name][tc_name] = results_tc return cts_results