def test_error_callback():
    sleep_time = 1
    errors = []
    err_count = 0

    def failing_job(msg):
        raise Exception(msg)

    def err(e):
        nonlocal errors, err_count
        cause = str(e).strip().split()[-1]  # get last word from traceback
        errors.append(cause)
        err_count += 1

    def err_specific(e):
        nonlocal errors, err_count
        cause = str(e).strip().split()[-1]  # get last word from traceback
        errors.append(cause + "_specific")
        err_count += 1

    s = TaskScheduler(on_job_error=err)
    s.every(sleep_time).do(failing_job, msg='one', do_parallel=True)
    s.every(sleep_time).do(failing_job, msg='two')
    s.every(sleep_time).do(failing_job, msg='three',
                           do_parallel=True).catch(err_specific)
    time.sleep(sleep_time + 0.5)
    s.check()
    time.sleep(0.5)
    assert (sorted(errors) == sorted(['one', 'two', 'three_specific'])
            )  # err callbacks were called
    assert (err_count == 3)
    assert (s.jobs[0].did_fail() == True)
    pretty_print(s.jobs[0].to_dict())
def test_print_capture():
    def slow_job(sleep_time):
        time.sleep(sleep_time)
        print("Slow job completed")

    sleep_time = 1
    log_file_path = 'testlog.log'
    s = TaskScheduler(log_filepath=log_file_path)
    s.every(1).do(slow_job, sleep_time=sleep_time, do_parallel=True)
    s.check()

    counter = 4
    while counter > 0:
        print("outside")
        counter -= 1
        print('running:', s.jobs[0].is_running)
        s.check()
        time.sleep(0.5)
    print("stopping")
    s.join()
    j0 = s.jobs[0].to_dict()
    assert ('Slow job completed' in j0['logs']['log'])
    assert ('===' in j0['logs']['log'])
    assert ('outside' not in j0['logs']['log'])
    assert ('stopping' not in j0['logs']['log'])
    pretty_print(j0)
    # test log file
    assert (os.path.isfile(log_file_path) == True)
    with open(log_file_path, 'r') as lf:
        assert ('Slow job completed' in lf.read())
    for h in LOGGER.handlers:
        h.close()
        LOGGER.removeHandler(h)
    if os.path.isfile(log_file_path): os.remove(log_file_path)
    assert (os.path.isfile(log_file_path) == False)
def test_registry():
    s = TaskScheduler()
    s.every("businessday").at("10:00").do(job, x="hello", y="world")  # Job
    s.on('2019-05-16').do(job, x="hello", y="world")  # OneTimeJob
    s.every(5).at("10:00").do(job, x="hello", y="world")  # RepeatJob
    s.every('2nd').strict_date(False).at("10:00").do(job, x="hello",
                                                     y="world")  # MonthlyJob
    assert len(s.jobs) == 4
def test_job_docstring():
    def job_with_descr():
        '''job test docsting'''
        print("docstring test")

    def job_without_descr():
        print("no docstring test")

    s = TaskScheduler()
    j_w_descr = s.every(1).do(job_with_descr)
    j_wo_descr = s.every(1).do(job_without_descr)

    assert (j_w_descr.to_dict()['doc'] == 'job test docsting')
    assert (j_wo_descr.to_dict()['doc'] == None)
    pretty_print(j_w_descr.to_dict())
def test_holidays():
    s = TaskScheduler()  # default holidays calendar
    s.every("businessday").at("10:00").do(job, x="hello", y="world")
    assert (s.jobs[0]._job_must_run_today(date_parse("2020-04-09")) == True)
    assert (s.jobs[0]._job_must_run_today(date_parse("2020-10-12")) == False
            )  # Columbus Day is a US holiday by default

    s = TaskScheduler(holidays_calendar=TradingHolidays())
    s.every("businessday").at("10:00").do(job, x="hello", y="world")
    assert (s.jobs[0]._job_must_run_today(date_parse("2020-04-09")) == True)
    assert (s.jobs[0]._job_must_run_today(date_parse("2020-04-11")) == False
            )  # saturday
    assert (s.jobs[0]._job_must_run_today(date_parse("2020-10-12")) == True
            )  # test Custom calendar with Columbus Day removed

    s.every("trading-holiday").at("10:00").do(job, x="hello", y="world")
    assert (s.jobs[1]._job_must_run_today(date_parse("2020-01-01")) == True)
    assert (s.jobs[1]._job_must_run_today(date_parse("2020-01-02")) == False)
def test_monthly():
    def day_suffixed_str(day):
        suffix = 'th' if 11 <= day <= 13 else {
            1: 'st',
            2: 'nd',
            3: 'rd'
        }.get(day % 10, 'th')
        return str(day) + suffix

    today = dt.now().replace(hour=23, minute=59, second=0, microsecond=0)
    yesterday = (dt.now() - timedelta(days=1)).replace(hour=23,
                                                       minute=59,
                                                       second=0,
                                                       microsecond=0)
    s = TaskScheduler()

    j = s.every(day_suffixed_str(today.day)).strict_date(True).at("23:59").do(
        job, x="hello", y="world")
    assert (j.next_timestamp == dt.timestamp(today))

    # yesterday's date is scheduled to next month
    j = s.every(day_suffixed_str(
        yesterday.day)).strict_date(False).at("23:59").do(job,
                                                          x="hello",
                                                          y="world")
    assert (j.next_timestamp == dt.timestamp(yesterday + monthdelta(1)))

    # strict_date is False. So 31st will just be the last day of the month
    j = s.every("31st").strict_date(False).at("23:59").do(job,
                                                          x="hello",
                                                          y="world")
    eom = (dt.now() + monthdelta(1)).replace(
        day=1, hour=23, minute=59, second=0, microsecond=0) - timedelta(days=1)
    assert (j.next_timestamp == dt.timestamp(eom))

    # strict_date is True. So next schedule will be when month has 31st
    j = s.every("31st").strict_date(True).at("23:59").do(job,
                                                         x="hello",
                                                         y="world")
    day = dt.now()
    while ((day + monthdelta(1)).replace(day=1) - timedelta(days=1)).day != 31:
        day += monthdelta(1)
    assert (j.next_timestamp == dt.timestamp(
        day.replace(day=31, hour=23, minute=59, second=0, microsecond=0)))

    with pytest.raises(BadScheduleError):
        # error because .strict_date() is not called
        s.every("1st").at("23:59").do(job, x="hello", y="world")

    assert len(s.jobs) == 4
def test_repeat():
    d = time.time()
    sleep_time = 1
    s = TaskScheduler()
    s.every(sleep_time).do(job, x="hello", y="world")
    assert (abs(s.jobs[0].next_timestamp - (d + sleep_time)) < 0.1)
    time.sleep(sleep_time + 0.5)
    s.check()
    assert (abs(s.jobs[0].next_timestamp - (d + (2 * sleep_time))) < 0.1)
def test_onetime():
    yesterday = dt.now() - timedelta(days=1)
    tomorrow = (dt.now() + timedelta(days=1)).replace(hour=23,
                                                      minute=59,
                                                      second=0,
                                                      microsecond=0)
    s = TaskScheduler()
    s.on(yesterday.strftime("%Y-%m-%d")).at("23:59").do(job,
                                                        x="hello",
                                                        y="world")
    s.on(tomorrow.strftime("%Y-%m-%d")).at("23:59").do(job,
                                                       x="hello",
                                                       y="world")
    for j in s.jobs:
        assert (j.next_timestamp == dt.timestamp(tomorrow)
                or j.next_timestamp == 0)
    assert len(s.jobs) == 2
    s.check()
    assert len(s.jobs) == 1
def test_day_of_week():
    now = dt.now()
    today_str = now.strftime("%A").lower()
    in2sec_str = now.strftime("%H:%M")
    s = TaskScheduler()
    s.every(today_str).at(in2sec_str).do(job, x="hello", y=today_str)
    assert len(s.jobs) == 1
    time.sleep(0.5)
    s.check()
    # test if next run greater than 6 days, less than 8 days from now
    test_timestamp = time.time()
    assert s.jobs[0].next_timestamp > test_timestamp + (6 * 24 * 60 * 60)
    assert s.jobs[0].next_timestamp < test_timestamp + (8 * 24 * 60 * 60)
def test_repeat_parallel():
    d = time.time()
    sleep_time = 1
    s = TaskScheduler()
    s.every(sleep_time).do(job, x="hello", y="world", do_parallel=True)
    s.every(sleep_time).do(job, x="hello", y="world", do_parallel=True)
    ts = s.jobs[0].next_timestamp
    assert (abs(ts - (d + sleep_time)) < 0.1)
    time.sleep(sleep_time + 0.5)
    s.check()
    assert (s.jobs[0].next_timestamp == ts)  # still not rescheduled
    time.sleep(0.5)
    assert (s.jobs[0].next_timestamp != ts)  # rescheduled parallely
    assert (abs(s.jobs[0].next_timestamp - (d + (2 * sleep_time))) < 0.1)
    assert (abs(s.jobs[0].next_timestamp - s.jobs[1].next_timestamp) < 0.1)
def test_parallel_stopper():
    def job(x, y):
        time.sleep(2)
        print(x, y)

    s = TaskScheduler(check_interval=1)
    s.every(1).do(job, x="hello", y="world", do_parallel=True)

    def stopp():
        # job will start in 1 second, and finish in 3 seconds. Attempting to stop at the 2 second mark
        time.sleep(2)
        print("stopping thread")
        s.stop()

    t = threading.Thread(target=stopp)
    t.start()
    s.start()
    assert (any([j.is_running for j in s.jobs]) == False
            )  # successfully stopped all parallel tasks
def test_regular():
    d = dt.now().replace(hour=23, minute=59, second=0, microsecond=0)
    s = TaskScheduler()
    s.every("day").at("23:59").do(job, x="hello", y="world")
    assert (s.jobs[0].next_timestamp == dt.timestamp(d))
def test_badinterval():
    s = TaskScheduler()
    with pytest.raises(BadScheduleError):
        s.every("potato").at("10:00").do(job, x="hello", y="world")
    with pytest.raises(BadScheduleError):
        s.every("2020-02-30").at("10:00").do(job, x="hello",
                                             y="world")  # OneTimeJob
    with pytest.raises(BadScheduleError):
        s.every(0).at("10:00").do(job, x="hello", y="world")  # RepeatJob
    with pytest.raises(BadScheduleError):
        # error because .strict_date() is not called
        s.every("31st").at("10:00").do(job, x="hello", y="world")  # MonthlyJob
    with pytest.raises(BadScheduleError):
        s.every("32nd").strict_date(False).at("10:00").do(
            job, x="hello", y="world")  # MonthlyJob
예제 #14
0
from flask import Flask
from flask_production import CherryFlask, TaskScheduler
from flask_production.plugins import ReadOnlyTaskMonitor

import time
import pytest

app = Flask(__name__)
sched = TaskScheduler()
monitor = ReadOnlyTaskMonitor(app, sched=sched, display_name="Web Test")

toggle = False

@app.route("/", methods=['GET'])
def main():
	return 'Main dummy page'


def wash_car():
	"""
	This is a dummy job that is scheduled to wash my car
	Note: objects in the mirror are closer than they appear
	"""
	global toggle
	toggle = not toggle
	if toggle:
		count = 50
		while count > 0:
			time.sleep(0.1)
			print("washing..\n")
			count -= 1