passerelle/tests/test_jobs.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

199 lines
8.2 KiB
Python
Raw Normal View History

import datetime
import os
from unittest import mock
import isodate
import pytest
from django.core.management import call_command
from django.core.management.base import CommandError
import tests.utils
2019-09-17 14:24:23 +02:00
from passerelle.base.models import Job, ResourceLog, SkipJob
from passerelle.utils.jsonresponse import APIError
from tests.test_base_adresse import BaseAdresse, StreetModel
@pytest.fixture
def base_adresse(db):
return tests.utils.setup_access_rights(BaseAdresse.objects.create(slug='base-adresse', zipcode='73'))
@mock.patch('passerelle.utils.Request.get')
def test_jobs(mocked_get, app, base_adresse, freezer):
Job.objects.all().delete() # remove jobs automatically added at connector creation
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
with open(filepath, 'rb') as ban_file:
mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
freezer.move_to('2019-01-01 00:00:00')
job = base_adresse.add_job('update_streets_data')
assert job.status == 'registered'
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'completed'
assert StreetModel.objects.count() == 3
# don't delete streets if bano file is empty
mocked_get.return_value = tests.utils.FakedResponse(content=b'', status_code=200)
freezer.move_to('2019-01-01 12:00:00')
job = base_adresse.add_job('update_streets_data')
assert job.status == 'registered'
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'failed'
assert Job.objects.get(id=job.id).status_details == {'error_summary': 'Exception: bano file is empty'}
assert ResourceLog.objects.all().count() == 1
assert ResourceLog.objects.all()[0].message == (
'error running update_streets_data job (bano file is empty)'
)
assert StreetModel.objects.count() == 3
with open(filepath, 'rb') as ban_file:
mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
StreetModel.objects.all().delete()
2019-09-17 14:24:23 +02:00
ResourceLog.objects.all().delete()
job = base_adresse.add_job('update_streets_data')
mocked_get.side_effect = Exception('hello')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'failed'
assert Job.objects.get(id=job.id).status_details == {'error_summary': 'Exception: hello'}
2019-09-17 14:24:23 +02:00
assert ResourceLog.objects.all().count() == 1
assert ResourceLog.objects.all()[0].message == 'error running update_streets_data job (hello)'
job = base_adresse.add_job('update_streets_data')
mocked_get.side_effect = SkipJob()
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
# use after_timestamp with SkipJob
freezer.move_to('2019-01-01 00:00:00')
mocked_get.side_effect = SkipJob(after_timestamp=isodate.parse_datetime('2019-01-02T00:00:00+00:00'))
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
mocked_get.side_effect = None
freezer.move_to('2019-01-01 12:00:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
freezer.move_to('2019-01-02 01:00:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'completed'
# use after_timestamp with SkipJob and seconds
job = base_adresse.add_job('update_streets_data')
freezer.move_to('2019-01-01 00:00:00')
mocked_get.side_effect = SkipJob(after_timestamp=3600)
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
mocked_get.side_effect = None
freezer.move_to('2019-01-01 00:30:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
freezer.move_to('2019-01-01 01:01:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'completed'
# use after_timestamp with SkipJob and timedelta
job = base_adresse.add_job('update_streets_data')
freezer.move_to('2019-01-01 00:00:00')
mocked_get.side_effect = SkipJob(after_timestamp=datetime.timedelta(seconds=3600))
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
mocked_get.side_effect = None
freezer.move_to('2019-01-01 00:30:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
freezer.move_to('2019-01-01 01:01:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'completed'
# use after_timestamp with add_job
freezer.move_to('2019-01-01 00:00:00')
job = base_adresse.add_job(
'update_streets_data', after_timestamp=isodate.parse_datetime('2019-01-02T00:00:00+00:00')
2021-02-20 16:26:01 +01:00
)
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
freezer.move_to('2019-01-02 01:00:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'completed'
# use after_timestamp with add_job and seconds
freezer.move_to('2019-01-01 00:00:00')
job = base_adresse.add_job('update_streets_data', after_timestamp=3600)
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
freezer.move_to('2019-01-01 01:01:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'completed'
# use after_timestamp with add_job and seconds
freezer.move_to('2019-01-01 00:00:00')
job = base_adresse.add_job('update_streets_data', after_timestamp=datetime.timedelta(seconds=3600))
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
freezer.move_to('2019-01-01 01:01:00')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'completed'
# don't run jobs if connector is down
StreetModel.objects.all().delete()
with mock.patch('passerelle.apps.base_adresse.models.BaseAdresse.down') as down:
down.side_effect = lambda: True
with open(filepath, 'rb') as ban_file:
mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
job = base_adresse.add_job('update_streets_data')
assert job.status == 'registered'
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'registered'
@mock.patch('passerelle.utils.Request.get')
def test_runjob(mocked_get, app, base_adresse, freezer):
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
with open(filepath, 'rb') as ban_file:
mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
freezer.move_to('2019-01-01 00:00:00')
job = base_adresse.add_job('update_streets_data')
assert job.status == 'registered'
call_command('runjob', '--job-id=%s' % job.pk)
assert Job.objects.get(id=job.id).status == 'completed'
assert StreetModel.objects.count() == 3
with pytest.raises(CommandError) as e:
call_command('runjob', '--job-id=%s' % job.pk)
assert 'cannot run job, status is completed' in str(e.value)
date = datetime.date(year=2019, month=1, day=2)
job = base_adresse.add_job('update_streets_data', after_timestamp=date)
with pytest.raises(CommandError) as e:
call_command('runjob', '--job-id=%s' % job.pk)
assert 'cannot run job, should be run after 2019-01-02 00:00:00+00:00' in str(e.value)
@mock.patch('passerelle.utils.Request.get')
def test_jobs_api_error_log_level(mocked_get, app, base_adresse, freezer):
Job.objects.all().delete() # remove jobs automatically added at connector creation
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
with open(filepath, 'rb') as ban_file:
mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
job = base_adresse.add_job('update_streets_data')
mocked_get.side_effect = Exception('hello')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'failed'
assert ResourceLog.objects.all().count() == 1
assert ResourceLog.objects.all()[0].level == 'error'
job = base_adresse.add_job('update_streets_data')
mocked_get.side_effect = APIError('hello')
base_adresse.jobs()
assert Job.objects.get(id=job.id).status == 'failed'
assert ResourceLog.objects.all().count() == 2
assert ResourceLog.objects.all()[1].level == 'warning'