You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2012/10/02 13:25:01 UTC
svn commit: r1392847 - in
/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests:
Derby5937SlaveShutdownTest.java Derby5937SlaveShutdownTest.policy
ReplicationSuite.java build.xml
Author: kahatlen
Date: Tue Oct 2 11:25:01 2012
New Revision: 1392847
URL: http://svn.apache.org/viewvc?rev=1392847&view=rev
Log:
DERBY-5937: File handle is leaked when a Slave replication is shutdown with failover=true
Added a test case that exposes the bug when run on Windows.
Added:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.java (with props)
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.policy (with props)
Modified:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/ReplicationSuite.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/build.xml
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.java?rev=1392847&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.java Tue Oct 2 11:25:01 2012
@@ -0,0 +1,216 @@
+/*
+
+Derby - Class org.apache.derbyTesting.functionTests.tests.replicationTests.Derby5937SlaveShutdownTest
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+package org.apache.derbyTesting.functionTests.tests.replicationTests;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.functionTests.util.PrivilegedFileOpsForTests;
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.NetworkServerTestSetup;
+import org.apache.derbyTesting.junit.SecurityManagerSetup;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+/**
+ * <p>
+ * Regression test case for DERBY-5937. After fail-over, the slave database
+ * will leak a file handle for the active log file.
+ * </p>
+ *
+ * <p>
+ * The test case will set up replication between a master database and a
+ * slave database, perform fail-over to the slave, and then shut down the
+ * slave database. Finally, it attempts to delete the slave database. On
+ * Windows, this fails if DERBY-5937 is not fixed, because one of the log
+ * files is still held open, and Windows doesn't allow deletion of open
+ * files.
+ * </p>
+ */
+public class Derby5937SlaveShutdownTest extends BaseJDBCTestCase {
+
+ private static final String MASTER_DB = "d5937-master-db";
+ private static final String SLAVE_DB = "d5937-slave-db";
+
+ private static final String FAILOVER_SUCCESS = "XRE20";
+ private static final String DB_SHUTDOWN_SUCCESS = "08006";
+
+ private static final long RETRY_INTERVAL = 50L;
+
+ public Derby5937SlaveShutdownTest(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ if (JDBC.vmSupportsJDBC3()) {
+ Class klass = Derby5937SlaveShutdownTest.class;
+ // The default security policy doesn't allow derby.jar to do
+ // networking, which is needed for replication, so install a custom
+ // policy for this test.
+ return new SecurityManagerSetup(
+ TestConfiguration.singleUseDatabaseDecorator(
+ TestConfiguration.embeddedSuite(klass), MASTER_DB),
+ klass.getName().replace('.', '/') + ".policy", true);
+ } else {
+ // The test doesn't run on J2ME.
+ return new TestSuite("Derby5937SlaveShutdownTest - skipped");
+ }
+ }
+
+ public void testSlaveFailoverLeak() throws Exception {
+ // First establish a connection so that the database is created.
+ getConnection().close();
+
+ // Then shut down the database cleanly so that it can be used
+ // to seed the replication slave.
+ final TestConfiguration config = TestConfiguration.getCurrent();
+ config.shutdownDatabase();
+
+ // Copy the database to the slave.
+ final String masterDb = config.getDatabasePath(MASTER_DB);
+ final String slaveDb = config.getDatabasePath(SLAVE_DB);
+ PrivilegedFileOpsForTests.copy(new File(masterDb), new File(slaveDb));
+
+ // And start the slave.
+ SlaveThread slave = new SlaveThread(config);
+ slave.start();
+
+ Properties p = new Properties();
+ p.setProperty("startMaster", "true");
+ p.setProperty("slaveHost", config.getHostName());
+ p.setProperty("slavePort", String.valueOf(config.getPort()));
+
+ // Start the master. This will fail until the slave is up, so do
+ // it in a loop until successful or time runs out.
+ long giveUp =
+ System.currentTimeMillis() + NetworkServerTestSetup.getWaitTime();
+ Connection c = null;
+ while (c == null) {
+ try {
+ c = config.openPhysicalConnection(masterDb,
+ config.getUserName(), config.getUserPassword(), p);
+ } catch (SQLException sqle) {
+ slave.checkError(); // Exit early if the slave has failed
+ if (System.currentTimeMillis() > giveUp) {
+ fail("Master won't start", sqle);
+ } else {
+ println("Retrying after startMaster failed with: " + sqle);
+ Thread.sleep(RETRY_INTERVAL);
+ }
+ }
+ }
+ c.close();
+
+ // Wait for the slave thread to complete, which it will do once
+ // it's connected to the master.
+ slave.join();
+ slave.checkError();
+
+ // Perform fail-over.
+ p.clear();
+ p.setProperty("failover", "true");
+ try {
+ config.openPhysicalConnection(masterDb,
+ config.getUserName(), config.getUserPassword(), p);
+ fail("failover should receive exception");
+ } catch (SQLException sqle) {
+ assertSQLState(FAILOVER_SUCCESS, sqle);
+ }
+
+ // Shut down the slave database. This will fail until failover is
+ // complete, so do it in a loop until successful or time runs out.
+ giveUp =
+ System.currentTimeMillis() + NetworkServerTestSetup.getWaitTime();
+ p.clear();
+ p.setProperty("shutdown", "true");
+ while (true) {
+ try {
+ config.openPhysicalConnection(slaveDb,
+ config.getUserName(), config.getUserPassword(), p);
+ fail("Shutdown of slave database didn't throw an exception");
+ } catch (SQLException sqle) {
+ if (DB_SHUTDOWN_SUCCESS.equals(sqle.getSQLState())) {
+ // The expected shutdown exception was thrown. Break out
+ // of the loop.
+ break;
+ } else if (System.currentTimeMillis() > giveUp) {
+ fail("Could not shut down slave database", sqle);
+ } else {
+ println("Retrying after failover failed with: " + sqle);
+ Thread.sleep(RETRY_INTERVAL);
+ }
+ }
+ }
+
+ // This call used to fail on Windows because one of the log files
+ // was still open.
+ assertDirectoryDeleted(new File(slaveDb));
+ }
+
+ /**
+ * Helper thread which starts a replication slave and blocks until the
+ * slave is connected to a master database.
+ */
+ private class SlaveThread extends Thread {
+
+ private final TestConfiguration config;
+ private volatile Throwable error;
+
+ SlaveThread(TestConfiguration config) {
+ this.config = config;
+ }
+
+ public void run() {
+ try {
+ run_();
+ } catch (Throwable t) {
+ error = t;
+ }
+ }
+
+ private void run_() throws Exception {
+ println("Slave thread started.");
+
+ Properties p = new Properties();
+ p.setProperty("startSlave", "true");
+ p.setProperty("slaveHost", config.getHostName());
+ p.setProperty("slavePort", String.valueOf(config.getPort()));
+
+ try {
+ config.openPhysicalConnection(config.getDatabasePath(SLAVE_DB),
+ config.getUserName(), config.getUserPassword(), p);
+ fail("startSlave should throw exception");
+ } catch (SQLException sqle) {
+ assertSQLState("XRE08", sqle);
+ }
+ }
+
+ void checkError() {
+ if (error != null) {
+ fail("Slave thread failed", error);
+ }
+ }
+ }
+}
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.policy
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.policy?rev=1392847&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.policy (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.policy Tue Oct 2 11:25:01 2012
@@ -0,0 +1,29 @@
+//
+// Derby - org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.policy
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Test specific permissions for test:
+// replicationTests/Derby5937SlaveShutdownTest.java
+// The permissions below are expected to be added to the set of default
+// permissions granted to the test framework.
+//
+grant codeBase "${derbyTesting.codejar}derby.jar" {
+ permission java.net.SocketPermission "127.0.0.1", "connect,resolve,accept";
+ permission java.net.SocketPermission "localhost", "connect,resolve,accept";
+};
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/Derby5937SlaveShutdownTest.policy
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/ReplicationSuite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/ReplicationSuite.java?rev=1392847&r1=1392846&r2=1392847&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/ReplicationSuite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/ReplicationSuite.java Tue Oct 2 11:25:01 2012
@@ -84,6 +84,9 @@ public class ReplicationSuite extends Ba
suite.addTest(ReplicationRun_Local_3_p6.suite());
suite.addTest(ReplicationRun_Local_Derby4910.suite());
+
+ // Enable when DERBY-5937 has been fixed.
+ //suite.addTest(Derby5937SlaveShutdownTest.suite());
}
return suite;
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/build.xml?rev=1392847&r1=1392846&r2=1392847&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/build.xml (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/replicationTests/build.xml Tue Oct 2 11:25:01 2012
@@ -58,7 +58,7 @@
<!-- ============ Begin Targets ============== -->
- <target name="FTOtestsubdir" depends="compilet1"/>
+ <target name="FTOtestsubdir" depends="compilet1,copyfiles"/>
<!-- mkdir / init target may not be necessary, just here for reference... -->
<target name="init">
@@ -87,6 +87,11 @@
</javac>
</target>
+ <target name="copyfiles">
+ <copy todir="${out.dir}/${this.dir}">
+ <fileset dir="${derby.testing.src.dir}/${this.dir}" includes="*.policy"/>
+ </copy>
+ </target>
<!-- ============= End Targets ============== -->