From 6d27dfe96010d05786e9a5441e1790c04500b99e Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Sat, 23 Sep 2006 23:25:24 +0000
Subject: [PATCH] Add test cases for the error log account status notification handler, the traditional work queue, and the cancel extended operation.

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TraditionalWorkQueueTestCase.java                     |  132 ++++++
 opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java                  |  860 ++++++++++++++++++++++++++++++++++++++++
 opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java |  224 ++++++++++
 3 files changed, 1,216 insertions(+), 0 deletions(-)

diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java
new file mode 100644
index 0000000..5e205ed
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CancelExtendedOperationTestCase.java
@@ -0,0 +1,860 @@
+/*
+ * 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.extensions;
+
+
+
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.core.AddOperation;
+import org.opends.server.plugins.DelayPreOpPlugin;
+import org.opends.server.protocols.asn1.ASN1Element;
+import org.opends.server.protocols.asn1.ASN1Integer;
+import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.protocols.asn1.ASN1Reader;
+import org.opends.server.protocols.asn1.ASN1Sequence;
+import org.opends.server.protocols.asn1.ASN1Writer;
+import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.protocols.ldap.AddRequestProtocolOp;
+import org.opends.server.protocols.ldap.AddResponseProtocolOp;
+import org.opends.server.protocols.ldap.BindRequestProtocolOp;
+import org.opends.server.protocols.ldap.BindResponseProtocolOp;
+import org.opends.server.protocols.ldap.CompareRequestProtocolOp;
+import org.opends.server.protocols.ldap.CompareResponseProtocolOp;
+import org.opends.server.protocols.ldap.DeleteRequestProtocolOp;
+import org.opends.server.protocols.ldap.DeleteResponseProtocolOp;
+import org.opends.server.protocols.ldap.ExtendedRequestProtocolOp;
+import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.protocols.ldap.LDAPFilter;
+import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.protocols.ldap.LDAPModification;
+import org.opends.server.protocols.ldap.LDAPResultCode;
+import org.opends.server.protocols.ldap.ModifyRequestProtocolOp;
+import org.opends.server.protocols.ldap.ModifyResponseProtocolOp;
+import org.opends.server.protocols.ldap.ModifyDNRequestProtocolOp;
+import org.opends.server.protocols.ldap.ModifyDNResponseProtocolOp;
+import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
+import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.Control;
+import org.opends.server.types.DereferencePolicy;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+import org.opends.server.types.Modification;
+import org.opends.server.types.ModificationType;
+import org.opends.server.types.ResultCode;
+import org.opends.server.types.SearchScope;
+
+import static org.testng.Assert.*;
+
+import static org.opends.server.protocols.ldap.LDAPConstants.*;
+import static org.opends.server.util.ServerConstants.*;
+
+
+
+/**
+ * A set of test cases for the cancel extended oepration handler.
+ */
+public class CancelExtendedOperationTestCase
+       extends ExtensionsTestCase
+{
+  /**
+   * Ensures that the Directory Server is running, and enables the delay plugin
+   * so that new requests will be artificially delayed.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @BeforeClass()
+  public void startServer()
+         throws Exception
+  {
+    TestCaseUtils.startServer();
+  }
+
+
+
+  /**
+   * Tests the ability to cancel an add operation.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelAddOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create an add request and send it to the server.  Make sure to include
+    // the delay request control so it won't complete before we can send the
+    // cancel request.
+    ArrayList<LDAPAttribute> attributes = new ArrayList<LDAPAttribute>();
+
+    ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>(2);
+    values.add(new ASN1OctetString("top"));
+    values.add(new ASN1OctetString("organizationalUnit"));
+    attributes.add(new LDAPAttribute("objectClass", values));
+
+    values = new ArrayList<ASN1OctetString>(1);
+    values.add(new ASN1OctetString("People"));
+    attributes.add(new LDAPAttribute("ou", values));
+
+    AddRequestProtocolOp addRequest =
+         new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
+                                  attributes);
+    message = new LDAPMessage(2, addRequest,
+                       DelayPreOpPlugin.createDelayLDAPControlList(5000));
+    writer.writeElement(message.encode());
+
+
+    // Create a cancel request and send it to the server.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read two response messages from the server.  One should be an add
+    // response and the other should be an extended response.  They should both
+    // have a result code of "cancelled".
+    for (int i=0; i < 2; i++)
+    {
+      message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+      switch (message.getProtocolOpType())
+      {
+        case OP_TYPE_ADD_RESPONSE:
+          AddResponseProtocolOp addResponse =
+               message.getAddResponseProtocolOp();
+          assertEquals(addResponse.getResultCode(), LDAPResultCode.CANCELED);
+          break;
+        case OP_TYPE_EXTENDED_RESPONSE:
+          ExtendedResponseProtocolOp extendedResponse =
+               message.getExtendedResponseProtocolOp();
+          assertEquals(extendedResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        default:
+      }
+    }
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests the ability to cancel a compare operation.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelCompareOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a compare request and send it to the server.  Make sure to include
+    // the delay request control so it won't complete before we can send the
+    // cancel request.
+    CompareRequestProtocolOp compareRequest =
+         new CompareRequestProtocolOp(new ASN1OctetString("o=test"), "o",
+                                      new ASN1OctetString("test"));
+    message = new LDAPMessage(2, compareRequest,
+                       DelayPreOpPlugin.createDelayLDAPControlList(5000));
+    writer.writeElement(message.encode());
+
+
+    // Create a cancel request and send it to the server.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read two response messages from the server.  One should be a compare
+    // response and the other should be an extended response.  They should both
+    // have a result code of "cancelled".
+    for (int i=0; i < 2; i++)
+    {
+      message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+      switch (message.getProtocolOpType())
+      {
+        case OP_TYPE_COMPARE_RESPONSE:
+          CompareResponseProtocolOp compareResponse =
+               message.getCompareResponseProtocolOp();
+          assertEquals(compareResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        case OP_TYPE_EXTENDED_RESPONSE:
+          ExtendedResponseProtocolOp extendedResponse =
+               message.getExtendedResponseProtocolOp();
+          assertEquals(extendedResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        default:
+      }
+    }
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests the ability to cancel a delete operation.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelDeleteOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Add an entry to the server that we can delete.
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: device",
+         "cn: test");
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+    AddOperation addOperation =
+         conn.processAdd(e.getDN(), e.getObjectClasses(), e.getUserAttributes(),
+                         e.getOperationalAttributes());
+    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a delete request and send it to the server.  Make sure to include
+    // the delay request control so it won't complete before we can send the
+    // cancel request.
+    DeleteRequestProtocolOp deleteRequest =
+         new DeleteRequestProtocolOp(new ASN1OctetString("cn=test,o=test"));
+    message = new LDAPMessage(2, deleteRequest,
+                       DelayPreOpPlugin.createDelayLDAPControlList(5000));
+    writer.writeElement(message.encode());
+
+
+    // Create a cancel request and send it to the server.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read two response messages from the server.  One should be a delete
+    // response and the other should be an extended response.  They should both
+    // have a result code of "cancelled".
+    for (int i=0; i < 2; i++)
+    {
+      message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+      switch (message.getProtocolOpType())
+      {
+        case OP_TYPE_DELETE_RESPONSE:
+          DeleteResponseProtocolOp deleteResponse =
+               message.getDeleteResponseProtocolOp();
+          assertEquals(deleteResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        case OP_TYPE_EXTENDED_RESPONSE:
+          ExtendedResponseProtocolOp extendedResponse =
+               message.getExtendedResponseProtocolOp();
+          assertEquals(extendedResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        default:
+      }
+    }
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests the ability to cancel an extended operation.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelExtendedOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a "Who Am I?" extended oepration and send it to the server.  Make
+    // sure to include the delay request control so it won't complete before we
+    // can send the cancel request.
+    ExtendedRequestProtocolOp whoAmIRequest =
+         new ExtendedRequestProtocolOp(OID_WHO_AM_I_REQUEST, null);
+    message = new LDAPMessage(2, whoAmIRequest,
+                       DelayPreOpPlugin.createDelayLDAPControlList(5000));
+    writer.writeElement(message.encode());
+
+
+    // Create a cancel request and send it to the server.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read two response messages from the server.  They should both be extended
+    // responses and they should both have result codes of "cancelled".
+    for (int i=0; i < 2; i++)
+    {
+      message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+      ExtendedResponseProtocolOp extendedResponse =
+           message.getExtendedResponseProtocolOp();
+      assertEquals(extendedResponse.getResultCode(), LDAPResultCode.CANCELED);
+    }
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests the ability to cancel a modify operation.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelModifyOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a modify request and send it to the server.  Make sure to include
+    // the delay request control so it won't complete before we can send the
+    // cancel request.
+    ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>(1);
+    values.add(new ASN1OctetString("foo"));
+
+    ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>(1);
+    mods.add(new LDAPModification(ModificationType.REPLACE,
+                                  new LDAPAttribute("description", values)));
+
+    ModifyRequestProtocolOp modifyRequest =
+         new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods);
+    message = new LDAPMessage(2, modifyRequest,
+                       DelayPreOpPlugin.createDelayLDAPControlList(5000));
+    writer.writeElement(message.encode());
+
+
+    // Create a cancel request and send it to the server.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read two response messages from the server.  One should be a modify
+    // response and the other should be an extended response.  They should both
+    // have a result code of "cancelled".
+    for (int i=0; i < 2; i++)
+    {
+      message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+      switch (message.getProtocolOpType())
+      {
+        case OP_TYPE_MODIFY_RESPONSE:
+          ModifyResponseProtocolOp modifyResponse =
+               message.getModifyResponseProtocolOp();
+          assertEquals(modifyResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        case OP_TYPE_EXTENDED_RESPONSE:
+          ExtendedResponseProtocolOp extendedResponse =
+               message.getExtendedResponseProtocolOp();
+          assertEquals(extendedResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        default:
+      }
+    }
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests the ability to cancel a modify DN operation.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelModifyDNOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Add an entry to the server that we can rename.
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: device",
+         "cn: test");
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+    AddOperation addOperation =
+         conn.processAdd(e.getDN(), e.getObjectClasses(), e.getUserAttributes(),
+                         e.getOperationalAttributes());
+    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a modify DN request and send it to the server.  Make sure to
+    // include the delay request control so it won't complete before we can send
+    // the cancel request.
+    ModifyDNRequestProtocolOp modifyDNRequest =
+         new ModifyDNRequestProtocolOp(new ASN1OctetString("cn=test,o=test"),
+                                       new ASN1OctetString("cn=test2"), true);
+    message = new LDAPMessage(2, modifyDNRequest,
+                       DelayPreOpPlugin.createDelayLDAPControlList(5000));
+    writer.writeElement(message.encode());
+
+
+    // Create a cancel request and send it to the server.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read two response messages from the server.  One should be a modify DN
+    // response and the other should be an extended response.  They should both
+    // have a result code of "cancelled".
+    for (int i=0; i < 2; i++)
+    {
+      message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+      switch (message.getProtocolOpType())
+      {
+        case OP_TYPE_MODIFY_DN_RESPONSE:
+          ModifyDNResponseProtocolOp modifyDNResponse =
+               message.getModifyDNResponseProtocolOp();
+          assertEquals(modifyDNResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        case OP_TYPE_EXTENDED_RESPONSE:
+          ExtendedResponseProtocolOp extendedResponse =
+               message.getExtendedResponseProtocolOp();
+          assertEquals(extendedResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        default:
+      }
+    }
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests the ability to cancel a search operation.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelSearchOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a search request and send it to the server.  Make sure to include
+    // the delay request control so it won't complete before we can send the
+    // cancel request.
+    SearchRequestProtocolOp searchRequest =
+         new SearchRequestProtocolOp(new ASN1OctetString("o=test"),
+                                     SearchScope.BASE_OBJECT,
+                                     DereferencePolicy.NEVER_DEREF_ALIASES, 0,
+                                     0, false,
+                                     LDAPFilter.decode("(match=false)"),
+                                     new LinkedHashSet<String>());
+    message = new LDAPMessage(2, searchRequest,
+                       DelayPreOpPlugin.createDelayLDAPControlList(5000));
+    writer.writeElement(message.encode());
+
+
+    // Create a cancel request and send it to the server.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read two response messages from the server.  One should be a search
+    // result done and the other should be an extended response.  They should
+    // both have a result code of "cancelled".
+    for (int i=0; i < 2; i++)
+    {
+      message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+      switch (message.getProtocolOpType())
+      {
+        case OP_TYPE_SEARCH_RESULT_DONE:
+          SearchResultDoneProtocolOp searchResultDone =
+               message.getSearchResultDoneProtocolOp();
+          assertEquals(searchResultDone.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        case OP_TYPE_EXTENDED_RESPONSE:
+          ExtendedResponseProtocolOp extendedResponse =
+               message.getExtendedResponseProtocolOp();
+          assertEquals(extendedResponse.getResultCode(),
+                       LDAPResultCode.CANCELED);
+          break;
+        default:
+      }
+    }
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests the attempt to cancel an operation that doesn't exist.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelNoSuchOperation()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a cancel request and send it to the server.
+    ArrayList<ASN1Element> sequenceElements = new ArrayList<ASN1Element>(1);
+    sequenceElements.add(new ASN1Integer(2));
+    ASN1Sequence valueSequence = new ASN1Sequence(sequenceElements);
+    ASN1OctetString extendedValue = new ASN1OctetString(valueSequence.encode());
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, extendedValue);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read the response message from the server.  It should be an extended
+    // response with a result code of "no such operation".
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    ExtendedResponseProtocolOp extendedResponse =
+         message.getExtendedResponseProtocolOp();
+    assertEquals(extendedResponse.getResultCode(),
+                 LDAPResultCode.NO_SUCH_OPERATION);
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests sending a cancel request with no request value.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelNoValue()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a cancel request and send it to the server.
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST, null);
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read the response message from the server.  It should be an extended
+    // response with a result code of "no such operation".
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    ExtendedResponseProtocolOp extendedResponse =
+         message.getExtendedResponseProtocolOp();
+    assertEquals(extendedResponse.getResultCode(),
+                 LDAPResultCode.PROTOCOL_ERROR);
+
+    socket.close();
+  }
+
+
+
+  /**
+   * Tests sending a cancel request with a malformed request value.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCancelMalformedValue()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+
+    // Create a new connection to the Directory Server and authenticate as
+    // the Directory Manager.
+    Socket socket = new Socket("127.0.0.1",
+                               (int) TestCaseUtils.getServerLdapPort());
+    ASN1Reader reader = new ASN1Reader(socket);
+    ASN1Writer writer = new ASN1Writer(socket);
+
+    BindRequestProtocolOp bindRequest =
+         new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+                                   3, new ASN1OctetString("password"));
+    LDAPMessage message = new LDAPMessage(1, bindRequest);
+    writer.writeElement(message.encode());
+
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
+    assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
+
+
+    // Create a cancel request and send it to the server.
+    ExtendedRequestProtocolOp extendedRequest =
+         new ExtendedRequestProtocolOp(OID_CANCEL_REQUEST,
+                                       new ASN1OctetString("malformed"));
+    message = new LDAPMessage(3, extendedRequest);
+    writer.writeElement(message.encode());
+
+
+    // Read the response message from the server.  It should be an extended
+    // response with a result code of "no such operation".
+    message = LDAPMessage.decode(reader.readElement().decodeAsSequence());
+    ExtendedResponseProtocolOp extendedResponse =
+         message.getExtendedResponseProtocolOp();
+    assertEquals(extendedResponse.getResultCode(),
+                 LDAPResultCode.PROTOCOL_ERROR);
+
+    socket.close();
+  }
+}
+
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java
new file mode 100644
index 0000000..303b454
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java
@@ -0,0 +1,224 @@
+/*
+ * 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.extensions;
+
+
+
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.api.AccountStatusNotificationHandler;
+import org.opends.server.config.ConfigEntry;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.InitializationException;
+import org.opends.server.types.AccountStatusNotificationType;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+
+import static org.testng.Assert.*;
+
+
+
+/**
+ * A set of test cases for the error log account status notification handler.
+ */
+public class ErrorLogAccountStatusNotificationHandlerTestCase
+       extends ExtensionsTestCase
+{
+  /**
+   * Ensures that the Directory Server is running.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @BeforeClass()
+  public void startServer()
+         throws Exception
+  {
+    TestCaseUtils.startServer();
+  }
+
+
+
+  /**
+   * Retrieves a set of invalid configuration entries that should cause the
+   * notification handler initialization to fail.
+   *
+   * @return  A set of invalid configuration entries that should cause the
+   *          notification handler initialization to fail.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @DataProvider(name = "invalidConfigs")
+  public Object[][] getInvalidConfigs()
+         throws Exception
+  {
+    List<Entry> entries = TestCaseUtils.makeEntries(
+         "dn: cn=Error Log Handler,cn=Account Status Notification Handlers," +
+              "cn=config",
+         "objectClass: top",
+         "objectClass: ds-cfg-account-status-notification-handler",
+         "objectClass: ds-cfg-error-log-account-status-notification-handler",
+         "cn: Error Log Handler",
+         "ds-cfg-account-status-notification-handler-class: org.opends." +
+              "server.extensions.ErrorLogAccountStatusNotificationHandler",
+         "ds-cfg-account-status-notification-handler-enabled: true",
+         "",
+         "dn: cn=Error Log Handler,cn=Account Status Notification Handlers," +
+              "cn=config",
+         "objectClass: top",
+         "objectClass: ds-cfg-account-status-notification-handler",
+         "objectClass: ds-cfg-error-log-account-status-notification-handler",
+         "cn: Error Log Handler",
+         "ds-cfg-account-status-notification-handler-class: org.opends." +
+              "server.extensions.ErrorLogAccountStatusNotificationHandler",
+         "ds-cfg-account-status-notification-handler-enabled: true",
+         "ds-cfg-account-status-notification-type: invalid",
+         "",
+         "dn: cn=Error Log Handler,cn=Account Status Notification Handlers," +
+              "cn=config",
+         "objectClass: top",
+         "objectClass: ds-cfg-account-status-notification-handler",
+         "objectClass: ds-cfg-error-log-account-status-notification-handler",
+         "cn: Error Log Handler",
+         "ds-cfg-account-status-notification-handler-class: org.opends." +
+              "server.extensions.ErrorLogAccountStatusNotificationHandler",
+         "ds-cfg-account-status-notification-handler-enabled: true",
+         "ds-cfg-account-status-notification-type: password-reset",
+         "ds-cfg-account-status-notification-type: invalid");
+
+
+    Object[][] configEntries = new Object[entries.size()][1];
+    for (int i=0; i < configEntries.length; i++)
+    {
+      configEntries[i] = new Object[] { entries.get(i) };
+    }
+
+    return configEntries;
+  }
+
+
+
+  /**
+   * Tests to ensure that the notification handler initialization fails with an
+   * invalid configuration.
+   *
+   * @param  e  The configuration entry to use to initialize the account status
+   *            notificaton handler.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test(dataProvider = "invalidConfigs",
+        expectedExceptions = { ConfigException.class,
+                               InitializationException.class })
+  public void testInalidConfigs(Entry e)
+         throws Exception
+  {
+    DN parentDN =
+            DN.decode("cn=Account Status Notification Handlers,cn=config");
+    ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
+    ConfigEntry configEntry = new ConfigEntry(e, parentEntry);
+
+    ErrorLogAccountStatusNotificationHandler handler =
+         new ErrorLogAccountStatusNotificationHandler();
+    handler.initializeStatusNotificationHandler(configEntry);
+  }
+
+
+
+  /**
+   * Tests to ensure that the error log account status notification handler is
+   * configured and enabled within the Directory Server.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testHandlerEnabled()
+         throws Exception
+  {
+    String dnStr = "cn=Error Log Handler,cn=Account Status Notification " +
+                        "Handlers,cn=config";
+    DN handlerDN = DN.decode(dnStr);
+    AccountStatusNotificationHandler handler =
+         DirectoryServer.getAccountStatusNotificationHandler(handlerDN);
+    assertNotNull(handler);
+    assertTrue(handler instanceof ErrorLogAccountStatusNotificationHandler);
+  }
+
+
+
+  /**
+   * Retrieves the set of valid notification types that may be used with an
+   * account status notification handler.
+   *
+   * @return  The set of valid notification types that may be used with an
+   *          account status notification handler.
+   */
+  @DataProvider(name = "notificationTypes")
+  public Object[][] getNotificationTypes()
+  {
+    AccountStatusNotificationType[] notificationTypes =
+         AccountStatusNotificationType.values();
+
+    Object[][] typeArray = new Object[notificationTypes.length][1];
+    for (int i=0; i < notificationTypes.length; i++)
+    {
+      typeArray[i] = new Object[] { notificationTypes[i] };
+    }
+
+    return typeArray;
+  }
+
+
+
+  /**
+   * Tests the <CODE>handleStatusNotification</CODE> method.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test(dataProvider = "notificationTypes")
+  public void testHandleStatusNotification(
+                   AccountStatusNotificationType notificationType)
+         throws Exception
+  {
+    String dnStr = "cn=Error Log Handler,cn=Account Status Notification " +
+                        "Handlers,cn=config";
+    DN handlerDN = DN.decode(dnStr);
+    AccountStatusNotificationHandler handler =
+         DirectoryServer.getAccountStatusNotificationHandler(handlerDN);
+    assertNotNull(handler);
+
+    DN userDN = DN.decode("uid=test.user,o=test");
+    handler.handleStatusNotification(notificationType, userDN, 1,
+                                     "Test Notification");
+  }
+}
+
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TraditionalWorkQueueTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TraditionalWorkQueueTestCase.java
new file mode 100644
index 0000000..61dd634
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TraditionalWorkQueueTestCase.java
@@ -0,0 +1,132 @@
+/*
+ * 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.extensions;
+
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.api.WorkQueue;
+import org.opends.server.config.ConfigEntry;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.ModifyOperation;
+import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.Modification;
+import org.opends.server.types.ModificationType;
+import org.opends.server.types.DN;
+import org.opends.server.tools.LDAPSearch;
+import org.opends.server.types.ResultCode;
+
+import static org.testng.Assert.*;
+
+
+
+/**
+ * A set of test cases for the traditional work queue.
+ */
+public class TraditionalWorkQueueTestCase
+       extends ExtensionsTestCase
+{
+  /**
+   * Ensures that the Directory Server is running.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @BeforeClass()
+  public void startServer()
+         throws Exception
+  {
+    TestCaseUtils.startServer();
+  }
+
+
+
+  /**
+   * Tests to ensure that the work queue is configured and enabled within the
+   * Directory Server.
+   */
+  @Test()
+  public void testWorkQueueEnabled()
+  {
+    WorkQueue workQueue = DirectoryServer.getWorkQueue();
+    assertNotNull(workQueue);
+    assertTrue(workQueue instanceof TraditionalWorkQueue);
+  }
+
+
+
+  /**
+   * Verifies that the number of worker threads can be altered on the fly.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  public void testChangingNumWorkerThreads()
+         throws Exception
+  {
+    DN     dn   = DN.decode("cn=Work Queue,cn=config");
+    String attr = "ds-cfg-num-worker-threads";
+    ArrayList<Modification> mods = new ArrayList<Modification>();
+    mods.add(new Modification(ModificationType.REPLACE,
+                              new Attribute(attr, "30")));
+
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+    ModifyOperation modifyOperation = conn.processModify(dn, mods);
+    assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
+
+    mods.clear();
+    mods.add(new Modification(ModificationType.REPLACE,
+                              new Attribute(attr, "24")));
+    modifyOperation = conn.processModify(dn, mods);
+    assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
+
+
+    // Perform seven external searches so that we can make sure that the
+    // unneeded worker threads can die off.
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-b", "",
+      "-s", "base",
+      "(objectClass=*)",
+      "1.1"
+    };
+
+    for (int i=0; i < 7; i++)
+    {
+      assertEquals(LDAPSearch.mainSearch(args, false, null, null), 0);
+    }
+  }
+}
+

--
Gitblit v1.10.0