From 7c30dbb5403772b323df3ad907d9ed15d23b5aee Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Thu, 29 Apr 2010 20:35:40 +0000
Subject: [PATCH] Last batch of changes for this week. This adds support for the IETF based Password Policy for LDAP as SubEntry. Also resolves the following issues : - 4544 :  initializeBackend() should not set JE env config params directly. - 4478 : ECL in draft compat mode / search lastchangenumber can be very long - 4538 : Virtual attributes not retrieved when entry cache configured - 4547 : Search Filter Matching differ for cn=Directory Manager and plain user. - 4514 : Logs shows unexpected message with replication monitoring data missing (Partial fix) - 4534 : Replication using security does not work after server restart - 4516 : SEVERE_ERROR: servers (...) have the same ServerId In addition, they also improve reliability and performance in various areas including CollectiveAttributes, Virtual Attributes and Subentries management, Schema loading, Replication...

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/DbHandlerTest.java |  274 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 271 insertions(+), 3 deletions(-)

diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/DbHandlerTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/DbHandlerTest.java
index e71ef29..36912e1 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/DbHandlerTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/DbHandlerTest.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2009 Sun Microsystems, Inc.
+ *      Copyright 2006-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.replication.server;
 
@@ -30,6 +30,7 @@
 import java.net.ServerSocket;
 
 import org.opends.server.TestCaseUtils;
+import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.replication.ReplicationTestCase;
 import org.opends.server.replication.common.ChangeNumber;
 import org.opends.server.replication.common.ChangeNumberGenerator;
@@ -37,13 +38,29 @@
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 import static org.opends.server.TestCaseUtils.*;
+import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
+import static org.opends.server.loggers.debug.DebugLogger.getTracer;
 
 /**
  * Test the dbHandler class
  */
 public class DbHandlerTest extends ReplicationTestCase
 {
-  @Test()
+  // The tracer object for the debug logger
+  private static final DebugTracer TRACER = getTracer();
+  /**
+   * Utility - log debug message - highlight it is from the test and not
+   * from the server code. Makes easier to observe the test steps.
+   */
+  private void debugInfo(String tn, String s)
+  {
+    if (debugEnabled())
+    {
+      TRACER.debugInfo("** TEST " + tn + " ** " + s);
+    }
+  }
+
+  @Test(enabled=true)
   void testDbHandlerTrim() throws Exception
   {
     File testRoot = null;
@@ -265,7 +282,7 @@
    * The clear feature is used when a replication server receives a request
    * to reset the generationId of a given domain.
    */
-  @Test()
+  @Test(enabled=true)
   void testDbHandlerClear() throws Exception
   {
     File testRoot = null;
@@ -345,4 +362,255 @@
         TestCaseUtils.deleteDirectory(testRoot);
     }
   }
+  /**
+   * Test the logic that manages counter records in the DbHandler in order to
+   * optimize the counting of record in the replication changelog db.
+   * @throws Exception
+   */
+  @Test(enabled=true)
+  void testDbCounts() throws Exception
+  {
+    // It's worth testing with 2 different setting for counterRecord
+    // - a counter record is put every 10 Update msg in the db - just a unit
+    //   setting.
+    // - a counter record is put every 1000 Update msg in the db - something
+    //   closer to real setting.
+    // In both cases, we want to test the counting algorithm, 
+    // - when start and stop are before the first counter record, 
+    // - when start and stop are before and after the first counter record, 
+    // - when start and stop are after the first counter record, 
+    // - when start and stop are before and after more than one counter record, 
+    // After a purge.
+    // After shutdowning/closing and reopening the db.
+    testDBCount(40, 10);
+    testDBCount(4000, 1000);
+  }
+
+  private void testDBCount(int max, int counterWindow) throws Exception
+  {
+    String tn = "testDBCount("+max+","+counterWindow+")";
+    debugInfo(tn, "Starting test");
+
+    File testRoot = null;
+    ReplicationServer replicationServer = null;
+    ReplicationDbEnv dbEnv = null;
+    DbHandler handler = null;
+    ReplicationIterator ri = null;
+    int actualCnt = 0;
+    String testcase;
+    try
+    {
+      TestCaseUtils.startServer();
+
+      //  find  a free port for the replicationServer
+      ServerSocket socket = TestCaseUtils.bindFreePort();
+      int changelogPort = socket.getLocalPort();
+      socket.close();
+
+      // configure a ReplicationServer.
+      ReplServerFakeConfiguration conf =
+        new ReplServerFakeConfiguration(changelogPort, null, 0,
+            2, 0, 100000, null);
+      replicationServer = new ReplicationServer(conf);
+
+      // create or clean a directory for the dbHandler
+      String buildRoot = System.getProperty(TestCaseUtils.PROPERTY_BUILD_ROOT);
+      String path = buildRoot + File.separator + "build" + File.separator +
+      "unit-tests" + File.separator + "dbHandlercp";
+      testRoot = new File(path);
+      if (testRoot.exists())
+      {
+        TestCaseUtils.deleteDirectory(testRoot);
+      }
+      testRoot.mkdirs();
+
+      dbEnv = new ReplicationDbEnv(path, replicationServer);
+
+      // Create the handler
+      handler =
+        new DbHandler( 1, TEST_ROOT_DN_STRING,
+            replicationServer, dbEnv, 10);
+      handler.setCounterWindowSize(counterWindow);
+
+      // Populate the db with 'max' msg
+      int mySeqnum = 1;
+      ChangeNumber cnarray[] = new ChangeNumber[2*(max+1)];
+      long now = System.currentTimeMillis();
+      for (int i=1; i<=max; i++)
+      {        
+        cnarray[i] = new ChangeNumber(now+i, mySeqnum, 1);
+        mySeqnum+=2;
+        DeleteMsg update1 = new DeleteMsg(TEST_ROOT_DN_STRING, cnarray[i], "uid");
+        handler.add(update1);
+      }
+      handler.flush();
+
+      // Test first and last
+      ChangeNumber cn1 = handler.getFirstChange();
+      assertEquals(cn1, cnarray[1], "First change");
+      ChangeNumber cnlast = handler.getLastChange();
+      assertEquals(cnlast, cnarray[max], "Last change");
+
+      // Test count in different subcases trying to handle all special cases
+      // regarding the 'counter' record and 'count' algorithm
+      testcase="FROM change1 TO change1 ";
+      actualCnt = handler.getCount(cnarray[1], cnarray[1]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, 1, testcase);
+
+      testcase="FROM change1 TO change2 ";
+      actualCnt = handler.getCount(cnarray[1], cnarray[2]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, 2, testcase);
+
+      testcase="FROM change1 TO counterWindow="+(counterWindow);
+      actualCnt = handler.getCount(cnarray[1], cnarray[counterWindow]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, counterWindow, testcase);
+
+      testcase="FROM change1 TO counterWindow+1="+(counterWindow+1);
+      actualCnt = handler.getCount(cnarray[1], cnarray[counterWindow+1]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, counterWindow+1, testcase);
+      
+      testcase="FROM change1 TO 2*counterWindow="+(2*counterWindow);
+      actualCnt = handler.getCount(cnarray[1], cnarray[2*counterWindow]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, 2*counterWindow, testcase);
+
+      testcase="FROM change1 TO 2*counterWindow+1="+((2*counterWindow)+1);
+      actualCnt = handler.getCount(cnarray[1], cnarray[(2*counterWindow)+1]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, (2*counterWindow)+1, testcase);
+
+      testcase="FROM change2 TO change5 ";
+      actualCnt = handler.getCount(cnarray[2], cnarray[5]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, 4, testcase);
+
+      testcase="FROM counterWindow+2 TO counterWindow+5 ";
+      actualCnt = handler.getCount(cnarray[(counterWindow+2)], cnarray[(counterWindow+5)]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, 4, testcase);
+
+      testcase="FROM change2 TO counterWindow+5 ";
+      actualCnt = handler.getCount(cnarray[2], cnarray[(counterWindow+5)]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, counterWindow+4, testcase);
+
+      testcase="FROM counterWindow+4 TO counterWindow+4 ";
+      actualCnt = handler.getCount(cnarray[(counterWindow+4)], cnarray[(counterWindow+4)]);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, 1, testcase);
+
+      // Now test with changes older than first or newer than last
+      ChangeNumber olderThanFirst = null;
+      ChangeNumber newerThanLast =
+        new ChangeNumber(System.currentTimeMillis() + (2*(max+1)), 100, 1);
+
+      // Now we want to test with start and stop outside of the db
+      
+      testcase="FROM our first generated change TO now (> newest change in the db)";
+      actualCnt = handler.getCount(cnarray[1], newerThanLast);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, max, testcase);
+
+      testcase="FROM null (start of time) TO now (> newest change in the db)";
+      actualCnt = handler.getCount(olderThanFirst, newerThanLast);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, max, testcase);
+
+      // Now we want to test that after closing and reopening the db, the
+      // counting algo is well reinitialized and when new messages are added
+      // the new counter are correctly generated.
+      debugInfo(tn,"SHUTDOWN handler and recreate");
+      handler.shutdown();
+      
+      handler =
+        new DbHandler( 1, TEST_ROOT_DN_STRING,
+            replicationServer, dbEnv, 10);
+      handler.setCounterWindowSize(counterWindow);
+
+      // Test first and last
+      cn1 = handler.getFirstChange();
+      assertEquals(cn1, cnarray[1], "First change");
+      cnlast = handler.getLastChange();
+      assertEquals(cnlast, cnarray[max], "Last change");
+
+      testcase="FROM our first generated change TO now (> newest change in the db)";
+      actualCnt = handler.getCount(cnarray[1], newerThanLast);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, max, testcase);
+
+      // Populate the db with 'max' msg
+      for (int i=max+1; i<=(2*max); i++)
+      {        
+        cnarray[i] = new ChangeNumber(now+i, mySeqnum, 1);
+        mySeqnum+=2;
+        DeleteMsg update1 = new DeleteMsg(TEST_ROOT_DN_STRING, cnarray[i], "uid");
+        handler.add(update1);
+      }
+      handler.flush();
+
+      // Test first and last
+      cn1 = handler.getFirstChange();
+      assertEquals(cn1, cnarray[1], "First change");
+      cnlast = handler.getLastChange();
+      assertEquals(cnlast, cnarray[2*max], "Last change");
+
+      testcase="FROM our first generated change TO now (> newest change in the db)";
+      actualCnt = handler.getCount(cnarray[1], newerThanLast);
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, (2*max), testcase);
+      
+      //
+      
+      handler.setPurgeDelay(100);
+      sleep(4000);
+      int totalCount = handler.getCount(null, null);
+      debugInfo(tn,testcase + " After purge, total count=" + totalCount);
+      
+      testcase="AFTER PURGE (first, last)=";
+      debugInfo(tn,testcase + handler.getFirstChange() + handler.getLastChange());
+      assertEquals(handler.getLastChange(), cnarray[2*max], "Last=");
+           
+      testcase="AFTER PURGE ";
+      actualCnt = handler.getCount(cnarray[1], newerThanLast);
+      int expectedCnt;
+      if (totalCount>1)
+      {
+        expectedCnt = ((handler.getLastChange().getSeqnum()
+                    - handler.getFirstChange().getSeqnum() + 1)/2)+1;
+      }
+      else
+      {
+        expectedCnt = 1;
+      }
+      debugInfo(tn,testcase + " actualCnt=" + actualCnt);
+      assertEquals(actualCnt, expectedCnt, testcase);
+
+      // Clear ...
+      debugInfo(tn,"clear:");
+      handler.clear();
+
+      // Check the db is cleared.
+      assertEquals(null, handler.getFirstChange());
+      assertEquals(null, handler.getLastChange());
+      debugInfo(tn,"Success");
+
+    }
+    finally
+    {
+      if (ri!=null)
+        ri.releaseCursor();
+      if (handler != null)
+        handler.shutdown();
+      if (dbEnv != null)
+        dbEnv.shutdown();
+      if (replicationServer != null)
+        replicationServer.remove();
+      if (testRoot != null)
+        TestCaseUtils.deleteDirectory(testRoot);
+    }
+  }
 }

--
Gitblit v1.10.0