You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2011/10/17 16:53:13 UTC
svn commit: r1185228 - in
/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core:
ConcurrentImportTest.java ConsistencyCheck.java TestHelper.java
persistence/AutoFixCorruptNode.java
Author: reschke
Date: Mon Oct 17 14:53:13 2011
New Revision: 1185228
URL: http://svn.apache.org/viewvc?rev=1185228&view=rev
Log:
JCR-3105: add test case for breaking and fixing version storage (also add hook for running consistency check in "fix" mode)
Modified:
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentImportTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConsistencyCheck.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/persistence/AutoFixCorruptNode.java
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentImportTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentImportTest.java?rev=1185228&r1=1185227&r2=1185228&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentImportTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentImportTest.java Mon Oct 17 14:53:13 2011
@@ -215,7 +215,7 @@ public class ConcurrentImportTest extend
private void checkConsistency() throws RepositoryException {
try {
- ConsistencyReport rep = TestHelper.checkConsistency(testRootNode.getSession());
+ ConsistencyReport rep = TestHelper.checkConsistency(testRootNode.getSession(), false);
assertEquals("Found broken nodes in repository: " + rep, 0, rep.getItems().size());
} catch (NotExecutableException ex) {
// ignore
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConsistencyCheck.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConsistencyCheck.java?rev=1185228&r1=1185227&r2=1185228&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConsistencyCheck.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConsistencyCheck.java Mon Oct 17 14:53:13 2011
@@ -40,12 +40,12 @@ public class ConsistencyCheck extends Ab
+ getHelper().getRepository());
ConsistencyReport rep = TestHelper.checkConsistency(testRootNode
- .getSession());
+ .getSession(), false);
assertEquals("Found broken nodes in repository: " + rep, 0, rep
.getItems().size());
rep = TestHelper
- .checkVersionStoreConsistency(testRootNode.getSession());
+ .checkVersionStoreConsistency(testRootNode.getSession(), false);
assertEquals("Found broken nodes in version storage: " + rep, 0, rep
.getItems().size());
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java?rev=1185228&r1=1185227&r2=1185228&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java Mon Oct 17 14:53:13 2011
@@ -47,13 +47,14 @@ public class TestHelper {
* Runs a consistency check on the workspace used by the specified session.
*
* @param session the Session accessing the workspace to be checked
+ * @param runFix whether to attempt fixup
* @throws RepositoryException if an error occurs while getting the
* workspace with the given name.
* @throws NotExecutableException if the {@link PersistenceManager} does
* not implement {@link ConsistencyChecker}, or if the associated
* {@link Repository} is not a {@link RepositoryImpl}.
*/
- public static ConsistencyReport checkConsistency(Session session)
+ public static ConsistencyReport checkConsistency(Session session, boolean runFix)
throws NotExecutableException, RepositoryException {
Repository r = session.getRepository();
if (!(r instanceof RepositoryImpl)) {
@@ -65,7 +66,7 @@ public class TestHelper {
if (!(pm instanceof ConsistencyChecker)) {
throw new NotExecutableException();
} else {
- return ((ConsistencyChecker) pm).check(null, true, false);
+ return ((ConsistencyChecker) pm).check(null, true, runFix);
}
}
}
@@ -74,12 +75,13 @@ public class TestHelper {
* Runs a consistency check on the versioning store used by the specified session.
*
* @param session the Session accessing the workspace to be checked
+ * @param runFix whether to attempt fixup
* @throws RepositoryException
* @throws NotExecutableException if the {@link PersistenceManager} does
* not implement {@link ConsistencyChecker}, or if the associated
* {@link Repository} is not a {@link RepositoryImpl}.
*/
- public static ConsistencyReport checkVersionStoreConsistency(Session session)
+ public static ConsistencyReport checkVersionStoreConsistency(Session session, boolean runFix)
throws NotExecutableException, RepositoryException {
Repository r = session.getRepository();
if (!(r instanceof RepositoryImpl)) {
@@ -91,7 +93,7 @@ public class TestHelper {
if (!(pm instanceof ConsistencyChecker)) {
throw new NotExecutableException();
} else {
- return ((ConsistencyChecker) pm).check(null, true, false);
+ return ((ConsistencyChecker) pm).check(null, true, runFix);
}
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/persistence/AutoFixCorruptNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/persistence/AutoFixCorruptNode.java?rev=1185228&r1=1185227&r2=1185228&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/persistence/AutoFixCorruptNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/persistence/AutoFixCorruptNode.java Mon Oct 17 14:53:13 2011
@@ -20,8 +20,10 @@ import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
+import java.sql.SQLException;
import java.util.UUID;
+import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Repository;
@@ -70,19 +72,11 @@ public class AutoFixCorruptNode extends
s.save();
s.logout();
- // remove the bundle for /test/missing directly in the database
- Connection conn = DriverManager.getConnection("jdbc:derby:" + TEST_DIR
- + "/workspaces/default/db");
- PreparedStatement prep = conn
- .prepareStatement("delete from DEFAULT_BUNDLE where NODE_ID_HI=? and NODE_ID_LO=?");
- prep.setLong(1, id.getMostSignificantBits());
- prep.setLong(2, id.getLeastSignificantBits());
- prep.executeUpdate();
- conn.close();
+ destroyBundle(id, "workspaces/default");
s = openSession(rep, false);
try {
- ConsistencyReport r = TestHelper.checkConsistency(s);
+ ConsistencyReport r = TestHelper.checkConsistency(s, false);
assertNotNull(r);
assertNotNull(r.getItems());
assertEquals(1, r.getItems().size());
@@ -93,7 +87,117 @@ public class AutoFixCorruptNode extends
rep.shutdown();
FileUtils.deleteDirectory(new File("repository"));
}
+ }
+
+ public void testMissingVHR() throws Exception {
+
+ // new repository
+ TransientRepository rep = new TransientRepository(new File(TEST_DIR));
+ Session s = openSession(rep, false);
+
+ String oldVersionRecoveryProp = System
+ .getProperty("org.apache.jackrabbit.version.recovery");
+
+ try {
+ Node root = s.getRootNode();
+
+ // add nodes /test and /test/missing
+ Node test = root.addNode("test");
+ test.addMixin("mix:versionable");
+
+ s.save();
+
+ Node vhr = s.getWorkspace().getVersionManager()
+ .getVersionHistory(test.getPath());
+
+ assertNotNull(vhr);
+
+ Node brokenNode = vhr;
+ String vhrRootVersionId = vhr.getNode("jcr:rootVersion").getIdentifier();
+
+ UUID destroy = UUID.fromString(brokenNode.getIdentifier());
+ s.logout();
+
+ destroyBundle(destroy, "version");
+
+ s = openSession(rep, false);
+ ConsistencyReport report = TestHelper.checkVersionStoreConsistency(s, false);
+ assertTrue("Report should have reported broken nodes", !report.getItems().isEmpty());
+
+ try {
+ test = s.getRootNode().getNode("test");
+ vhr = s.getWorkspace().getVersionManager()
+ .getVersionHistory(test.getPath());
+ fail("should not get here");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ s.logout();
+
+ System.setProperty("org.apache.jackrabbit.version.recovery", "true");
+
+ s = openSession(rep, false);
+
+ test = s.getRootNode().getNode("test");
+ // versioning should be disabled now
+ assertFalse(test.isNodeType("mix:versionable"));
+
+ try {
+ // try to enable versioning again
+ test.addMixin("mix:versionable");
+ s.save();
+
+ fail("enabling versioning succeeded unexpectedly");
+ }
+ catch (Exception e) {
+ // we expect this to fail
+ }
+
+ s.logout();
+
+ // now redo after running fixup on versioning storage
+ s = openSession(rep, false);
+
+ report = TestHelper.checkVersionStoreConsistency(s, true);
+ assertTrue("Report should have reported broken nodes", !report.getItems().isEmpty());
+ int reportitems = report.getItems().size();
+
+ // problems should now be fixed
+ report = TestHelper.checkVersionStoreConsistency(s, false);
+ assertTrue("Some problems should have been fixed but are not: " + report, report.getItems().size() < reportitems);
+
+ test = s.getRootNode().getNode("test");
+ // versioning should be disabled now
+ assertFalse(test.isNodeType("mix:versionable"));
+
+ // try to enable versioning again
+ test.addMixin("mix:versionable");
+ s.save();
+
+ Node oldRootVersion = s.getNodeByIdentifier(vhrRootVersionId);
+ try {
+ String path = oldRootVersion.getPath();
+ fail("got path " + path + " for a node believed to be orphaned");
+ }
+ catch (ItemNotFoundException ex) {
+ // orphaned
+ }
+
+ Node newRootVersion = s.getWorkspace().getVersionManager()
+ .getVersionHistory(test.getPath()).getRootVersion();
+ assertFalse(
+ "new root version should be a different node than the one destroyed by the test case",
+ newRootVersion.getIdentifier().equals(vhrRootVersionId));
+ assertNotNull("new root version should have a intact path",
+ newRootVersion.getPath());
+ } finally {
+ s.logout();
+ System.setProperty("org.apache.jackrabbit.version.recovery",
+ oldVersionRecoveryProp == null ? ""
+ : oldVersionRecoveryProp);
+ }
}
public void testAutoFix() throws Exception {
@@ -111,15 +215,7 @@ public class AutoFixCorruptNode extends
s.save();
s.logout();
- // remove the bundle for /test/missing directly in the database
- Connection conn = DriverManager.getConnection("jdbc:derby:" + TEST_DIR
- + "/workspaces/default/db");
- PreparedStatement prep = conn
- .prepareStatement("delete from DEFAULT_BUNDLE where NODE_ID_HI=? and NODE_ID_LO=?");
- prep.setLong(1, id.getMostSignificantBits());
- prep.setLong(2, id.getLeastSignificantBits());
- prep.executeUpdate();
- conn.close();
+ destroyBundle(id, "workspaces/default");
// login and try the operation
s = openSession(rep, false);
@@ -155,7 +251,18 @@ public class AutoFixCorruptNode extends
rep.shutdown();
FileUtils.deleteDirectory(new File("repository"));
+ }
+ private void destroyBundle(UUID id, String where) throws SQLException {
+ Connection conn = DriverManager.getConnection("jdbc:derby:" + TEST_DIR
+ + "/" + where + "/db");
+ String table = where.equals("version") ? "VERSION_BUNDLE" : "DEFAULT_BUNDLE";
+ PreparedStatement prep = conn.prepareStatement("delete from " + table
+ + " where NODE_ID_HI=? and NODE_ID_LO=?");
+ prep.setLong(1, id.getMostSignificantBits());
+ prep.setLong(2, id.getLeastSignificantBits());
+ prep.executeUpdate();
+ conn.close();
}
private Session openSession(Repository rep, boolean autoFix)
@@ -168,5 +275,4 @@ public class AutoFixCorruptNode extends
}
return rep.login(cred);
}
-
}