From 8be8fb738c2abe5b5e85c96f3dd6d29a3f9784fb Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Fri, 13 Oct 2006 02:58:54 +0000
Subject: [PATCH] Add additional test cases for add, delete, and modify operations.
---
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java | 122 +++++++
opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperation.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperation.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/Operation.java | 16
opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/CompareOperation.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperation.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java | 15
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java | 340 ++++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/core/UnbindOperation.java | 15
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java | 358 +++++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java | 15
14 files changed, 986 insertions(+), 0 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperation.java
index 0471a6f..8e6aff3 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperation.java
@@ -417,6 +417,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ // Abandon operations cannot be canceled.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java
index fd3807b..a3b2cad 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java
@@ -2466,6 +2466,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ this.cancelRequest = cancelRequest;
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java
index d964244..807c88b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/BindOperation.java
@@ -2299,6 +2299,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ // Bind operations cannot be canceled.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/CompareOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/CompareOperation.java
index 287b24f..ab312d8 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/CompareOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/CompareOperation.java
@@ -1153,6 +1153,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ this.cancelRequest = cancelRequest;
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperation.java
index 8c93089..230ef40 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperation.java
@@ -1318,6 +1318,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ this.cancelRequest = cancelRequest;
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperation.java
index 458ceb9..77eb4f7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperation.java
@@ -771,6 +771,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ this.cancelRequest = cancelRequest;
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java
index caf5af8..7c275e4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java
@@ -2116,6 +2116,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ this.cancelRequest = cancelRequest;
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
index 1956a1b..7c5669c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -2808,6 +2808,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ this.cancelRequest = cancelRequest;
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/Operation.java b/opendj-sdk/opends/src/server/org/opends/server/core/Operation.java
index fc49f53..0d85d66 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/Operation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/Operation.java
@@ -928,6 +928,22 @@
/**
+ * Sets the cancel request for this operation, if applicable. This should
+ * only be used for testing purposes (e.g., for ensuring a cancel request is
+ * submitted before processing begins on an operation, or to allow for
+ * cancelling an internal operation).
+ *
+ * @param cancelRequest The cancel request to set for this operation.
+ *
+ * @return <CODE>true</CODE> if the cancel request was set, or
+ * <CODE>false</CODE> if it was not for some reason (e.g., the
+ * specified operation cannot be cancelled).
+ */
+ abstract boolean setCancelRequest(CancelRequest cancelRequest);
+
+
+
+ /**
* Retrieves the cancel request that has been issued for this operation, if
* there is one. This method should not be called by post-operation or
* post-response plugins.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java
index d0feac0..5fdaccf 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java
@@ -2179,6 +2179,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ this.cancelRequest = cancelRequest;
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/UnbindOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/UnbindOperation.java
index 593995f..9a2f096 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/UnbindOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/UnbindOperation.java
@@ -306,6 +306,21 @@
* {@inheritDoc}
*/
@Override()
+ boolean setCancelRequest(CancelRequest cancelRequest)
+ {
+ assert debugEnter(CLASS_NAME, "setCancelRequest",
+ String.valueOf(cancelRequest));
+
+ // Unbind operations cannot be canceled.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public final void toString(StringBuilder buffer)
{
assert debugEnter(CLASS_NAME, "toString", "java.lang.StringBuilder");
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
index 415d0ab..4f0e9ca 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
@@ -31,13 +31,16 @@
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.locks.Lock;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.Backend;
+import org.opends.server.plugins.DisconnectClientPlugin;
import org.opends.server.plugins.UpdatePreOpPlugin;
+import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Reader;
import org.opends.server.protocols.asn1.ASN1Sequence;
@@ -53,15 +56,18 @@
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
+import org.opends.server.types.CancelRequest;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
+import org.opends.server.types.LockManager;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.ResultCode;
import org.opends.server.types.WritabilityMode;
import static org.testng.Assert.*;
+import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.opends.server.util.ServerConstants.*;
@@ -1885,5 +1891,357 @@
assertEquals(changeListener.getAddCount(), 0);
DirectoryServer.deregisterChangeNotificationListener(changeListener);
}
+
+
+
+ /**
+ * Tests an add operation that gets canceled before startup.
+ *
+ * @throws Exception If an unexpected probem occurs.
+ */
+ @Test()
+ public void testCancelBeforeStartup()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ new AddOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ null, entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+
+ CancelRequest cancelRequest = new CancelRequest(false,
+ "testCancelBeforeStartup");
+ addOperation.setCancelRequest(cancelRequest);
+ addOperation.run();
+ assertEquals(addOperation.getResultCode(), ResultCode.CANCELED);
+ }
+
+
+
+ /**
+ * Tests an add operation in which the server cannot obtain a lock on the
+ * target entry because there is already a read lock held on it.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test(groups = { "slow" })
+ public void testCannotLockEntry()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Lock entryLock = LockManager.lockRead(DN.decode("ou=People,o=test"));
+
+ try
+ {
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation =
+ conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+ finally
+ {
+ LockManager.unlock(DN.decode("ou=People,o=test"), entryLock);
+ }
+ }
+
+
+
+ /**
+ * Tests an add operation that should be disconnected in a pre-parse plugin.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisconnectInPreParseAdd()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(5000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ AddRequestProtocolOp addRequest =
+ new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ message = new LDAPMessage(2, addRequest,
+ DisconnectClientPlugin.createDisconnectLDAPControlList("PreParse"));
+ w.writeElement(message.encode());
+
+ ASN1Element element = r.readElement();
+ if (element != null)
+ {
+ // If we got an element back, then it must be a notice of disconnect
+ // unsolicited notification.
+ message = LDAPMessage.decode(element.decodeAsSequence());
+ assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+ }
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
+
+
+
+ /**
+ * Tests an add operation that should be disconnected in a pre-operation
+ * plugin.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisconnectInPreOperationAdd()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(5000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ AddRequestProtocolOp addRequest =
+ new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ message = new LDAPMessage(2, addRequest,
+ DisconnectClientPlugin.createDisconnectLDAPControlList(
+ "PreOperation"));
+ w.writeElement(message.encode());
+
+ ASN1Element element = r.readElement();
+ if (element != null)
+ {
+ // If we got an element back, then it must be a notice of disconnect
+ // unsolicited notification.
+ message = LDAPMessage.decode(element.decodeAsSequence());
+ assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+ }
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
+
+
+
+ /**
+ * Tests an add operation that should be disconnected in a post-operation
+ * plugin.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisconnectInPostOperationAdd()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(5000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ AddRequestProtocolOp addRequest =
+ new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ message = new LDAPMessage(2, addRequest,
+ DisconnectClientPlugin.createDisconnectLDAPControlList(
+ "PostOperation"));
+ w.writeElement(message.encode());
+
+ ASN1Element element = r.readElement();
+ if (element != null)
+ {
+ // If we got an element back, then it must be a notice of disconnect
+ // unsolicited notification.
+ message = LDAPMessage.decode(element.decodeAsSequence());
+ assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+ }
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
+
+
+
+ /**
+ * Tests an add operation that should be disconnected in a post-response
+ * plugin.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisconnectInPostResponseAdd()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(5000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<LDAPAttribute> attrs = new ArrayList<LDAPAttribute>();
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("top"));
+ values.add(new ASN1OctetString("organizationalUnit"));
+ attrs.add(new LDAPAttribute("objectClass", values));
+
+ values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("People"));
+ attrs.add(new LDAPAttribute("ou", values));
+
+ AddRequestProtocolOp addRequest =
+ new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
+ attrs);
+ message = new LDAPMessage(2, addRequest,
+ DisconnectClientPlugin.createDisconnectLDAPControlList(
+ "PostResponse"));
+ w.writeElement(message.encode());
+
+responseLoop:
+ while (true)
+ {
+ ASN1Element element = r.readElement();
+ if (element == null)
+ {
+ // The connection has been closed.
+ break responseLoop;
+ }
+
+ message = LDAPMessage.decode(element.decodeAsSequence());
+ switch (message.getProtocolOpType())
+ {
+ case OP_TYPE_ADD_RESPONSE:
+ // This was expected. The disconnect didn't happen until after the
+ // response was sent.
+ break;
+ case OP_TYPE_EXTENDED_RESPONSE:
+ // The server is notifying us that it will be closing the connection.
+ break responseLoop;
+ default:
+ // This is a problem. It's an unexpected response.
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+
+ throw new Exception("Unexpected response message " + message +
+ " encountered in " +
+ "testDisconnectInPostResponseAdd");
+ }
+ }
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
index c997aa1..343ed1a 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
@@ -30,6 +30,7 @@
import java.net.Socket;
import java.util.ArrayList;
+import java.util.concurrent.locks.Lock;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -50,9 +51,11 @@
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.tools.LDAPDelete;
import org.opends.server.types.ByteString;
+import org.opends.server.types.CancelRequest;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
+import org.opends.server.types.LockManager;
import org.opends.server.types.ResultCode;
import org.opends.server.types.WritabilityMode;
@@ -767,6 +770,64 @@
/**
+ * Tests a delete operation that gets canceled before startup.
+ *
+ * @throws Exception If an unexpected probem occurs.
+ */
+ @Test()
+ public void testCancelBeforeStartup()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ DeleteOperation deleteOperation =
+ new DeleteOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ null, new ASN1OctetString("o=test"));
+
+ CancelRequest cancelRequest = new CancelRequest(false,
+ "testCancelBeforeStartup");
+ deleteOperation.setCancelRequest(cancelRequest);
+ deleteOperation.run();
+ assertEquals(deleteOperation.getResultCode(), ResultCode.CANCELED);
+ }
+
+
+
+ /**
+ * Tests a delete operation in which the server cannot obtain a lock on the
+ * target entry because there is already a read lock held on it.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test(groups = { "slow" })
+ public void testCannotLockEntry()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Lock entryLock = LockManager.lockRead(DN.decode("o=test"));
+
+ try
+ {
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ DeleteOperation deleteOperation =
+ conn.processDelete(new ASN1OctetString("o=test"));
+ assertFalse(deleteOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+ finally
+ {
+ LockManager.unlock(DN.decode("o=test"), entryLock);
+ }
+ }
+
+
+
+ /**
* Tests a delete operation that should be disconnected in a pre-parse plugin.
*
* @throws Exception If an unexpected problem occurs.
@@ -997,5 +1058,66 @@
s.close();
} catch (Exception e) {}
}
+
+
+
+ /**
+ * Tests to ensure that any registered notification listeners are invoked for
+ * a successful delete operation.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testSuccessWithNotificationListener()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ TestChangeNotificationListener changeListener =
+ new TestChangeNotificationListener();
+ DirectoryServer.registerChangeNotificationListener(changeListener);
+ assertEquals(changeListener.getAddCount(), 0);
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ DeleteOperation deleteOperation =
+ conn.processDelete(new ASN1OctetString("o=test"));
+ assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS);
+ retrieveCompletedOperationElements(deleteOperation);
+
+ assertEquals(changeListener.getDeleteCount(), 1);
+ DirectoryServer.deregisterChangeNotificationListener(changeListener);
+ }
+
+
+
+ /**
+ * Tests to ensure that any registered notification listeners are not invoked
+ * for a failed delete operation.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testFailureWithNotificationListener()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ TestChangeNotificationListener changeListener =
+ new TestChangeNotificationListener();
+ DirectoryServer.registerChangeNotificationListener(changeListener);
+ assertEquals(changeListener.getAddCount(), 0);
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ DeleteOperation deleteOperation =
+ conn.processDelete(new ASN1OctetString("cn=nonexistent,o=test"));
+ assertFalse(deleteOperation.getResultCode() == ResultCode.SUCCESS);
+
+ assertEquals(changeListener.getDeleteCount(), 0);
+ DirectoryServer.deregisterChangeNotificationListener(changeListener);
+ }
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
index dc15f84..f43db15 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
@@ -31,13 +31,16 @@
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.locks.Lock;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.Backend;
+import org.opends.server.plugins.DisconnectClientPlugin;
import org.opends.server.plugins.UpdatePreOpPlugin;
+import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Reader;
import org.opends.server.protocols.asn1.ASN1Sequence;
@@ -54,9 +57,11 @@
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
+import org.opends.server.types.CancelRequest;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
+import org.opends.server.types.LockManager;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.ObjectClass;
@@ -65,6 +70,7 @@
import static org.testng.Assert.*;
+import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.opends.server.util.ServerConstants.*;
@@ -3643,5 +3649,339 @@
assertEquals(changeListener.getModifyCount(), 0);
DirectoryServer.deregisterChangeNotificationListener(changeListener);
}
+
+
+
+ /**
+ * Tests a modify operation that gets canceled before startup.
+ *
+ * @throws Exception If an unexpected probem occurs.
+ */
+ @Test()
+ public void testCancelBeforeStartup()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ LDAPAttribute attr = new LDAPAttribute("description", values);
+
+ ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>();
+ mods.add(new LDAPModification(ModificationType.REPLACE, attr));
+
+ ModifyOperation modifyOperation =
+ new ModifyOperation(conn, conn.nextOperationID(), conn.nextMessageID(),
+ null, new ASN1OctetString("o=test"), mods);
+
+ CancelRequest cancelRequest = new CancelRequest(false,
+ "testCancelBeforeStartup");
+ modifyOperation.setCancelRequest(cancelRequest);
+ modifyOperation.run();
+ assertEquals(modifyOperation.getResultCode(), ResultCode.CANCELED);
+ }
+
+
+
+ /**
+ * Tests a modify operation in which the server cannot obtain a lock on the
+ * target entry because there is already a read lock held on it.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test(groups = { "slow" })
+ public void testCannotLockEntry()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Lock entryLock = LockManager.lockRead(DN.decode("o=test"));
+
+ try
+ {
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ LDAPAttribute attr = new LDAPAttribute("description", values);
+
+ ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>();
+ mods.add(new LDAPModification(ModificationType.REPLACE, attr));
+
+ ModifyOperation modifyOperation =
+ conn.processModify(new ASN1OctetString("o=test"), mods);
+ assertFalse(modifyOperation.getResultCode() == ResultCode.SUCCESS);
+ }
+ finally
+ {
+ LockManager.unlock(DN.decode("o=test"), entryLock);
+ }
+ }
+
+
+
+ /**
+ * Tests a modify operation that should be disconnected in a pre-parse plugin.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisconnectInPreParseModify()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(5000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ LDAPAttribute attr = new LDAPAttribute("description", values);
+
+ ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>();
+ mods.add(new LDAPModification(ModificationType.REPLACE, attr));
+
+ ModifyRequestProtocolOp modifyRequest =
+ new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods);
+ message = new LDAPMessage(2, modifyRequest,
+ DisconnectClientPlugin.createDisconnectLDAPControlList("PreParse"));
+ w.writeElement(message.encode());
+
+ ASN1Element element = r.readElement();
+ if (element != null)
+ {
+ // If we got an element back, then it must be a notice of disconnect
+ // unsolicited notification.
+ message = LDAPMessage.decode(element.decodeAsSequence());
+ assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+ }
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
+
+
+
+ /**
+ * Tests a modify operation that should be disconnected in a pre-operation
+ * plugin.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisconnectInPreOperationModify()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(5000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ LDAPAttribute attr = new LDAPAttribute("description", values);
+
+ ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>();
+ mods.add(new LDAPModification(ModificationType.REPLACE, attr));
+
+ ModifyRequestProtocolOp modifyRequest =
+ new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods);
+ message = new LDAPMessage(2, modifyRequest,
+ DisconnectClientPlugin.createDisconnectLDAPControlList(
+ "PreOperation"));
+ w.writeElement(message.encode());
+
+ ASN1Element element = r.readElement();
+ if (element != null)
+ {
+ // If we got an element back, then it must be a notice of disconnect
+ // unsolicited notification.
+ message = LDAPMessage.decode(element.decodeAsSequence());
+ assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+ }
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
+
+
+
+ /**
+ * Tests a modify operation that should be disconnected in a post-operation
+ * plugin.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisconnectInPostOperationModify()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(5000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ LDAPAttribute attr = new LDAPAttribute("description", values);
+
+ ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>();
+ mods.add(new LDAPModification(ModificationType.REPLACE, attr));
+
+ ModifyRequestProtocolOp modifyRequest =
+ new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods);
+ message = new LDAPMessage(2, modifyRequest,
+ DisconnectClientPlugin.createDisconnectLDAPControlList(
+ "PostOperation"));
+ w.writeElement(message.encode());
+
+ ASN1Element element = r.readElement();
+ if (element != null)
+ {
+ // If we got an element back, then it must be a notice of disconnect
+ // unsolicited notification.
+ message = LDAPMessage.decode(element.decodeAsSequence());
+ assertEquals(message.getProtocolOpType(), OP_TYPE_EXTENDED_RESPONSE);
+ }
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
+
+
+
+ /**
+ * Tests a modify operation that should be disconnected in a post-response
+ * plugin.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisconnectInPostResponseModify()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Socket s = new Socket("127.0.0.1", (int) TestCaseUtils.getServerLdapPort());
+ ASN1Reader r = new ASN1Reader(s);
+ ASN1Writer w = new ASN1Writer(s);
+ r.setIOTimeout(5000);
+
+ BindRequestProtocolOp bindRequest =
+ new BindRequestProtocolOp(new ASN1OctetString("cn=Directory Manager"),
+ 3, new ASN1OctetString("password"));
+ LDAPMessage message = new LDAPMessage(1, bindRequest);
+ w.writeElement(message.encode());
+
+ message = LDAPMessage.decode(r.readElement().decodeAsSequence());
+ BindResponseProtocolOp bindResponse =
+ message.getBindResponseProtocolOp();
+ assertEquals(bindResponse.getResultCode(), 0);
+
+
+ ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+ values.add(new ASN1OctetString("foo"));
+ LDAPAttribute attr = new LDAPAttribute("description", values);
+
+ ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>();
+ mods.add(new LDAPModification(ModificationType.REPLACE, attr));
+
+ ModifyRequestProtocolOp modifyRequest =
+ new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods);
+ message = new LDAPMessage(2, modifyRequest,
+ DisconnectClientPlugin.createDisconnectLDAPControlList(
+ "PostResponse"));
+ w.writeElement(message.encode());
+
+responseLoop:
+ while (true)
+ {
+ ASN1Element element = r.readElement();
+ if (element == null)
+ {
+ // The connection has been closed.
+ break responseLoop;
+ }
+
+ message = LDAPMessage.decode(element.decodeAsSequence());
+ switch (message.getProtocolOpType())
+ {
+ case OP_TYPE_MODIFY_RESPONSE:
+ // This was expected. The disconnect didn't happen until after the
+ // response was sent.
+ break;
+ case OP_TYPE_EXTENDED_RESPONSE:
+ // The server is notifying us that it will be closing the connection.
+ break responseLoop;
+ default:
+ // This is a problem. It's an unexpected response.
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+
+ throw new Exception("Unexpected response message " + message +
+ " encountered in " +
+ "testDisconnectInPostResponseModify");
+ }
+ }
+
+ try
+ {
+ s.close();
+ } catch (Exception e) {}
+ }
}
--
Gitblit v1.10.0