def _create_lock_store(store: Optional[LockStore]) -> LockStore: if store is not None: return store return InMemoryLockStore()
async def test_switch_forms_with_same_slot(default_agent: Agent): """Tests switching of forms, where the first slot is the same in both forms. Tests the fix for issue 7710""" # Define two forms in the domain, with same first slot slot_a = "my_slot_a" form_1 = "my_form_1" utter_ask_form_1 = f"Please provide the value for {slot_a} of form 1" form_2 = "my_form_2" utter_ask_form_2 = f"Please provide the value for {slot_a} of form 2" domain = f""" version: "2.0" nlu: - intent: order_status examples: | - check status of my order - when are my shoes coming in - intent: return examples: | - start a return - I don't want my shoes anymore forms: {form_1}: {slot_a}: - type: from_entity entity: number {form_2}: {slot_a}: - type: from_entity entity: number responses: utter_ask_{form_1}_{slot_a}: - text: {utter_ask_form_1} utter_ask_{form_2}_{slot_a}: - text: {utter_ask_form_2} """ domain = Domain.from_yaml(domain) # Driving it like rasa/core/processor processor = MessageProcessor( default_agent.interpreter, default_agent.policy_ensemble, domain, InMemoryTrackerStore(domain), InMemoryLockStore(), TemplatedNaturalLanguageGenerator(domain.templates), ) # activate the first form tracker = DialogueStateTracker.from_events( "some-sender", evts=[ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("order status", { "name": "form_1", "confidence": 1.0 }), DefinePrevUserUtteredFeaturization(False), ], ) # rasa/core/processor.predict_next_action prediction = PolicyPrediction([], "some_policy") action_1 = FormAction(form_1, None) await processor._run_action( action_1, tracker, CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), prediction, ) events_expected = [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("order status", { "name": "form_1", "confidence": 1.0 }), DefinePrevUserUtteredFeaturization(False), ActionExecuted(form_1), ActiveLoop(form_1), SlotSet(REQUESTED_SLOT, slot_a), BotUttered( text=utter_ask_form_1, metadata={"template_name": f"utter_ask_{form_1}_{slot_a}"}, ), ] assert tracker.applied_events() == events_expected next_events = [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("return my shoes", { "name": "form_2", "confidence": 1.0 }), DefinePrevUserUtteredFeaturization(False), ] tracker.update_with_events( next_events, domain, ) events_expected.extend(next_events) # form_1 is still active, and bot will first validate if the user utterance # provides valid data for the requested slot, which is rejected await processor._run_action( action_1, tracker, CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), prediction, ) events_expected.extend([ActionExecutionRejected(action_name=form_1)]) assert tracker.applied_events() == events_expected # Next, bot predicts form_2 action_2 = FormAction(form_2, None) await processor._run_action( action_2, tracker, CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), prediction, ) events_expected.extend([ ActionExecuted(form_2), ActiveLoop(form_2), SlotSet(REQUESTED_SLOT, slot_a), BotUttered( text=utter_ask_form_2, metadata={"template_name": f"utter_ask_{form_2}_{slot_a}"}, ), ]) assert tracker.applied_events() == events_expected
# issue one long- and one short-lived ticket _ = list(map(lock.issue_ticket, [k for k in [0.01, 10]])) # both tickets are there assert len(lock.tickets) == 2 # sleep and only one ticket should be left time.sleep(0.02) lock.remove_expired_tickets() assert len(lock.tickets) == 1 @pytest.mark.parametrize( "lock_store", [InMemoryLockStore(), FakeRedisLockStore()]) def test_create_lock_store(lock_store: LockStore): conversation_id = "my id 0" # create and lock lock = lock_store.create_lock(conversation_id) lock_store.save_lock(lock) lock = lock_store.get_lock(conversation_id) assert lock assert lock.conversation_id == conversation_id def test_raise_connection_exception_redis_lock_store(monkeypatch: MonkeyPatch): monkeypatch.setattr(rasa.core.lock_store, "RedisLockStore", Mock(side_effect=ConnectionError()))
"env_value,lock_store,expected", [ (1, "redis", 1), (4, "redis", 4), (None, "redis", 1), (0, "redis", 1), (-4, "redis", 1), ("illegal value", "redis", 1), (None, None, 1), (None, "in_memory", 1), (5, "in_memory", 1), (2, None, 1), (0, "in_memory", 1), (3, "tests/core/test_utils.CustomRedisLockStore", 3), (3, RedisLockStore(), 3), (2, InMemoryLockStore(), 1), (3, CustomRedisLockStore(), 3), ], ) def test_get_number_of_sanic_workers( env_value: Optional[Text], lock_store: Union[LockStore, Text, None], expected: Optional[int], ): # remember pre-test value of SANIC_WORKERS env var pre_test_value = os.environ.get(ENV_SANIC_WORKERS) # set env var to desired value and make assertion if env_value is not None: os.environ[ENV_SANIC_WORKERS] = str(env_value)