Exemplo n.º 1
0
def test_simple(monkeypatch, config_yaml, expected_events):
    monkeypatch.setattr(yacron.cron, "RunningJob", TracingRunningJob)
    cron = yacron.cron.Cron(None, config_yaml=config_yaml)

    events = []

    async def wait_and_quit():
        the_job = None
        while True:
            ts, event, job = await TracingRunningJob._TRACE.get()
            print(ts, event)
            if the_job is None:
                job = the_job
            else:
                assert job is the_job
            events.append(event)
            if event in {'report_success', 'report_permanent_failure'}:
                break
        cron.signal_shutdown()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(
        wait_and_quit(),
        cron.run()))
    assert events == expected_events
Exemplo n.º 2
0
def test_concurrency_policy(monkeypatch, policy,
                            expected_numjobs, expected_max_running):
    monkeypatch.setattr(yacron.cron, "RunningJob", TracingRunningJob)
    START_TIME = datetime.datetime(year=1999, month=12, day=31, hour=12,
                                   minute=0, second=59, microsecond=750000)

    t0 = time.perf_counter()

    def get_now():
        return (START_TIME +
                datetime.timedelta(seconds=(time.perf_counter() - t0)))
    monkeypatch.setattr("yacron.cron.get_now", get_now)

    cron = yacron.cron.Cron(
        None,
        config_yaml=CONCURRENT_JOB.format(policy=policy),
    )

    events = []
    numjobs = 0
    max_running = 0

    async def wait_and_quit():
        nonlocal numjobs, max_running
        known_jobs = {}
        pending_jobs = set()
        running_jobs = set()
        while not (known_jobs and not pending_jobs):
            ts, event, job = await TracingRunningJob._TRACE.get()
            try:
                jobnum = known_jobs[job]
            except KeyError:
                if known_jobs:
                    jobnum = max(known_jobs.values()) + 1
                else:
                    jobnum = 1
                known_jobs[job] = jobnum
                pending_jobs.add(jobnum)
                running_jobs.add(jobnum)
                numjobs += 1
            print(ts, event, jobnum)
            events.append((jobnum, event))
            if event in {'report_success', 'report_permanent_failure'}:
                pending_jobs.discard(jobnum)
            if event in {'report_success', 'report_permanent_failure',
                         'cancelled'}:
                running_jobs.discard(jobnum)
            max_running = max(len(running_jobs), max_running)
        cron.signal_shutdown()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(
        wait_and_quit(),
        cron.run()))
    import pprint
    pprint.pprint(events)
    assert (numjobs, max_running) == (expected_numjobs, expected_max_running)
Exemplo n.º 3
0
def test_fail_retry(monkeypatch):
    monkeypatch.setattr(yacron.cron, "RunningJob", TracingRunningJob)
    cron = yacron.cron.Cron(None, config_yaml=RETRYING_JOB_THAT_FAILS)

    events = []

    async def wait_and_quit():
        known_jobs = {}
        while True:
            ts, event, job = await TracingRunningJob._TRACE.get()
            try:
                jobnum = known_jobs[job]
            except KeyError:
                if known_jobs:
                    jobnum = max(known_jobs.values()) + 1
                else:
                    jobnum = 1
                known_jobs[job] = jobnum
            print(ts, event, jobnum)
            events.append((jobnum, event))
            if jobnum == 3 and event == 'report_permanent_failure':
                break
        cron.signal_shutdown()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(wait_and_quit(), cron.run()))
    assert events == [
        # initial attempt
        (1, 'create'),
        (1, 'start'),
        (1, 'started'),
        (1, 'wait'),
        (1, 'waited'),
        (1, 'report_failure'),
        # first retry
        (2, 'create'),
        (2, 'start'),
        (2, 'started'),
        (2, 'wait'),
        (2, 'waited'),
        (2, 'report_failure'),
        # second retry
        (3, 'create'),
        (3, 'start'),
        (3, 'started'),
        (3, 'wait'),
        (3, 'waited'),
        (3, 'report_failure'),
        (3, 'report_permanent_failure')
    ]
Exemplo n.º 4
0
def test_execution_timeout(monkeypatch):
    monkeypatch.setattr(yacron.cron, "RunningJob", TracingRunningJob)
    cron = yacron.cron.Cron(None, config_yaml=JOB_THAT_HANGS)

    events = []
    jobs_stdout = {}

    async def wait_and_quit():
        known_jobs = {}
        while True:
            ts, event, job = await TracingRunningJob._TRACE.get()
            try:
                jobnum = known_jobs[job]
            except KeyError:
                if known_jobs:
                    jobnum = max(known_jobs.values()) + 1
                else:
                    jobnum = 1
                known_jobs[job] = jobnum
            print(ts, event, jobnum)
            events.append((jobnum, event))
            if jobnum == 1 and event == 'report_permanent_failure':
                jobs_stdout[jobnum] = job.stdout
                break
        cron.signal_shutdown()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(wait_and_quit(), cron.run()))
    assert events == [
        # initial attempt
        (1, 'create'),
        (1, 'start'),
        (1, 'started'),
        (1, 'wait'),
        (1, 'cancel'),
        (1, 'cancelled'),
        (1, 'waited'),
        (1, 'report_failure'),
        (1, 'report_permanent_failure')
    ]
    assert jobs_stdout[1] == 'starting...\n'
Exemplo n.º 5
0
def test_concurrency_and_backoff(monkeypatch):
    monkeypatch.setattr(yacron.cron, "RunningJob", TracingRunningJob)
    START_TIME = datetime.datetime(year=1999,
                                   month=12,
                                   day=31,
                                   hour=12,
                                   minute=0,
                                   second=59,
                                   microsecond=750000)
    STOP_TIME = datetime.datetime(year=1999,
                                  month=12,
                                  day=31,
                                  hour=12,
                                  minute=1,
                                  second=00,
                                  microsecond=250000)

    t0 = time.perf_counter()

    def get_now():
        return (START_TIME +
                datetime.timedelta(seconds=(time.perf_counter() - t0)))

    def get_reltime(ts):
        return (START_TIME + datetime.timedelta(seconds=(ts - t0)))

    monkeypatch.setattr("yacron.cron.get_now", get_now)

    cron = yacron.cron.Cron(None, config_yaml=RETRYING_JOB_THAT_FAILS2)

    events = []
    numjobs = 0

    async def wait_and_quit():
        nonlocal numjobs
        known_jobs = {}
        pending_jobs = set()
        running_jobs = set()
        while get_now() < STOP_TIME:
            try:
                ts, event, job = await asyncio.wait_for(
                    TracingRunningJob._TRACE.get(), 0.1)
            except asyncio.TimeoutError:
                continue
            try:
                jobnum = known_jobs[job]
            except KeyError:
                if known_jobs:
                    jobnum = max(known_jobs.values()) + 1
                else:
                    jobnum = 1
                known_jobs[job] = jobnum
                pending_jobs.add(jobnum)
                running_jobs.add(jobnum)
                numjobs += 1
            print(get_reltime(ts), event, jobnum)
            events.append((jobnum, event))
            if event in {'report_success', 'report_permanent_failure'}:
                pending_jobs.discard(jobnum)
            if event in {
                    'report_success', 'report_permanent_failure', 'cancelled'
            }:
                running_jobs.discard(jobnum)
        cron.signal_shutdown()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(wait_and_quit(), cron.run()))
    import pprint
    pprint.pprint(events)
    assert numjobs == 2