def test_job_cloud_file(self):
        # test that job_cloud_file() does not set job.status after yield
        job = Job.objects.create()
        job.status = Job.CLOUD_FILE_DOWNLOADED  # an arbitrary one that's not PENDING (default) or SUCCESS
        job.save()
        with patch('utils.cloud_file.download_file') as download_file_mock:
            # test when caller sets status - exposes bug where job_cloud_file() was setting to SUCCESS
            with job_cloud_file(job.pk) as (job, cloud_file_fp):
                job.status = Job.CLOUD_FILE_UPLOADED
                job.save()
            job.refresh_from_db()
            self.assertEqual(Job.CLOUD_FILE_UPLOADED, job.status)

            # test when __enter__() raises JobTimeoutException
            job.status = Job.CLOUD_FILE_DOWNLOADED
            job.save()
            download_file_mock.side_effect = JobTimeoutException(
                'download_file_mock Exception')
            with self.assertRaises(JobTimeoutException):
                with job_cloud_file(job.pk) as (job, cloud_file_fp):
                    pass
            job.refresh_from_db()
            self.assertEqual(Job.TIMEOUT, job.status)

            # test when __enter__() raises BotoCoreError
            job.status = Job.CLOUD_FILE_DOWNLOADED
            job.save()
            download_file_mock.side_effect = BotoCoreError()
            with self.assertRaises(BotoCoreError):
                with job_cloud_file(job.pk) as (job, cloud_file_fp):
                    pass
            job.refresh_from_db()
            self.assertEqual(Job.FAILED, job.status)

            # test when __enter__() raises Exception
            job.status = Job.CLOUD_FILE_DOWNLOADED
            job.save()
            download_file_mock.side_effect = Exception(
                'download_file_mock Exception')
            with self.assertRaises(Exception):
                with job_cloud_file(job.pk) as (job, cloud_file_fp):
                    pass
            job.refresh_from_db()
            self.assertEqual(Job.FAILED, job.status)
示例#2
0
    def test__upload_forecast_worker_deletes_forecast(self):
        # verifies that _upload_forecast_worker() deletes the (presumably empty) Forecast that's passed to it by
        # upload functions if the file is invalid. here we mock load_predictions_from_json_io_dict() to throw the two
        # exceptions that cause deletes: JobTimeoutException and Exception
        _, _, po_user, _, _, _, _, _ = get_or_create_super_po_mo_users(
            is_create_super=True)
        project, time_zero, forecast_model, forecast = _make_docs_project(
            po_user)
        forecast.issued_at -= datetime.timedelta(
            days=1)  # older version avoids unique constraint errors
        forecast.save()

        for exception, exp_job_status in [
            (Exception('load_preds_mock Exception'), Job.FAILED),
            (JobTimeoutException('load_preds_mock JobTimeoutException'),
             Job.TIMEOUT)
        ]:
            with patch('forecast_app.models.job.job_cloud_file') as job_cloud_file_mock, \
                    patch('utils.forecast.load_predictions_from_json_io_dict') as load_preds_mock, \
                    patch('utils.forecast.cache_forecast_metadata') as cache_metatdata_mock, \
                    open('forecast_app/tests/predictions/docs-predictions.json') as cloud_file_fp:
                load_preds_mock.side_effect = exception
                forecast2 = Forecast.objects.create(
                    forecast_model=forecast_model, time_zero=time_zero)
                job = Job.objects.create()
                job.input_json = {
                    'forecast_pk': forecast2.pk,
                    'filename': 'a name!'
                }
                job.save()

                job_cloud_file_mock.return_value.__enter__.return_value = (
                    job, cloud_file_fp)
                try:
                    _upload_forecast_worker(job.pk)
                except JobTimeoutException as jte:
                    pass  # expected re-raise of this exception
                job.refresh_from_db()
                self.assertEqual(exp_job_status, job.status)
                self.assertIsNone(
                    Forecast.objects.filter(
                        id=forecast2.id).first())  # deleted
示例#3
0
    def test_create_tasks_throws_timeout_exception(self, importer, send_mail):
        importer.create_tasks.side_effect = JobTimeoutException()
        uploader_name = 'Cersei Lannister'
        project = ProjectFactory.create()
        form_data = {'type': 'csv', 'csv_url': 'http://google.es'}
        subject = 'Your import task has timed out'
        with patch.dict(self.flask_app.config, {'BRAND': 'GOT'}):
            body = '\n'.join(
                ['Hello,\n',
                 'Import task to your project {} by {} failed because the file was too large.',
                 'It was able to process approximately {} tasks.',
                 'Please break up your task upload into smaller CSV files.',
                 'Thank you,\n',
                 u'The {} team.']).format(project.name, uploader_name,
                                         0, self.flask_app.config['BRAND'])

            email_data = dict(recipients=[project.owner.email_addr],
                              subject=subject, body=body)
            assert_raises(JobTimeoutException, import_tasks, project.id, uploader_name, **form_data)
            send_mail.assert_called_once_with(email_data)
示例#4
0
 def setup_death_penalty(self):
     exception = JobTimeoutException(
         'Gevent Job exceeded maximum timeout value (%d seconds).' %
         self._timeout)
     self.gevent_timeout = gevent.Timeout(self._timeout, exception)
     self.gevent_timeout.start()