def request_population(n, dir): """Creates a ReqManager with a pregenerated population of N requests. The ReqManager and a list of Requests are passed to the calling code. """ with ReqManager(str(dir)) as reqmanager: requests = [] for i in range(n): req = Request(Activity(), 60, comment=str(i)) req._reqid = shortuuid.encode(uuid.UUID(int=i)) reqmanager.add(req) requests.append(req) yield (reqmanager, requests)
def test_execute_logs_exception(reqmanager, caplog): req = reqmanager.add(Request(Activity(), 1)) req.state = State.due os.chmod(req.dir, 0o000) # simulates I/O error reqmanager.execute() assert 'Permission denied' in caplog.text os.chmod(req.dir, 0o755) # py.test cannot clean up 0o000 dirs
def test_postpone(connect, reqmanager): req = reqmanager.add(Request(Activity(), 90)) req.state = State.postpone postp = connect().postpone_maintenance reqmanager.postpone() postp.assert_called_once_with({req.id: {'postpone_by': 180}}) assert req.state == State.postpone assert req.next_due is None
def test_execute_marks_service_status(connect, reqmanager): req = reqmanager.add(Request(Activity(), 1)) req.state = State.due reqmanager.execute() assert [ unittest.mock.call(unittest.mock.ANY, False), unittest.mock.call(unittest.mock.ANY, True), ] == connect().mark_node_service_status.call_args_list
def test_explicitly_deleted(connect, reqmanager): req = reqmanager.add(Request(Activity(), 90)) req.state = State.deleted arch = connect().end_maintenance reqmanager.archive() arch.assert_called_once_with( {req.id: {"duration": None, "result": "deleted"}} )
def test_execute_not_performed_on_connection_error( execute, connect, reqmanager ): connect().mark_node_service_status.side_effect = socket.error() req = reqmanager.add(Request(Activity(), 1)) req.state = State.due with pytest.raises(OSError): reqmanager.execute() assert execute.mock_calls == []
def test_execute_logs_exception(connect, reqmanager, log): req = reqmanager.add(Request(Activity(), 1)) req.state = State.due os.chmod(req.dir, 0o000) # simulates I/O error reqmanager.execute() log.has( "execute-request-failed", request=req.id, level="error", exc_info=True ) os.chmod(req.dir, 0o755) # py.test cannot clean up 0o000 dirs
def test_delete_disappeared_requests(connect, reqmanager): req = reqmanager.add(Request(Activity(), 1, "comment")) sched = connect().schedule_maintenance sched.return_value = { req.id: {"time": "2016-04-20T15:12:40.9+00:00"}, "123abc": {"time": None}, } endm = connect().end_maintenance reqmanager.schedule() endm.assert_called_once_with({"123abc": {"result": "deleted"}})
def test_schedule_requests(connect, reqmanager): req = reqmanager.add(Request(Activity(), 1, "comment")) rpccall = connect().schedule_maintenance rpccall.return_value = {req.id: {"time": "2016-04-20T15:12:40.9+00:00"}} reqmanager.schedule() rpccall.assert_called_once_with( {req.id: {"estimate": 1, "comment": "comment"}} ) assert req.next_due == datetime.datetime( 2016, 4, 20, 15, 12, 40, 900000, tzinfo=pytz.UTC )
def test_list(reqmanager): r1 = Request(Activity(), "14m", "pending request") reqmanager.add(r1) r2 = Request(Activity(), "2h", "due request") r2.state = State.due r2.next_due = datetime.datetime(2016, 4, 20, 12, tzinfo=pytz.UTC) reqmanager.add(r2) r3 = Request(Activity(), "1m 30s", "error request") r3.state = State.error r3.next_due = datetime.datetime(2016, 4, 20, 11, tzinfo=pytz.UTC) att = Attempt() att.duration = datetime.timedelta(seconds=75) att.returncode = 1 r3.attempts = [att] reqmanager.add(r3) assert ( str(reqmanager) == """\ St Id Scheduled Estimate Comment e {id3} 2016-04-20 11:00 UTC 1m 30s error request (duration: 1m 15s) * {id2} 2016-04-20 12:00 UTC 2h due request - {id1} --- TBA --- 14m pending request\ """.format( id1=r1.id[:7], id2=r2.id[:7], id3=r3.id[:7] ) )
def test_execute_activity_no_reboot(connect, run, reqmanager, log): activity = Activity() req = reqmanager.add(Request(activity, 1)) req.state = State.due reqmanager.execute(run_all_now=True) run.assert_has_calls( [ call('echo "entering demo"', shell=True, check=True), call('echo "leaving demo"', shell=True, check=True), ] ) assert log.has("enter-maintenance") assert log.has("leave-maintenance")
def test_delete_disappeared_requests(connect, reqmanager): req = reqmanager.add(Request(Activity(), 1, 'comment')) sched = connect().schedule_maintenance sched.return_value = { req.id: { 'time': '2016-04-20T15:12:40.9+00:00' }, '123abc': { 'time': None }, } endm = connect().end_maintenance reqmanager.schedule() endm.assert_called_once_with({'123abc': {'result': 'deleted'}})
def test_execute_activity_with_reboot(connect, run, reqmanager, log): activity = Activity() activity.reboot_needed = RebootType.WARM req = reqmanager.add(Request(activity, 1)) req.state = State.due reqmanager.execute(run_all_now=True) run.assert_has_calls( [ call('echo "entering demo"', shell=True, check=True), call("reboot", check=True, capture_output=True, text=True), ] ) assert log.has("enter-maintenance") assert log.has("maintenance-reboot") assert not log.has("leave-maintenance")
def test_execute_proceeds_on_connection_error(connect, reqmanager): connect().mark_node_service_status.side_effect = socket.error() req = reqmanager.add(Request(Activity(), 1)) req.state = State.due reqmanager.execute() assert req.state == State.success