def wipe(*, postgres_dsn, data_dir, yes, dry_run): if postgres_dsn: cluster = pgcluster.get_remote_pg_cluster(postgres_dsn) elif data_dir: cluster = pgcluster.get_local_pg_cluster(data_dir) cluster.set_connection_params( pgconnparams.ConnectionParameters( user='******', database='template1', ), ) else: raise click.UsageError( 'either --postgres-dsn or --data-dir is required') if not yes and not click.confirm( 'This will DELETE all EdgeDB data from the target ' 'PostgreSQL instance. ARE YOU SURE?'): click.echo('OK. Not proceeding.') status = cluster.get_status() cluster_started_by_us = False if status != 'running': if isinstance(cluster, pgcluster.RemoteCluster): click.secho(f'Remote cluster is not running', fg='red') sys.exit(1) else: cluster.start(port=edbcluster.find_available_port()) cluster_started_by_us = True try: asyncio.run(do_wipe(cluster, dry_run)) finally: if cluster_started_by_us: cluster.stop()
async def test_server_ops_ignore_other_tenants_single_role(self): with tempfile.TemporaryDirectory() as td: cluster = await pgcluster.get_local_pg_cluster(td, log_level='s') cluster.set_connection_params( pgconnparams.ConnectionParameters( user='******', database='template1', ), ) self.assertTrue(await cluster.ensure_initialized()) cluster.add_hba_entry( type="local", database="all", user="******", auth_method="trust", ) await cluster.start() conn = await cluster.connect() setup = """\ CREATE ROLE single WITH LOGIN CREATEDB; CREATE DATABASE single; REVOKE ALL ON DATABASE single FROM PUBLIC; GRANT CONNECT ON DATABASE single TO single; GRANT ALL ON DATABASE single TO single;\ """ for sql in setup.split('\n'): await conn.execute(sql) await conn.close() try: await self._test_server_ops_ignore_other_tenants(td, 'single') finally: await cluster.stop()
def test_server_ops_postgres_recovery(self): async def test(pgdata_path): async with tb.start_edgedb_server( postgres_dsn= f'postgres:///?user=postgres&host={pgdata_path}', reset_auth=True, runstate_dir=None if devmode.is_in_dev_mode() else pgdata_path, ) as sd: con = await sd.connect() try: val = await con.query_single('SELECT 123') self.assertEqual(int(val), 123) # stop the postgres cluster.stop() # TODO: Use BackendUnavailableError here, same below with self.assertRaisesRegex( errors.EdgeDBError, 'Postgres is not available', ): await con.query_single('SELECT 123+456') # bring postgres back await self.loop.run_in_executor(None, cluster.start) # give the EdgeDB server some time to recover deadline = time.monotonic() + 5 while time.monotonic() < deadline: try: val = await con.query_single('SELECT 123+456') break except errors.EdgeDBError: # TODO: ditto pass self.assertEqual(int(val), 579) finally: await con.aclose() with tempfile.TemporaryDirectory() as td: cluster = pgcluster.get_local_pg_cluster(td, log_level='s') cluster.set_connection_params( pgconnparams.ConnectionParameters( user='******', database='template1', ), ) self.assertTrue(cluster.ensure_initialized()) cluster.start() try: self.loop.run_until_complete(test(td)) finally: cluster.stop()
async def test_server_ops_ignore_other_tenants(self): with tempfile.TemporaryDirectory() as td: cluster = await pgcluster.get_local_pg_cluster(td, log_level='s') cluster.set_connection_params( pgconnparams.ConnectionParameters( user='******', database='template1', ), ) self.assertTrue(await cluster.ensure_initialized()) await cluster.start() try: await self._test_server_ops_ignore_other_tenants( td, 'postgres') finally: await cluster.stop()
def test_server_ops_postgres_multitenant(self): async def test(pgdata_path, tenant): async with tb.start_edgedb_server( auto_shutdown=True, tenant_id=tenant, reset_auth=True, postgres_dsn= f'postgres:///?user=postgres&host={pgdata_path}', runstate_dir=None if devmode.is_in_dev_mode() else pgdata_path, ) as sd: con = await sd.connect() try: await con.execute(f'CREATE DATABASE {tenant}') await con.execute(f'CREATE SUPERUSER ROLE {tenant}') databases = await con.query('SELECT sys::Database.name') self.assertEqual(set(databases), {'edgedb', tenant}) roles = await con.query('SELECT sys::Role.name') self.assertEqual(set(roles), {'edgedb', tenant}) finally: await con.aclose() async def run(): async with taskgroup.TaskGroup() as tg: tg.create_task(test(td, 'tenant1')) tg.create_task(test(td, 'tenant2')) with tempfile.TemporaryDirectory() as td: cluster = pgcluster.get_local_pg_cluster(td) cluster.set_connection_params( pgconnparams.ConnectionParameters( user='******', database='template1', ), ) self.assertTrue(cluster.ensure_initialized()) cluster.start() try: self.loop.run_until_complete(run()) finally: cluster.stop()
def test_server_ops_detect_postgres_pool_size(self): port = edgedb_cluster.find_available_port() actual = random.randint(50, 100) async def test(host): bootstrap_command = ( r'CONFIGURE SYSTEM INSERT Auth ' r'{ priority := 0, method := (INSERT Trust) }') async with tb.start_edgedb_server( auto_shutdown=True, bootstrap_command=bootstrap_command, max_allowed_connections=None, postgres_dsn=f'postgres:///?user=postgres&port={port}&' f'host={host}', ) as sd: con = await edgedb.async_connect(user='******', host=sd.host, port=sd.port) try: max_connections = await con.query_one( 'SELECT cfg::SystemConfig.__pg_max_connections ' 'LIMIT 1') # TODO: remove LIMIT 1 after #2402 self.assertEqual(int(max_connections), actual) finally: await con.aclose() with tempfile.TemporaryDirectory() as td: cluster = pgcluster.get_local_pg_cluster(td, max_connections=actual) cluster.set_connection_params( pgconnparams.ConnectionParameters( user='******', database='template1', ), ) self.assertTrue(cluster.ensure_initialized()) cluster.start(port=port) try: self.loop.run_until_complete(test(td)) finally: cluster.stop()
def test_server_ops_detect_postgres_pool_size(self): actual = random.randint(50, 100) async def test(pgdata_path): async with tb.start_edgedb_server( auto_shutdown=True, max_allowed_connections=None, postgres_dsn= f'postgres:///?user=postgres&host={pgdata_path}', reset_auth=True, runstate_dir=None if devmode.is_in_dev_mode() else pgdata_path, ) as sd: con = await sd.connect() try: max_connections = await con.query_single( ''' SELECT cfg::InstanceConfig.__pg_max_connections LIMIT 1 ''') # TODO: remove LIMIT 1 after #2402 self.assertEqual(int(max_connections), actual) finally: await con.aclose() with tempfile.TemporaryDirectory() as td: cluster = pgcluster.get_local_pg_cluster(td, max_connections=actual, log_level='s') cluster.set_connection_params( pgconnparams.ConnectionParameters( user='******', database='template1', ), ) self.assertTrue(cluster.ensure_initialized()) cluster.start() try: self.loop.run_until_complete(test(td)) finally: cluster.stop()