Ejemplo n.º 1
0
    def test_get_job_does_not_return_api_key(self):
        '''The dict that get_job() returns should not contain the API key.'''
        client = test_client()
        mock_result_url(RESULT_URL)
        event = _mock_test_callback_url(client)

        response = client.post('/job',
                               data=json.dumps({
                                   "job_type": "example",
                                   "api_key": 42,
                                   "data": {
                                       "time": 0.1
                                   },
                                   "result_url": RESULT_URL
                               }),
                               content_type='application/json')
        return_data = json.loads(response.data)

        timeout = 10.0
        assert event.wait(timeout), (
            "_TEST_CALLBACK_URL was not called within {timeout} "
            "seconds".format(timeout=timeout))

        job_ = db.get_job(return_data['job_id'])
        assert not job_['api_key'], job_
Ejemplo n.º 2
0
    def test_get_job_with_unknown_error(self):
        '''Test getting a job that failed with a random exception.

        A random exception type caused by an error in the job function code,
        as opposed to a deliberately raised JobError.

        '''
        client = test_client()
        mock_result_url(RESULT_URL)
        event = _mock_test_callback_url(client)

        response = client.post('/job/exception',
                               data=json.dumps({
                                   "job_type": "example",
                                   "api_key": 42,
                                   "data": {
                                       "time": "not_a_time"
                                   },
                                   "result_url": RESULT_URL
                               }),
                               content_type='application/json')

        login(client)

        timeout = 10.0
        assert event.wait(timeout), (
            "_TEST_CALLBACK_URL was not called within {timeout} "
            "seconds".format(timeout=timeout))

        response = client.get('/job/exception')

        job_status_data = json.loads(response.data)
        job_status_data.pop('requested_timestamp')
        job_status_data.pop('finished_timestamp')
        error = job_status_data.pop('error')

        assert job_status_data == {
            u'status': u'error',
            u'sent_data': {
                "time": "not_a_time"
            },
            u'job_id': u'exception',
            u'job_type': u'example',
            u'data': None,
            u'metadata': {},
            u'logs': [],
            u'result_url': RESULT_URL
        }, job_status_data
        assert 'TypeError' in error["message"], error["message"]

        # get_job() shouldn't return the API key, either.
        job_ = db.get_job(job_status_data['job_id'])
        assert not job_['api_key'], job_
Ejemplo n.º 3
0
    def test_get_job_with_known_error(self):
        '''Test getting a job that failed with a JobError.

        Among other things, we expect the job dict to have an "error" key with
        the error string from the job function as its value.

        '''
        client = test_client()
        mock_result_url(RESULT_URL)
        event = _mock_test_callback_url(client)

        response = client.post('/job/missing_time',
                               data=json.dumps({
                                   "job_type": "example",
                                   "api_key": 42,
                                   "data": {},
                                   "result_url": RESULT_URL
                               }),
                               content_type='application/json')

        login(client)

        timeout = 10.0
        assert event.wait(timeout), (
            "_TEST_CALLBACK_URL was not called within {timeout} "
            "seconds".format(timeout=timeout))

        response = client.get('/job/missing_time')

        job_status_data = json.loads(response.data)
        job_status_data.pop('requested_timestamp')
        job_status_data.pop('finished_timestamp')

        assert job_status_data == {
            u'status': u'error',
            u'sent_data': {},
            u'job_id': u'missing_time',
            u'job_type': u'example',
            u'error': {
                "message": u'time not in input'
            },
            u'data': None,
            u'metadata': {},
            u'logs': [],
            u'result_url': RESULT_URL
        }, job_status_data

        # get_job() shouldn't return the API key, either.
        job_ = db.get_job(job_status_data['job_id'])
        assert not job_['api_key'], job_
Ejemplo n.º 4
0
    def test_asynchronous_post_with_bad_result_url(self):
        """It should store an error if given a bad result URL.

        If given an asynchronous job request with a bad result URL
        ckanserviceprovider should store a
        "Process completed but unable to post to result_url" error.

        This error overwrites any error that might have happened with the job
        itself!

        """
        client = test_client()
        event = _mock_test_callback_url(client)

        httpretty.register_uri(httpretty.POST, RESULT_URL, status=404)

        response = client.post(
            '/job/with_bad_result',
            data=json.dumps({
                "job_type": "example",
                "api_key": 42,
                "data": {"time": 0.1},
                "metadata": {'key': 'value'},
                "result_url": RESULT_URL}),
            content_type='application/json')

        timeout = 10.0
        assert event.wait(timeout), (
            "_TEST_CALLBACK_URL was not called within {timeout} "
            "seconds".format(timeout=timeout))

        login(client)
        response = client.get('/job/with_bad_result')
        job_status_data = json.loads(response.data)
        job_status_data.pop('requested_timestamp')
        job_status_data.pop('finished_timestamp')
        assert job_status_data == {
            u'status': u'complete',
            u'sent_data': {u'time': 0.1},
            u'job_id': u'with_bad_result',
            u'job_type': u'example',
            u'error': {"message": 'Process completed but unable to post to '
                                  'result_url'},
            u'data': u'Slept for 0.1 seconds.',
            u'metadata': {'key': 'value'},
            u'logs': [],
            u'result_url': RESULT_URL}, job_status_data

        job_ = db.get_job(job_status_data['job_id'])
        assert not job_['api_key'], job_
Ejemplo n.º 5
0
    def test_get_job_with_unknown_error(self):
        '''Test getting a job that failed with a random exception.

        A random exception type caused by an error in the job function code,
        as opposed to a deliberately raised JobError.

        '''
        client = test_client()
        mock_result_url(RESULT_URL)
        event = _mock_test_callback_url(client)

        response = client.post(
            '/job/exception',
            data=json.dumps({
                "job_type": "example",
                "api_key": 42,
                "data": {"time": "not_a_time"},
                "result_url": RESULT_URL}),
            content_type='application/json')

        login(client)

        timeout = 10.0
        assert event.wait(timeout), (
            "_TEST_CALLBACK_URL was not called within {timeout} "
            "seconds".format(timeout=timeout))

        response = client.get('/job/exception')

        job_status_data = json.loads(response.data)
        job_status_data.pop('requested_timestamp')
        job_status_data.pop('finished_timestamp')
        error = job_status_data.pop('error')

        assert job_status_data == {u'status': u'error',
                                   u'sent_data': {"time": "not_a_time"},
                                   u'job_id': u'exception',
                                   u'job_type': u'example',
                                   u'data': None,
                                   u'metadata': {},
                                   u'logs': [],
                                   u'result_url': RESULT_URL}, job_status_data
        assert 'TypeError' in error["message"], error["message"]

        # get_job() shouldn't return the API key, either.
        job_ = db.get_job(job_status_data['job_id'])
        assert not job_['api_key'], job_
Ejemplo n.º 6
0
    def test_get_job_with_known_error(self):
        '''Test getting a job that failed with a JobError.

        Among other things, we expect the job dict to have an "error" key with
        the error string from the job function as its value.

        '''
        client = test_client()
        mock_result_url(RESULT_URL)
        event = _mock_test_callback_url(client)

        response = client.post(
            '/job/missing_time',
            data=json.dumps({
                "job_type": "example",
                "api_key": 42,
                "data": {},
                "result_url": RESULT_URL}),
            content_type='application/json')

        login(client)

        timeout = 10.0
        assert event.wait(timeout), (
            "_TEST_CALLBACK_URL was not called within {timeout} "
            "seconds".format(timeout=timeout))

        response = client.get('/job/missing_time')

        job_status_data = json.loads(response.data)
        job_status_data.pop('requested_timestamp')
        job_status_data.pop('finished_timestamp')

        assert job_status_data == {u'status': u'error',
                                   u'sent_data': {},
                                   u'job_id': u'missing_time',
                                   u'job_type': u'example',
                                   u'error': {"message": u'time not in input'},
                                   u'data': None,
                                   u'metadata': {},
                                   u'logs': [],
                                   u'result_url': RESULT_URL}, job_status_data

        # get_job() shouldn't return the API key, either.
        job_ = db.get_job(job_status_data['job_id'])
        assert not job_['api_key'], job_
Ejemplo n.º 7
0
    def test_get_job_does_not_return_api_key(self):
        '''The dict that get_job() returns should not contain the API key.'''
        client = test_client()
        mock_result_url(RESULT_URL)
        event = _mock_test_callback_url(client)

        response = client.post(
            '/job',
            data=json.dumps(
                {"job_type": "example",
                 "api_key": 42,
                 "data": {"time": 0.1},
                 "result_url": RESULT_URL}),
            content_type='application/json')
        return_data = json.loads(response.data)

        timeout = 10.0
        assert event.wait(timeout), (
            "_TEST_CALLBACK_URL was not called within {timeout} "
            "seconds".format(timeout=timeout))

        job_ = db.get_job(return_data['job_id'])
        assert not job_['api_key'], job_
Ejemplo n.º 8
0
    def test_synchronous_post(self):
        '''Posting a synchronous job should get a JSON response with result.

        User posts a synchronous job request, ckan-service-provider runs the
        job and returns an HTTP response with a JSON body containing the job
        result.

        '''
        client = test_client()
        response = client.post('/job/echobasic',
                               data=json.dumps({
                                   "metadata": {
                                       "key": "value",
                                       "moo": "moo",
                                       "mimetype": "text/csv"
                                   },
                                   "job_type": "echo",
                                   "api_key": 42,
                                   "data": "ping"
                               }),
                               content_type='application/json')

        return_data = json.loads(response.data)
        return_data.pop('requested_timestamp')
        return_data.pop('finished_timestamp')
        job_key = return_data.pop('job_key')

        job_ = db.get_job(return_data['job_id'])
        assert not job_['api_key'], job_

        assert_equal(
            return_data, {
                u'status': u'complete',
                u'sent_data': u'ping',
                u'job_id': u'echobasic',
                u'job_type': u'echo',
                u'result_url': None,
                u'error': None,
                u'data': u'>ping',
                u'logs': [],
                u'metadata': {
                    "key": "value",
                    "moo": "moo",
                    "mimetype": "text/csv"
                }
            })

        login(client)
        response = client.get('/job/echobasic')
        assert response.status_code == 200, response.status
        job_status_data = json.loads(response.data)
        job_status_data.pop('requested_timestamp')
        job_status_data.pop('finished_timestamp')

        assert_equal(return_data, job_status_data)

        headers = {'Authorization': job_key}
        response = client.get('/job/echobasic/data', headers=headers)
        assert response.status_code == 200, response.status

        if sys.version_info[0] < 3:
            assert_equal(response.data, u'>ping')
        else:
            assert_equal(response.data, b'>ping')
        assert 'text/csv' in response.content_type, response.content_type

        response = client.post('/job/echobasic',
                               data=json.dumps({
                                   "job_type": "echo",
                                   "api_key": 42,
                                   "data": "ping"
                               }),
                               content_type='application/json')

        return_data = json.loads(response.data)
        assert_equal(return_data,
                     {u'error': u'job_id echobasic already exists'})

        response = client.post('/job/echoknownbad',
                               data=json.dumps({
                                   "job_type": "echo",
                                   "api_key": 42,
                                   "data": ">ping"
                               }),
                               content_type='application/json')
        assert response.status_code == 200, response.status
        return_data = json.loads(response.data)
        return_data.pop('requested_timestamp')
        return_data.pop('finished_timestamp')
        return_data.pop('job_key')
        assert_equal(
            return_data, {
                u'status': u'error',
                u'sent_data': u'>ping',
                u'job_id': u'echoknownbad',
                u'job_type': u'echo',
                u'result_url': None,
                u'error': {
                    "message": u'Do not start message with >'
                },
                u'data': None,
                u'logs': [],
                u'metadata': {}
            })

        response = client.post('/job/echounknownbad',
                               data=json.dumps({
                                   "job_type": "echo",
                                   "api_key": 42,
                                   "data": 1
                               }),
                               content_type='application/json')
        return_data = json.loads(response.data)
        assert 'AttributeError' in return_data['error']['message']

        response = client.post('/job/echobad_url',
                               data=json.dumps({
                                   "job_type": "echo",
                                   "api_key": 42,
                                   "data": "moo",
                                   "result_url": "http://bad_url"
                               }),
                               content_type='application/json')
        return_data = json.loads(response.data)
        return_data.pop('requested_timestamp')
        return_data.pop('finished_timestamp')
        return_data.pop('job_key')
        assert_equal(
            return_data, {
                u'status': u'complete',
                u'sent_data': u'moo',
                u'job_id': u'echobad_url',
                u'job_type': u'echo',
                u'result_url': u'http://bad_url',
                u'error': {
                    "message":
                    u'Process completed but unable to post to '
                    'result_url'
                },
                u'data': u'>moo',
                u'logs': [],
                u'metadata': {}
            })
Ejemplo n.º 9
0
    def test_asynchronous_post_with_bad_result_url(self):
        """It should store an error if given a bad result URL.

        If given an asynchronous job request with a bad result URL
        ckanserviceprovider should store a
        "Process completed but unable to post to result_url" error.

        This error overwrites any error that might have happened with the job
        itself!

        """
        client = test_client()
        event = _mock_test_callback_url(client)

        httpretty.register_uri(httpretty.POST, RESULT_URL, status=404)

        response = client.post('/job/with_bad_result',
                               data=json.dumps({
                                   "job_type": "example",
                                   "api_key": 42,
                                   "data": {
                                       "time": 0.1
                                   },
                                   "metadata": {
                                       'key': 'value'
                                   },
                                   "result_url": RESULT_URL
                               }),
                               content_type='application/json')

        timeout = 10.0
        assert event.wait(timeout), (
            "_TEST_CALLBACK_URL was not called within {timeout} "
            "seconds".format(timeout=timeout))

        login(client)
        response = client.get('/job/with_bad_result')
        job_status_data = json.loads(response.data)
        job_status_data.pop('requested_timestamp')
        job_status_data.pop('finished_timestamp')
        assert job_status_data == {
            u'status': u'complete',
            u'sent_data': {
                u'time': 0.1
            },
            u'job_id': u'with_bad_result',
            u'job_type': u'example',
            u'error': {
                "message": 'Process completed but unable to post to '
                'result_url'
            },
            u'data': u'Slept for 0.1 seconds.',
            u'metadata': {
                'key': 'value'
            },
            u'logs': [],
            u'result_url': RESULT_URL
        }, job_status_data

        job_ = db.get_job(job_status_data['job_id'])
        assert not job_['api_key'], job_
Ejemplo n.º 10
0
    def test_synchronous_post(self):
        '''Posting a synchronous job should get a JSON response with result.

        User posts a synchronous job request, ckan-service-provider runs the
        job and returns an HTTP response with a JSON body containing the job
        result.

        '''
        client = test_client()
        response = client.post(
            '/job/echobasic',
            data=json.dumps({"metadata": {"key": "value",
                                          "moo": "moo",
                                          "mimetype": "text/csv"},
                             "job_type": "echo",
                             "api_key": 42,
                             "data": "ping"}),
            content_type='application/json')

        return_data = json.loads(response.data)
        return_data.pop('requested_timestamp')
        return_data.pop('finished_timestamp')
        job_key = return_data.pop('job_key')

        job_ = db.get_job(return_data['job_id'])
        assert not job_['api_key'], job_

        assert_equal(
            return_data,
            {u'status': u'complete',
             u'sent_data': u'ping',
             u'job_id': u'echobasic',
             u'job_type': u'echo',
             u'result_url': None,
             u'error': None,
             u'data': u'>ping',
             u'logs': [],
             u'metadata': {"key": "value", "moo": "moo",
                           "mimetype": "text/csv"}})

        login(client)
        response = client.get('/job/echobasic')
        assert response.status_code == 200, response.status
        job_status_data = json.loads(response.data)
        job_status_data.pop('requested_timestamp')
        job_status_data.pop('finished_timestamp')

        assert_equal(return_data, job_status_data)

        headers = {'Authorization': job_key}
        response = client.get('/job/echobasic/data', headers=headers)
        assert response.status_code == 200, response.status
        assert_equal(response.data, u'>ping')
        assert 'text/csv' in response.content_type, response.content_type

        response = client.post(
            '/job/echobasic',
            data=json.dumps({"job_type": "echo",
                             "api_key": 42,
                             "data": "ping"}),
            content_type='application/json')

        return_data = json.loads(response.data)
        assert_equal(
            return_data, {u'error': u'job_id echobasic already exists'})

        response = client.post(
            '/job/echoknownbad',
            data=json.dumps({"job_type": "echo",
                             "api_key": 42,
                             "data": ">ping"}),
            content_type='application/json')
        assert response.status_code == 200, response.status
        return_data = json.loads(response.data)
        return_data.pop('requested_timestamp')
        return_data.pop('finished_timestamp')
        return_data.pop('job_key')
        assert_equal(
            return_data,
            {u'status': u'error',
             u'sent_data': u'>ping',
             u'job_id': u'echoknownbad',
             u'job_type': u'echo',
             u'result_url': None,
             u'error': {"message": u'Do not start message with >'},
             u'data': None,
             u'logs': [],
             u'metadata': {}})

        response = client.post(
            '/job/echounknownbad',
            data=json.dumps({"job_type": "echo",
                             "api_key": 42,
                             "data": 1}),
            content_type='application/json')
        return_data = json.loads(response.data)
        assert 'AttributeError' in return_data['error']['message']

        response = client.post(
            '/job/echobad_url',
            data=json.dumps({"job_type": "echo",
                             "api_key": 42,
                             "data": "moo",
                             "result_url": "http://bad_url"}),
            content_type='application/json')
        return_data = json.loads(response.data)
        return_data.pop('requested_timestamp')
        return_data.pop('finished_timestamp')
        return_data.pop('job_key')
        assert_equal(
            return_data,
            {u'status': u'complete',
             u'sent_data': u'moo',
             u'job_id': u'echobad_url',
             u'job_type': u'echo',
             u'result_url': u'http://bad_url',
             u'error': {
                 "message": u'Process completed but unable to post to '
                            'result_url'},
             u'data': u'>moo',
             u'logs': [],
             u'metadata': {}})