def test_that_extensions_features_are_cached(self): bus_client = self.make_bus() confd_client = self.make_mock_confd() bus_client.send_extension_feature_edited() bus_client.send_user_dnd_update('123', True) def assert_extensions_features(): assert_that( confd_client.requests()['requests'], has_item( has_entries({ 'method': 'GET', 'path': '/1.1/extensions/features' })), ) until.assert_(assert_extensions_features, tries=5) confd_client.reset() bus_client.send_user_dnd_update('123', True) def assert_no_extensions_features(): assert_that( confd_client.requests()['requests'], not_( has_item( has_entries({ 'method': 'GET', 'path': '/1.1/extensions/features' }))), ) until.assert_(assert_no_extensions_features, tries=5)
def test_restrict_on_with_slow_wazo_auth(self): APIAssetLaunchingTestCase.stop_chatd_service() APIAssetLaunchingTestCase.stop_auth_service() APIAssetLaunchingTestCase.start_chatd_service() self.reset_clients() def _returns_503(): try: self.chatd.config.get() except ChatdError as e: assert e.status_code == 503 except requests.RequestException as e: raise AssertionError(e) until.assert_(_returns_503, tries=10) APIAssetLaunchingTestCase.start_auth_service() self.reset_clients() def _not_return_503(): try: response = self.chatd.config.get() assert_that(response, has_key('debug')) except Exception as e: raise AssertionError(e) until.assert_(_not_return_503, tries=10)
def test_restrict_on_with_slow_wazo_auth(self): config_file = '/etc/wazo-call-logd/conf.d/01-master-tenant.yml' self.filesystem.create_file( config_file, content='auth: {master_tenant_uuid: ""}', ) self.stop_service('auth') self.restart_service('call-logd') self.reset_clients() def _returns_503(): try: assert_that( calling(self.call_logd.config.get), raises( CallLogdError, has_properties( status_code=503, error_id='not-initialized', ), ), ) except ConnectionError: raise AssertionError until.assert_(_returns_503, tries=10) self.filesystem.remove_file(config_file) self.start_service('auth') self.restart_service('call-logd') self.reset_clients() CallLogdEverythingUpWaitStrategy().wait(self)
def test_participant_leaves_sends_event(self): meeting_uuid = MEETING1_UUID tenant_uuid = MEETING1_TENANT_UUID self.confd.set_meetings( MockMeeting( uuid=meeting_uuid, tenant_uuid=tenant_uuid, name='meeting' ), ) bus_events = self.bus.accumulator(f'meetings.{meeting_uuid}.participants.left') channel_id = self.given_call_in_meeting(MEETING1_EXTENSION, caller_id_name='participant1') self.ari.channels.hangup(channelId=channel_id) def participant_left_event_received(expected_caller_id_name): assert_that( bus_events.accumulate(with_headers=True), has_item( has_entries( message=has_entries( data=has_entries( caller_id_name=expected_caller_id_name, ) ), headers=has_entries({ 'name': 'meeting_participant_left', 'meeting_uuid': meeting_uuid, 'tenant_uuid': tenant_uuid, }) ) ) ) until.assert_(participant_left_event_received, 'participant1', timeout=10)
def test_record(self): meeting_uuid = MEETING1_UUID self.confd.set_meetings( MockMeeting(uuid=meeting_uuid, name='meeting'), ) self.given_call_in_meeting(MEETING1_EXTENSION, caller_id_name='participant1') def latest_record_file(): record_files = self.docker_exec(['ls', '-t', '/var/spool/asterisk/monitor'], 'ari') latest_record_file = record_files.split(b'\n')[0].decode('utf-8') return os.path.join('/var/spool/asterisk/monitor', latest_record_file) def file_size(file_path): return int(self.docker_exec(['stat', '-c', '%s', file_path], 'ari').strip()) self.calld_client.meetings.record(meeting_uuid) record_file = latest_record_file() record_file_size_1 = file_size(record_file) def record_file_is_growing(): record_file_size_2 = file_size(record_file) assert_that(record_file_size_1, less_than(record_file_size_2)) until.assert_(record_file_is_growing, timeout=10, message='file did not grow') def record_file_is_closed(): record_file = latest_record_file() writing_pids = self.docker_exec(['fuser', record_file], 'ari').strip() return writing_pids == b'' self.calld_client.meetings.stop_record(meeting_uuid) assert_that(record_file_is_closed(), is_(True))
def test_refresh_token_deleted_event(self, user, token): client_id = 'foobar' routing_key = 'auth.users.{user_uuid}.tokens.{client_id}.deleted'.format( user_uuid=user['uuid'], client_id=client_id, ) msg_accumulator = self.bus.accumulator(routing_key) self.client.token.delete(user['uuid'], client_id) def bus_received_msg(): assert_that( msg_accumulator.accumulate(with_headers=True), contains_exactly( has_entries( message=has_entries( data={ 'client_id': client_id, 'user_uuid': user['uuid'], 'tenant_uuid': user['tenant_uuid'], 'mobile': True, } ), headers=has_entry('tenant_uuid', user['tenant_uuid']), ) ), ) until.assert_(bus_received_msg, tries=10, interval=0.25)
def test_event_on_login(self, user_line_extension, agent): event_accumulator = self.bus.accumulator('status.agent') self.agentd.agents.login_agent_by_number( agent['number'], user_line_extension['exten'], user_line_extension['context'], ) def event_received(): events = event_accumulator.accumulate(with_headers=True) assert_that( events, contains( has_entries( message=has_entries(data=has_entries( agent_id=agent['id'], status='logged_in')), headers=all_of( has_entry(f"agent_id:{agent['id']}", True), has_key('tenant_uuid'), ), )), ), until.assert_(event_received, tries=3)
def test_refresh_token_deleted(self, user, token): client_id = token.client_id user_uuid = user.uuid routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) self.bus.send_refresh_token_deleted_event(client_id, user_uuid, user.tenant_uuid) def refresh_token_deleted(): result = self._session.query(models.RefreshToken).all() assert_that( result, not_( has_items( has_properties(client_id=client_id, user_uuid=user_uuid))), ) until.assert_(refresh_token_deleted, tries=3) event = event_accumulator.accumulate(with_headers=True) assert_that( event, contains( has_entries( message=has_entries(data=has_entries(mobile=False)), headers=has_entries(tenant_uuid=str(TOKEN_TENANT_UUID)), )), )
def test_user_line_associated(self, user): line_id = random.randint(1, 1000000) line_name = 'created-line' user_uuid = user.uuid routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) self.bus.send_user_line_associated_event(line_id, user_uuid, user.tenant_uuid, line_name) def user_line_associated(): result = self._session.query(models.Line).all() assert_that( result, has_items( has_properties( id=line_id, user_uuid=user_uuid, endpoint_name=f'PJSIP/{line_name}', )), ) until.assert_(user_line_associated, tries=3) event = event_accumulator.accumulate(with_headers=True) assert_that( event, contains( has_entries( message=has_entries(data=has_entries(lines=contains( has_entries(id=line_id, state='unavailable')))), headers=has_entries(tenant_uuid=str(TOKEN_TENANT_UUID)), )), )
def test_last_participant_hangup(self): user_uuid = make_user_uuid() token = self.make_user_token(user_uuid) self.calld_client.set_token(token) adhoc_conference_id, call_ids = self.given_adhoc_conference(user_uuid, participant_count=1) host_call_id, participant1_call_id = call_ids host_events = self.adhoc_conference_events_for_user(user_uuid) self.ari.channels.hangup(channelId=participant1_call_id) def calls_are_hungup(): assert_that(host_call_id, self.c.is_hungup()) assert_that(participant1_call_id, self.c.is_hungup()) until.assert_(calls_are_hungup, timeout=10) def bus_events_are_sent(): assert_that( host_events.accumulate(with_headers=True), has_item( has_entries( message=has_entries({ 'name': 'conference_adhoc_deleted', 'data': { 'conference_id': adhoc_conference_id, } }), headers=has_entries( name='conference_adhoc_deleted', tenant_uuid=VALID_TENANT, ) ) ) ) until.assert_(bus_events_are_sent, timeout=10)
def given_adhoc_conference(self, *user_uuids, participant_count): participant_call_ids = [] user_uuids = list(user_uuids) host_uuid = user_uuids.pop(0) try: participant_uuid = user_uuids.pop(0) except IndexError: participant_uuid = None host_call_id, participant_call_id = self.real_asterisk.given_bridged_call_stasis(caller_uuid=host_uuid, callee_uuid=participant_uuid) participant_call_ids.append(participant_call_id) for _ in range(participant_count - 1): try: participant_uuid = user_uuids.pop(0) except IndexError: participant_uuid = None _, participant_call_id = self.real_asterisk.given_bridged_call_stasis(caller_uuid=host_uuid, callee_uuid=participant_uuid) participant_call_ids.append(participant_call_id) host_events = self.bus.accumulator('conferences.users.{}.adhoc.#'.format(host_uuid)) calld_client = self.make_user_calld(host_uuid) adhoc_conference = calld_client.adhoc_conferences.create_from_user( host_call_id, *participant_call_ids ) def adhoc_conference_complete(): join_events = [event for event in host_events.accumulate() if event['name'] == 'conference_adhoc_participant_joined'] assert_that(join_events, has_length(participant_count + 2)) until.assert_(adhoc_conference_complete, timeout=10) return adhoc_conference['conference_id'], [host_call_id] + participant_call_ids
def test_user_create_adhoc_conference_participant_not_in_stasis(self): host_uuid = make_user_uuid() participant1_uuid = make_user_uuid() participant2_uuid = make_user_uuid() token = self.make_user_token(host_uuid) self.calld_client.set_token(token) host_call1_id, participant1_call_id = self.real_asterisk.given_bridged_call_not_stasis(caller_uuid=host_uuid, callee_uuid=participant1_uuid) host_call2_id, participant2_call_id = self.real_asterisk.given_bridged_call_not_stasis(caller_uuid=host_uuid, callee_uuid=participant2_uuid) adhoc_conference = self.calld_client.adhoc_conferences.create_from_user( host_call1_id, participant1_call_id, participant2_call_id, ) assert_that(adhoc_conference, has_entries({ 'conference_id': anything(), })) def calls_are_bridged(): host_call1 = self.calld_client.calls.get_call(host_call1_id) assert_that(host_call1, has_entries({ 'talking_to': has_entries({ participant1_call_id: anything(), participant2_call_id: anything(), }) })) assert_that(host_call2_id, self.c.is_hungup()) until.assert_(calls_are_bridged, timeout=10)
def test_refresh_token_created(self, user): client_id = 'my-client-id' user_uuid = user.uuid routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) self.bus.send_refresh_token_created_event(client_id, user_uuid, user.tenant_uuid, mobile=True) def refresh_token_created(): result = self._session.query(models.RefreshToken).all() assert_that( result, has_items( has_properties(client_id=client_id, user_uuid=user_uuid)), ) until.assert_(refresh_token_created, tries=3) event = event_accumulator.accumulate() assert_that( event, contains(has_entries(data=has_entries(mobile=True))), )
def test_when_stasis_channel_destroyed_when_empty_values(self): call_id = new_call_id() events = self.bus.accumulator(routing_key='calls.call.ended') self.stasis.event_channel_destroyed( channel_id=call_id, stasis_app=STASIS_APP, line_id='', sip_call_id='', creation_time='2016-02-01T15:00:00.000-0500', ) def assert_function(): assert_that( events.accumulate(with_headers=True), has_item( has_entries(message=has_entries({ 'name': 'call_ended', 'origin_uuid': XIVO_UUID, 'data': has_entries({ 'creation_time': '2016-02-01T15:00:00.000-0500', 'sip_call_id': '', 'line_id': None, 'hangup_time': is_(a_timestamp()), }) }), headers=has_entries( name='call_ended', tenant_uuid=VALID_TENANT, )))) until.assert_(assert_function, tries=5)
def test_delete_device_when_deleting_tenant(_, user, line, sip, extension, device): # This test only uses provd for getting the device. Why? Because confd does not expose # the `config` field and we need it. with associations.line_endpoint_sip(line, sip, check=False), associations.user_line( user, line, check=False ), associations.line_extension( line, extension, check=False ), associations.line_device( line, device, check=False ): device_provd = provd.devices.get(device['id']) config = provd.configs.get(device_provd['config']) with BaseIntegrationTest.delete_auth_tenant(DELETED_TENANT): BusClientHeaders.send_tenant_deleted(DELETED_TENANT, 'slug3') def device_deleted(): assert_that( calling(provd.devices.get).with_args(device['id']), raises(ProvdError, matching=has_properties(status_code=404)), ) assert_that( calling(provd.configs.get).with_args(config['id']), raises(ProvdError, matching=has_properties(status_code=404)), ) until.assert_(device_deleted, tries=5)
def test_user_line_dissociated(self, user, line): line_id = line.id user_uuid = user.uuid routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) self.bus.send_line_dissociated_event(line_id, user_uuid, user.tenant_uuid) def user_line_dissociated(): result = self._session.query(models.Line).all() assert_that( result, not_(has_items(has_properties(id=line_id, user_uuid=user_uuid)))) until.assert_(user_line_dissociated, tries=3) event = event_accumulator.accumulate(with_headers=True) assert_that( event, contains( has_entries( message=has_entries(data=has_entries(lines=empty())), headers=has_entries(tenant_uuid=str(TOKEN_TENANT_UUID)), )), )
def test_refresh_token_created_event(self, user): routing_key = 'auth.users.{uuid}.tokens.*.created'.format(**user) msg_accumulator = self.bus.accumulator(routing_key) client_id = 'mytestapp' self._post_token( 'foo', 'bar', session_type='Mobile', access_type='offline', client_id=client_id, ) def bus_received_msg(): assert_that( msg_accumulator.accumulate(with_headers=True), contains_exactly( has_entries( message=has_entries( data={ 'client_id': client_id, 'user_uuid': user['uuid'], 'tenant_uuid': user['tenant_uuid'], 'mobile': True, } ), headers=has_entry('tenant_uuid', user['tenant_uuid']), ) ), ) until.assert_(bus_received_msg, tries=10, interval=0.25)
def test_device_state_changed(self, endpoint, user, line): line_id = line.id endpoint_name = endpoint.name routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) self.bus.send_device_state_changed_event(endpoint_name, 'ONHOLD') def endpoint_state_changed(): self._session.expire_all() result = self._session.query(models.Endpoint).all() assert_that( result, has_items(has_properties(name=endpoint_name, state='available'))) until.assert_(endpoint_state_changed, tries=3) event = event_accumulator.accumulate(with_headers=True) assert_that( event, contains( has_entries( message=has_entries(data=has_entries(lines=contains( has_entries(id=line_id, state='available')))), headers=has_entries(tenant_uuid=str(TOKEN_TENANT_UUID)), )), )
def test_message_is_received_after_error(self): bus_events = self.bus.accumulator('dird.test') crash_event = {'name': 'crash_ping', 'data': {'payload': 'ping'}} self.bus.publish( crash_event, headers={'name': 'crash_ping'}, routing_key='dird.test', ) ping_event = {'name': 'dird_ping', 'data': {'payload': 'ping'}} self.bus.publish( ping_event, headers={'name': 'dird_ping'}, routing_key='dird.test', ) def pong_bus_event_received(): assert_that( bus_events.accumulate(with_headers=True), has_item( has_entries( message=has_entries(data=has_entries( payload='pong', ), ), headers=has_entry('name', 'dird_pong'), )), ) until.assert_(pong_bus_event_received, tries=5)
def test_new_channel(self, _, user, line): line_id = line.id channel_name = f'{line.endpoint_name}-1234' routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) self.bus.send_new_channel_event(channel_name) def channel_created(): self._session.expire_all() result = self._session.query(models.Channel).all() assert_that( result, has_items( has_properties(name=channel_name, state='progressing')), ) until.assert_(channel_created, tries=3) event = event_accumulator.accumulate(with_headers=True) assert_that( event, contains( has_entries( message=has_entries(data=has_entries(lines=contains( has_entries(id=line_id, state='progressing')))), headers=has_entries(tenant_uuid=str(TOKEN_TENANT_UUID)), )), )
def test_that_dnd_event_triggers_ami_command(self): amid_client = self.make_amid() bus_client = self.make_bus() bus_client.send_user_dnd_update('123', True) def assert_amid_request(): assert_that( amid_client.requests()['requests'], has_item( has_entries({ 'method': 'POST', 'path': '/1.0/action/PJSIPNotify', 'json': has_entries({ 'Endpoint': 'line-123', 'Variable': [ 'Content-Type=message/sipfrag', 'Event=ACTION-URI', 'Content=key=DNDOn', ], }), })), ) until.assert_(assert_amid_request, tries=5)
def test_unhold(self, _, user, line, channel): channel_name = channel.name routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) self.bus.send_unhold_event(channel_name) def channel_unheld(): self._session.expire_all() result = self._session.query(models.Channel).all() assert_that( result, has_items(has_properties(name=channel_name, state='talking'))) until.assert_(channel_unheld, tries=3) event = event_accumulator.accumulate(with_headers=True) assert_that( event, contains( has_entries( message=has_entries(data=has_entries(lines=contains( has_entries(id=LINE_ID, state='talking')))), headers=has_entries(tenant_uuid=str(TOKEN_TENANT_UUID)), )), )
def test_mute_unmute_participant(self): meeting_uuid = MEETING1_UUID self.confd.set_meetings( MockMeeting(uuid=meeting_uuid, name='meeting'), ) self.given_call_in_meeting(MEETING1_EXTENSION, caller_id_name='participant1') participants = self.calld_client.meetings.list_participants(meeting_uuid) participant = participants['items'][0] self.calld_client.meetings.mute_participant(meeting_uuid, participant['id']) def participant_is_muted(): participants = self.calld_client.meetings.list_participants(meeting_uuid) assert_that(participants, has_entries({ 'total': 1, 'items': contains_exactly(has_entry('muted', True)) })) until.assert_(participant_is_muted, timeout=10, message='Participant was not muted') self.calld_client.meetings.unmute_participant(meeting_uuid, participant['id']) def participant_is_not_muted(): participants = self.calld_client.meetings.list_participants(meeting_uuid) assert_that(participants, has_entries({ 'total': 1, 'items': contains_exactly(has_entry('muted', False)) })) until.assert_(participant_is_not_muted, timeout=10, message='Participant is still muted')
def test_do_not_disturb(self, user): routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) user_uuid = str(user.uuid) self.bus.send_dnd_event(user_uuid, user.tenant_uuid, True) def dnd_updated(): self._session.expire_all() result = self._session.query(models.User).all() assert_that( result, has_items(has_properties(uuid=user.uuid, do_not_disturb=True))) until.assert_(dnd_updated, tries=3) event = event_accumulator.accumulate(with_headers=True) assert_that( event, contains( has_entries( message=has_entries( data=has_entries(uuid=user_uuid, do_not_disturb=True)), headers=has_entries(tenant_uuid=str(TOKEN_TENANT_UUID)), )), )
def test_delete(self, user): routing_key = 'auth.users.{}.external.foo.deleted'.format(user['uuid']) msg_accumulator = self.bus.accumulator(routing_key) self.client.external.create('foo', user['uuid'], self.original_data) base.assert_http_error(404, self.client.external.delete, 'notfoo', user['uuid']) base.assert_http_error(404, self.client.external.delete, 'foo', UNKNOWN_UUID) base.assert_no_error(self.client.external.delete, 'foo', user['uuid']) def bus_received_msg(): assert_that( msg_accumulator.accumulate(with_headers=True), contains_exactly( has_entries( message=has_entries( data={ 'user_uuid': user['uuid'], 'external_auth_name': 'foo', } ), headers=has_key('tenant_uuid'), ) ), ) until.assert_(bus_received_msg, tries=10, interval=0.25) base.assert_http_error(404, self.client.external.get, 'foo', user['uuid'])
def test_session_created(self, user): session_uuid = uuid.uuid4() user_uuid = user.uuid routing_key = f'chatd.users.{user.uuid}.presences.updated' event_accumulator = self.bus.accumulator(routing_key) self.bus.send_session_created_event(session_uuid, user_uuid, user.tenant_uuid, mobile=True) def session_created(): result = self._session.query(models.Session).all() assert_that( result, has_items( has_properties(uuid=session_uuid, user_uuid=user_uuid, mobile=True)), ) until.assert_(session_created, tries=3) event = event_accumulator.accumulate(with_headers=True) assert_that( event, contains( has_entries( message=has_entries(data=has_entries(connected=True)), headers=has_entries(tenant_uuid=str(TOKEN_TENANT_UUID)), )), )
def test_given_rabbitmq_restarts_during_call_when_stasis_channel_destroyed_then_stat_call_end(self): call_id = new_call_id() self.ari.set_channels(MockChannel(id=call_id)) self.stasis.event_stasis_start( channel_id=call_id, stasis_app=STASIS_APP, stasis_app_instance=STASIS_APP_INSTANCE, ) self.restart_service('rabbitmq') CalldEverythingOkWaitStrategy().wait(self) # wait for calld to reconnect to rabbitmq self.reset_bus_client() events = self.bus.accumulator(routing_key='collectd.calls', exchange=BUS_EXCHANGE_COLLECTD) self.stasis.event_channel_destroyed( channel_id=call_id, stasis_app=STASIS_APP, ) def assert_calld_sent_end_call_stat(): expected_message = 'PUTVAL [^/]+/calls-{app}.{app_instance}/counter-end .* N:1' expected_message = expected_message.format(app=STASIS_APP, app_instance=STASIS_APP_INSTANCE) assert_that(events.accumulate(), has_item(matches_regexp(expected_message))) until.assert_(assert_calld_sent_end_call_stat, tries=5)
def test_create_default_templates_when_not_exist(): response = confd.endpoints.sip.templates.get(wazo_tenant=CREATED_TENANT) assert_that(response.items, empty()) with BaseIntegrationTest.create_auth_tenant(CREATED_TENANT): BusClientHeaders.send_tenant_created(CREATED_TENANT, 'myslug') def templates_created(): response = confd.endpoints.sip.templates.get(wazo_tenant=CREATED_TENANT) assert_that( response.items, contains_inanyorder( has_entries(label='global'), has_entries(label='webrtc'), has_entries(label='webrtc_video'), has_entries(label='meeting_guest'), has_entries(label='registration_trunk'), has_entries(label='twilio_trunk'), ), ) def slug_created(): # There's no API to check the tenant slug. It is part of any new group name response = confd.groups.post({'label': 'ignore'}, wazo_tenant=CREATED_TENANT) assert_that(response.item, has_entries(name=starts_with('grp-myslug-'))) until.assert_(templates_created, tries=5) until.assert_(slug_created, tries=5)
def test_restrict_on_with_slow_wazo_auth(self): self.stop_chatd_service() self.stop_auth_service() self.start_chatd_service() def _returns_503(): try: self.chatd.config.get() except ChatdError as e: assert e.status_code == 503 except requests.RequestException as e: raise AssertionError(e) until.assert_(_returns_503, timeout=START_TIMEOUT) self.start_auth_service() def _not_return_503(): try: response = self.chatd.config.get() assert_that(response, has_key('debug')) except Exception as e: raise AssertionError(e) until.assert_(_not_return_503, timeout=START_TIMEOUT)
def test_that_forward_no_answer_triggers_ami_command(self): amid_client = self.make_amid() bus_client = self.make_bus() bus_client.send_user_forward_update('noanswer', '123', '1001', True) def assert_amid_request(): assert_that( amid_client.requests()['requests'], has_items( has_entries({ 'method': 'POST', 'path': '/1.0/action/Command', 'json': has_entries({ 'command': 'devstate change Custom:*735123***222*1001 INUSE' }), }), has_entries({ 'method': 'POST', 'path': '/1.0/action/Command', 'json': has_entries({ 'command': 'devstate change Custom:*735123***222 INUSE' }), }), ), ) until.assert_(assert_amid_request, tries=5)