def test_patch_history_operations(runner, config_file, config_profile, database_test_patch_history_operations, db_systems_test_patch_history_operations): # by db-system params = [ 'patch-history', 'list', 'by-db-system', '--db-system-id', db_systems_test_patch_history_operations[0] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) if len(result.output) > 0: json_result = json.loads(result.output) if len(json_result['data']) > 0: patch_history_entry_id = json_result['data'][0]['id'] params = [ 'patch-history', 'get', 'by-db-system', '--db-system-id', db_systems_test_patch_history_operations[0], '--patch-history-entry-id', patch_history_entry_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) # by database params = [ 'patch-history', 'list', 'by-database', '--database-id', database_test_patch_history_operations ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) if len(result.output) > 0: json_result = json.loads(result.output) if len(json_result['data']) > 0: patch_history_entry_id = json_result['data'][0]['id'] params = [ 'patch-history', 'get', 'by-database', '--database-id', database_test_patch_history_operations, '--patch-history-entry-id', patch_history_entry_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result)
def test_update_db_system(runner, config_file, config_profile, db_systems_test_update_db_system): params = [ 'system', 'update', '--db-system-id', db_systems_test_update_db_system[0], '--cpu-core-count', '6', '--ssh-authorized-keys-file', util.SSH_AUTHORIZED_KEYS_FILE, '--force' # disable confirm prompt for overwriting ssh keys list ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until([ 'db', 'system', 'get', '--db-system-id', db_systems_test_update_db_system[0] ], 'AVAILABLE', max_wait_seconds=DB_SYSTEM_UPDATE_TIME) # db system has updated so verify new fields params = [ 'system', 'get', '--db-system-id', db_systems_test_update_db_system[0] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) json_result = json.loads(result.output) assert json_result['data']['cpu-core-count'] == 6 print("Updated DB System: " + result.output)
def test_launch_exa_db_system(runner, config_file, config_profile, networking_test_launch_exa_db_system): DB_SYSTEM_SHAPE = 'Exadata.Quarter2.92' # provision DB systems params = [ 'system', 'launch', '--admin-password', ADMIN_PASSWORD, '--availability-domain', networking_test_launch_exa_db_system['availability_domain'], '--compartment-id', util.COMPARTMENT_ID, '--cpu-core-count', DB_SYSTEM_CPU_CORE_COUNT, '--database-edition', DB_SYSTEM_DB_EXTREME_EDITION, '--time-zone', 'US/Pacific', '--db-name', 'clidbexa', '--db-version', DB_VERSION, '--display-name', 'CliDbSysExa', '--hostname', 'cliexa', '--shape', DB_SYSTEM_SHAPE, '--ssh-authorized-keys-file', util.SSH_AUTHORIZED_KEYS_FILE, '--subnet-id', networking_test_launch_exa_db_system['subnet_ocid_1'], '--backup-subnet-id', networking_test_launch_exa_db_system['subnet_ocid_2'], '--sparse-diskgroup', 'true' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) print(str(result.output)) json_result = json.loads(result.output) db_system_id_1 = json_result['data']['id'] print("Wating for DB System to launch...") # launch db system util.wait_until(['db', 'system', 'get', '--db-system-id', db_system_id_1], 'PROVISIONING', max_wait_seconds=DB_SYSTEM_PROVISIONING_TIME_SEC) print("DB System launched successfully!") if SKIP_CLEAN_UP_RESOURCES: print("Skipping clean up of DB systems and dependent resources.") return success_terminating_db_systems = True try: # terminate db system params = [ 'system', 'terminate', '--db-system-id', db_system_id_1, '--force' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) # validate that it goes into terminating state params = ['system', 'get', '--db-system-id', db_system_id_1] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) state = json.loads(result.output)['data']['lifecycle-state'] assert "TERMINAT" in state # TODO: Re-enable this after this is re-recorded using CLI tenancy. util.wait_until( ['db', 'system', 'get', '--db-system-id', db_system_id_1], 'TERMINATED', max_wait_seconds=DB_SYSTEM_PROVISIONING_TIME_SEC, succeed_if_not_found=True) except Exception as error: util.print_latest_exception(error) success_terminating_db_systems = False assert success_terminating_db_systems
def test_patch_operations(runner, config_file, config_profile, database_test_patch_operations, db_systems_test_patch_operations): # by db-system params = [ 'patch', 'list', 'by-db-system', '--db-system-id', db_systems_test_patch_operations[0] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) if len(result.output) > 0: json_result = json.loads(result.output) if len(json_result['data']) > 0: patch_id = json_result['data'][0]['id'] print("Getting patch {} for db system {}".format( patch_id, db_systems_test_patch_operations[0])) params = [ 'patch', 'get', 'by-db-system', '--db-system-id', db_systems_test_patch_operations[0], '--patch-id', patch_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) json_result = json.loads(result.output) if 'APPLY' in json_result['data']['available-actions']: print('Applying patch: {} to db system: {}'.format( patch_id, db_systems_test_patch_operations[0])) params = [ 'db-system', 'patch', '--db-system-id', db_systems_test_patch_operations[0], '--patch-id', patch_id, '--patch-action', 'APPLY' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until([ 'db', 'system', 'get', '--db-system-id', db_systems_test_patch_operations[0] ], 'AVAILABLE', max_wait_seconds=DB_PATCH_TIME_SEC) # by database params = [ 'patch', 'list', 'by-database', '--database-id', database_test_patch_operations ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) if len(result.output) > 0: json_result = json.loads(result.output) if len(json_result['data']) > 0: patch_id = json_result['data'][0]['id'] print("Getting patch {} for database {}".format( patch_id, database_test_patch_operations)) params = [ 'patch', 'get', 'by-database', '--database-id', database_test_patch_operations, '--patch-id', patch_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) json_result = json.loads(result.output) if 'APPLY' in json_result['data']['available-actions']: print('Applying patch: {} to database: {}'.format( patch_id, database_test_patch_operations)) params = [ 'database', 'patch', '--database-id', database_test_patch_operations, '--patch-id', patch_id, '--patch-action', 'APPLY' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until([ 'db', 'database', 'get', '--database-id', database_test_patch_operations ], 'AVAILABLE', max_wait_seconds=DB_PATCH_TIME_SEC)
def test_exa_database_operations(runner, config_file, config_profile, exa_db_systems_test_database_operations): # create database params = [ 'database', 'create', '--db-system-id', exa_db_systems_test_database_operations[0], '--db-version', DB_VERSION, '--admin-password', ADMIN_PASSWORD, '--db-name', 'clidbop4' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) json_result = json.loads(result.output) database_id = json_result['data']['id'] # get database util.wait_until(['db', 'database', 'get', '--database-id', database_id], 'AVAILABLE', max_wait_seconds=DB_PROVISIONING_TIME_SEC) # list databases params = [ 'database', 'list', '--compartment-id', util.COMPARTMENT_ID, '--db-system-id', exa_db_systems_test_database_operations[0] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) # list databases with --limit 0 params = [ 'database', 'list', '--compartment-id', util.COMPARTMENT_ID, '--db-system-id', exa_db_systems_test_database_operations[0], '--limit', '0' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) assert len(result.output) == 0 # update database params = [ 'database', 'update', '--database-id', database_id, '--auto-backup-enabled', 'true', '--recovery-window-in-days', DB_RECOVERY_WINDOW, '--force' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) json_result = json.loads(result.output) assert json_result['data']['db-backup-config'][ 'auto-backup-enabled'] is True util.wait_until(['db', 'database', 'get', '--database-id', database_id], 'AVAILABLE', max_wait_seconds=DB_PROVISIONING_TIME_SEC) # delete database params = ['database', 'delete', '--database-id', database_id, '--force'] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until(['db', 'database', 'get', '--database-id', database_id], 'TERMINATED', max_wait_seconds=DB_TERMINATING_TIME_SEC, succeed_if_not_found=True) util.wait_until([ 'db', 'system', 'get', '--db-system-id', exa_db_systems_test_database_operations[0] ], 'AVAILABLE', max_wait_seconds=DB_TERMINATING_TIME_SEC)
def test_backup_operations(runner, config_file, config_profile, db_systems_test_backup_operations, database_test_backup_operations): # create backup print("Creating backup..") params = [ 'backup', 'create', '--database-id', database_test_backup_operations, '--display-name', util.random_name('CliDbBackup') ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) json_result = json.loads(result.output) backup_id = json_result['data']['id'] # get backup print("Getting backup..") util.wait_until(['db', 'backup', 'get', '--backup-id', backup_id], 'ACTIVE', max_wait_seconds=DB_BACKUP_TIME_SEC) # list backups by database params = [ 'backup', 'list', '--database-id', database_test_backup_operations ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) print(result.output) assert len(json.loads(result.output)['data']) > 0 # list backups by compartment params = ['backup', 'list', '--compartment-id', util.COMPARTMENT_ID] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) print(result.output) assert len(json.loads(result.output)['data']) > 0 # restore from backup params = [ 'database', 'restore', '--database-id', database_test_backup_operations, '--latest', 'true' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until([ 'db', 'database', 'get', '--database-id', database_test_backup_operations ], 'AVAILABLE', max_wait_seconds=DB_BACKUP_TIME_SEC) # in order to create from backup we have to delete this database print("Deleting database in order to create from backup...") params = [ 'database', 'delete', '--database-id', database_test_backup_operations, '--force' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until([ 'db', 'database', 'get', '--database-id', database_test_backup_operations ], 'TERMINATED', max_wait_seconds=DB_TERMINATING_TIME_SEC, succeed_if_not_found=True) util.wait_until([ 'db', 'system', 'get', '--db-system-id', db_systems_test_backup_operations[0] ], 'AVAILABLE', max_wait_seconds=DB_TERMINATING_TIME_SEC) # create from backup params = [ 'database', 'create-from-backup', '--db-system-id', db_systems_test_backup_operations[0], '--backup-id', backup_id, '--admin-password', ADMIN_PASSWORD, '--db-name', 'renameDb', '--backup-tde-password', ADMIN_PASSWORD ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) db_created_from_backup = json.loads(result.output)['data']['id'] util.wait_until( ['db', 'database', 'get', '--database-id', db_created_from_backup], 'AVAILABLE', max_wait_seconds=DB_PROVISIONING_TIME_SEC) print("Restored Database with a new database name") params = [ 'system', 'get', '--db-system-id', db_systems_test_backup_operations[0] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) print(json.loads(result.output)['data']) subnet = json.loads(result.output)['data']['subnet-id'] availbility_domain = json.loads( result.output)['data']['availability-domain'] print("Launching new Dbsystem from backup with renamed database ") # Launch dbsystem params_1 = [ 'system', 'launch-from-backup', '--ssh-authorized-keys-file', util.SSH_AUTHORIZED_KEYS_FILE, '--backup-id', backup_id, '--subnet-id', subnet, '--hostname', util.random_name('cli-test-hostname', insert_underscore=False), '--db-name', 'renameDb', '--availability-domain', availbility_domain, '--shape', DB_SYSTEM_SHAPE, '--display-name', util.random_name('CliDbSysDisplayName', insert_underscore=False), '--initial-data-storage-size-in-gb', '256', '--compartment-id', util.COMPARTMENT_ID, '--admin-password', ADMIN_PASSWORD, '--backup-tde-password', ADMIN_PASSWORD, '--cpu-core-count', '4', '--database-edition', DB_SYSTEM_DB_EXTREME_EDITION ] result = invoke(runner, config_file, config_profile, params_1) util.validate_response(result) dbsystem_from_backup = json.loads(result.output)['data']['id'] print("New dbsystem ocid:", dbsystem_from_backup) util.wait_until( ['db', 'system', 'get', '--db-system-id', dbsystem_from_backup], 'AVAILABLE', max_wait_seconds=DB_SYSTEM_PROVISIONING_TIME_SEC) print("DB Systems provisioned successfully!") # delete backup print("Deleting backup") params = ['backup', 'delete', '--backup-id', backup_id, '--force'] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until(['db', 'backup', 'get', '--backup-id', backup_id], 'TERMINATED', max_wait_seconds=DB_PROVISIONING_TIME_SEC, succeed_if_not_found=True) print("Deleting dbsystem") params = [ 'system', 'terminate', '--db-system-id', dbsystem_from_backup, '--force' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until( ['db', 'system', 'get', '--db-system-id', dbsystem_from_backup], 'TERMINATED', max_wait_seconds=DB_SYSTEM_PROVISIONING_TIME_SEC) print("backup test ends")
def test_data_guard_with_new_db(runner, config_file, config_profile, vm_database_test_data_guard_with_new_db, vm_db_system_test_data_guard_with_new_db): # Get the subnet of the existing database params = ['system', 'get', '--db-system-id', vm_db_system_test_data_guard_with_new_db[0]] result = invoke(runner, config_file, config_profile, params) subnet_id = json.loads(result.output)['data']['subnet-id'] availability_domain = json.loads(result.output)['data']['availability-domain'] # CREATE using a new DB rather than an existing one. # 'database' comes from vm_db_system_test_data_guard_with_new_db[0] and the second one will be created. print("Creating Data Guard Association...") params = [ 'data-guard-association', 'create', 'with-new-db-system', '--database-id', vm_database_test_data_guard_with_new_db, '--creation-type', 'NewDbSystem', '--database-admin-password', ADMIN_PASSWORD, '--protection-mode', 'MAXIMUM_PERFORMANCE', '--transport-type', 'ASYNC', '--availability-domain', availability_domain, '--display-name', 'DataGuardDb', # The combined hostname and domain cannot be longer than 56 characters. '--hostname', 'host-dg-new-db', '--subnet-id', subnet_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) data_guard_association_id = json.loads(result.output)['data']['id'] print("data-guard-association", result.output) util.wait_until(['db', 'data-guard-association', 'get', '--database-id', vm_database_test_data_guard_with_new_db, '--data-guard-association-id', data_guard_association_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until(['db', 'system', 'get', '--db-system-id', vm_db_system_test_data_guard_with_new_db[0]], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # LIST params = [ 'data-guard-association', 'list', '--database-id', vm_database_test_data_guard_with_new_db ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) assert len(json.loads(result.output)['data']) > 0 # GET params = [ 'data-guard-association', 'get', '--database-id', vm_database_test_data_guard_with_new_db, '--data-guard-association-id', data_guard_association_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) peer_database_id = json.loads(result.output)['data']['peer-database-id'] peer_db_system_id = json.loads(result.output)['data']['peer-db-system-id'] peer_data_guard_association_id = json.loads(result.output)['data']['peer-data-guard-association-id'] # ensure both databases are available util.wait_until(['db', 'database', 'get', '--database-id', vm_database_test_data_guard_with_new_db], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until(['db', 'database', 'get', '--database-id', peer_database_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # FAILOVER # Data Guard Association action FAILOVER only allowed on Standby database. # - Primary -> disabled_standby # - Standby -> Primary print("Attempting Data Guard failover...") params = [ 'data-guard-association', 'failover', '--database-id', peer_database_id, '--data-guard-association-id', peer_data_guard_association_id, '--database-admin-password', ADMIN_PASSWORD ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) # wait until both databases are available again util.wait_until(['db', 'database', 'get', '--database-id', vm_database_test_data_guard_with_new_db], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until(['db', 'database', 'get', '--database-id', peer_database_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # REINSTATE # 'disabled_standby' -> standby print("Attempting Data Guard reinstate...") params = [ 'data-guard-association', 'reinstate', '--database-id', peer_database_id, '--data-guard-association-id', peer_data_guard_association_id, '--database-admin-password', ADMIN_PASSWORD ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until(['db', 'database', 'get', '--database-id', vm_database_test_data_guard_with_new_db], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until(['db', 'database', 'get', '--database-id', peer_database_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # SWITCHOVER # primary (original standby) -> standby # standby (original primary) -> primary print("Attempting Data Guard switchover...") params = [ 'data-guard-association', 'switchover', '--database-id', peer_database_id, '--data-guard-association-id', peer_data_guard_association_id, '--database-admin-password', ADMIN_PASSWORD ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until(['db', 'database', 'get', '--database-id', vm_database_test_data_guard_with_new_db], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until(['db', 'database', 'get', '--database-id', peer_database_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # Delete the Data Guard Association By Termininating the DataGuard DB System. params = [ 'system', 'terminate', '--db-system-id', peer_db_system_id, '--force' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) # validate that it goes into terminating state params = [ 'system', 'get', '--db-system-id', peer_db_system_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) state = json.loads(result.output)['data']['lifecycle-state'] assert "TERMINAT" in state util.wait_until(['db', 'system', 'get', '--db-system-id', peer_db_system_id], 'TERMINATED', max_wait_seconds=DB_SYSTEM_PROVISIONING_TIME_SEC, succeed_if_not_found=True) util.wait_until(['db', 'system', 'get', '--db-system-id', vm_db_system_test_data_guard_with_new_db[0]], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # LIST params = [ 'data-guard-association', 'list', '--database-id', vm_database_test_data_guard_with_new_db ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) assert len(json.loads(result.output)['data']) > 0
def test_db_node_operations(runner, config_file, config_profile, db_systems_test_db_node_operations): # list nodes in db-system params = [ 'node', 'list', '--compartment-id', util.COMPARTMENT_ID, '--db-system-id', db_systems_test_db_node_operations[0] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) json_result = json.loads(result.output) # assert there is at least one node in the system assert len(json_result['data']) > 0 node_id = json_result['data'][0]['id'] # get node params = [ 'node', 'get', '--db-node-id', node_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) # # test node actions # # db node stop params = [ 'node', 'stop', '--db-node-id', node_id ] print('Stopping DB Node...') result = invoke(runner, config_file, config_profile, params) util.validate_response(result) assert json.loads(result.output)['data']['lifecycle-state'] == "STOPPING" # db node start params = [ 'node', 'start', '--db-node-id', node_id ] print('Starting DB Node...') result = invoke(runner, config_file, config_profile, params) util.validate_response(result) assert json.loads(result.output)['data']['lifecycle-state'] == "STARTING" # db node reset params = [ 'node', 'reset', '--db-node-id', node_id ] print('Reseting DB Node...') result = invoke(runner, config_file, config_profile, params) util.validate_response(result) assert json.loads(result.output)['data']['lifecycle-state'] == "STOPPING" params = [ 'node', 'get', '--db-node-id', node_id ] result = invoke(runner, config_file, config_profile, params) reset_state = json.loads(result.output)['data']['lifecycle-state'] while reset_state == "STOPPING" or reset_state == "STOPPED": result = invoke(runner, config_file, config_profile, params) reset_state = json.loads(result.output)['data']['lifecycle-state'] print(result.output) # db node soft-reset params = [ 'node', 'soft-reset', '--db-node-id', node_id ] print('Soft reseting DB Node...') result = invoke(runner, config_file, config_profile, params) util.validate_response(result) assert json.loads(result.output)['data']['lifecycle-state'] == "STOPPING" util.wait_until(['db', 'system', 'get', '--db-system-id', db_systems_test_db_node_operations[0]], 'AVAILABLE', max_wait_seconds=DB_NODE_OPERATION_TIME)
def test_data_guard_operations(runner, config_file, config_profile, database_test_data_guard_operations, db_systems_test_data_guard_operations): # verify db system 1 is available params = [ 'system', 'get', '--db-system-id', db_systems_test_data_guard_operations[0] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) db_system_1_state = json.loads(result.output)['data']['lifecycle-state'] # verify db system 2 is available params = [ 'system', 'get', '--db-system-id', db_systems_test_data_guard_operations[1] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) db_system_2_state = json.loads(result.output)['data']['lifecycle-state'] if db_system_1_state != "AVAILABLE": print("Waiting for DB system 1 to become AVAILABLE") util.wait_until([ 'db', 'system', 'get', '--db-system-id', db_systems_test_data_guard_operations[0] ], 'AVAILABLE', max_wait_seconds=300) if db_system_2_state != "AVAILABLE": print("Waiting for DB system 2 to become AVAILABLE") util.wait_until([ 'db', 'system', 'get', '--db-system-id', db_systems_test_data_guard_operations[1] ], 'AVAILABLE', max_wait_seconds=300) # CREATE # data guard requires 2 distinct DB systems # 'database' comes from db_systems[0] and db_systems[1] is used as the peer db system print("Creating Data Guard Association. . .") params = [ 'data-guard-association', 'create', 'from-existing-db-system', '--database-id', database_test_data_guard_operations, '--creation-type', 'ExistingDbSystem', '--database-admin-password', ADMIN_PASSWORD, '--protection-mode', 'MAXIMUM_PERFORMANCE', '--transport-type', 'ASYNC', '--peer-db-system-id', db_systems_test_data_guard_operations[1] ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) data_guard_association_id = json.loads(result.output)['data']['id'] util.wait_until([ 'db', 'data-guard-association', 'get', '--database-id', database_test_data_guard_operations, '--data-guard-association-id', data_guard_association_id ], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until([ 'db', 'system', 'get', '--db-system-id', db_systems_test_data_guard_operations[0] ], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until([ 'db', 'system', 'get', '--db-system-id', db_systems_test_data_guard_operations[1] ], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # LIST params = [ 'data-guard-association', 'list', '--database-id', database_test_data_guard_operations ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) assert len(json.loads(result.output)['data']) > 0 # GET params = [ 'data-guard-association', 'get', '--database-id', database_test_data_guard_operations, '--data-guard-association-id', data_guard_association_id ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) peer_database_id = json.loads(result.output)['data']['peer-database-id'] peer_data_guard_association_id = json.loads( result.output)['data']['peer-data-guard-association-id'] # ensure both databases are available util.wait_until([ 'db', 'database', 'get', '--database-id', database_test_data_guard_operations ], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until( ['db', 'database', 'get', '--database-id', peer_database_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # FAILOVER # Data Guard Association action FAILOVER only allowed on Standby database. # - Primary -> disabled_standby # - Standby -> Primary print("Attempting Data Guard failover...") params = [ 'data-guard-association', 'failover', '--database-id', peer_database_id, '--data-guard-association-id', peer_data_guard_association_id, '--database-admin-password', ADMIN_PASSWORD ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) # wait until both databases are available again util.wait_until([ 'db', 'database', 'get', '--database-id', database_test_data_guard_operations ], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until( ['db', 'database', 'get', '--database-id', peer_database_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # REINSTATE # 'disabled_standby' -> standby print("Attempting Data Guard reinstate...") params = [ 'data-guard-association', 'reinstate', '--database-id', peer_database_id, '--data-guard-association-id', peer_data_guard_association_id, '--database-admin-password', ADMIN_PASSWORD ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until([ 'db', 'database', 'get', '--database-id', database_test_data_guard_operations ], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until( ['db', 'database', 'get', '--database-id', peer_database_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # SWITCHOVER # primary (original standby) -> standby # standby (original primary) -> primary print("Attempting Data Guard switchover...") params = [ 'data-guard-association', 'switchover', '--database-id', peer_database_id, '--data-guard-association-id', peer_data_guard_association_id, '--database-admin-password', ADMIN_PASSWORD ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until([ 'db', 'database', 'get', '--database-id', database_test_data_guard_operations ], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) util.wait_until( ['db', 'database', 'get', '--database-id', peer_database_id], 'AVAILABLE', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME) # DELETE DATA GUARD ASSOCIATION BY DELETING STANDBY DB (this allows us to clean up the DB System) print("Deleting peer database...") params = [ 'database', 'delete', '--database-id', peer_database_id, '--force' ] result = invoke(runner, config_file, config_profile, params) util.validate_response(result) util.wait_until( ['db', 'database', 'get', '--database-id', peer_database_id], 'TERMINATED', max_wait_seconds=DATA_GUARD_ASSOCIATION_OPERATION_TIME, succeed_if_not_found=True)