From 9e87cf54bdad6b73da706a9adc8e31a2b467d224 Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Fri, 08 Sep 2006 13:42:18 +0000
Subject: [PATCH] Add Synchronization unitTest and code coverage

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SyncMessagesTest.java        |   63 ++++
 opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ModifyConflictTest.java      |  444 ++++++++++++++++++++++---------
 opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationMsgTest.java  |  156 ++++++++++
 opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ServerStateTest.java         |  134 +++++++++
 opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationTestCase.java |   35 ++
 5 files changed, 692 insertions(+), 140 deletions(-)

diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ModifyConflictTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ModifyConflictTest.java
index 21f2ee9..b10fcc5 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ModifyConflictTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ModifyConflictTest.java
@@ -31,18 +31,17 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
-
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 
 import static org.opends.server.synchronization.OperationContext.*;
 
-import org.opends.server.SchemaFixture;
+import org.opends.server.core.AddOperation;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ModifyOperation;
+import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.protocols.internal.InternalClientConnection;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
@@ -54,89 +53,206 @@
 import org.opends.server.types.ObjectClass;
 
 /*
- * Test the conflict resolution for modify operations
- * This is still a work in progress.
- * currently implemented tests
- *  - check that an replace with a smaller csn is ignored
- * should test :
- *  - conflict with multi-valued attributes
- *  - conflict with single-valued attributes
- *  - conflict with options
- *  - conflict with binary attributes
- *  - Replace, add, delete attribute, delete attribute value
- *  - conflict on the objectclass attribute
+ * Test the conflict resolution for modify operations As a consequence,
+ * this will also test the Historical.java Class This is still a work in
+ * progress. currently implemented tests - check that an replace with a
+ * smaller csn is ignored should test : - conflict with multi-valued
+ * attributes - conflict with single-valued attributes - conflict with
+ * options - conflict with binary attributes - Replace, add, delete
+ * attribute, delete attribute value - conflict on the objectclass
+ * attribute
  */
 
-
-public class ModifyConflictTest extends SynchronizationTestCase
+public class ModifyConflictTest
+    extends SynchronizationTestCase
 {
 
   /**
-   * Test that conflict between a modify-replace and modify-add
-   * for multi-valued attributes are handled correctly.
+   * Test that conflict between a modify-replace and modify-add for
+   * multi-valued attributes@DataProvider(name = "ackMsg") are handled
+   * correctly.
    */
   @Test()
-  public void replaceAndAdd()
-         throws Exception
+  public void replaceAndAdd() throws Exception
   {
-    /*
-     * Objectclass and DN do not have any impact on the modifty conflict
-     * resolution for the description attribute.
-     * Always use the same values for all these tests.
-     */
     DN dn = DN.decode("dc=com");
     Map<ObjectClass, String> objectClasses = new HashMap<ObjectClass, String>();
     ObjectClass org = DirectoryServer.getObjectClass("organization");
     objectClasses.put(org, "organization");
 
-    /*
-     * start with a new entry with an empty description
-     */
     Entry entry = new Entry(dn, objectClasses, null, null);
+
+    // Construct a new random UUID. and add it into the entry
+    UUID uuid = UUID.randomUUID();
+
+    // Create the att values list of uuid
+    LinkedHashSet<AttributeValue> valuesUuid = new LinkedHashSet<AttributeValue>(
+        1);
+    valuesUuid.add(new AttributeValue(Historical.entryuuidAttrType,
+        new ASN1OctetString(uuid.toString())));
+    ArrayList<Attribute> uuidList = new ArrayList<Attribute>(1);
+    Attribute uuidAttr = new Attribute(Historical.entryuuidAttrType,
+        "entryUUID", valuesUuid);
+    uuidList.add(uuidAttr);
+
+    /*
+     * Add the uuid in the entry
+     */
+    Map<AttributeType, List<Attribute>> operationalAttributes = entry
+        .getOperationalAttributes();
+    operationalAttributes.put(Historical.entryuuidAttrType, uuidList);
+ 
+    // Create the att values list of historicalAttr
+    String stringVal =
+      "ds-sync-hist:00000108b3a6cbb800000001:repl:00000108b3a6cbb800000002";
+
+  AttributeValue val = new AttributeValue(Historical.historicalAttrType,
+      stringVal);
+    LinkedHashSet<AttributeValue> valuesHist =
+      new LinkedHashSet<AttributeValue>(1);
+    valuesHist.add(val);
+    ArrayList<Attribute> histList = new ArrayList<Attribute>(1);
+    Attribute histAttr = new Attribute(Historical.historicalAttrType,
+        "ds-sync-hist", valuesHist);
+    histList.add(histAttr);
+
+    //Add the historical att in the entry
+    operationalAttributes.put(Historical.historicalAttrType,histList) ;
+    
+    // load historical from the entry
     Historical hist = Historical.load(entry);
 
     /*
      * simulate a modify-replace done at time t10
      */
     testModify(entry, hist, "description", ModificationType.REPLACE,
-               "init value", 10, true);
+        "init value", 10, true);
 
     /*
      * Now simulate an add at an earlier date that the previous replace
      * conflict resolution should remove it.
      */
     testModify(entry, hist, "description", ModificationType.ADD,
-               "older value", 1, false);
+        "older value", 1, false);
 
     /*
      * Now simulate an add at an earlier date that the previous replace
-     * conflict resolution should remove it.
-     * (a second time to make sure...)
+     * conflict resolution should remove it. (a second time to make
+     * sure...)
      */
     testModify(entry, hist, "description", ModificationType.ADD,
-               "older value", 2, false);
+        "older value", 2, false);;
 
     /*
      * Now simulate an add at a later date that the previous replace.
      * conflict resolution should keep it
      */
-    testModify(entry, hist, "description", ModificationType.ADD,
-               "new value", 11, true);
+    testModify(entry, hist, "description", ModificationType.ADD, "new value",
+        11, true);
 
   }
 
+  /*
+   * helper function.
+   */
+  private void testHistoricalAndFake(
+      Historical hist, Entry entry)
+  {
+
+    // Get the historical uuid associated to the entry
+    // (the one that needs to be tested)
+    String uuid = hist.getEntryUuid(entry);
+
+    // Get the Entry uuid in String format
+    List<Attribute> uuidAttrs = entry
+        .getOperationalAttribute(Historical.entryuuidAttrType);
+    uuidAttrs.get(0).getValues().iterator().next().toString();
+
+    if (uuidAttrs != null)
+    {
+      if (uuidAttrs.size() > 0)
+      {
+        Attribute att = uuidAttrs.get(0);
+        String retrievedUuid = (att.getValues().iterator().next()).toString();
+        assertTrue(retrievedUuid.equals(uuid));
+      }
+    }
+    
+    try
+    {
+      Historical dup = hist.duplicate();
+      // TODO Check values
+    }
+    catch (RuntimeException e)
+    {
+      assertTrue(false) ;
+    }
+    
+    
+    // Test FakeOperation
+    try
+    {
+      Iterable<FakeOperation> fks = Historical.generateFakeOperations(entry);
+      if (fks.iterator().hasNext())
+      {
+        FakeOperation fk = fks.iterator().next();
+        assertTrue(new FakeOperationComparator().compare(fk, fk) == 0);
+        assertTrue(new FakeOperationComparator().compare(null , fk) < 0);
+        SynchronizationMessage generatedMsg = fk.generateMessage() ;
+        if (generatedMsg instanceof UpdateMessage)
+        {
+          UpdateMessage new_name = (UpdateMessage) generatedMsg;
+          assertEquals(new_name.getUniqueId(),uuid);
+          
+        }
+        
+      }
+      
+    }
+    catch (RuntimeException e)
+    {
+      assertTrue(false) ;
+    }
+  }
+
+  /*
+   * helper function.
+   */
+  private void testHistorical(
+      Historical hist, AddOperation addOp)
+  {
+
+    // Get the historical uuid associated to the entry
+    // (the one that needs to be tested)
+    String uuid = hist.getEntryUuid(addOp);
+
+    // Get the op uuid in String format
+    List<Attribute> uuidAttrs = addOp.getOperationalAttributes().get(
+        Historical.entryuuidAttrType);
+    uuidAttrs.get(0).getValues().iterator().next().toString();
+
+    if (uuidAttrs != null)
+    {
+      if (uuidAttrs.size() > 0)
+      {
+        Attribute att = uuidAttrs.get(0);
+        String retrievedUuid = (att.getValues().iterator().next()).toString();
+        assertTrue(retrievedUuid.equals(uuid));
+      }
+    }
+  }
+
   /**
    * Test that conflict between a modify-delete-attribute and modify-add
    * for multi-valued attributes are handled correctly.
    */
   @Test()
-  public void deleteAndAdd()
-         throws Exception
+  public void deleteAndAdd() throws Exception
   {
     /*
      * Objectclass and DN do not have any impact on the modifty conflict
-     * resolution for the description attribute.
-     * Always use the same values for all these tests.
+     * resolution for the description attribute. Always use the same values
+     * for all these tests.
      */
     DN dn = DN.decode("dc=com");
     Map<ObjectClass, String> objectClasses = new HashMap<ObjectClass, String>();
@@ -147,95 +263,174 @@
      * start with a new entry with an empty description
      */
     Entry entry = new Entry(dn, objectClasses, null, null);
+
+    // Construct a new random UUID. and add it into the entry
+    UUID uuid = UUID.randomUUID();
+
+    // Create the att values list
+    LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(
+        1);
+    values.add(new AttributeValue(Historical.entryuuidAttrType,
+        new ASN1OctetString(uuid.toString())));
+    ArrayList<Attribute> uuidList = new ArrayList<Attribute>(1);
+    Attribute uuidAttr = new Attribute(Historical.entryuuidAttrType,
+        "entryUUID", values);
+    uuidList.add(uuidAttr);
+
+    /*
+     * Add the uuid in the entry
+     */
+    Map<AttributeType, List<Attribute>> operationalAttributes = entry
+        .getOperationalAttributes();
+
+    operationalAttributes.put(Historical.entryuuidAttrType, uuidList);
+    
+    // Create the att values list of historicalAttr
+    String stringVal =
+      "ds-sync-hist:00000108b3a6cbb800000001:del:00000108b3a6cbb800000002";
+
+  AttributeValue val = new AttributeValue(Historical.historicalAttrType,
+      stringVal);
+    LinkedHashSet<AttributeValue> valuesHist =
+      new LinkedHashSet<AttributeValue>(1);
+    valuesHist.add(val);
+    ArrayList<Attribute> histList = new ArrayList<Attribute>(1);
+    Attribute histAttr = new Attribute(Historical.historicalAttrType,
+        "ds-sync-hist", valuesHist);
+
+    //Add the historical att in the entry
+    entry.putAttribute(Historical.historicalAttrType,histList) ;
+    
+    // load historical from the entry
+
     Historical hist = Historical.load(entry);
 
     /*
-     * simulate a delete of the whole description attribute done at time t10
+     * simulate a delete of the whole description attribute done at time
+     * t10
      */
-    testModify(entry, hist, "description", ModificationType.DELETE,
-               null, 10, true);
+    testModify(entry, hist, "description", ModificationType.DELETE, null, 10,
+        true);
 
     /*
-     * Now simulate an add at an earlier date that the previous delete.
-     * The conflict resolution should detect that this add must be ignored.
-     */
-    testModify(entry, hist, "description",  ModificationType.ADD,
-               "older value", 1, false);
-
-    /*
-     * Now simulate an add at an earlier date that the previous delete.
-     * The conflict resolution should detect that this add must be ignored.
-     * (a second time to make sure that historical information is kept...)
+     * Now simulate an add at an earlier date that the previous delete. The
+     * conflict resolution should detect that this add must be ignored.
      */
     testModify(entry, hist, "description", ModificationType.ADD,
-               "older value", 2, false);
+        "older value", 1, false);
+
+    /*
+     * Now simulate an add at an earlier date that the previous delete. The
+     * conflict resolution should detect that this add must be ignored. (a
+     * second time to make sure that historical information is kept...)
+     */
+    testModify(entry, hist, "description", ModificationType.ADD,
+        "older value", 2, false);
 
     /*
      * Now simulate an add at a later date that the previous delete.
      * conflict resolution should keep it
      */
-    testModify(entry, hist, "description", ModificationType.ADD,
-               "new value", 11, true);
+    testModify(entry, hist, "description", ModificationType.ADD, "new value",
+        11, true);
 
   }
 
   /**
-  * Test that conflict between a modify-add and modify-add
-  * for multi-valued attributes are handled correctly.
-  */
- @Test()
- public void addAndAdd()
-        throws Exception
- {
-   /*
-    * Objectclass and DN do not have any impact on the modifty conflict
-    * resolution for the description attribute.
-    * Always use the same values for all these tests.
-    */
-   DN dn = DN.decode("dc=com");
-   Map<ObjectClass, String> objectClasses = new HashMap<ObjectClass, String>();
-   ObjectClass org = DirectoryServer.getObjectClass("organization");
-   objectClasses.put(org, "organization");
+   * Test that conflict between a modify-add and modify-add for
+   * multi-valued attributes are handled correctly.
+   */
+  @Test()
+  public void addAndAdd() throws Exception
+  {
+    /*
+     * Objectclass and DN do not have any impact on the modifty conflict
+     * resolution for the description attribute. Always use the same values
+     * for all these tests.
+     */
+    DN dn = DN.decode("dc=com");
+    Map<ObjectClass, String> objectClasses = new HashMap<ObjectClass, String>();
+    ObjectClass org = DirectoryServer.getObjectClass("organization");
+    objectClasses.put(org, "organization");
 
-   /*
-    * start with a new entry with an empty description
-    */
-   Entry entry = new Entry(dn, objectClasses, null, null);
-   Historical hist = Historical.load(entry);
+    /*
+     * start with a new entry with an empty description
+     */
+    Entry entry = new Entry(dn, objectClasses, null, null);
 
-   /*
-    * simulate a add of the description attribute done at time t10
-    */
-   testModify(entry, hist, "description", ModificationType.ADD,
-              "init value", 10, true);
+    // Construct a new random UUID. and add it into the entry
+    UUID uuid = UUID.randomUUID();
 
-   /*
-    * Now simulate an add at an earlier date that the previous add.
-    * The conflict resolution should detect that this add must be kept.
-    */
-   testModify(entry, hist, "description", ModificationType.ADD,
-              "older value", 1, true);
+    // Create the att values list
+    LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(
+        1);
+    values.add(new AttributeValue(Historical.entryuuidAttrType,
+        new ASN1OctetString(uuid.toString())));
+    ArrayList<Attribute> uuidList = new ArrayList<Attribute>(1);
+    Attribute uuidAttr = new Attribute(Historical.entryuuidAttrType,
+        "entryUUID", values);
+    uuidList.add(uuidAttr);
 
-   /*
-    * Now simulate an add at an earlier date that the previous add.
-    * The conflict resolution should detect that this add must be kept.
-    * (a second time to make sure that historical information is kept...)
-    */
-   testModify(entry, hist, "description", ModificationType.ADD,
-              "older value", 2, false);
+    /*
+     * Add the uuid in the entry
+     */
+    Map<AttributeType, List<Attribute>> operationalAttributes = entry
+        .getOperationalAttributes();
 
-   /*
-    * Now simulate an add at a later date that the previous add.
-    * conflict resolution should keep it
-    */
-   testModify(entry, hist, "description", ModificationType.ADD,
-              "new value", 11, true);
- }
+    operationalAttributes.put(Historical.entryuuidAttrType, uuidList);
+    // Create the att values list of historicalAttr
+    String stringVal =
+      "ds-sync-hist:00000108b3a6cbb800000001:add:00000108b3a6cbb800000002";
+
+  AttributeValue val = new AttributeValue(Historical.historicalAttrType,
+      stringVal);
+    LinkedHashSet<AttributeValue> valuesHist =
+      new LinkedHashSet<AttributeValue>(1);
+    valuesHist.add(val);
+    ArrayList<Attribute> histList = new ArrayList<Attribute>(1);
+    Attribute histAttr = new Attribute(Historical.historicalAttrType,
+        "ds-sync-hist", valuesHist);
+    histList.add(histAttr);
+
+    //Add the historycal att in the entry
+    entry.putAttribute(Historical.historicalAttrType,histList) ;
+    
+    // load historical from the entry
+    
+    Historical hist = Historical.load(entry);
+
+    /*
+     * simulate a add of the description attribute done at time t10
+     */
+    testModify(entry, hist, "description", ModificationType.ADD,
+        "init value", 10, true);
+    /*
+     * Now simulate an add at an earlier date that the previous add. The
+     * conflict resolution should detect that this add must be kept.
+     */
+    testModify(entry, hist, "description", ModificationType.ADD,
+        "older value", 1, true);
+
+    /*
+     * Now simulate an add at an earlier date that the previous add. The
+     * conflict resolution should detect that this add must be kept. (a
+     * second time to make sure that historical information is kept...)
+     */
+    testModify(entry, hist, "description", ModificationType.ADD,
+        "older value", 2, false);
+
+    /*
+     * Now simulate an add at a later date that the previous add. conflict
+     * resolution should keep it
+     */
+    testModify(entry, hist, "description", ModificationType.ADD, "new value",
+        11, true);
+  }
 
   /*
    * helper function.
    */
-  private static void testModify(Entry entry,
+  private void testModify(Entry entry,
       Historical hist, String attrName,
       ModificationType modType, String value,
       int date, boolean keepChangeResult)
@@ -254,17 +449,27 @@
     List<Modification> mods = new ArrayList<Modification>();
     Modification mod = new Modification(modType, attr);
     mods.add(mod);
-
+    
     ModifyOperation modOp = new ModifyOperation(connection, 1, 1, null,
-                                              entry.getDN(), mods);
+        entry.getDN(), mods);
     ModifyContext ctx = new ModifyContext(t, "uniqueId");
     modOp.setAttachment(SYNCHROCONTEXT, ctx);
 
     hist.replayOperation(modOp, entry);
-
+    if (modType.intValue() == ModificationType.ADD.intValue())
+    {
+      AddOperation addOp = new AddOperation(connection, 1, 1, null, entry
+          .getDN(), entry.getObjectClasses(), entry.getUserAttributes(),
+          entry.getOperationalAttributes());
+      testHistorical(hist, addOp);
+    }
+    else
+    {
+      testHistoricalAndFake(hist, entry);
+    }
     /*
-     * The last older change should have been detected as conflicting
-     * and should be removed by the conflict resolution code.
+     * The last older change should have been detected as conflicting and
+     * should be removed by the conflict resolution code.
      */
     if (keepChangeResult)
     {
@@ -277,27 +482,4 @@
       assertEquals(0, mods.size());
     }
   }
-  
-  /**
-   * Set up the environment for performing the tests in this suite.
-   *
-   * @throws Exception
-   *           If the environment could not be set up.
-   */
-  @BeforeClass
-  public void setUp() throws Exception {
-    // This test suite depends on having the schema available.
-    SchemaFixture.FACTORY.setUp();
-  }
-
-  /**
-   * Tears down the environment for performing the tests in this suite.
-   *
-   * @throws Exception
-   *           If the environment could not be finalized.
-   */
-  @AfterClass
-  public void tearDown() throws Exception {
-    SchemaFixture.FACTORY.tearDown();
-  }
 }
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ServerStateTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ServerStateTest.java
new file mode 100644
index 0000000..40ab358
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/ServerStateTest.java
@@ -0,0 +1,134 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.synchronization;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.zip.DataFormatException;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+import org.opends.server.api.ClientConnection;
+import org.opends.server.core.AddOperation;
+import org.opends.server.core.DeleteOperation;
+import org.opends.server.core.DirectoryException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.ModifyDNOperation;
+import org.opends.server.core.ModifyOperation;
+import org.opends.server.core.Operation;
+import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.synchronization.ModifyMsg;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.Control;
+import org.opends.server.types.DN;
+import org.opends.server.types.Modification;
+import org.opends.server.types.ModificationType;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.RDN;
+import org.opends.server.util.TimeThread;
+
+import static org.opends.server.synchronization.OperationContext.*;
+
+/**
+ * Test the ServerState
+ */
+public class ServerStateTest extends SynchronizationTestCase
+{
+ 
+  /**
+   * Create ChangeNumber Data
+   */
+  @DataProvider(name = "changeNumberData")
+  public Object[][] createChangeNumberData() {
+    return new Object[][] {
+       {new ChangeNumber(1, (short) 0, (short) 1)},
+       {new ChangeNumber(TimeThread.getTime(), (short) 123, (short) 45)}
+    };
+  }
+
+  /**
+   * Create a new ServerState object
+   */
+  @Test(dataProvider = "changeNumberData")
+  public void serverStateTest(ChangeNumber cn)
+         throws Exception
+  {
+    // Check constructor
+    DN dn = DN.decode("cn=com");
+    ServerState serverState = new ServerState(dn) ;
+    
+    // Check Load
+    // serverState.loadState() ;
+    // TODO Check result
+    
+    // Check getServerStateDn()
+    DN returned_DN = serverState.getServerStateDn();
+    // TODO Check the returned DN  
+
+    // Check update
+    assertFalse(serverState.update(null));
+    assertTrue(serverState.update(cn));
+    assertFalse(serverState.update(cn));
+    ChangeNumber cn1, cn2, cn3;
+    cn1 = new ChangeNumber(cn.getTime()+1,cn.getSeqnum(),cn.getServerId());
+    cn2 = new ChangeNumber(cn1.getTime(),cn1.getSeqnum()+1,cn1.getServerId());
+    cn3 = new ChangeNumber(cn2.getTime(),cn2.getSeqnum(),(short)(cn2.getServerId()+1));
+    
+    assertTrue(serverState.update(cn1)) ;
+    assertTrue(serverState.update(cn2)) ;
+    assertTrue(serverState.update(cn3)) ;
+    
+    // Check toStringSet
+    ChangeNumber[] cns = {cn2,cn3};
+    Set<String> stringSet = serverState.toStringSet();
+    assertEquals(cns.length, stringSet.size()); 
+    // TODO Check the value
+    
+    // Check getMaxChangeNumber
+    assertEquals(cn2.compareTo(serverState.getMaxChangeNumber(cn2.getServerId())),0);
+    assertEquals(cn3.compareTo(serverState.getMaxChangeNumber(cn3.getServerId())),0);
+    
+    // Check the toString
+    String stringRep = serverState.toString() ;
+    // TODO Check the value
+    
+    // Check getBytes
+    byte[] b = serverState.getBytes();
+    ServerState generatedServerState = new ServerState(b,0,b.length -1) ;
+    assertEquals(b, generatedServerState.getBytes()) ;
+    
+  }
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SyncMessagesTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SyncMessagesTest.java
new file mode 100644
index 0000000..faea894
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SyncMessagesTest.java
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.synchronization;
+
+import java.lang.reflect.Field;
+
+import org.opends.server.messages.MessageHandler;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+
+/**
+ * Test of ValueInfo
+ */
+public class SyncMessagesTest extends SynchronizationTestCase
+{
+  /**
+   * Create a ValueInfo and check the methods
+   */
+  @Test()
+  public void synchroMessagesTest()
+         throws Exception
+  {
+    SynchMessages.registerMessages() ;
+    Field fields[] = SynchMessages.class.getFields() ;
+    SynchMessages synMsg = new SynchMessages() ;
+    for (Field f : fields)
+    {
+      if (f.getClass().equals(Integer.class))
+      {
+        // Get the id
+        String msg = MessageHandler.getMessage(f.getInt(synMsg));
+        assertFalse(msg.startsWith("Unknown message for message ID"));
+      }
+    }
+  }
+
+
+}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationMsgTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationMsgTest.java
index bcc98c9..3296cdb 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationMsgTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationMsgTest.java
@@ -27,6 +27,7 @@
 package org.opends.server.synchronization;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.zip.DataFormatException;
@@ -35,6 +36,8 @@
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 
+import org.opends.server.api.ClientConnection;
+import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.DirectoryException;
 import org.opends.server.core.DirectoryServer;
@@ -49,6 +52,7 @@
 import org.opends.server.types.DN;
 import org.opends.server.types.Modification;
 import org.opends.server.types.ModificationType;
+import org.opends.server.types.ObjectClass;
 import org.opends.server.types.RDN;
 import org.opends.server.util.TimeThread;
 
@@ -132,7 +136,9 @@
     DN dn = DN.decode(rawdn);
     InternalClientConnection connection = new InternalClientConnection();
     ModifyMsg msg = new ModifyMsg(changeNumber, dn, mods, "fakeuniqueid");
-    ModifyMsg generatedMsg = new ModifyMsg(msg.getBytes());
+    ModifyMsg generatedMsg = (ModifyMsg) SynchronizationMessage
+        .generateMsg(msg.getBytes());
+    
 
     assertEquals(msg.getChangeNumber(), generatedMsg.getChangeNumber());
 
@@ -141,19 +147,66 @@
 
     assertEquals(op.getClass(), ModifyOperation.class);
     assertEquals(generatedOperation.getClass(), ModifyOperation.class);
-
+    
     ModifyOperation mod1 = (ModifyOperation) op;
     ModifyOperation mod2 = (ModifyOperation) generatedOperation;
 
     assertEquals(mod1.getRawEntryDN(), mod2.getRawEntryDN());
     assertEquals( mod1.getAttachment(SYNCHROCONTEXT),
                   mod2.getAttachment(SYNCHROCONTEXT));
-
     /*
      * TODO : test that the generated mod equals the original mod.
      */
-  }
 
+    // Check pending change
+    testPendingChange(changeNumber,op,msg);
+  }
+  
+  /**
+   * Create a Update Message from the data provided above.
+   * The call getBytes() to test the encoding of the Msg and
+   * create another ModifyMsg from the encoded byte array.
+   * Finally test that both Msg matches.
+   */
+  @Test(dataProvider = "modifyEncodeDecode")
+  public void updateMsgTest(ChangeNumber changeNumber,
+                               String rawdn, List<Modification> mods)
+         throws Exception
+  {
+    DN dn = DN.decode(rawdn);
+    InternalClientConnection connection = new InternalClientConnection();
+    ModifyMsg msg = new ModifyMsg(changeNumber, dn, mods, "fakeuniqueid");;
+    
+    // Check uuid
+    assertEquals("fakeuniqueid", msg.getUniqueId());
+    
+    // Check isAssured
+    assertFalse(msg.isAssured());
+    msg.setAssured();
+    assertTrue(msg.isAssured());
+    
+    // Check equals
+    ModifyMsg generatedMsg = (ModifyMsg) SynchronizationMessage
+        .generateMsg(msg.getBytes());
+    assertFalse(msg.equals(null));
+    assertFalse(msg.equals(new Object()));
+    assertTrue(msg.equals(generatedMsg));
+    
+    // Check hashCode
+    assertEquals(msg.hashCode(), generatedMsg.hashCode());
+    
+    // Check compareTo
+    assertEquals(msg.compareTo(generatedMsg), 0);
+    
+    // Check Get / Set DN
+    assertTrue(dn.equals(DN.decode(msg.getDn())));
+    
+    String fakeDN = "cn=fake cn";
+    msg.setDn(fakeDN) ;
+    assertEquals(msg.getDn(), fakeDN) ;
+
+  }
+  
   /**
    * Build some data for the DeleteMsg test below.
    * @throws DirectoryException
@@ -183,7 +236,10 @@
       (short) 123, (short) 45);
     op.setAttachment(SYNCHROCONTEXT, new DeleteContext(cn, "uniqueid"));
     DeleteMsg msg = new DeleteMsg(op);
-    DeleteMsg generatedMsg = new DeleteMsg(msg.getBytes());
+    DeleteMsg generatedMsg = (DeleteMsg) SynchronizationMessage
+        .generateMsg(msg.getBytes());
+    
+    assertEquals(msg.toString(), generatedMsg.toString());
 
     assertEquals(msg.getChangeNumber(), generatedMsg.getChangeNumber());
 
@@ -194,6 +250,10 @@
     DeleteOperation mod2 = (DeleteOperation) generatedOperation;
 
     assertEquals(op.getRawEntryDN(), mod2.getRawEntryDN());
+    
+    // Create an update message from this op
+    DeleteMsg updateMsg = (DeleteMsg) UpdateMessage.generateMsg(op, true);
+    assertEquals(msg.getChangeNumber(), updateMsg.getChangeNumber());
   }
 
   @DataProvider(name = "modifyDnEncodeDecode")
@@ -225,7 +285,8 @@
     op.setAttachment(SYNCHROCONTEXT,
         new ModifyDnContext(cn, "uniqueid", "newparentId"));
     ModifyDNMsg msg = new ModifyDNMsg(op);
-    ModifyDNMsg generatedMsg = new ModifyDNMsg(msg.getBytes());
+    ModifyDNMsg generatedMsg = (ModifyDNMsg) SynchronizationMessage
+        .generateMsg(msg.getBytes());
     Operation generatedOperation = generatedMsg.createOperation(connection);
     ModifyDNOperation mod2 = (ModifyDNOperation) generatedOperation;
 
@@ -234,6 +295,10 @@
     assertEquals(op.getRawNewRDN(), mod2.getRawNewRDN());
     assertEquals(op.deleteOldRDN(), mod2.deleteOldRDN());
     assertEquals(op.getRawNewSuperior(), mod2.getRawNewSuperior());
+    
+    // Create an update message from this op
+    ModifyDNMsg updateMsg = (ModifyDNMsg) UpdateMessage.generateMsg(op, true);
+    assertEquals(msg.getChangeNumber(), updateMsg.getChangeNumber());
   }
 
   @DataProvider(name = "addEncodeDecode")
@@ -255,6 +320,10 @@
     Attribute objectClass =
       new Attribute(DirectoryServer.getObjectClassAttributeType(),
         "objectClass", ocValues);
+    HashMap<ObjectClass,String> objectClassList= 
+      new HashMap<ObjectClass,String>();
+    objectClassList.put(DirectoryServer.getObjectClass("organization"),
+        "organization");
 
     AttributeType org = DirectoryServer.getAttributeType("o", true);
     ArrayList<Attribute> userAttributes = new ArrayList<Attribute>(1);
@@ -262,6 +331,10 @@
     values.add(new AttributeValue(org, "com"));
     Attribute attr = new Attribute(org, "o", values);
     userAttributes.add(attr);
+    HashMap<AttributeType,List<Attribute>> userAttList= 
+      new HashMap<AttributeType,List<Attribute>>();
+    userAttList.put(org,userAttributes);
+
 
     ArrayList<Attribute> operationalAttributes = new ArrayList<Attribute>(1);
     org = DirectoryServer.getAttributeType("creatorsname", true);
@@ -269,6 +342,9 @@
     values.add(new AttributeValue(org, "dc=creator"));
     attr = new Attribute(org, "creatorsname", values);
     operationalAttributes.add(attr);
+    HashMap<AttributeType,List<Attribute>> opList= 
+      new HashMap<AttributeType,List<Attribute>>();
+    opList.put(org,operationalAttributes);
 
     ChangeNumber cn = new ChangeNumber(TimeThread.getTime(),
                                       (short) 123, (short) 45);
@@ -276,9 +352,42 @@
     AddMsg msg = new AddMsg(cn, rawDN, "thisIsaUniqueID", "parentUniqueId",
                             objectClass, userAttributes,
                             operationalAttributes);
-    AddMsg generatedMsg = new AddMsg(msg.getBytes());
+    AddMsg generatedMsg = (AddMsg) SynchronizationMessage.generateMsg(msg
+        .getBytes());
     assertEquals(msg.getBytes(), generatedMsg.getBytes());
+    assertEquals(msg.toString(), generatedMsg.toString());
     // TODO : should test that generated attributes match original attributes.
+    
+    // Create an new Add Operation from the current addMsg
+    InternalClientConnection connection = new InternalClientConnection();
+    AddOperation addOp = msg.createOperation(connection, rawDN) ;
+    // TODO : should test that generated attributes match original attributes.
+    // List<LDAPAttribute> rawAtt = addOp.getRawAttributes();
+    
+    
+    assertEquals(msg.getBytes(), generatedMsg.getBytes());
+    assertEquals(msg.toString(), generatedMsg.toString());
+    
+    //Create an Add operation and generate and Add msg from it
+    DN dn = DN.decode(rawDN);
+
+    addOp = new AddOperation((ClientConnection) connection,
+        (long) 1, 1, null, dn, objectClassList, userAttList, opList);
+    OperationContext opCtx = new AddContext(cn, "thisIsaUniqueID",
+        "parentUniqueId");
+    addOp.setAttachment(SYNCHROCONTEXT, opCtx);
+    
+    generatedMsg = new AddMsg(addOp);
+    assertEquals(msg.getBytes(), generatedMsg.getBytes());
+    assertEquals(msg.toString(), generatedMsg.toString());
+    // TODO : should test that generated attributes match original attributes.
+    
+    
+    // Create an update message from this op
+    AddMsg updateMsg = (AddMsg) UpdateMessage.generateMsg(addOp, true);
+    assertEquals(msg.getChangeNumber(), updateMsg.getChangeNumber());
+
+    
   }
 
   /**
@@ -328,6 +437,37 @@
     }
 
     // Check that retrieved CN is OK
-    msg2 = new  AckMessage(msg1.getBytes());
+    msg2 = (AckMessage) SynchronizationMessage.generateMsg(msg1.getBytes());
   }
+  
+  /**
+   * Test PendingChange
+   */
+  private void testPendingChange(ChangeNumber cn, Operation op, SynchronizationMessage msg)
+  {
+    if (! (msg instanceof UpdateMessage))
+    {
+      return ;
+    }
+    UpdateMessage updateMsg = (UpdateMessage) msg;
+    PendingChange pendingChange = new PendingChange(cn,null,null);
+    
+    pendingChange.setCommitted(false);
+    assertFalse(pendingChange.isCommitted()) ;
+    pendingChange.setCommitted(true);
+    assertTrue(pendingChange.isCommitted()) ;
+    
+
+    assertTrue(cn.compareTo(pendingChange.getChangeNumber()) == 0);
+    
+    assertEquals(pendingChange.getMsg(), null) ;
+    pendingChange.setMsg(updateMsg);
+    assertEquals(updateMsg.getBytes(), pendingChange.getMsg().getBytes());
+    
+    assertEquals(pendingChange.getOp(), null) ;
+    pendingChange.setOp(op);
+    assertEquals(op.getClass(), op.getClass());
+    
+  }
+
 }
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationTestCase.java
index ed677c1..5ac1eb8 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/synchronization/SynchronizationTestCase.java
@@ -27,11 +27,44 @@
 package org.opends.server.synchronization;
 
 import org.opends.server.DirectoryServerTestCase;
+import org.opends.server.SchemaFixture;
 import org.testng.annotations.Test;
 
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+
 /**
  * An abstract class that all synchronization unit test should extend. 
  */
 @Test(groups = { "precommit", "synchronization" })
 public abstract class SynchronizationTestCase extends DirectoryServerTestCase
-{}
+{
+  
+
+  /**
+   * Tears down the environment for performing the tests in this suite.
+   * 
+   * @throws Exception
+   *         If the environment could not be finalized.
+   */
+  @AfterClass
+  public void tearDown() throws Exception
+  {
+    SchemaFixture.FACTORY.tearDown();
+  }
+  
+
+  /**
+   * Set up the environment for performing the tests in this suite.
+   * 
+   * @throws Exception
+   *         If the environment could not be set up.
+   */
+  @BeforeClass
+  public void setUp() throws Exception
+  {
+    // This test suite depends on having the schema available.
+    SchemaFixture.FACTORY.setUp();
+  }
+
+}

--
Gitblit v1.10.0