summaryrefslogtreecommitdiff
path: root/qpid/java/bdbstore/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/bdbstore/src/test')
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java193
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/testclient/BackupTestClient.java120
2 files changed, 193 insertions, 120 deletions
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java
new file mode 100644
index 0000000000..342c185b99
--- /dev/null
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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.qpid.server.store.berkeleydb;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.test.utils.Piper;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.util.FileUtils;
+
+/**
+ * Tests the BDB backup script can successfully perform a backup and that
+ * backup can be restored and used by the Broker.
+ */
+public class BDBBackupTest extends QpidBrokerTestCase
+{
+ protected static final Logger LOGGER = Logger.getLogger(BDBBackupTest.class);
+
+ private static final String BACKUP_SCRIPT = "/bin/backup.sh";
+ private static final String BACKUP_COMPLETE_MESSAGE = "Hot Backup Completed";
+
+ private static final String TEST_VHOST = "test";
+ private static final String SYSTEM_TMP_DIR = System.getProperty("java.io.tmpdir");
+
+ private File _backupToDir;
+ private File _backupFromDir;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _backupToDir = new File(SYSTEM_TMP_DIR + File.separator + getTestName());
+ _backupToDir.mkdirs();
+
+ final String qpidWork = getBroker(DEFAULT_PORT).getWorkingDirectory();
+
+ // It would be preferable to lookup the store path using #getConfigurationStringProperty("virtualhosts...")
+ // but the config as known to QBTC does not pull-in the virtualhost section from its separate source file
+ _backupFromDir = new File(qpidWork + "/bdbstore/" + TEST_VHOST + "-store");
+ boolean fromDirExistsAndIsDir = _backupFromDir.isDirectory();
+ assertTrue("backupFromDir " + _backupFromDir + " should already exist", fromDirExistsAndIsDir);
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ FileUtils.delete(_backupToDir, true);
+ }
+ }
+
+ public void testBackupAndRestoreMaintainsMessages() throws Exception
+ {
+ sendNumberedMessages(0, 10);
+ invokeBdbBackup(_backupFromDir, _backupToDir);
+ sendNumberedMessages(10, 20);
+ confirmBrokerHasMessages(0, 20);
+ stopBroker();
+
+ deleteStore(_backupFromDir);
+ replaceStoreWithBackup(_backupToDir, _backupFromDir);
+
+ startBroker();
+ confirmBrokerHasMessages(0, 10);
+ }
+
+ private void sendNumberedMessages(final int startIndex, final int endIndex) throws JMSException, Exception
+ {
+ Connection con = getConnection();
+ Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Destination destination = session.createQueue(getTestQueueName());
+ // Create queue by consumer side-effect
+ session.createConsumer(destination).close();
+
+ final int numOfMessages = endIndex - startIndex;
+ final int batchSize = 0;
+ sendMessage(session, destination, numOfMessages, startIndex, batchSize);
+ con.close();
+ }
+
+ private void confirmBrokerHasMessages(final int startIndex, final int endIndex) throws Exception
+ {
+ Connection con = getConnection();
+ Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ con.start();
+ Destination destination = session.createQueue(getTestQueueName());
+ MessageConsumer consumer = session.createConsumer(destination);
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ Message msg = consumer.receive(RECEIVE_TIMEOUT);
+ assertNotNull("Message " + i + " not received", msg);
+ assertEquals("Did not receive the expected message", i, msg.getIntProperty(INDEX));
+ }
+
+ Message msg = consumer.receive(100);
+ if(msg != null)
+ {
+ fail("No more messages should be received, but received additional message with index: " + msg.getIntProperty(INDEX));
+ }
+ con.close();
+ }
+
+ private void invokeBdbBackup(final File backupFromDir, final File backupToDir) throws Exception
+ {
+ if (String.valueOf(System.getProperty("os.name")).toLowerCase().contains("windows"))
+ {
+ BDBBackup.main(new String[]{"-todir", backupToDir.getAbsolutePath(), "-fromdir", backupFromDir.getAbsolutePath()});
+ }
+ else
+ {
+ runBdbBackupScript(backupFromDir, backupToDir);
+ }
+ }
+
+ private void runBdbBackupScript(final File backupFromDir, final File backupToDir) throws IOException,
+ InterruptedException
+ {
+ Process backupProcess = null;
+ try
+ {
+ String qpidHome = System.getProperty(QPID_HOME);
+ ProcessBuilder pb = new ProcessBuilder(qpidHome + BACKUP_SCRIPT, "-todir", backupToDir.getAbsolutePath(), "-fromdir", backupFromDir.getAbsolutePath());
+ pb.redirectErrorStream(true);
+ Map<String, String> env = pb.environment();
+ env.put(QPID_HOME, qpidHome);
+
+ LOGGER.debug("Backup command is " + pb.command());
+ backupProcess = pb.start();
+ Piper piper = new Piper(backupProcess.getInputStream(), _testcaseOutputStream, null, BACKUP_COMPLETE_MESSAGE);
+ piper.start();
+ piper.await(2, TimeUnit.SECONDS);
+ backupProcess.waitFor();
+ piper.join();
+
+ LOGGER.debug("Backup command completed " + backupProcess.exitValue());
+ assertEquals("Unexpected exit value from backup script", 0, backupProcess.exitValue());
+ }
+ finally
+ {
+ if (backupProcess != null)
+ {
+ backupProcess.getErrorStream().close();
+ backupProcess.getInputStream().close();
+ backupProcess.getOutputStream().close();
+ }
+ }
+ }
+
+ private void replaceStoreWithBackup(File source, File dst) throws Exception
+ {
+ LOGGER.debug("Copying store " + source + " to " + dst);
+ FileUtils.copyRecursive(source, dst);
+ }
+
+ private void deleteStore(File storeDir)
+ {
+ LOGGER.debug("Deleting store " + storeDir);
+ FileUtils.delete(storeDir, true);
+ }
+
+}
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/testclient/BackupTestClient.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/testclient/BackupTestClient.java
deleted file mode 100644
index f6344b3d7d..0000000000
--- a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/testclient/BackupTestClient.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *
- * 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.qpid.server.store.berkeleydb.testclient;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.ping.PingDurableClient;
-import org.apache.qpid.server.store.berkeleydb.BDBBackup;
-import org.apache.qpid.util.CommandLineParser;
-
-import java.util.Properties;
-
-/**
- * BackupTestClient extends {@link PingDurableClient} with an action that takes a BDB backup when a configurable
- * message count is reached. This enables a test user to restore this beackup, knowing how many committed but undelivered
- * messages were in the backup, in order to check that all are re-delivered when the backup is retored.
- *
- * <p><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Perform BDB Backup on configurable message count.
- * </table>
- */
-public class BackupTestClient extends PingDurableClient
-{
- /** Used for debugging. */
- private static final Logger log = Logger.getLogger(BackupTestClient.class);
-
- /** Holds the from directory to take backups from. */
- private String fromDir;
-
- /** Holds the to directory to store backups in. */
- private String toDir;
-
- /**
- * Default constructor, passes all property overrides to the parent.
- *
- * @param overrides Any property overrides to apply to the defaults.
- *
- * @throws Exception Any underlying exception is allowed to fall through.
- */
- BackupTestClient(Properties overrides) throws Exception
- {
- super(overrides);
- }
-
- /**
- * Starts the ping/wait/receive process. From and to directory locations for the BDB backups must be specified
- * on the command line:
- *
- * <p/><table><caption>Command Line</caption>
- * <tr><th> Option <th> Comment
- * <tr><td> -fromdir <td> The path to the directory to back the bdb log file from.
- * <tr><td> -todir <td> The path to the directory to save the backed up bdb log files to.
- * </table>
- *
- * @param args The command line arguments.
- */
- public static void main(String[] args)
- {
- try
- {
- // Use the same command line format as BDBBackup utility, (compulsory from and to directories).
- Properties options =
- CommandLineParser.processCommandLine(args, new CommandLineParser(BDBBackup.COMMAND_LINE_SPEC),
- System.getProperties());
- BackupTestClient pingProducer = new BackupTestClient(options);
-
- // Keep the from and to directories for backups.
- pingProducer.fromDir = options.getProperty("fromdir");
- pingProducer.toDir = options.getProperty("todir");
-
- // Create a shutdown hook to terminate the ping-pong producer.
- Runtime.getRuntime().addShutdownHook(pingProducer.getShutdownHook());
-
- // Ensure that the ping pong producer is registered to listen for exceptions on the connection too.
- // pingProducer.getConnection().setExceptionListener(pingProducer);
-
- // Run the test procedure.
- int sent = pingProducer.send();
- pingProducer.waitForUser("Press return to begin receiving the pings.");
- pingProducer.receive(sent);
-
- System.exit(0);
- }
- catch (Exception e)
- {
- System.err.println(e.getMessage());
- log.error("Top level handler caught execption.", e);
- System.exit(1);
- }
- }
-
- /**
- * Supplies a triggered action extension, based on message count. This action takes a BDB log file backup.
- */
- public void takeAction()
- {
- BDBBackup backupUtil = new BDBBackup();
- backupUtil.takeBackupNoLock(fromDir, toDir);
- System.out.println("Took backup of BDB log files from directory: " + fromDir);
- }
-}