def test_cancel_job_with_job_scheduled(): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 0) scheduler.cancel_job("good_job") jj = scheduler.get_jobs_of_type("good_job") assert len(jj) == 0
def test_build_status(): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 0) scheduler.schedule_job("odd_job", {"k": "v"}, "channel", TS, 10) scheduler.schedule_suppression("odd_job", T(-5), T(5)) scheduler.schedule_suppression("good_job", T(5), T(15)) scheduler.reserve_job() status = bot._build_status() assert (status == """ The time is 2019-12-10 11:12:13+00:00 There is 1 running job: * [1] good_job (started at 2019-12-10 11:12:13+00:00) There is 1 scheduled job: * [2] odd_job (starting after 2019-12-10 11:12:23+00:00) There is 1 active suppression: * [1] odd_job (from 2019-12-10 11:12:08+00:00 to 2019-12-10 11:12:18+00:00) There is 1 scheduled suppression: * [2] good_job (from 2019-12-10 11:12:18+00:00 to 2019-12-10 11:12:28+00:00) """.strip())
def test_cancel_job_with_no_jobs_of_same_type_scheduled(): scheduler.schedule_job("odd_job", {"k": "v"}, "channel") scheduler.cancel_job("good_job") jj = scheduler.get_jobs_of_type("odd_job") assert len(jj) == 1
def test_reserve_job_with_one_job_due_to_run(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 5) freezer.move_to(T(10)) job_id = scheduler.reserve_job() job = scheduler.get_job(job_id) assert_job_matches(job, "good_job", {"k": "v"}, "channel", T(5), T(10))
def test_reserve_job_with_job_running(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 5) freezer.move_to(T(10)) scheduler.reserve_job() scheduler.schedule_job("good_job", {"k": "w"}, "channel1", TS, 5) freezer.move_to(T(20)) assert not scheduler.reserve_job()
def test_reserve_job_with_suppression_in_progress_for_another_job_type(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 5) scheduler.schedule_suppression("odd_job", T(10), T(20)) freezer.move_to(T(15)) job_id = scheduler.reserve_job() job = scheduler.get_job(job_id) assert_job_matches(job, "good_job", {"k": "v"}, "channel", T(5), T(15))
def test_reserve_job_with_suppression_in_future(freezer): scheduler.schedule_suppression("good_job", T(15), T(20)) scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 5) freezer.move_to(T(10)) job_id = scheduler.reserve_job() job = scheduler.get_job(job_id) assert_job_matches(job, "good_job", {"k": "v"}, "channel", T(5), T(10))
def test_mark_job_done(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 0) freezer.move_to(T(10)) job_id = scheduler.reserve_job() scheduler.mark_job_done(job_id) assert not scheduler.get_jobs()
def test_schedule_job_with_job_of_same_type_scheduled(): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 0) scheduler.schedule_job("good_job", {"k": "w"}, "channel1", TS, 10) jj = scheduler.get_jobs_of_type("good_job") assert len(jj) == 1 assert_job_matches(jj[0], "good_job", {"k": "w"}, "channel1", T(10), None)
def test_schedule_job_with_no_jobs_of_same_type_already_scheduled(): scheduler.schedule_job("odd_job", {"k": "v"}, "channel") scheduler.schedule_job("good_job", {"k": "v"}, "channel") jj = scheduler.get_jobs_of_type("good_job") assert len(jj) == 1 assert_job_matches(jj[0], "good_job", {"k": "v"}, "channel", T(0), None)
def test_cancel_job_with_job_running(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 0) freezer.move_to(T(5)) scheduler.reserve_job() scheduler.cancel_job("good_job") jj = scheduler.get_jobs_of_type("good_job") assert len(jj) == 1
def test_reserve_job_with_another_job_running(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 5) freezer.move_to(T(10)) scheduler.reserve_job() scheduler.schedule_job("odd_job", {"k": "w"}, "channel1", TS, 5) freezer.move_to(T(20)) job_id = scheduler.reserve_job() job = scheduler.get_job(job_id) assert_job_matches(job, "odd_job", {"k": "w"}, "channel1", T(15), T(20))
def test_schedule_job_with_job_of_same_type_running(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 0) freezer.move_to(T(5)) scheduler.reserve_job() scheduler.schedule_job("good_job", {"k": "w"}, "channel1", TS, 5) jj = scheduler.get_jobs_of_type("good_job") assert len(jj) == 2 assert_job_matches(jj[0], "good_job", {"k": "v"}, "channel", T(0), T(5)) assert_job_matches(jj[1], "good_job", {"k": "w"}, "channel1", T(10), None)
def test_job_success_with_unsafe_shell_args(): log_dir = build_log_dir("test_paramaterised_job_2") scheduler.schedule_job("test_paramaterised_job_2", {"thing_to_echo": "<poem>"}, "channel", TS, 0) job = scheduler.reserve_job() with assert_slack_client_sends_messages( web_api=[("logs", "about to start"), ("channel", "succeeded")]): do_job(job) with open(os.path.join(log_dir, "stdout")) as f: assert f.read() == "<poem>\n" with open(os.path.join(log_dir, "stderr")) as f: assert f.read() == ""
def test_job_failure(): log_dir = build_log_dir("test_bad_job") scheduler.schedule_job("test_bad_job", {}, "channel", TS, 0) job = scheduler.reserve_job() with assert_slack_client_sends_messages( web_api=[("logs", "about to start"), ("channel", "failed")]): do_job(job) with open(os.path.join(log_dir, "stdout")) as f: assert f.read() == "" with open(os.path.join(log_dir, "stderr")) as f: assert f.read() == "cat: no-poem: No such file or directory\n"
def test_job_failure_when_command_not_found(): log_dir = build_log_dir("test_really_bad_job") scheduler.schedule_job("test_really_bad_job", {}, "channel", TS, 0) job = scheduler.reserve_job() with assert_slack_client_sends_messages( web_api=[("logs", "about to start"), ("channel", "failed")]): do_job(job) with open(os.path.join(log_dir, "stdout")) as f: assert f.read() == "" with open(os.path.join(log_dir, "stderr")) as f: assert f.read() == "/bin/sh: 1: dog: not found\n"
def test_job_success_and_report(): log_dir = build_log_dir("test_reported_job") scheduler.schedule_job("test_reported_job", {}, "channel", TS, 0) job = scheduler.reserve_job() with assert_slack_client_sends_messages( web_api=[("logs", "about to start"), ("channel", "the owl")]): do_job(job) with open(os.path.join(log_dir, "stdout")) as f: assert f.read() == "the owl and the pussycat\n" with open(os.path.join(log_dir, "stderr")) as f: assert f.read() == ""
def test_job_success_with_parameterised_args(): log_dir = build_log_dir("test_paramaterised_job") scheduler.schedule_job("test_paramaterised_job", {"path": "poem"}, "channel", TS, 0) job = scheduler.reserve_job() with assert_slack_client_sends_messages( web_api=[("logs", "about to start"), ("channel", "succeeded")]): do_job(job) with open(os.path.join(log_dir, "stdout")) as f: assert f.read() == "the owl and the pussycat\n" with open(os.path.join(log_dir, "stderr")) as f: assert f.read() == ""
def test_job_with_callback(): log_dir = build_log_dir("test_job_to_test_callback") scheduler.schedule_job("test_job_to_test_callback", {}, "channel", TS, 0) job = scheduler.reserve_job() with assert_slack_client_sends_messages( web_api=[("logs", "about to start"), ("channel", "succeeded")]): do_job(job) with open(os.path.join(log_dir, "stdout")) as f: url = f.read().strip() client = webserver.app.test_client() with assert_slack_client_sends_messages(web_api=[("channel", "Job done", TS)]): rsp = client.post(url, data='{"message": "Job done"}') assert rsp.status_code == 200
def test_schedule_job_with_job_of_same_type_running_and_another_scheduled(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel") freezer.move_to(T(5)) scheduler.reserve_job() scheduler.schedule_job("good_job", {"k": "w"}, "channel1", 5) scheduler.schedule_job("good_job", ["args2"], "channel2", 15) jj = scheduler.get_jobs_of_type("good_job") assert len(jj) == 2 assert_job_matches(jj[0], "good_job", {"k": "v"}, "channel", T(0), T(5)) assert_job_matches(jj[1], "good_job", ["args2"], "channel2", T(20), None)
def test_run_once(): # Because this mock gets used in a subprocess (I think) we can't actually # get any information out of it about how it was used. slack_client = Mock() scheduler.schedule_suppression("test_good_job", T(-15), T(-5)) scheduler.schedule_suppression("test_bad_job", T(-15), T(-5)) scheduler.schedule_suppression("test_really_bad_job", T(-5), T(5)) scheduler.schedule_job("test_good_job", {}, "channel", TS, 0) scheduler.schedule_job("test_bad_job", {}, "channel", TS, 0) scheduler.schedule_job("test_really_bad_job", {}, "channel", TS, 0) processes = run_once(slack_client, config) for p in processes: p.join() assert os.path.exists(build_log_dir("test_good_job")) assert os.path.exists(build_log_dir("test_bad_job")) assert not os.path.exists(build_log_dir("test_really_bad_job"))
def test_reserve_job_with_no_jobs_due_to_run(): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 5) assert not scheduler.reserve_job()
def test_reserve_job_with_suppression_in_progress(freezer): scheduler.schedule_job("good_job", {"k": "v"}, "channel", TS, 5) scheduler.schedule_suppression("good_job", T(10), T(20)) freezer.move_to(T(15)) assert not scheduler.reserve_job()