mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Valery Kharseko
3 days ago d07bb318976a8e1c65b1c26b431b0909380ce473
opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/ReplayDuringImportTest.java
@@ -37,6 +37,7 @@
import org.opends.server.replication.ReplicationTestCase;
import org.opends.server.replication.common.CSN;
import org.opends.server.replication.common.CSNGenerator;
import org.opends.server.replication.protocol.DeleteMsg;
import org.opends.server.replication.protocol.DoneMsg;
import org.opends.server.replication.protocol.EntryMsg;
import org.opends.server.replication.protocol.InitializeRequestMsg;
@@ -70,6 +71,10 @@
 * The exporter is a broker of this test, so that the test says when the entries arrive: the
 * change is replayed while the import is waiting for them - or, for the request, while the
 * exporter is holding the answer.
 * <p>
 * The {@code timeOut} each case declares is what it is expected to take at the most; it is
 * not what bounds it. {@code TestListener} sets the timeout of every test method from the
 * {@code org.opends.test.timeout} property, ten minutes under Maven and none outside it.
 */
@SuppressWarnings("javadoc")
public class ReplayDuringImportTest extends ReplicationTestCase
@@ -326,6 +331,72 @@
  }
  /**
   * A total update forgets the deliveries which were folded into no warning, along with
   * the changes they were deliveries of (issue #942).
   * <p>
   * The changes listed as pending do not outlive the ServerState the import replaces, and
   * the recovery from a failed replay goes with them - the session restart backoff, and the
   * count the next warning about a change being asked for again says it stands for. The
   * first warning over the imported data must not count the deliveries of a change which
   * is not listed anymore.
   * <p>
   * Nothing sends a change of this test again - the exporter never had it - so the count
   * is fed by two changes failing within one interval rather than by one change delivered
   * twice: the first is warned about, the second is folded into no warning. The changes
   * are deletes: a short circuit on the modifies would be tripped by the ServerState being
   * saved to the base entry and by the import disabling the backend it replaces.
   */
  @Test(timeOut = 120_000)
  public void aWarningAfterTheImportDoesNotCountTheDeliveriesBefore() throws Exception
  {
    final Entry warnedAbout = TestCaseUtils.addEntry(
        "dn: cn=warnedAbout," + EXAMPLE_DN,
        "objectClass: top",
        "objectClass: person",
        "cn: warnedAbout",
        "sn: warnedAbout");
    final Entry folded = TestCaseUtils.addEntry(
        "dn: cn=folded," + EXAMPLE_DN,
        "objectClass: top",
        "objectClass: person",
        "cn: folded",
        "sn: folded");
    final String warnedAboutUUID = getEntryUUID(warnedAbout.getName());
    final String foldedUUID = getEntryUUID(folded.getName());
    final String[] exported = exportedEntries();
    ShortCircuitPlugin.registerShortCircuit(
        OperationType.DELETE, "PreParse", ResultCode.UNAVAILABLE.intValue());
    try
    {
      replayMsg(new DeleteMsg(warnedAbout.getName(), gen.newCSN(), warnedAboutUUID));
      replayMsg(new DeleteMsg(folded.getName(), gen.newCSN(), foldedUUID));
      startImportInto(exported.length);
      finishImport(exported);
      /*
       * Only the timestamp of the throttle is put back, so that the failure over the
       * imported data is warned about straight away: the count is the domain's to keep or
       * to forget.
       */
      domain.resetReplayRetryWarningThrottle();
      final CSN csn = gen.newCSN();
      replayMsg(new DeleteMsg(DN.valueOf(IMPORTED_ENTRY_DN), csn, IMPORTED_ENTRY_UUID));
      final List<String> warnings = errorLogRecordsOf(WARN_REPLAY_RETRYING_CHANGE.ordinal(), csn);
      assertThat(warnings).as("the change which fails over the imported data must be warned about")
          .isNotEmpty();
      assertThat(warnings.get(0))
          .as("the first warning after the import must not count the deliveries before it")
          .contains(" 0 further deliveries");
    }
    finally
    {
      ShortCircuitPlugin.deregisterShortCircuit(OperationType.DELETE, "PreParse");
    }
  }
  /**
   * Has the exporter start a total update into this replica, and returns once the backend
   * of the domain is deregistered for it: from then on the import is reading the session,
   * and a change replayed here is replayed into no backend.