async def test_deploy_release_many_apps(patch, magic, async_mock): patch.object(Apps, 'make_logger_for_app') patch.object(Database, 'update_release_state', new=async_mock()) patch.init(TooManyActiveApps) patch.object(TooManyActiveApps, '__str__', return_value='too_many') stories = {'services': {}} Apps.apps = {} try: for i in range(20): Apps.apps[f'app_{i}'] = magic() Apps.apps[f'app_{i}'].owner_uuid = 'owner_uuid' stories['services'][f'service_{i}'] = {} await Apps.deploy_release(config={}, release=Release( app_uuid='app_id', app_name='app_name', version='app_version', environment={}, stories=stories, maintenance=False, always_pull_images=False, app_dns='app_dns', state='QUEUED', deleted=False, owner_uuid='owner_uuid', owner_email='*****@*****.**', app_environment=AppEnvironment.PRODUCTION )) TooManyActiveApps.__init__.assert_called_with(20, 5) Database.update_release_state.mock.assert_called() finally: Apps.apps = {} # Cleanup.
async def test_reload_app_no_story(patch, config, logger, db, async_mock): app_id = 'app_id' app_name = 'app_name' patch.object(Apps, 'destroy_app', new=async_mock()) patch.object(Apps, 'deploy_release', new=async_mock()) release = Release( app_uuid=app_id, app_name=app_name, version=1, environment={}, stories=None, maintenance=False, always_pull_images=False, app_dns='app_dns', state='QUEUED', deleted=True, owner_uuid='owner_uuid', owner_email='owner_email', app_environment=AppEnvironment.PRODUCTION ) patch.object(Database, 'get_release_for_deployment', new=async_mock(return_value=release)) await Apps.reload_app(config, logger, app_id) Apps.deploy_release.mock.assert_not_called()
async def test_get_release_for_deployment(patch, config, pool, async_mock, app_environment): app_id = 'my_app_id' expected_query = """ with latest as (select app_uuid, max(id) as id from releases where state != 'NO_DEPLOY'::release_state group by app_uuid) select app_uuid, id as version, config environment, payload stories, apps.name as app_name, maintenance, always_pull_images, hostname app_dns, state, deleted, apps.owner_uuid, owner_emails.email as owner_email, environment app_environment from latest inner join releases using (app_uuid, id) inner join apps on (latest.app_uuid = apps.uuid) inner join app_dns using (app_uuid) left join app_public.owner_emails on (apps.owner_uuid = owner_emails.owner_uuid) where app_uuid = $1; """ patch.object(pool.con, 'fetchrow', new=async_mock( return_value={ 'app_uuid': 'my_app_uuid', 'app_name': 'my_app_name', 'version': 'my_version', 'environment': 'my_environment', 'app_environment': app_environment, 'stories': 'my_stories', 'maintenance': 'my_maintenance', 'always_pull_images': 'my_always_pull_images', 'app_dns': 'my_app_dns', 'state': 'my_state', 'deleted': 'my_deleted', 'owner_uuid': 'my_owner_uuid', 'owner_email': 'my_owner_email' })) ret = await Database.get_release_for_deployment(config, app_id) assert Database.get_pooled_conn.call_count == 1 assert ret == Release(app_uuid='my_app_uuid', app_name='my_app_name', version='my_version', environment='my_environment', stories='my_stories', maintenance='my_maintenance', always_pull_images='my_always_pull_images', app_dns='my_app_dns', state='my_state', deleted='my_deleted', owner_uuid='my_owner_uuid', owner_email='my_owner_email', app_environment=AppEnvironment[app_environment]) pool.con.fetchrow.mock.assert_called_with(expected_query, app_id)
def test_app_init(magic, config, logger, env, always_pull_images): services = magic() stories = magic() expected_secrets = {} if env: for k, v in env.items(): if not isinstance(v, dict): expected_secrets[k.lower()] = v version = 100 app_config = magic() config.APP_DOMAIN = 'asyncyapp.com' app = App(app_data=AppData(release=Release( app_uuid='app_id', app_name='app_name', app_dns='app_dns', version=version, stories=stories, always_pull_images=always_pull_images, environment=env, owner_uuid='owner_1', owner_email='*****@*****.**', maintenance=False, deleted=False, state='QUEUED', app_environment=AppEnvironment.PRODUCTION), app_config=app_config, services=services, config=config, logger=logger)) if env is None: env = {} assert app.app_id == 'app_id' assert app.app_dns == 'app_dns' assert app.config == config assert app.logger == logger assert app.owner_uuid == 'owner_1' assert app.owner_email == '*****@*****.**' assert app.stories == stories['stories'] assert app.services == services assert app.always_pull_images == always_pull_images assert app.environment == env assert app.app_context['hostname'] == f'{app.app_dns}.asyncyapp.com' assert app.app_context['version'] == version assert app.app_context['secrets'] == expected_secrets assert app.entrypoint == stories['entrypoint'] assert app.app_config == app_config if always_pull_images is True: assert app.image_pull_policy() == 'Always' else: assert app.image_pull_policy() == 'IfNotPresent'
def app(config, logger, magic): return App(app_data=AppData(release=Release( app_uuid='app_uuid', app_name='app_name', app_dns='app_dns', owner_uuid='owner_uuid', owner_email='*****@*****.**', environment={}, stories=magic(), version=magic(), always_pull_images=False, maintenance=False, deleted=False, state='QUEUED', app_environment=AppEnvironment.PRODUCTION), config=config, logger=logger, services={}, app_config=magic()))
async def test_deploy_release_many_volumes(patch, async_mock): patch.object(Apps, 'make_logger_for_app') patch.object(Database, 'update_release_state', new=async_mock()) patch.init(TooManyVolumes) patch.object(TooManyVolumes, '__str__', return_value='too_many_vols') stories = {'services': {}} for i in range(10): stories['services'][f'service_{i}'] = { ServiceConstants.config: { 'volumes': { 'a': {}, 'b': {} } } } patch.object(Apps, 'get_services', new=async_mock(return_value=stories['services'])) await Apps.deploy_release( config={}, release=Release( app_uuid='app_id', app_name='app_name', version='app_version', environment={}, stories=stories, maintenance=False, always_pull_images=False, app_dns='app_dns', state='QUEUED', deleted=False, owner_uuid='owner_uuid', owner_email='owner_email', app_environment=AppEnvironment.PRODUCTION ) ) TooManyVolumes.__init__.assert_called_with(20, 15) Database.update_release_state.mock.assert_called()
async def test_deploy_release(config, magic, patch, deleted, async_mock, raise_exc, maintenance, always_pull_images): patch.object(Reporter, 'capture_evt') patch.object(ReportingEvent, 'from_release') patch.object(Kubernetes, 'clean_namespace', new=async_mock()) patch.object(Containers, 'init', new=async_mock()) patch.object(Database, 'update_release_state', new=async_mock()) app_logger = magic() patch.object(Apps, 'make_logger_for_app', return_value=app_logger) Apps.apps = {} services = magic() app_config = magic() patch.object(Apps, 'get_app_config', return_value=app_config) patch.object(Apps, 'get_services', new=async_mock(return_value=services)) patch.init(App) if raise_exc is not None: patch.object(App, 'bootstrap', new=async_mock(side_effect=raise_exc())) else: patch.object(App, 'bootstrap', new=async_mock()) release = Release( app_uuid='app_id', app_name='app_name', version='version', environment={'env': True}, stories={'stories': True}, maintenance=maintenance, always_pull_images=always_pull_images, app_dns='app_dns', state='QUEUED', deleted=deleted, owner_uuid='owner_uuid', owner_email='owner_email', app_environment=AppEnvironment.PRODUCTION ) await Apps.deploy_release(config=config, release=release) if maintenance: assert Database.update_release_state.mock.call_count == 0 app_logger.warn.assert_called() elif deleted: app_logger.warn.assert_called() Database.update_release_state.mock.assert_called_with( app_logger, config, 'app_id', 'version', ReleaseState.NO_DEPLOY) else: assert Database.update_release_state.mock.mock_calls[0] == mock.call( app_logger, config, 'app_id', 'version', ReleaseState.DEPLOYING) App.__init__.assert_called_with(app_data=AppData( release=release, config=config, logger=app_logger, services=services, app_config=app_config )) App.bootstrap.mock.assert_called() Containers.init.mock.assert_called() assert Apps.apps.get('app_id') is not (raise_exc is None) if raise_exc == exc: # ReportingEvent.from_release.assert_called_with( # app.release, 'App Destroy Failed', exc_info=err) Reporter.capture_evt.assert_called_with( ReportingEvent.from_release.return_value) assert \ Database.update_release_state.mock.mock_calls[1] \ == mock.call(app_logger, config, 'app_id', 'version', ReleaseState.TEMP_DEPLOYMENT_FAILURE) elif raise_exc == asyncy_exc: assert \ Database.update_release_state.mock.mock_calls[1] \ == mock.call(app_logger, config, 'app_id', 'version', ReleaseState.FAILED) else: assert \ Database.update_release_state.mock.mock_calls[1] \ == mock.call(app_logger, config, 'app_id', 'version', ReleaseState.DEPLOYED)
async def test_reload_app(patch, config, logger, db, async_mock, magic, raise_exc, previous_state, app_environment_db, app_environment_config): config.APP_ENVIRONMENT = AppEnvironment[app_environment_config] old_app = magic() app_id = 'app_id' app_name = 'app_name' app_dns = 'app_dns' Apps.apps = {app_id: old_app} patch.object(Reporter, 'capture_evt') patch.object(ReportingEvent, 'from_release') app_logger = magic() patch.object(Apps, 'make_logger_for_app', return_value=app_logger) patch.object(Database, 'update_release_state', new=async_mock()) patch.object(Apps, 'destroy_app', new=async_mock()) if raise_exc: patch.object(Apps, 'deploy_release', new=async_mock(side_effect=raise_exc())) else: patch.object(Apps, 'deploy_release', new=async_mock()) release = Release( app_uuid=app_id, app_name=app_name, version=1, environment={}, stories={}, maintenance=False, always_pull_images=False, app_dns=app_dns, state=previous_state, deleted=True, owner_uuid='owner_uuid', owner_email='*****@*****.**', app_environment=AppEnvironment[app_environment_db] ) patch.object(Database, 'get_release_for_deployment', new=async_mock(return_value=release)) await Apps.reload_app(config, logger, app_id) Apps.destroy_app.mock.assert_called_with(old_app, silent=True, update_db_state=True) if AppEnvironment[app_environment_db] != \ AppEnvironment[app_environment_config]: Apps.deploy_release.mock.assert_not_called() logger.info.assert_called() logger.error.assert_not_called() logger.warn.assert_not_called() Database.update_release_state.mock.assert_not_called() return if previous_state == 'FAILED': Apps.deploy_release.mock.assert_not_called() logger.warn.assert_called() logger.error.assert_not_called() Database.update_release_state.mock.assert_not_called() return Apps.deploy_release.mock.assert_called_with( config=config, release=release ) if raise_exc: logger.error.assert_called() assert ReportingEvent.from_release.mock_calls[0][1][0] == release assert ReportingEvent.from_release.mock_calls[0][1][ 1] == Events.APP_RELOAD_FAILED assert isinstance( ReportingEvent.from_release.mock_calls[0][2]['exc_info'], BaseException) Reporter.capture_evt.assert_called_with( ReportingEvent.from_release.return_value) else: logger.error.assert_not_called() if raise_exc == asyncio_timeout_exc: Database.update_release_state.mock.assert_called_with( app_logger, config, 'app_id', 1, ReleaseState.TIMED_OUT)