def _init_suffix(topo, suffix_info): index = suffix_info['index'] # Init suffix_info values suffix = f'dc=suffix{index},' + BASE_SUFFIX suffix_info['suffix'] = suffix ldif_dir = topo.standalone.get_ldif_dir() bak_dir = topo.standalone.get_bak_dir() suffix_info['name'] = f'suffix{index}' suffix_info['rbak'] = bak_dir + f'/r_i4585.bak' # For archive2db suffix_info['wbak'] = bak_dir + f'/w_i4585.bak' # For db2archive suffix_info['rldif'] = ldif_dir + f'/r_suffix{index}.ldif' # For ldif2db suffix_info['wldif'] = ldif_dir + f'/w_suffix{index}.ldif' # For db2ldif # create suffix backend be = Backend(topo.standalone) be.create(properties={'cn': suffix_info['name'], 'nsslapd-suffix': suffix}) # Generate rldif ldif file, populate backend, and generate rbak archive dbgen_users(topo.standalone, NBUSERS, suffix_info['rldif'], suffix) # Populate the backend result = _run_ldif2db(topo, ONLINE, suffix_info) assert (result == 0) # Generate archive (only second suffix is created) if index == 2: shutil.rmtree(suffix_info['rbak'], ignore_errors=True) result = _job_db2archive(topo, ONLINE, suffix_info['rbak']) assert (result == 0)
def test_missing_backend(topo): """Test that an error is returned when a restore is performed for a backend that is no longer present. :id: 889b8028-35cf-41d7-91f6-bc5193683646 :setup: Standalone Instance :steps: 1. Create a second backend 2. Perform a back up 3. Remove one of the backends from the config 4. Perform a restore :expectedresults: 1. Success 2. Success 3. Success 4. Failure """ # Create a new backend BE_NAME = 'backupRoot' BE_SUFFIX = 'dc=back,dc=up' props = { 'cn': BE_NAME, 'nsslapd-suffix': BE_SUFFIX, BACKEND_SAMPLE_ENTRIES: INSTALL_LATEST_CONFIG } be = Backend(topo.standalone) backend_entry = be.create(properties=props) # perform backup backup_dir_name = "backup-%s" % datetime.now().strftime( "%Y_%m_%d_%H_%M_%S") archive = os.path.join(topo.standalone.ds_paths.backup_dir, backup_dir_name) backup_task = BackupTask(topo.standalone) task_properties = {'nsArchiveDir': archive} backup_task.create(properties=task_properties) backup_task.wait() assert backup_task.get_exit_code() == 0 # Remove new backend backend_entry.delete() # Restore the backup - it should fail restore_task = RestoreTask(topo.standalone) task_properties = {'nsArchiveDir': archive} restore_task.create(properties=task_properties) restore_task.wait() assert restore_task.get_exit_code() != 0
def create_backend(inst, rdn, suffix): # We only support dc= in this test. assert suffix.startswith('dc=') be1 = Backend(inst) be1.create(properties={ 'cn': rdn, 'nsslapd-suffix': suffix, }, create_mapping_tree=False) # Now we temporarily make the MT for this node so we can add the base entry. mts = MappingTrees(inst) mt = mts.create(properties={ 'cn': suffix, 'nsslapd-state': 'backend', 'nsslapd-backend': rdn, }) # Create the domain entry create_base_domain(inst, suffix) # Now delete the mt mt.delete() return be1
def test_usn_local_mode(plugin): """ Test that when USN is operating in local mode, each backend has an instance of the USN Plug-in with a USN counter specific to that backend database. """ # assert local mode assert not plugin.is_global_mode_set() ou_value = "People2" ou_suffix = DEFAULT_SUFFIX # create a new backend plugin._instance.backends.create(None, properties={ BACKEND_NAME: "People2Data", BACKEND_SUFFIX: "ou=" + ou_value + "," + ou_suffix, }) # create a new sub-suffix stored in the new backend ou2 = create_test_ou(plugin._instance, ou=ou_value, suffix=ou_suffix) root_dse = RootDSE(plugin._instance) lastusn_b1 = lambda: root_dse.get_attr_val_int("lastusn;userroot") lastusn_b2 = lambda: root_dse.get_attr_val_int("lastusn;people2data") assert lastusn_b1() == lastusn_b2() == -1 # add a user in the default backend; trigger the plugin user_b1 = create_test_user(plugin._instance) user_b1.replace('sn', 'surname2') user_b1.replace('sn', 'surname3') # add a user in the new backend user_b2 = create_test_user(plugin._instance, suffix=ou2.dn) # assert the USN counter is different for each backend assert user_b1.get_attr_val_int("entryusn") == lastusn_b1() == 2 assert user_b2.get_attr_val_int("entryusn") == lastusn_b2() == 0 # reset USN for subsequent test cases b = Backend(plugin._instance, dn="cn=people2data," + DN_LDBM) reset_USN(plugin, [user_b1, user_b2, ou2, b])
def test_usn_global_mode(plugin): """ Test that when USN is operating in global mode, there is a global instance of the USN Plug-in with a global USN counter that applies to changes made to the entire directory (all backends). """ plugin.enable_global_mode() plugin._instance.restart() assert plugin.is_global_mode_set() # create a new backend and a new sub-suffix stored in the new backend ou_value = "People4" ou_suffix = DEFAULT_SUFFIX plugin._instance.backends.create(None, properties={ BACKEND_NAME: "People4Data", BACKEND_SUFFIX: "ou=" + ou_value + "," + ou_suffix, }) root_dse = RootDSE(plugin._instance) assert "lastusn" in root_dse.get_all_attrs() ou2 = create_test_ou(plugin._instance, ou=ou_value, suffix=ou_suffix) assert ou2.get_attr_val_int("entryusn") == 0 # add a user in the default backend user_b1 = create_test_user(plugin._instance) # add a user in the new backend user_b2 = create_test_user(plugin._instance, suffix=ou2.dn) # assert that a global USN counter is used for all backends assert user_b1.get_attr_val_int("entryusn") == 1 assert user_b2.get_attr_val_int("entryusn") == 2 # reset USN for subsequent test cases b = Backend(plugin._instance, dn="cn=people4data," + DN_LDBM) reset_USN(plugin, [user_b1, user_b2, ou2, b])
def test_multiple_changelogs(topo): """Test the multiple suffixes can be replicated with the new per backend changelog. :id: eafcdb57-4ea2-4887-a0a8-9e4d295f4f4d :setup: Supplier Instance, Consumer Instance :steps: 1. Create s second suffix 2. Enable replication for second backend 3. Perform some updates on both backends and make sure replication is working for both backends :expectedresults: 1. Success 2. Success 3. Success """ supplier = topo.ms['supplier1'] consumer = topo.cs['consumer1'] # Create second suffix dc=second_backend on both replicas for inst in [supplier, consumer]: # Create the backends props = {'cn': 'secondRoot', 'nsslapd-suffix': SECOND_SUFFIX} be = Backend(inst) be.create(properties=props) be.create_sample_entries('001004002') # Setup replication for second suffix repl = ReplicationManager(SECOND_SUFFIX) repl.create_first_supplier(supplier) repl.join_consumer(supplier, consumer) # Test replication works for each backend for suffix in [DEFAULT_SUFFIX, SECOND_SUFFIX]: replicas = Replicas(supplier) replica = replicas.get(suffix) log.info("Testing replication for: " + suffix) assert replica.test_replication([consumer])
def test_multiple_changelogs_export_import(topo): """Test that we can export and import the replication changelog :id: b74fcaaf-a13f-4ee0-98f9-248b281f8700 :setup: Supplier Instance, Consumer Instance :steps: 1. Create s second suffix 2. Enable replication for second backend 3. Perform some updates on a backend, and export the changelog 4. Do an export and import while the server is idle 5. Do an import while the server is under load :expectedresults: 1. Success 2. Success 3. Success 4. Success 5. Success """ SECOND_SUFFIX = 'dc=second_suffix' supplier = topo.ms['supplier1'] consumer = topo.cs['consumer1'] supplier.config.set('nsslapd-errorlog-level', '0') # Create second suffix dc=second_backend on both replicas for inst in [supplier, consumer]: # Create the backends props = {'cn': 'secondRoot', 'nsslapd-suffix': SECOND_SUFFIX} be = Backend(inst) try: be.create(properties=props) be.create_sample_entries('001004002') except ldap.UNWILLING_TO_PERFORM: pass # Setup replication for second suffix try: repl = ReplicationManager(SECOND_SUFFIX) repl.create_first_supplier(supplier) repl.join_consumer(supplier, consumer) except ldap.ALREADY_EXISTS: pass # Put the replica under load, and export the changelog replicas = Replicas(supplier) replica = replicas.get(DEFAULT_SUFFIX) doMods1 = DoMods(supplier, task="export") doMods1.start() replica.begin_task_cl2ldif() doMods1.join() replica.task_finished() # allow some time to pass, and test replication time.sleep(1) assert replica.test_replication([consumer]) # While idle, go an export and import, and make sure replication still works log.info("Testing idle server with CL export and import...") replica.begin_task_cl2ldif() replica.task_finished() replica.begin_task_ldif2cl() replica.task_finished() assert replica.test_replication([consumer]) # stability test, put the replica under load, import the changelog, and make # sure server did not crash. log.info("Testing busy server with CL import...") doMods2 = DoMods(supplier, task="import") doMods2.start() replica.begin_task_ldif2cl() doMods2.join() replica.task_finished() # Replication will be broken so no need to test it. This is just make sure # the import works, and the server is stable assert supplier.status() assert consumer.status()
def test_tombstone_cleanup(plugin): """ Assert that the USN plugin removes tombstone entries when the cleanup task is run. Test removal for a specific backend, a specific suffix, and up to a given USN number. """ # create a new backend and a new sub-suffix stored in the new backend ou_value = "People3" ou_suffix = DEFAULT_SUFFIX plugin._instance.backends.create(None, properties={ BACKEND_NAME: "People3Data", BACKEND_SUFFIX: "ou=" + ou_value + "," + ou_suffix, }) ou2 = create_test_ou(plugin._instance, ou=ou_value, suffix=ou_suffix) tombstones_b1 = DSLdapObjects(plugin._instance) tombstones_b1._basedn = "ou=People," + DEFAULT_SUFFIX tombstones_b1._objectclasses = ['nsTombstone'] tombstones_b2 = DSLdapObjects(plugin._instance) tombstones_b2._basedn = ou2.dn tombstones_b2._objectclasses = ['nsTombstone'] root_dse = RootDSE(plugin._instance) lastusn_b1 = lambda: root_dse.get_attr_val_int("lastusn;userroot") assert lastusn_b1() == -1 user1_b1 = create_test_user(plugin._instance) user2_b1 = create_test_user(plugin._instance) user3_b1 = create_test_user(plugin._instance) user1_b2 = create_test_user(plugin._instance, suffix=ou2.dn) user2_b2 = create_test_user(plugin._instance, suffix=ou2.dn) # assert no tombstones exist at this point assert not tombstones_b1.list() assert not tombstones_b2.list() # create 3 tombstone entries on default backend user1_b1.delete() user2_b1.delete() user3_b1.delete() # assert there are 3 tombstone entries indeed on default backend assert len(tombstones_b1.list()) == 3 assert not tombstones_b2.list() assert lastusn_b1() == 5 # remove all tombstone entries from default backend, with a USN value up to 4 task = plugin.cleanup(suffix=DEFAULT_SUFFIX, max_usn=lastusn_b1() - 1) task.wait() # assert all tombstone entries were deleted but the last one on default backend assert len(tombstones_b1.list()) == 1 assert not tombstones_b2.list() # create 2 tombstone entries on new backend user1_b2.delete() user2_b2.delete() # assert there are 2 tombstone entries indeed on new backend assert len(tombstones_b2.list()) == 2 assert len(tombstones_b1.list()) == 1 # remove all tombstone entries from ou2 suffix task = plugin.cleanup(suffix=ou2.dn) task.wait() # assert there are no tombstone entries stored on ou2 suffix assert not tombstones_b2.list() assert len(tombstones_b1.list()) == 1 # reset USN for subsequent test cases b = Backend(plugin._instance, dn="cn=people3data," + DN_LDBM) reset_USN(plugin, [ou2, b])