def test_setup_invalid_does_not_stop(self): setupd = self.make_setupd(VALID_TOKEN) body = { 'engine_language': 'en_US', 'engine_password': '******', 'engine_internal_address': '10.1.1.1', 'engine_license': True, 'nestbox_host': 'nestbox', 'nestbox_port': 443, 'nestbox_verify_certificate': False, 'nestbox_service_id': 'test', 'nestbox_service_key': 'foobar', 'nestbox_instance_name': 'my-wazo', 'nestbox_engine_host': 'wazo.example.com', 'nestbox_engine_port': 443, } assert_that( calling(setupd.setup.create).with_args(body), raises(SetupdError).matching( has_properties( status_code=500, error_id='setup-token-failed', )), ) def setupd_is_stopped(): return not self.service_status('setupd')['State']['Running'] try: until.true(setupd_is_stopped, timeout=10) except until.NoMoreTries: return else: raise AssertionError('wazo-setupd stopped after failed setup')
def test_given_one_http_subscription_when_restart_rabbitmq_then_callback_still_triggered( self, subscription): self.restart_service('rabbitmq') ConnectedWaitStrategy().wait(self.make_webhookd(MASTER_TOKEN)) # FIXME(sileht): BusClient should reconnect automatically self.bus = self.make_bus() until.true(self.bus.is_up, timeout=5, message='rabbitmq did not come back up') self.bus.publish( trigger_event(), routing_key=SOME_ROUTING_KEY, headers={'name': TRIGGER_EVENT_NAME}, ) until.assert_( self.make_third_party_verify_callback(request={ 'method': 'GET', 'path': '/test' }), timeout=10, interval=0.5, )
def given_bridged_call_stasis(self, caller_uuid=None, callee_uuid=None): bridge = self.ari.bridges.create(type='mixing') caller = self.stasis_channel() caller_uuid = caller_uuid or str(uuid.uuid4()) caller.setChannelVar(variable='XIVO_USERUUID', value=caller_uuid) bridge.addChannel(channel=caller.id) callee = self.stasis_channel() callee_uuid = callee_uuid or str(uuid.uuid4()) callee.setChannelVar(variable='XIVO_USERUUID', value=callee_uuid) bridge.addChannel(channel=callee.id) calld = self.make_calld(VALID_TOKEN) def channels_have_been_created_in_calld(caller_id, callee_id): calls = calld.calls.list_calls( application=STASIS_APP, application_instance=STASIS_APP_INSTANCE) channel_ids = [call['call_id'] for call in calls['items']] return (caller_id in channel_ids and callee_id in channel_ids) until.true(channels_have_been_created_in_calld, callee.id, caller.id, tries=3) return caller.id, callee.id
def setUp(self): super().setUp() self.tenant_uuid = SUB_TENANT self.tenant_name = 'mytenant' bus_port = self.service_port(5672, 'rabbitmq') bus = BusClient.from_connection_fields(host='localhost', port=bus_port) until.true(bus.is_up, timeout=5) bus_url = 'amqp://{username}:{password}@{host}:{port}//'.format( username='******', password='******', host='localhost', port=bus_port) connection = kombu.Connection(bus_url) connection.connect() marshaler = Marshaler('the-xivo-uuid') exchange = kombu.Exchange('xivo', type='topic') producer = kombu.Producer(connection, exchange=exchange, auto_declare=True) self.publisher = Publisher(producer, marshaler) self.mock_auth_client = MockAuthClient('localhost', self.service_port(9497, 'auth')) def wait_for_dird_bus_connection(): response = self.client.status.get() assert_that(response, has_entries(bus_consumer={'status': 'ok'})) until.assert_(wait_for_dird_bus_connection, timeout=6)
def auth_stopped(self): self.stop_service('auth') yield self.start_service('auth') auth = self.make_auth() until.true(auth.is_up, timeout=5, message='wazo-auth did not come back up') self.configured_wazo_auth()
def setUpClass(cls): super().setUpClass() database = cls.new_db_client() until.true(database.is_up, timeout=5, message='Postgres did not come back up') bootstrap.create_initial_user( database.uri, cls.username, cls.password, bootstrap.PURPOSE, bootstrap.DEFAULT_POLICY_NAME, ) port = cls.service_port(9497, 'auth') cls.client = Client( 'localhost', port=port, prefix=None, https=False, username=cls.username, password=cls.password, ) token_data = cls.client.token.new(backend='wazo_user', expiration=7200) cls.admin_user_uuid = token_data['metadata']['uuid'] cls.client.set_token(token_data['token']) cls.top_tenant_uuid = cls.get_top_tenant()['uuid']
def auth_stopped(self): self.stop_service('auth') yield self.start_service('auth') auth = self.make_auth() until.true(auth.is_up, tries=5, message='wazo-auth did not come back up')
def auth_stopped(self): self.stop_service('auth') yield self.start_service('auth') self.reset_clients() until.true(self.auth.is_up, tries=5, message='wazo-auth did not come back up')
def start_listening(self): self._bus_thread = threading.Thread(target=self._start_consuming) self._bus_thread.start() def is_listening(): return self._consumer and self._consumer.is_running() until.true(is_listening, tries=20, interval=0.5)
def restart_postgres(self): self.restart_service('postgres') database = self.new_db_client() until.true(database.is_up, timeout=5, message='Postgres did not come back up') helpers.deinit_db() helpers.init_db(database.uri)
def amid_stopped(cls): cls.stop_service('amid') try: yield finally: cls.start_service('amid') cls.reset_clients() until.true(cls.amid.is_up, tries=5)
def test_when_asterisk_sends_non_json_events_then_calld_reconnects(self): self.stasis.non_json_message() until.false(self._calld_is_not_connected, tries=3, message='wazo-calld did not disconnect from ARI') until.true(self._calld_is_connected, tries=3, message='wazo-calld did not reconnect to ARI')
def test_given_no_ssl_private_key_when_calld_starts_then_calld_stops(self): def calld_is_stopped(): status = self.service_status() return not status['State']['Running'] until.true(calld_is_stopped, tries=10, message='wazo-calld did not stop while missing SSL private key') log = self.service_logs() assert_that(log, contains_string("No such file or directory: '/usr/local/share/ssl/calld/invalid.key'"))
def test_given_no_ari_when_ctid_ng_starts_then_ctid_ng_stops(self): def ctid_ng_is_stopped(): status = self.service_status() return not status['State']['Running'] until.true(ctid_ng_is_stopped, tries=10, message='xivo-ctid-ng did not stop while starting with no ARI') log = self.service_logs() assert_that(log, contains_string("ARI server unreachable... stopping"))
def test_given_no_ssl_private_key_when_ctid_ng_starts_then_ctid_ng_stops(self): def ctid_ng_is_stopped(): status = self.service_status() return not status['State']['Running'] until.true(ctid_ng_is_stopped, tries=10, message='xivo-ctid-ng did not stop while missing SSL private key') log = self.service_logs() assert_that(log, contains_string("No such file or directory: '/usr/share/xivo-certs/server.key'"))
def test_when_asterisk_restart_then_calld_reconnects(self): until.true(self._calld_is_connected, tries=3) self.restart_service('ari') self.reset_clients() assert_that(self.service_logs(), contains_string("ARI connection error")) until.true(self._calld_is_connected, tries=3)
def test_given_no_ari_when_calld_starts_then_calld_stops(self): def calld_is_stopped(): status = self.service_status() return not status['State']['Running'] until.true( calld_is_stopped, tries=10, message='wazo-calld did not stop while starting with no ARI') log = self.service_logs() assert_that(log, contains_string("ARI server unreachable... stopping"))
def test_given_http_subscription_to_localhost_when_bus_event_then_callback_called( self, subscription): self.bus.publish( trigger_event(), routing_key=SOME_ROUTING_KEY, headers={ 'name': TRIGGER_EVENT_NAME, 'user_uuid:{uuid}'.format(uuid=ALICE_USER_UUID): True, }, ) until.true(self.sentinel.called, timeout=10, interval=0.5)
def stasis_channel(self): def channel_is_in_stasis(channel_id): try: self.ari.channels.setChannelVar(channelId=channel_id, variable='TEST_STASIS', value='') return True except ARINotInStasis: return False new_channel = self.ari.channels.originate(endpoint=ENDPOINT_AUTOANSWER, app=STASIS_APP, appArgs=[STASIS_APP_INSTANCE]) until.true(channel_is_in_stasis, new_channel.id, tries=2) return new_channel
def test_given_no_ssl_private_key_when_ui_starts_then_ui_stops(self): def _is_stopped(): status = self.service_status() return not status['State']['Running'] until.true( _is_stopped, tries=10, message='wazo-ui did not stop while missing SSL private key') log = self.service_logs() assert_that( log, contains_string( "No such file or directory: '/usr/share/xivo-certs/unavailable.key'" ))
def given_bridged_call_not_stasis(self, caller_uuid=None, callee_uuid=None, caller_variables=None): caller_uuid = caller_uuid or str(uuid.uuid4()) callee_uuid = callee_uuid or str(uuid.uuid4()) variables = { 'XIVO_USERUUID': caller_uuid, '__CALLEE_XIVO_USERUUID': callee_uuid } variables.update(caller_variables or {}) caller = self.ari.channels.originate( endpoint=ENDPOINT_AUTOANSWER, context='local', extension='dial-autoanswer', variables={'variables': variables}) def bridged_channel(caller): try: bridge = next(bridge for bridge in self.ari.bridges.list() if caller.id in bridge.json['channels']) callee_channel_id = next( iter(set(bridge.json['channels']) - {caller.id})) return callee_channel_id except StopIteration: return False callee_channel_id = until.true(bridged_channel, caller, timeout=3) return caller.id, callee_channel_id
def test_external_oauth2(self, user): routing_key = 'auth.users.{}.external.foo.authorized'.format( user['uuid']) msg_accumulator = self.new_message_accumulator(routing_key) token = 'a-token' result = self.client.external.create('foo', user['uuid'], self.original_data) time.sleep(1) # wazo-auth needs some time to connect its websocket self.authorize_oauth2('foo', result['state'], token) def oauth2_is_done(): try: return self.client.external.get('foo', user['uuid']) except requests.HTTPError: return False data = until.true(oauth2_is_done, timeout=5, interval=0.25) assert_that(data, has_entries(access_token=token)) def bus_received_msg(): assert_that( msg_accumulator.accumulate(), contains( has_entries(data=dict(user_uuid=user['uuid'], external_auth_name='foo')))) until.assert_(bus_received_msg, tries=10, interval=0.25)
def given_mobile_call(self): user_uuid = str(uuid.uuid4()) line_id = SOME_LINE_ID self.confd.set_users( MockUser(uuid=user_uuid, line_ids=[line_id], mobile='mobile-autoanswer')) self.confd.set_lines( MockLine(id=line_id, name=SOME_LINE_NAME, protocol='local', context='local')) token = self.given_user_token(user_uuid) calld = self.make_calld(token) call = calld.calls.make_call_from_user( extension='dial-autoanswer', from_mobile=True, variables={'CALLEE_XIVO_USERUUID': user_uuid}) def bridged_channel(caller): try: bridge = next(bridge for bridge in self.ari.bridges.list() if caller in bridge.json['channels']) callee = next(iter(set(bridge.json['channels']) - {caller})) return callee except StopIteration: return False callee = until.true(bridged_channel, call['call_id'], timeout=3) return call['call_id'], callee, user_uuid
def test_given_ctid_ng_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.bus.listen_events(routing_key='collectd.calls', exchange='collectd') self.stasis.event_stasis_start(channel_id=call_id) self.restart_service('ctid-ng') until.true(self.ari.websockets, tries=5) # wait for xivo-ctid-ng to come back up self.stasis.event_channel_destroyed(channel_id=call_id) def assert_ctid_ng_sent_end_call_stat(): expected_message = 'PUTVAL [^/]+/calls-{app}.{app_instance}/counter-end .* N:1' expected_message = expected_message.format(app=STASIS_APP_NAME, app_instance=STASIS_APP_INSTANCE_NAME) assert_that(self.bus.events(), has_item(matches_regexp(expected_message))) until.assert_(assert_ctid_ng_sent_end_call_stat, tries=5)
def test_given_no_ssl_certificate_when_ctid_ng_starts_then_ctid_ng_stops( self): def ctid_ng_is_stopped(): status = self.service_status() return not status['State']['Running'] until.true( ctid_ng_is_stopped, tries=10, message='xivo-ctid-ng did not stop while missing SSL certificate') log = self.service_logs() assert_that( log, contains_string( "No such file or directory: '/usr/share/xivo-certs/server.crt'" ))
def test_setup_valid_stops(self): setupd = self.make_setupd(VALID_TOKEN) confd = self.make_confd() confd.set_wizard_discover({ "timezone": 'America/Montreal', "hostname": 'wazo-engine', "domain": 'example.com', 'interfaces': [{ 'interface': 'my-interface', 'ip_address': '10.1.1.1', 'netmask': '255.0.0.0', }], 'gateways': [{ 'gateway': '10.254.254.254' }], "nameservers": ['10.2.2.2'], }) confd.set_wizard({'configured': False}) instance_uuid = str(uuid.uuid4()) deployd = self.make_deployd() deployd.set_post_instance({'uuid': instance_uuid}) body = { 'engine_language': 'en_US', 'engine_password': '******', 'engine_internal_address': '10.1.1.1', 'engine_license': True, 'nestbox_host': 'nestbox', 'nestbox_port': 443, 'nestbox_verify_certificate': False, 'nestbox_service_id': 'nestbox-user', 'nestbox_service_key': 'secret', 'nestbox_instance_name': 'my-wazo', 'nestbox_engine_host': 'wazo.example.com', 'nestbox_engine_port': 6666, } setupd.setup.create(body) def setupd_is_stopped(): return not self.service_status('setupd')['State']['Running'] until.true(setupd_is_stopped, timeout=10)
def test_participant_joins_sends_event(self): conference_id = CONFERENCE1_ID self.confd.set_conferences( MockConference(id=conference_id, name='conference'), ) bus_events = self.bus.accumulator( 'conferences.{}.participants.joined'.format(conference_id)) self.given_call_in_conference(CONFERENCE1_EXTENSION, caller_id_name='participant1') def participant_joined_event_received(expected_caller_id_name): caller_id_names = [ event['data']['caller_id_name'] for event in bus_events.accumulate() ] return expected_caller_id_name in caller_id_names until.true(participant_joined_event_received, 'participant1', tries=3)
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) self.restart_service('rabbitmq') until.true(self.bus.is_up, tries=int(os.environ.get('INTEGRATION_TEST_TIMEOUT', 30))) # wait for rabbitmq to come back up self.bus.listen_events(routing_key='collectd.calls', exchange='collectd') self.stasis.event_channel_destroyed(channel_id=call_id) def assert_ctid_ng_sent_end_call_stat(): expected_message = 'PUTVAL [^/]+/calls-{app}.{app_instance}/counter-end .* N:1' expected_message = expected_message.format(app=STASIS_APP_NAME, app_instance=STASIS_APP_INSTANCE_NAME) assert_that(self.bus.events(), has_item(matches_regexp(expected_message))) until.assert_(assert_ctid_ng_sent_end_call_stat, tries=5)
def test_participant_leaves_sends_event(self): conference_id = CONFERENCE1_ID self.confd.set_conferences( MockConference(id=conference_id, name='conference'), ) bus_events = self.bus.accumulator( 'conferences.{}.participants.left'.format(conference_id)) channel_id = self.given_call_in_conference( CONFERENCE1_EXTENSION, caller_id_name='participant1') self.ari.channels.get(channelId=channel_id).hangup() def participant_left_event_received(expected_caller_id_name): caller_id_names = [ event['data']['caller_id_name'] for event in bus_events.accumulate() ] return expected_caller_id_name in caller_id_names until.true(participant_left_event_received, 'participant1', timeout=10)
def test_given_ctid_ng_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.bus.listen_events(routing_key='collectd.calls', exchange='collectd') self.stasis.event_stasis_start(channel_id=call_id) self.restart_service('ctid-ng') until.true(self.ari.websockets, tries=5) # wait for xivo-ctid-ng to come back up self.stasis.event_channel_destroyed(channel_id=call_id) def assert_ctid_ng_sent_end_call_stat(): expected_message = 'PUTVAL [^/]+/calls-{app}.{app_instance}/counter-end .* N:1' expected_message = expected_message.format( app=STASIS_APP_NAME, app_instance=STASIS_APP_INSTANCE_NAME) assert_that(self.bus.events(), has_item(matches_regexp(expected_message))) until.assert_(assert_ctid_ng_sent_end_call_stat, tries=5)
def setUpClass(cls): super().setUpClass() database = cls.new_db_client() until.true(database.is_up, timeout=5, message='Postgres did not come back up') bootstrap.create_initial_user( database.uri, cls.username, cls.password, bootstrap.PURPOSE, bootstrap.DEFAULT_POLICY_NAME, ) cls.client = cls.new_auth_client(cls.username, cls.password) token_data = cls.client.token.new(backend='wazo_user', expiration=7200) cls.admin_user_uuid = token_data['metadata']['uuid'] cls.admin_token = token_data['token'] cls.client.set_token(token_data['token']) cls.top_tenant_uuid = cls.get_top_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) self.restart_service('rabbitmq') until.true( self.bus.is_up, tries=int(os.environ.get('INTEGRATION_TEST_TIMEOUT', 30))) # wait for rabbitmq to come back up self.bus.listen_events(routing_key='collectd.calls', exchange='collectd') self.stasis.event_channel_destroyed(channel_id=call_id) def assert_ctid_ng_sent_end_call_stat(): expected_message = 'PUTVAL [^/]+/calls-{app}.{app_instance}/counter-end .* N:1' expected_message = expected_message.format( app=STASIS_APP_NAME, app_instance=STASIS_APP_INSTANCE_NAME) assert_that(self.bus.events(), has_item(matches_regexp(expected_message))) until.assert_(assert_ctid_ng_sent_end_call_stat, tries=5)
def _simulate_user_authentication(self): authorize_url = AUTHORIZE_URL.format( self.service_port(80, 'oauth2sync')) response = requests.get(authorize_url) response.raise_for_status() def _is_google_token_fetched(): try: return self.client.external.get(GOOGLE, self.admin_user_uuid) except requests.HTTPError: return False # if the external auth-data already existed from a previous test we might get a false # positive in _is_google_token_fetched time.sleep(1.0) response = until.true(_is_google_token_fetched, timeout=15, interval=1) assert_that(response, not_(False), 'failed to simulate user authentication')
def test_that_adding_favorite_produces_bus_event(self): bus_port = self.service_port(5672, 'rabbitmq') bus = BusClient.from_connection_fields(host='localhost', port=bus_port) until.true(bus.is_up, tries=5) bus_events = bus.accumulator('directory.*.favorite.*') def favorite_bus_event_received(name): return name in (message['name'] for message in bus_events.accumulate()) with self.personal({'firstname': 'Alice'}) as alice: with self.favorite('personal', alice['id']): until.true(favorite_bus_event_received, 'favorite_added', tries=2) until.true(favorite_bus_event_received, 'favorite_deleted', tries=2)