def test_continues_after_time_since_entering_gate(app, current_state): label = LabelRef('foo', 'test_machine_timing') gate = app.config.state_machines['test_machine_timing'].states[0] with freeze_time('2018-01-24 12:00:00'), app.new_session(): state_machine.create_label( app, label, {}, ) # 1 day later, not enough to progress with freeze_time('2018-01-25 12:00:00'), app.new_session(): process_gate( app=app, state=gate, state_machine=state_machine, label=label, ) assert current_state(label) == 'start' # 2 days later with freeze_time('2018-01-26 12:00:00'), app.new_session(): process_gate( app=app, state=gate, state_machine=state_machine, label=label, ) assert current_state(label) == 'end'
def test_maintains_updated_field_on_label(app, mock_test_feed): label = LabelRef('foo', 'test_machine') with mock_test_feed(), app.new_session(): state_machine.create_label( app, label, {}, ) first_updated = app.session.query(Label.updated, ).filter_by( name=label.name, state_machine=label.state_machine, ).scalar() with mock_test_feed(), app.new_session(): state_machine.update_metadata_for_label( app, label, {'foo': 'bar'}, ) second_updated = app.session.query(Label.updated, ).filter_by( name=label.name, state_machine=label.state_machine, ).scalar() assert second_updated > first_updated
def test_stays_in_gate_if_gate_processing_fails(app, mock_test_feed, current_state): label = LabelRef('foo', 'test_machine') with mock_test_feed(), app.new_session(): state_machine.create_label( app, label, {}, ) assert current_state(label) == 'start' with mock_test_feed(), mock.patch( 'routemaster.context.Context._pre_warm_feeds', side_effect=RequestException, ), app.new_session(): state_machine.update_metadata_for_label( app, label, {'should_progress': True}, ) assert metadata_triggers_processed(app, label) is False assert current_state(label) == 'start'
def test_process_gate_not_eligible(app, mock_test_feed, assert_history): with mock_test_feed(), app.new_session(): state_machine.create_label( app, LabelRef('foo', 'test_machine'), {'should_progress': False}, ) assert_history([ (None, 'start'), ])
def test_label_get_state(app, mock_test_feed): label = LabelRef('foo', 'test_machine') with mock_test_feed(), app.new_session(): state_machine.create_label( app, label, {'foo': 'bar'}, ) with app.new_session(): assert state_machine.get_label_state(app, label).name == 'start'
def test_state_machine_progresses_automatically(app, mock_webhook, mock_test_feed, current_state): label = LabelRef('foo', 'test_machine') with mock_webhook() as webhook, mock_test_feed(), app.new_session(): state_machine.create_label( app, label, {'should_progress': True}, ) webhook.assert_called_once() assert current_state(label) == 'end'
def create_label(state_machine_name, label_name): """ Create a label with a given metadata, and start it in the state machine. Returns: - 201 Created: if the label is successfully created and started. - 409 Conflict: if the label already exists in the state machine. - 404 Not Found: if the state machine does not exist. - 400 Bad Request: if the request body is not a valid metadata. Successful return codes return the full created metadata for the label. """ app = server.config.app label = LabelRef(label_name, state_machine_name) data = request.get_json() try: initial_metadata = data['metadata'] except KeyError: abort(400, "No metadata given") try: initial_state_name = \ app.config.state_machines[state_machine_name].states[0].name metadata = state_machine.create_label(app, label, initial_metadata) return jsonify(metadata=metadata, state=initial_state_name), 201 except LookupError: msg = f"State machine '{state_machine_name}' does not exist" abort(404, msg) except LabelAlreadyExists: msg = f"Label {label_name} already exists in '{state_machine_name}'" abort(409, msg)
def test_state_machine_simple(app, mock_test_feed): label = LabelRef('foo', 'test_machine') with mock_test_feed(), app.new_session(): state_machine.create_label( app, label, {}, ) state_machine.update_metadata_for_label( app, label, {'foo': 'bar'}, ) with app.new_session(): assert state_machine.get_label_metadata(app, label) == {'foo': 'bar'}
def test_delete_label(app, assert_history, mock_test_feed): label_foo = LabelRef('foo', 'test_machine') with mock_test_feed(), app.new_session(): state_machine.create_label(app, label_foo, {}) state_machine.delete_label(app, label_foo) with app.new_session(): with pytest.raises(DeletedLabel): state_machine.get_label_metadata( app, label_foo, ) assert_history([ (None, 'start'), ('start', None), ])
def test_delete_label_only_deletes_target_label(app, assert_history, mock_test_feed): label_foo = LabelRef('foo', 'test_machine') label_bar = LabelRef('bar', 'test_machine') with mock_test_feed(), app.new_session(): state_machine.create_label(app, label_foo, {}) state_machine.create_label(app, label_bar, {}) state_machine.delete_label(app, label_foo) with app.new_session(): with pytest.raises(DeletedLabel): state_machine.get_label_metadata( app, label_foo, ) state_machine.get_label_metadata( app, label_bar, )
def test_state_machine_does_not_progress_when_not_eligible( app, mock_test_feed, current_state): label = LabelRef('foo', 'test_machine') with mock_test_feed(), app.new_session(): state_machine.create_label( app, label, {}, ) assert current_state(label) == 'start' with mock_test_feed(), app.new_session(): state_machine.update_metadata_for_label( app, label, {'should_progress': False}, ) assert current_state(label) == 'start'
def test_state_machine_progresses_on_update(app, mock_webhook, mock_test_feed, current_state): label = LabelRef('foo', 'test_machine') with mock_test_feed(), app.new_session(): state_machine.create_label( app, label, {}, ) assert current_state(label) == 'start' with mock_webhook() as webhook, mock_test_feed(), app.new_session(): state_machine.update_metadata_for_label( app, label, {'should_progress': True}, ) webhook.assert_called_once() assert metadata_triggers_processed(app, label) is True assert current_state(label) == 'end'