Ejemplo n.º 1
0
    def process_output(self, output, service_name, data_field_name):
        try:
            normalized_response_json = json.loads(output)
        except ValueError as e:
            print(
                'Failed to parse CLI output as valid JSON. Output: {}'.format(
                    output))
            raise e

        # convert the CLI response (keys with '-') to camelcase so that testing service can validate
        complex_parameter_type = {
            'module': service_name,
            'class': data_field_name[0].upper() + data_field_name[1:]
        }

        # remove 'data' temporarily to camelize all other fields
        response_data = normalized_response_json.pop('data', None)

        # camelize the rest of the response fields (data is removed so there is no corresponding complex type definition for the top level object)
        normalized_response_json = make_dict_keys_camel_case(
            normalized_response_json)

        # camelize response['data'] independently and specify the corresponding complex_parameter_type
        # this will correctly skip camelizing keys of dictionaries nested within the response such as 'metadata' or 'defined-tags'
        if response_data:
            normalized_response_json[
                data_field_name] = make_dict_keys_camel_case(
                    response_data,
                    complex_parameter_type=complex_parameter_type)
        return normalized_response_json
    def validate_result(self, service_name, api_name, container_id, request,
                        result, data_field_name, is_delete_operation):
        """
        Calls the testing service to validate a CLI command result.

        :param str service_name
            The name of the service to request input parameters for. The testing service uses the following template to
            construct the Java SDK request object:
            String.format("com.oracle.bmc.%s.requests.%sRequest", serviceName, apiName);

        :param str api_name
            The name of the API to request input parameters for. The testing service uses the following template to
            construct the Java SDK request object:
            String.format("com.oracle.bmc.%s.requests.%sRequest", serviceName, apiName);

        :param str container_id:
            The ID of the current container.

        :param str request:
            The json content of the request object.

        :param Result result:
            The result object from click.testing.CliRunner.

        :param str data_field_name:
            The CLI returns the main resource under the field name 'data' but we need to convert it to
            the name used in the Java SDK (e.g. for GetGroup data -> group)

        :return: None

        """
        # standardize service name to convention for Java SDK model namespaces (all lower case one word)
        java_package_name = service_name.replace('_', '').lower()

        request_class = 'com.oracle.bmc.{java_package_name}.requests.{api_name}Request'.format(
            java_package_name=java_package_name, api_name=api_name)
        response_class = 'com.oracle.bmc.{java_package_name}.responses.{api_name}Response'.format(
            java_package_name=java_package_name, api_name=api_name)

        success_url = '{service_root_url}/response'.format(
            service_root_url=SERVICE_ROOT_URL)
        error_url = '{service_root_url}/error'.format(
            service_root_url=SERVICE_ROOT_URL)
        data = {
            'containerId': container_id,
            'requestClass': request_class,
            'requestJson': json.dumps(request),
        }

        params = {"sessionId": self.session_id, "lang": SERVICE_LANGUAGE}

        if result.exit_code == 0:
            # remove known warnings from output that would break JSON parsing
            output = result.output.replace(LIST_NOT_ALL_ITEMS_RETURNED_WARNING,
                                           '')

            # list and delete CLI commands can return an empty string so specially handle those cases
            if len(output) == 0:
                if api_name.lower().startswith('list'):
                    normalized_response_json = {data_field_name: []}
                elif is_delete_operation:
                    normalized_response_json = {}
                else:
                    raise ValueError('CLI output was empty')
            else:
                try:
                    normalized_response_json = json.loads(output)
                except ValueError as e:
                    print(
                        'Failed to parse CLI output as valid JSON. Output: {}'.
                        format(output))
                    raise e

                # convert the CLI response (keys with '-') to camelcase so that testing service can validate
                complex_parameter_type = {
                    'module': service_name,
                    'class': data_field_name[0].upper() + data_field_name[1:]
                }

                # remove 'data' temporarily to camelize all other fields
                response_data = normalized_response_json.pop('data', None)

                # camelize the rest of the response fields (data is removed so there is no corresponding complex type definition for the top level object)
                normalized_response_json = make_dict_keys_camel_case(
                    normalized_response_json)

                # camelize response['data'] independently and specify the corresponding complex_parameter_type
                # this will correctly skip camelizing keys of dictionaries nested within the response such as 'metadata' or 'defined-tags'
                if response_data:
                    normalized_response_json[
                        data_field_name] = make_dict_keys_camel_case(
                            response_data,
                            complex_parameter_type=complex_parameter_type)

            # right now we only return the opc-request-id for errors but the validator looks for it
            # tempporarily bypassing this check by hardcoding one here
            normalized_response_json[
                'opcRequestId'] = use_or_generate_request_id(None)

            data['responseJson'] = json.dumps(normalized_response_json)
            data['responseClass'] = response_class

            response = requests.post(success_url,
                                     params=params,
                                     data=json.dumps(data))
            assert response.status_code == 200, response.content
            return response.content.decode("UTF-8")
        else:
            error = json.loads(result.output.replace('ServiceError:', ''))
            error['statusCode'] = error.pop('status')
            error['opcRequestId'] = error.pop('opc-request-id')

            data['errorJson'] = json.dumps(error)
            print('errorToValidate: {}'.format(json.dumps(data, indent=2)))

            response = requests.post(error_url,
                                     params=params,
                                     data=json.dumps(data))
            assert response.status_code == 200, response.content
            return response.content.decode("UTF-8")