Esempio n. 1
0
def update_job_labels(id, body, **kwargs):
    """
    Update labels on a job.

    :param id: Job ID
    :type id: str
    :param body:
    :type body: dict | bytes

    :rtype: UpdateJobLabelsResponse
    """
    payload = UpdateJobLabelsRequest.from_dict(body).labels
    url = '{cromwell_url}/{id}/labels'.format(cromwell_url=_get_base_url(),
                                              id=id)
    response = requests.patch(url,
                              json=payload,
                              auth=kwargs.get('auth'),
                              headers=kwargs.get('auth_headers'))

    if response.status_code != 200:
        handle_error(response)

    # Follow API spec
    result = response.json()
    return UpdateJobLabelsResponse(labels=result.get('labels'))
Esempio n. 2
0
def update_job_labels(id, body, **kwargs):
    """
    Update labels on a job.

    :param id: Job ID
    :type id: str
    :param body:
    :type body: dict | bytes

    :rtype: UpdateJobLabelsResponse
    """
    payload = UpdateJobLabelsRequest.from_dict(body).labels
    url = '{cromwell_url}/{id}/labels'.format(cromwell_url=_get_base_url(),
                                              id=id)
    response = requests.patch(url,
                              json=payload,
                              auth=kwargs.get('auth'),
                              headers=kwargs.get('auth_headers'))

    if response.status_code == InternalServerError.code:
        raise InternalServerError(response.json().get('message'))
    elif response.status_code == BadRequest.code:
        raise BadRequest(response.json().get('message'))
    elif response.status_code == NotFound.code:
        raise NotFound(response.json().get('message'))
    response.raise_for_status()

    # Follow API spec
    result = response.json()
    return UpdateJobLabelsResponse(labels=result.get('labels'))
    def test_update_job_labels_bad_request(self, mock_request):
        workflow_id = 'id'
        error_message = "Invalid label: `` did not match the regex [a-z]([-a-z0-9]*[a-z0-9])?."

        def _request_callback(request, context):
            context.status_code = 400
            return {"status": "fail", "message": error_message}

        update_label_url = self.base_url + '/{id}/labels'.format(
            id=workflow_id)
        mock_request.patch(update_label_url, json=_request_callback)

        payload = UpdateJobLabelsRequest(labels={"": "test_invalid_label"})
        response = self.client.open(
            '/jobs/{id}/updateLabels'.format(id=workflow_id),
            method='POST',
            data=json.dumps(payload),
            content_type='application/json')
        self.assertStatus(response, 400)
        self.assertEquals(json.loads(response.data)['detail'], error_message)
    def test_update_job_labels_undefined_unsupported_media_type_exception(
            self, mock_request):
        workflow_id = 'id'
        error_message = b'Invalid Content-type (), expected JSON data'

        def _request_callback(request, context):
            context.status_code = 415
            return error_message

        update_label_url = self.base_url + '/{id}/labels'.format(
            id=workflow_id)
        mock_request.patch(update_label_url, json=_request_callback)

        payload = UpdateJobLabelsRequest(labels={"test_label": None})
        response = self.client.open(
            '/jobs/{id}/updateLabels'.format(id=workflow_id),
            headers={'Accept': 'application/json'},
            method='POST',
            data=json.dumps(payload))
        self.assertStatus(response, 415)
        self.assertEquals(json.loads(response.data)['detail'], error_message)
    def test_update_job_labels_internal_server_error(self, mock_request):
        workflow_id = 'id'
        error_message = "Invalid workflow ID: test_invalid_workflow_id"

        def _request_callback(request, context):
            context.status_code = 500
            return {"status": "error", "message": error_message}

        update_label_url = self.base_url + '/{id}/labels'.format(
            id=workflow_id)
        mock_request.patch(update_label_url, json=_request_callback)

        payload = UpdateJobLabelsRequest(
            labels={"test_label": "test_label_value"})
        response = self.client.open(
            '/jobs/{id}/updateLabels'.format(id=workflow_id),
            method='POST',
            data=json.dumps(payload),
            content_type='application/json')
        self.assertStatus(response, 500)
        self.assertEquals(json.loads(response.data)['detail'], error_message)
    def test_update_job_labels_not_found(self, mock_request):
        """Note: This status code is not currently properly returned by the Cromwell actually the error 'Unrecognized
            workflow ID' will return with a status code 500 now, the Cromwell team will address this issue in
            the near future."""
        workflow_id = 'id'
        error_message = "Unrecognized workflow ID: 12345678-aaaa-bbbb-cccc-dddddddddddd"

        def _request_callback(request, context):
            context.status_code = 404
            return {"status": "error", "message": error_message}

        update_label_url = self.base_url + '/{id}/labels'.format(
            id=workflow_id)
        mock_request.patch(update_label_url, json=_request_callback)

        payload = UpdateJobLabelsRequest(
            labels={"test_label": "test_label_value"})
        response = self.client.open(
            '/jobs/{id}/updateLabels'.format(id=workflow_id),
            method='POST',
            data=json.dumps(payload),
            content_type='application/json')
        self.assertStatus(response, 404)
        self.assertEquals(json.loads(response.data)['detail'], error_message)
    def test_update_job_labels_returns_200(self, mock_request):
        """
        Test case for update_job_labels.

        Update job's labels. Currently Cromwell will ONLY return the UPDATED labels instead of ALL labels of the job,
            the Job Manager makes two separate HTTP requests here to Cromwell so that it can get ALL labels.
        """
        workflow_id = 'id'
        workflow_name = 'test'
        status = 'Succeeded'
        timestamp = '2017-11-08T05:06:41.424Z'
        inputs = {'test.inputs': 'gs://project-bucket/test/inputs.txt'}
        outputs = {
            'test.analysis.outputs': 'gs://project-bucket/test/outputs.txt'
        }
        labels = {}
        backend_log = '/cromwell/cromwell-executions/id/call-analysis/call-analysis-log'
        attempts = 1
        return_code = 0

        def _request_callback_labels(request, context):
            context.status_code = 200
            return {"labels": {"test_label": "test_label_value"}}

        def _request_callback_get_job(request, context):
            context.status_code = 200
            return {
                'workflowName': workflow_name,
                'id': workflow_id,
                'status': status,
                'calls': {
                    'test.analysis': [{
                        'executionStatus': 'Done',
                        'start': timestamp,
                        'end': timestamp,
                        'backendLog': backend_log,
                        'returnCode': return_code,
                        'inputs': inputs,
                        'outputs': outputs,
                        'attempt': attempts
                    }]
                },
                'inputs': inputs,
                'labels': labels,
                'outputs': outputs,
                'submission': timestamp,
                'end': timestamp,
                'start': timestamp,
                'failures': [
                    {'causedBy': [
                        {
                            'causedBy': [],
                            'message': 'Task test.analysis failed'
                        }
                    ],
                    'message': 'Workflow failed'}
                ]
            }  # yapf: disable

        update_label_url = self.base_url + '/{id}/labels'.format(
            id=workflow_id)
        cromwell_url = self.base_url + '/{id}/metadata'.format(id=workflow_id)

        mock_request.patch(update_label_url, json=_request_callback_labels)
        mock_request.get(cromwell_url, json=_request_callback_get_job)

        payload = UpdateJobLabelsRequest(
            labels={"test_label": "test_label_value"})
        response = self.client.open(
            '/jobs/{id}/updateLabels'.format(id=workflow_id),
            method='POST',
            data=json.dumps(payload),
            content_type='application/json')
        self.assertStatus(response, 200)
        self.assertEquals(response.json,
                          {"labels": {
                              "test_label": "test_label_value"
                          }})
    def test_update_job_labels_returns_all_labels(self, mock_request):

        workflow_id = 'id'
        workflow_name = 'test'
        status = 'Succeeded'
        timestamp = '2017-11-08T05:06:41.424Z'
        inputs = {'test.inputs': 'gs://project-bucket/test/inputs.txt'}
        outputs = {
            'test.analysis.outputs': 'gs://project-bucket/test/outputs.txt'
        }
        labels = {
            "existing_test_label1": "existing_test_label_value1",
            "existing_test_label2": "existing_test_label_value2"
        }
        backend_log = '/cromwell/cromwell-executions/id/call-analysis/call-analysis-log'
        attempts = 1
        return_code = 0

        def _request_callback_labels(request, context):
            context.status_code = 200
            return {
                "labels": {
                    "new_test_label": "new_test_label_value",
                    "existing_test_label1": "existing_test_label_value1",
                    "existing_test_label2": "existing_test_label_value2"
                }
            }

        def _request_callback_get_job(request, context):
            context.status_code = 200
            return {
                'workflowName': workflow_name,
                'id': workflow_id,
                'status': status,
                'calls': {
                    'test.analysis': [{
                        'executionStatus': 'Done',
                        'start': timestamp,
                        'end': timestamp,
                        'backendLog': backend_log,
                        'returnCode': return_code,
                        'inputs': inputs,
                        'attempt': attempts
                    }]
                },
                'inputs': inputs,
                'labels': labels,
                'outputs': outputs,
                'submission': timestamp,
                'end': timestamp,
                'start': timestamp,
                'failures': [
                    {'causedBy': [
                        {
                            'causedBy': [],
                            'message': 'Task test.analysis failed'
                        }
                    ],
                        'message': 'Workflow failed'}
                ]
            }  # yapf: disable

        update_label_url = self.base_url + '/{id}/labels'.format(
            id=workflow_id)
        cromwell_url = self.base_url + '/{id}/metadata'.format(id=workflow_id)
        mock_request.patch(update_label_url, json=_request_callback_labels)
        mock_request.get(cromwell_url, json=_request_callback_get_job)

        payload = UpdateJobLabelsRequest(
            labels={"new_test_label": "new_test_label_value"})
        response = self.client.open(
            '/jobs/{id}/updateLabels'.format(id=workflow_id),
            method='POST',
            data=json.dumps(payload),
            content_type='application/json')

        expected_result = UpdateJobLabelsResponse.from_dict({
            "labels": {
                "existing_test_label1": "existing_test_label_value1",
                "existing_test_label2": "existing_test_label_value2",
                "new_test_label": "new_test_label_value"
            }
        })

        result = UpdateJobLabelsResponse.from_dict(response.json)

        self.assertStatus(response, 200)
        self.assertDictEqual(result.labels, expected_result.labels)