getncchanges.py: Add test for adding links during replication
authorTim Beale <timbeale@catalyst.net.nz>
Tue, 13 Jun 2017 00:14:45 +0000 (12:14 +1200)
committerGarming Sam <garming@samba.org>
Mon, 18 Sep 2017 03:51:24 +0000 (05:51 +0200)
We have identified a case where the Samba server can send linked
attributes but not the target object. In this case, the Samba DRS client
would hit the "Failed to re-resolve GUID" case in replmd and silently
discard the linked attribute.

However, Samba will resend the linked attribute in the next cycle
(because its USN is still higher than the committed HWM), so it should
recover OK. On older releases, this may have caused problems if the
first error resulting in a hanging link (which might mean the second
time it's processed it still fails to be added).

Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
selftest/knownfail.d/getncchanges
source4/torture/drs/python/getncchanges.py

index c4d40f1694ea4ea357b031fcaf2c593e0ebfc0ae..0db7d66a6ed32981c021c4477338d5d531b3104a 100644 (file)
@@ -2,6 +2,8 @@
 # the link in a separate chunk before the target object
 samba4.drs.getncchanges.python\(vampire_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_get_tgt\(vampire_dc\)
 samba4.drs.getncchanges.python\(vampire_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_get_tgt_chain\(vampire_dc\)
+samba4.drs.getncchanges.python\(vampire_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_integrity_link_attr\(vampire_dc\)
+samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_integrity_link_attr\(promoted_dc\)
 # GET_TGT tests currently only work for testenvs that send the links at the
 # same time as the source objects. Currently this is only the vampire_dc
 samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_get_tgt\(promoted_dc\)
index c87523dcea560e4ca2fc631e3da6764e9599ca62..65d3748834de18eb5d8afcb2aeab4ce445c4bba2 100644 (file)
@@ -557,6 +557,53 @@ class DrsReplicaSyncIntegrityTestCase(drs_base.DrsBaseTestCase):
         # Check we received links for all the reportees
         self.assert_expected_links(expected_links)
 
+    def test_repl_integrity_link_attr(self):
+        """
+        Tests adding links to new objects while a replication is in progress.
+        """
+
+        # create some source objects for the linked attributes, sandwiched
+        # between 2 blocks of filler objects
+        filler = self.create_object_range(0, 100, prefix="filler")
+        reportees = self.create_object_range(0, 100, prefix="reportee")
+        filler += self.create_object_range(100, 200, prefix="filler")
+
+        # Start the replication and get the first block of filler objects
+        # (We're being mean here and setting the GET_TGT flag right from the
+        # start. On earlier Samba versions, if the client encountered an
+        # unknown target object and retried with GET_TGT, it would restart the
+        # replication cycle from scratch, which avoids the problem).
+        self.repl_get_next(get_tgt=True)
+
+        # create the target objects and add the links. These objects should be
+        # outside the scope of the Samba replication cycle, but the links should
+        # still get sent with the source object
+        managers = self.create_object_range(0, 100, prefix="manager")
+
+        for i in range(0, 100):
+            self.modify_object(reportees[i], "managedBy", managers[i])
+
+        expected_objects = managers + reportees + filler
+        expected_links = reportees
+
+        # complete the replication
+        while not self.replication_complete():
+            self.repl_get_next(get_tgt=True)
+
+        # If we didn't receive the most recently created objects in the last
+        # replication cycle, then kick off another replication to get them
+        if len(self.rxd_dn_list) < len(expected_objects):
+            self.repl_get_next()
+
+            while not self.replication_complete():
+                self.repl_get_next()
+
+        # Check we get all the objects we're expecting
+        self.assert_expected_data(expected_objects)
+
+        # Check we received links for all the parents
+        self.assert_expected_links(expected_links)
+
     def test_repl_get_anc_link_attr(self):
         """
         A basic GET_ANC test where the parents have linked attributes