def test_check_complete_error2(self):
        """Test check_for_completion() with complete job in error (2)."""
        with requests_mock.mock() as m:
            self.mock_server_1(m)
            session = Session('fake-host', 'fake-user', 'fake-pw')
            op_method = 'POST'
            op_uri = '/api/foo'
            job = Job(session, self.job_uri, op_method, op_uri)
            query_job_status_result = {
                'status': 'complete',
                'job-status-code': 500,
                'job-reason-code': 42,
                'job-results': {},  # it is not guaranteed to have any content
            }

            m.get(self.job_uri, json=query_job_status_result)
            m.delete(self.job_uri, status_code=204)

            with pytest.raises(HTTPError) as exc_info:
                job_status, op_result = job.check_for_completion()
            exc = exc_info.value

            assert exc.http_status == 500
            assert exc.reason == 42
            assert exc.message is None
    def test_check_complete_error4(self):
        """Test check_for_completion() with complete job in error (4)."""
        with requests_mock.mock() as m:
            self.mock_server_1(m)
            session = Session('fake-host', 'fake-user', 'fake-pw')
            op_method = 'POST'
            op_uri = '/api/foo'
            job = Job(session, self.job_uri, op_method, op_uri)
            query_job_status_result = {
                'status': 'complete',
                'job-status-code': 500,
                'job-reason-code': 42,
                'job-results': {
                    # Content is not documented for the error case.
                    # Some failures result in an 'message' field.
                    'message': 'bla message',
                },
            }

            m.get(self.job_uri, json=query_job_status_result)
            m.delete(self.job_uri, status_code=204)

            with pytest.raises(HTTPError) as exc_info:
                job_status, op_result = job.check_for_completion()
            exc = exc_info.value

            assert exc.http_status == 500
            assert exc.reason == 42
            assert exc.message == 'bla message'
def test_job_wait_complete3_success_result():
    """Test wait_for_completion() with successful complete job with a
    result."""
    with requests_mock.mock() as m:
        mock_server_1(m)
        session = Session('fake-host', 'fake-user', 'fake-pw')
        op_method = 'POST'
        op_uri = '/api/foo'
        job = Job(session, JOB_URI, op_method, op_uri)
        exp_op_result = {
            'foo': 'bar',
        }
        m.get(JOB_URI, [
            {
                'text': result_running_callback
            },
            {
                'text': result_complete_callback
            },
        ])
        m.delete(JOB_URI, status_code=204)

        op_result = job.wait_for_completion()

        assert op_result == exp_op_result
    def test_check_complete_success_result(self):
        """Test check_for_completion() with successful complete job with a
        result."""
        with requests_mock.mock() as m:
            self.mock_server_1(m)
            session = Session('fake-host', 'fake-user', 'fake-pw')
            op_method = 'POST'
            op_uri = '/api/foo'
            job = Job(session, self.job_uri, op_method, op_uri)
            exp_op_result = {
                'foo': 'bar',
            }
            query_job_status_result = {
                'status': 'complete',
                'job-status-code': 200,
                # 'job-reason-code' omitted because HTTP status good
                'job-results': exp_op_result,
            }
            m.get(self.job_uri, json=query_job_status_result)
            m.delete(self.job_uri, status_code=204)

            job_status, op_result = job.check_for_completion()

            assert job_status == 'complete'
            assert op_result == exp_op_result
def test_job_check_complete_error1():
    """Test check_for_completion() with complete job in error (1)."""
    with requests_mock.mock() as m:
        mock_server_1(m)
        session = Session('fake-host', 'fake-user', 'fake-pw')
        op_method = 'POST'
        op_uri = '/api/foo'
        job = Job(session, JOB_URI, op_method, op_uri)
        query_job_status_result = {
            'status': 'complete',
            'job-status-code': 500,
            'job-reason-code': 42,
            # no 'job-results' field (it is not guaranteed to be there)
        }

        m.get(JOB_URI, json=query_job_status_result)
        m.delete(JOB_URI, status_code=204)

        with pytest.raises(HTTPError) as exc_info:
            job.check_for_completion()
        exc = exc_info.value

        assert exc.http_status == 500
        assert exc.reason == 42
        assert exc.message is None
    def test_check_incomplete(self):
        """Test check_for_completion() with incomplete job."""
        with requests_mock.mock() as m:
            self.mock_server_1(m)
            session = Session('fake-host', 'fake-user', 'fake-pw')
            op_method = 'POST'
            op_uri = '/api/foo'
            job = Job(session, self.job_uri, op_method, op_uri)
            query_job_status_result = {
                'status': 'running',
            }
            m.get(self.job_uri, json=query_job_status_result)
            m.delete(self.job_uri, status_code=204)

            job_status, op_result = job.check_for_completion()

            assert job_status == 'running'
            assert op_result is None
def test_job_wait_complete3_timeout():
    """Test wait_for_completion() with timeout."""
    with requests_mock.mock() as m:
        mock_server_1(m)
        session = Session('fake-host', 'fake-user', 'fake-pw')
        op_method = 'POST'
        op_uri = '/api/foo'
        job = Job(session, JOB_URI, op_method, op_uri)
        m.get(JOB_URI, [
            {
                'text': result_running_callback
            },
            {
                'text': result_running_callback
            },
            {
                'text': result_complete_callback
            },
        ])
        m.delete(JOB_URI, status_code=204)

        # Here we provoke a timeout, by setting the timeout to less than
        # the time it would take to return the completed job status.
        # The time it would take is the sum of the following:
        # - 2 * 1 s (1 s is the sleep time in Job.wait_for_completion(),
        #   and this happens before each repeated status retrieval)
        # - 3 * 1 s (1 s is the sleep time in result_*_callback() in this
        #   module, and this happens in each mocked status retrieval)
        # Because status completion is given priority over achieving the
        # timeout duration, the timeout value needed to provoke the
        # timeout exception needs to be shorter by the last status
        # retrieval (the one that completes the job), so 3 s is the
        # boundary for the timeout value.
        operation_timeout = 2.9
        try:
            start_time = time.time()
            job.wait_for_completion(operation_timeout=operation_timeout)
            duration = time.time() - start_time
            raise AssertionError(
                "No OperationTimeout raised. Actual duration: %s s, "
                "timeout: %s s" % (duration, operation_timeout))
        except OperationTimeout as exc:
            msg = exc.args[0]
            assert msg.startswith("Waiting for completion of job")
def test_job_check_complete_success_noresult():
    """Test check_for_completion() with successful complete job without
    result."""
    with requests_mock.mock() as m:
        mock_server_1(m)
        session = Session('fake-host', 'fake-user', 'fake-pw')
        op_method = 'POST'
        op_uri = '/api/foo'
        job = Job(session, JOB_URI, op_method, op_uri)
        query_job_status_result = {
            'status': 'complete',
            'job-status-code': 200,
            # 'job-reason-code' omitted because HTTP status good
            # 'job-results' is optional and is omitted
        }
        m.get(JOB_URI, json=query_job_status_result)
        m.delete(JOB_URI, status_code=204)

        job_status, op_result = job.check_for_completion()

        assert job_status == 'complete'
        assert op_result is None
    def test_init(self):
        """Test initialization of Job object."""
        session = Session('fake-host', 'fake-user', 'fake-pw')

        # Jobs exist only for POST, but we want to test that the specified HTTP
        # method comes back regardless:
        op_method = 'GET'

        op_uri = '/api/bla'

        job = Job(session, self.job_uri, op_method, op_uri)

        assert job.uri == self.job_uri
        assert job.session == session
        assert job.op_method == op_method
        assert job.op_uri == op_uri