@@ -656,6 +656,7 @@ public void initializeTargetExport() throws Exception
656656 }
657657
658658 // Launch in S1 the task that will initialize S2
659+ waitForRemoteReplicas (server2ID );
659660 addTask (taskInitTargetS2 , ResultCode .SUCCESS , null );
660661
661662 // Signal RS we just entered the full update status
@@ -714,6 +715,7 @@ public void initializeTargetExportAll() throws Exception
714715 }
715716
716717 // Launch in S1 the task that will initialize S2
718+ waitForRemoteReplicas (server2ID , server3ID );
717719 addTask (taskInitTargetAll , ResultCode .SUCCESS , null );
718720
719721 // Tests that entries have been received by S2
@@ -1004,6 +1006,7 @@ public void initializeTargetExportMultiSS() throws Exception
10041006
10051007 // Launch in S1 the task that will initialize S2
10061008 log (testCase + " add task " + Thread .currentThread ());
1009+ waitForRemoteReplicas (server2ID );
10071010 addTask (taskInitTargetS2 , ResultCode .SUCCESS , null );
10081011
10091012 log (testCase + " " + server2 .getServerId () + " wait target " + Thread .currentThread ());
@@ -1027,6 +1030,47 @@ public void initializeTargetExportMultiSS() throws Exception
10271030 }
10281031 }
10291032
1033+ /**
1034+ * Tests that an InitializeTarget task failing its validation (the remote
1035+ * replica is unknown to the domain) does not leave the import/export
1036+ * context acquired (issue #730): the domain used to reject every subsequent
1037+ * total update as a simultaneous import/export.
1038+ */
1039+ @ Test (enabled =true )
1040+ public void initializeTargetUnknownRemote () throws Exception
1041+ {
1042+ String testCase = "initializeTargetUnknownRemote" ;
1043+ log ("Starting " + testCase );
1044+ try
1045+ {
1046+ replServer1 = createReplicationServer (replServer1ID , testCase );
1047+ connectServer1ToReplServer (replServer1ID );
1048+ addTestEntriesToDB ();
1049+
1050+ // DS(42424) is unknown in the topology: the task must fail to start...
1051+ Entry taskInitTargetUnknown = TestCaseUtils .makeEntry (
1052+ "dn: ds-task-id=" + UUID .randomUUID () + ",cn=Scheduled Tasks,cn=Tasks" ,
1053+ "objectclass: top" ,
1054+ "objectclass: ds-task" ,
1055+ "objectclass: ds-task-initialize-remote-replica" ,
1056+ "ds-task-class-name: org.opends.server.tasks.InitializeTargetTask" ,
1057+ "ds-task-initialize-domain-dn: " + EXAMPLE_DN ,
1058+ "ds-task-initialize-replica-server-id: " + 42424 );
1059+ addTask (taskInitTargetUnknown , ResultCode .SUCCESS , null );
1060+ waitTaskState (taskInitTargetUnknown , STOPPED_BY_ERROR , 20000 , null );
1061+
1062+ // ...but must not leave the import/export context acquired
1063+ assertFalse (replDomain .ieRunning (),
1064+ "ReplicationDomain: Import/Export is not expected to be running after a failed InitializeTarget" );
1065+
1066+ log ("Successfully ending " + testCase );
1067+ }
1068+ finally
1069+ {
1070+ afterTest (testCase );
1071+ }
1072+ }
1073+
10301074 private void waitForInitializeTargetMsg (String testCase ,
10311075 ReplicationBroker server ) throws Exception
10321076 {
@@ -1293,9 +1337,30 @@ public void initializeSimultaneous() throws Exception
12931337 * Disconnect broker and remove entries from the local DB
12941338 * @param testCase The name of the test case.
12951339 */
1340+ /**
1341+ * Waits until the local replication domain sees the provided replicas in
1342+ * its topology view, so that an InitializeTarget task does not race the
1343+ * topology propagation and fail to start with "the remote directory server
1344+ * DS(x) is unknown" - which, combined with the import/export context leak
1345+ * (issue #730), used to poison the domain for the rest of the test class.
1346+ */
1347+ private void waitForRemoteReplicas (Integer ... serverIds ) throws Exception
1348+ {
1349+ for (int serverId : serverIds )
1350+ {
1351+ for (int i = 0 ; i < 100 && !replDomain .getReplicaInfos ().containsKey (serverId ); i ++)
1352+ {
1353+ sleep (100 );
1354+ }
1355+ assertTrue (replDomain .getReplicaInfos ().containsKey (serverId ),
1356+ "DS(" + serverId + ") is not known to the local replication domain" );
1357+ }
1358+ }
1359+
12961360 private void afterTest (String testCase ) throws Exception
12971361 {
12981362 // Check that the domain has completed the import/export task.
1363+ boolean ieStillRunning = false ;
12991364 if (replDomain != null )
13001365 {
13011366 // race condition could cause the main thread to reach
@@ -1309,7 +1374,10 @@ private void afterTest(String testCase) throws Exception
13091374 }
13101375 sleep (500 );
13111376 }
1312- assertFalse (replDomain .ieRunning (), "ReplicationDomain: Import/Export is not expected to be running" );
1377+ // asserted only after the cleanup below: failing before it would leak
1378+ // the domain config, the brokers and the replication servers into the
1379+ // following tests and cascade the failure over the whole class
1380+ ieStillRunning = replDomain .ieRunning ();
13131381 }
13141382 // Remove domain config
13151383 super .cleanConfigEntries ();
@@ -1330,6 +1398,8 @@ private void afterTest(String testCase) throws Exception
13301398
13311399 Arrays .fill (replServerPort , 0 );
13321400 log ("Successfully cleaned " + testCase );
1401+
1402+ assertFalse (ieStillRunning , "ReplicationDomain: Import/Export is not expected to be running" );
13331403 }
13341404
13351405 /**
0 commit comments