From 36050c5587e30c0e0b740166c73c2d145c3471d1 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Wed, 30 Apr 2008 23:38:25 +0000
Subject: [PATCH] Fix for issue where deleteing the last few entries indexed by a VLV index might cause a NPE.
---
opends/src/server/org/opends/server/backends/jeb/VLVIndex.java | 12 +++
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVLVIndex.java | 98 +++++++++++++++++++++++++++-----
opends/src/server/org/opends/server/backends/jeb/SortValuesSet.java | 8 ++
opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java | 21 +++++++
4 files changed, 121 insertions(+), 18 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/jeb/SortValuesSet.java b/opends/src/server/org/opends/server/backends/jeb/SortValuesSet.java
index 94bf340..8fd9d1b 100644
--- a/opends/src/server/org/opends/server/backends/jeb/SortValuesSet.java
+++ b/opends/src/server/org/opends/server/backends/jeb/SortValuesSet.java
@@ -346,10 +346,16 @@
/**
* Encode this set to its database format.
*
- * @return The encoded bytes representing this set.
+ * @return The encoded bytes representing this set or null if
+ * this set is empty.
*/
public byte[] toDatabase()
{
+ if(size() == 0)
+ {
+ return null;
+ }
+
byte[] entryIDBytes = JebFormat.entryIDListToDatabase(entryIDs);
byte[] concatBytes = new byte[entryIDBytes.length + valuesBytes.length + 4];
int v = entryIDs.length;
diff --git a/opends/src/server/org/opends/server/backends/jeb/VLVIndex.java b/opends/src/server/org/opends/server/backends/jeb/VLVIndex.java
index 928a0ca..81c16ea 100644
--- a/opends/src/server/org/opends/server/backends/jeb/VLVIndex.java
+++ b/opends/src/server/org/opends/server/backends/jeb/VLVIndex.java
@@ -878,8 +878,16 @@
this);
boolean success = sortValuesSet.remove(entryID, values);
byte[] after = sortValuesSet.toDatabase();
- data.setData(after);
- put(txn, key, data);
+
+ if(after == null)
+ {
+ delete(txn, key);
+ }
+ else
+ {
+ data.setData(after);
+ put(txn, key, data);
+ }
if(success)
{
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
index 10ad394..1ef4ef4 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
@@ -72,6 +72,7 @@
import org.opends.server.config.ConfigException;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.DeleteOperation;
import org.opends.server.extensions.ConfigFileHandler;
import org.opends.server.loggers.TextAccessLogPublisher;
import org.opends.server.loggers.TextErrorLogPublisher;
@@ -1071,6 +1072,26 @@
+ /**
+ * Deletess the provided entry from the Directory Server using an
+ * internal operation.
+ *
+ * @param entry The entry to be added.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ public static void deleteEntry(Entry entry)
+ throws Exception
+ {
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ DeleteOperation deleteOperation = conn.processDelete(entry.getDN());
+ assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS);
+ }
+
+
+
public static boolean canBind(String dn, String pw) throws Exception
{
// Check that the user can bind.
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVLVIndex.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVLVIndex.java
index a9a9320..451e81a 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVLVIndex.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVLVIndex.java
@@ -88,6 +88,8 @@
TreeSet<SortValues> expectedSortedValues;
+ List<Entry> entries;
+
@BeforeClass
public void setUp() throws Exception {
TestCaseUtils.startServer();
@@ -112,21 +114,8 @@
suffixDN = DN.decode("dc=vlvtest,dc=com");
expectedSortedValues = new TreeSet<SortValues>();
- }
- @AfterClass
- public void cleanUp() throws Exception {
- }
-
- /**
- * Populates the JE DB with a set of test data.
- *
- * @throws Exception If an unexpected problem occurs.
- */
- private void populateDB()
- throws Exception
- {
- List<Entry> entries = TestCaseUtils.makeEntries(
+ entries = TestCaseUtils.makeEntries(
"dn: dc=vlvtest,dc=com",
"objectClass: top",
"objectClass: domain",
@@ -223,7 +212,20 @@
"sn: Zorro",
"cn: Zorro"
);
+ }
+ @AfterClass
+ public void cleanUp() throws Exception {
+ }
+
+ /**
+ * Populates the JE DB with a set of test data.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ private void populateDB()
+ throws Exception
+ {
long id = 1;
for(Entry entry : entries)
{
@@ -234,8 +236,74 @@
}
}
-
@Test
+ public void testDel() throws Exception
+ {
+ populateDB();
+
+ TestCaseUtils.deleteEntry(entries.get(1));
+ TestCaseUtils.deleteEntry(entries.get(entries.size() - 1));
+
+ be=(BackendImpl) DirectoryServer.getBackend(beID);
+ RootContainer rootContainer = be.getRootContainer();
+ EntryContainer entryContainer =
+ rootContainer.getEntryContainer(DN.decode("dc=vlvtest,dc=com"));
+
+ for(VLVIndex vlvIndex : entryContainer.getVLVIndexes())
+ {
+ if(vlvIndex.getName().contains("testvlvindex"))
+ {
+
+
+ SortValuesSet svs1 =
+ vlvIndex.getSortValuesSet(null, 0,
+ expectedSortedValues.first().getValues());
+
+ assertNotNull(svs1);
+ assertEquals(svs1.size(), 3);
+
+ SortValuesSet svs2 =
+ vlvIndex.getSortValuesSet(null, 0,
+ expectedSortedValues.last().getValues());
+
+ assertNotNull(svs2);
+ assertEquals(svs2.size(), 5);
+ }
+ }
+
+ for(int i = 2; i <= entries.size() - 2; i++)
+ {
+ TestCaseUtils.deleteEntry(entries.get(i));
+ }
+ // Delete the base entry
+ TestCaseUtils.deleteEntry(entries.get(0));
+
+ for(VLVIndex vlvIndex : entryContainer.getVLVIndexes())
+ {
+ if(vlvIndex.getName().contains("testvlvindex"))
+ {
+
+
+ SortValuesSet svs1 =
+ vlvIndex.getSortValuesSet(null, 0,
+ expectedSortedValues.first().getValues());
+
+ assertNotNull(svs1);
+ assertEquals(svs1.size(), 0);
+ assertNull(svs1.getKeyBytes());
+
+ SortValuesSet svs2 =
+ vlvIndex.getSortValuesSet(null, 0,
+ expectedSortedValues.last().getValues());
+
+ assertNotNull(svs2);
+ assertEquals(svs1.size(), 0);
+ assertNull(svs1.getKeyBytes());
+ }
+ }
+ }
+
+ @Test( dependsOnMethods = { "testDel" } )
public void testAdd() throws Exception
{
populateDB();
--
Gitblit v1.10.0