Example #1
0
 def _process_response_start(self, response):
     if response.status_code == httplib.INTERNAL_SERVER_ERROR:
         raise MetadataApiError('HTTP ERROR {}: {}'.format(response.status_code, response.content), response)
     ids = parseString(response.content).getElementsByTagName('id')
     if ids:
         self.process_id = ids[0].firstChild.nodeValue
     return response
Example #2
0
 def _handle_soap_error(self, headers, envelope, refresh, response):
     resp_xml = parseString(response.content)
     faultcode = resp_xml.getElementsByTagName("faultcode")
     if faultcode:
         faultcode = faultcode[0].firstChild.nodeValue
     faultstring = resp_xml.getElementsByTagName("faultstring")
     if faultstring:
         faultstring = faultstring[0].firstChild.nodeValue
     else:
         faultstring = response.text
     if (
         faultcode == "sf:INVALID_SESSION_ID"
         and self.task.org_config
         and self.task.org_config.refresh_token
     ):
         # Attempt to refresh token and recall request
         if refresh:
             self.task.org_config.refresh_oauth_token(
                 self.task.project_config.keychain
             )
             return self._call_mdapi(headers, envelope, refresh=False)
     # Log the error
     message = f"{faultcode}: {faultstring}"
     self._set_status("Failed", message)
     raise MetadataApiError(message, response)
Example #3
0
 def _process_response_status(self, response):
     if response.status_code == http.client.INTERNAL_SERVER_ERROR:
         raise MetadataApiError(
             "HTTP ERROR {}: {}".format(response.status_code, response.text),
             response,
         )
     resp_xml = parseString(response.content)
     done = resp_xml.getElementsByTagName("done")
     if done:
         if done[0].firstChild.nodeValue == "true":
             self._set_status("Done")
         else:
             state_detail = resp_xml.getElementsByTagName("stateDetail")
             if state_detail:
                 log = state_detail[0].firstChild.nodeValue
                 self._set_status("InProgress", log)
                 self.check_num = 1
             elif self.status == "InProgress":
                 self.check_num = 1
                 self._set_status(
                     "InProgress",
                     "next check in {} seconds".format(self._get_check_interval()),
                 )
             else:
                 self._set_status(
                     "Pending",
                     "next check in {} seconds".format(self._get_check_interval()),
                 )
     else:
         # If no done element was in the xml, fail logging the entire SOAP
         # envelope as the log
         self._set_status("Failed", response.text, response=response)
     return response
Example #4
0
 def _process_response_start(self, response):
     if response.status_code == http.client.INTERNAL_SERVER_ERROR:
         raise MetadataApiError(
             f"HTTP ERROR {response.status_code}: {response.text}", response
         )
     ids = parseString(response.content).getElementsByTagName("id")
     if ids:
         self.process_id = ids[0].firstChild.nodeValue
     return response
 def test_run_task_with_retry(self):
     project_config = create_project_config()
     project_config.get_latest_version = mock.Mock(return_value="1.0")
     project_config.config["project"]["package"]["namespace"] = "ns"
     task = create_task(InstallPackageVersion, {"version": "latest"}, project_config)
     not_yet = MetadataApiError("This package is not yet available", None)
     api = mock.Mock(side_effect=[not_yet, None])
     task.api_class = mock.Mock(return_value=api)
     task()
     self.assertEqual(2, api.call_count)
Example #6
0
 def __call__(self):
     self.task.logger.info("Pending")
     response = self._get_response()
     if self.status != "Failed":
         try:
             return self._process_response(response)
         except Exception as e:
             raise MetadataParseError(
                 f"Could not process MDAPI response: {str(e)}", response=response
             )
     else:
         raise MetadataApiError(response.text, response)
Example #7
0
    def _set_status(self, status, log=None, level=None, response=None):
        if not level:
            level = 'info'
            if status == 'Failed':
                level = 'error'
        logger = getattr(self.task.logger, level)
        self.status = status
        if log:
            logger('[{}]: {}'.format(status, log))
        else:
            logger('[{}]'.format(status))

        if level == 'error':
            raise MetadataApiError(log, response)
Example #8
0
 def _handle_soap_error(self, headers, envelope, refresh, response):
     faultcode = parseString(
         response.content).getElementsByTagName('faultcode')
     if faultcode:
         faultcode = faultcode[0].firstChild.nodeValue
     faultstring = parseString(
         response.content).getElementsByTagName('faultstring')
     if faultstring:
         faultstring = faultstring[0].firstChild.nodeValue
     else:
         faultstring = response.content
     if faultcode == 'sf:INVALID_SESSION_ID' and self.task.org_config and self.task.org_config.refresh_token:
         # Attempt to refresh token and recall request
         if refresh:
             self.task.org_config.refresh_oauth_token()
             return self._call_mdapi(headers, envelope, refresh=False)
     # Log the error
     message = '{}: {}'.format(faultcode, faultstring)
     self._set_status('Failed', message)
     raise MetadataApiError(message, response)
Example #9
0
 def _process_response_status(self, response):
     if response.status_code == httplib.INTERNAL_SERVER_ERROR:
         raise MetadataApiError('HTTP ERROR {}: {}'.format(response.status_code, response.content), response)
     resp_xml = parseString(response.content)
     done = resp_xml.getElementsByTagName('done')
     if done:
         if done[0].firstChild.nodeValue == 'true':
             self._set_status('Done')
         else:
             state_detail = resp_xml.getElementsByTagName('stateDetail')
             if state_detail:
                 log = state_detail[0].firstChild.nodeValue
                 self._set_status('InProgress', log)
                 self.check_num = 1
             elif self.status == 'InProgress':
                 self.check_num = 1
                 self._set_status('InProgress', 'next check in {} seconds'.format(self._get_check_interval()))
             else:
                 self._set_status('Pending', 'next check in {} seconds'.format(self._get_check_interval()))
     else:
         # If no done element was in the xml, fail logging the entire SOAP
         # envelope as the log
         self._set_status('Failed', response.content, response=response)
     return response
Example #10
0
    def _process_response(self, response):
        resp_xml = parseString(response.content)
        status = resp_xml.getElementsByTagName("status")
        if status:
            status = status[0].firstChild.nodeValue
        else:
            # If no status element is in the result xml, return fail and log
            # the entire SOAP envelope in the log
            self._set_status("Failed", response.text)
            return self.status
        # Only done responses should be passed so we need to handle any status
        # related to done
        if status in ["Succeeded", "SucceededPartial"]:
            self._set_status("Success", status)
        else:
            # If failed, parse out the problem text and raise appropriate exception
            messages = []

            component_failures = resp_xml.getElementsByTagName("componentFailures")
            for component_failure in component_failures:
                problems = component_failure.getElementsByTagName("problem")
                problem_types = component_failure.getElementsByTagName("problemType")
                failure_info = {
                    "component_type": None,
                    "file_name": None,
                    "line_num": None,
                    "column_num": None,
                    "problem": problems[0].firstChild.nodeValue
                    if problems
                    else "Unknown problem",
                    "problem_type": problem_types[0].firstChild.nodeValue
                    if problem_types
                    else "Error",
                }
                failure_info["component_type"] = self._get_element_value(
                    component_failure, "componentType"
                )
                full_name = self._get_element_value(component_failure, "fullName")
                file_name = self._get_element_value(component_failure, "fileName")
                failure_info["file_name"] = full_name or file_name
                failure_info["line_num"] = self._get_element_value(
                    component_failure, "lineNumber"
                )
                failure_info["column_num"] = self._get_element_value(
                    component_failure, "columnNumber"
                )

                created = (
                    component_failure.getElementsByTagName("created")[
                        0
                    ].firstChild.nodeValue
                    == "true"
                )
                deleted = (
                    component_failure.getElementsByTagName("deleted")[
                        0
                    ].firstChild.nodeValue
                    == "true"
                )
                failure_info["action"] = self._get_action(created, deleted)

                if failure_info["file_name"] and failure_info["line_num"]:
                    messages.append(
                        "{action} of {component_type} {file_name}: {problem_type} on line {line_num}, col {column_num}: {problem}".format(
                            **failure_info
                        )
                    )
                elif failure_info["file_name"]:
                    messages.append(
                        "{action} of {component_type} {file_name}: {problem_type}: {problem}".format(
                            **failure_info
                        )
                    )
                else:
                    messages.append(
                        "{action} of {component_type}: {problem_type}: {problem}".format(
                            **failure_info
                        )
                    )

            if messages:
                # Deploy failures due to a component failure should raise MetadataComponentFailure
                log = "\n\n".join(messages)
                self._set_status("Failed", log)
                raise MetadataComponentFailure(log, response)

            else:
                problems = resp_xml.getElementsByTagName("problem")
                for problem in problems:
                    messages.append(problem.firstChild.nodeValue)
                errorMessages = resp_xml.getElementsByTagName("errorMessage")
                for errorMessage in errorMessages:
                    messages.append(errorMessage.firstChild.nodeValue)
                if messages:
                    log = "\n\n".join(messages)
                    raise MetadataApiError(log, response)

            # Parse out any failure text (from test failures in production
            # deployments) and add to log
            failures = resp_xml.getElementsByTagName("failures")
            for failure in failures:
                # Get needed values from subelements
                namespace = self._get_element_value(failure, "namespace")
                stacktrace = self._get_element_value(failure, "stackTrace")
                message = ["Apex Test Failure: "]
                if namespace:
                    message.append(f"from namespace {namespace}: ")
                if stacktrace:
                    message.append(stacktrace)
                messages.append("".join(message))

            if messages:
                # Deploy failures due to a component failure should raise MetadataComponentFailure
                log = "\n\n".join(messages)
                self._set_status("Failed", log)
                raise ApexTestException(log)
            else:
                log = response.text
                self._set_status("Failed", log)
                raise MetadataApiError(log, response)

        return self.status
Example #11
0
    def _process_response(self, response):
        status = parseString(response.content).getElementsByTagName('status')
        if status:
            status = status[0].firstChild.nodeValue
        else:
            # If no status element is in the result xml, return fail and log
            # the entire SOAP envelope in the log
            self._set_status('Failed', response.content)
            return self.status
        # Only done responses should be passed so we need to handle any status
        # related to done
        if status in ['Succeeded', 'SucceededPartial']:
            self._set_status('Success', status)
        else:
            # If failed, parse out the problem text and raise appropriate exception
            messages = []
            resp_xml = parseString(response.content)

            component_failures = resp_xml.getElementsByTagName('componentFailures')
            for component_failure in component_failures:
                failure_info = {
                    'component_type': None,
                    'file_name': None,
                    'line_num': None,
                    'column_num': None,
                    'problem': component_failure.getElementsByTagName('problem')[0].firstChild.nodeValue,
                    'problem_type': component_failure.getElementsByTagName('problemType')[0].firstChild.nodeValue,
                }
                failure_info['component_type'] = self._get_element_value(
                    component_failure, 'componentType')
                full_name = self._get_element_value(component_failure, 'fullName')
                file_name = self._get_element_value(component_failure, 'fileName')
                failure_info['file_name'] = full_name or file_name
                failure_info['line_num'] = self._get_element_value(component_failure, 'lineNumber')
                failure_info['column_num'] = self._get_element_value(component_failure, 'columnNumber')
                
                created = component_failure.getElementsByTagName('created')[0].firstChild.nodeValue == 'true'
                deleted = component_failure.getElementsByTagName('deleted')[0].firstChild.nodeValue == 'true'
                failure_info['action'] = self._get_action(created, deleted)
  
                if failure_info['file_name'] and failure_info['line_num']: 
                    messages.append('{action} of {component_type} {file_name}: {problem_type} on line {line_num}, col {column_num}: {problem}'.format(**failure_info))
                elif failure_info['file_name']:
                    messages.append('{action} of {component_type} {file_name}: {problem_type}: {problem}'.format(**failure_info))
                else:
                    messages.append('{action} of {problem_type}: {problem}'.format(**failure_info))

            if messages:
                # Deploy failures due to a component failure should raise MetadataComponentFailure
                log = '\n\n'.join(messages)
                self._set_status('Failed', log)
                raise MetadataComponentFailure(log, response)
                
            else:
                problems = parseString(
                    response.content).getElementsByTagName('problem')
                for problem in problems:
                    messages.append(problem.firstChild.nodeValue)

            # Parse out any failure text (from test failures in production
            # deployments) and add to log
            failures = parseString(
                response.content).getElementsByTagName('failures')
            for failure in failures:
                # Get needed values from subelements
                namespace = self._get_element_value(failure, 'namespace')
                stacktrace = self._get_element_value(failure, 'stackTrace')
                message = ['Apex Test Failure: ', ]
                if namespace:
                    message.append('from namespace {}: '.format(namespace))
                if stacktrace:
                    message.append(stacktrace)
                messages.append(''.join(message))

            if messages:
                # Deploy failures due to a component failure should raise MetadataComponentFailure
                log = '\n\n'.join(messages)
                self._set_status('Failed', log)
                raise ApexTestException(log)
            else:
                log = response.content
                self._set_status('Failed', log)
                raise MetadataApiError(log, response)

        return self.status