diff options
| author | Robert Gemmell <robbie@apache.org> | 2013-09-23 23:42:30 +0000 |
|---|---|---|
| committer | Robert Gemmell <robbie@apache.org> | 2013-09-23 23:42:30 +0000 |
| commit | 469aa371040b2e0685f269937a4e49527a35e00c (patch) | |
| tree | 3896ba9cbfa5c23e9ebc187e25e673a253903670 /qpid/java/qpid-test-utils/src | |
| parent | 59710ea96cf37dc3859ada1dc5fb095b0b2bc6b4 (diff) | |
| download | qpid-python-469aa371040b2e0685f269937a4e49527a35e00c.tar.gz | |
QPID-5160: add a qpid-test-utils module instead of making every modules tests rely on the tests dir from the common module
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1525738 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/qpid-test-utils/src')
4 files changed, 681 insertions, 0 deletions
diff --git a/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/PortHelper.java b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/PortHelper.java new file mode 100644 index 0000000000..d3586c364f --- /dev/null +++ b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/PortHelper.java @@ -0,0 +1,127 @@ +/* + * 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.test.utils; + +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.ServerSocket; +import java.util.Set; + +import org.apache.log4j.Logger; + +public class PortHelper +{ + private static final Logger _logger = Logger.getLogger(PortHelper.class); + + private static final int DEFAULT_TIMEOUT_MILLIS = 5000; + + private int timeout = DEFAULT_TIMEOUT_MILLIS; + + public void waitUntilPortsAreFree(Set<Integer> ports) + { + _logger.debug("Checking if ports " + ports + " are free..."); + + for (Integer port : ports) + { + waitUntilPortIsFree(port); + } + + _logger.debug("ports " + ports + " are free"); + } + + private void waitUntilPortIsFree(int port) + { + long startTime = System.currentTimeMillis(); + long deadline = startTime + timeout; + boolean alreadyFailed = false; + + while (true) + { + if (System.currentTimeMillis() > deadline) + { + throw new RuntimeException("Timed out after " + timeout + " ms waiting for port " + port + " to become available"); + } + + if (isPortAvailable(port)) + { + if(alreadyFailed) + { + _logger.debug("port " + port + " is now available"); + } + return; + } + else + { + alreadyFailed = true; + } + + try + { + Thread.sleep(500); + } + catch (InterruptedException e) + { + Thread.currentThread().interrupt(); + } + } + } + + public boolean isPortAvailable(int port) + { + ServerSocket serverSocket = null; + DatagramSocket datagramSocket = null; + + try + { + serverSocket = new ServerSocket(port); + serverSocket.setReuseAddress(true); // ensures that the port is subsequently usable + datagramSocket = new DatagramSocket(port); + datagramSocket.setReuseAddress(true); + return true; + } + catch (IOException e) + { + _logger.debug("port " + port + " is not free"); + return false; + } + finally + { + if (serverSocket != null) + { + try + { + serverSocket.close(); + } + catch (IOException e) + { + throw new RuntimeException("Couldn't close port " + port + " that we created to check its availability", e); + } + } + if(datagramSocket != null) + { + datagramSocket.close(); + } + } + } + + public void setTimeout(int timeout) + { + this.timeout = timeout; + } +} diff --git a/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java new file mode 100644 index 0000000000..8f556ece5a --- /dev/null +++ b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java @@ -0,0 +1,284 @@ +/* + * + * 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.test.utils; + +import junit.framework.TestCase; +import junit.framework.TestResult; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + + +public class QpidTestCase extends TestCase +{ + public static final String QPID_HOME = System.getProperty("QPID_HOME"); + public static final String TEST_RESOURCES_DIR = QPID_HOME + "/../test-profiles/test_resources/"; + public static final String TMP_FOLDER = System.getProperty("java.io.tmpdir"); + public static final String LOG4J_CONFIG_FILE_PATH = System.getProperty("log4j.configuration.file"); + + private static final Logger _logger = Logger.getLogger(QpidTestCase.class); + + private final Map<Logger, Level> _loggerLevelSetForTest = new HashMap<Logger, Level>(); + private final Map<String, String> _propertiesSetForTest = new HashMap<String, String>(); + + private String _testName; + + /** + * Some tests are excluded when the property test.excludes is set to true. + * An exclusion list is either a file (prop test.excludesfile) which contains one test name + * to be excluded per line or a String (prop test.excludeslist) where tests to be excluded are + * separated by " ". Excluded tests are specified following the format: + * className#testName where className is the class of the test to be + * excluded and testName is the name of the test to be excluded. + * className#* excludes all the tests of the specified class. + */ + static + { + if (Boolean.getBoolean("test.exclude")) + { + _logger.info("Some tests should be excluded, building the exclude list"); + String exclusionListURIs = System.getProperties().getProperty("test.excludefiles", ""); + String exclusionListString = System.getProperties().getProperty("test.excludelist", ""); + List<String> exclusionList = new ArrayList<String>(); + + for (String uri : exclusionListURIs.split(";\\s*")) + { + File file = new File(uri); + if (file.exists()) + { + _logger.info("Using exclude file: " + uri); + try + { + BufferedReader in = new BufferedReader(new FileReader(file)); + String excludedTest = in.readLine(); + do + { + exclusionList.add(excludedTest); + excludedTest = in.readLine(); + } + while (excludedTest != null); + } + catch (IOException e) + { + _logger.warn("Exception when reading exclusion list", e); + } + } + else + { + _logger.info("Specified exclude file does not exist: " + uri); + } + } + + if (!exclusionListString.equals("")) + { + _logger.info("Using excludeslist: " + exclusionListString); + for (String test : exclusionListString.split("\\s+")) + { + exclusionList.add(test); + } + } + + _exclusionList = exclusionList; + } + } + + protected static final String MESSAGE_STORE_CLASS_NAME_KEY = "messagestore.class.name"; + protected static final String CONFIGURATION_STORE_CLASS_NAME_KEY = "configurationstore.class.name"; + + protected static final String MEMORY_STORE_CLASS_NAME = "org.apache.qpid.server.store.MemoryMessageStore"; + + private static List<String> _exclusionList; + + public QpidTestCase() + { + super(); + } + + public void run(TestResult testResult) + { + if (_exclusionList != null && (_exclusionList.contains(getClass().getPackage().getName() + ".*") || + _exclusionList.contains(getClass().getName() + "#*") || + _exclusionList.contains(getClass().getName() + "#" + getName()))) + { + _logger.info("Test: " + getName() + " is excluded"); + testResult.endTest(this); + } + else + { + super.run(testResult); + } + } + + public String getTestProfileMessageStoreClassName() + { + final String storeClass = System.getProperty(MESSAGE_STORE_CLASS_NAME_KEY); + _logger.debug("MESSAGE_STORE_CLASS_NAME_KEY " + storeClass); + + return storeClass != null ? storeClass : MEMORY_STORE_CLASS_NAME ; + } + + + public static final int MIN_PORT_NUMBER = 1; + public static final int MAX_PORT_NUMBER = 49151; + + + /** + * Gets the next available port starting at a port. + * + * @param fromPort the port to scan for availability + * @throws NoSuchElementException if there are no ports available + */ + public int getNextAvailable(int fromPort) + { + if ((fromPort < MIN_PORT_NUMBER) || (fromPort > MAX_PORT_NUMBER)) + { + throw new IllegalArgumentException("Invalid start port: " + fromPort); + } + + PortHelper portHelper = new PortHelper(); + for (int i = fromPort; i <= MAX_PORT_NUMBER; i++) + { + if (portHelper.isPortAvailable(i)) { + return i; + } + } + + throw new NoSuchElementException("Could not find an available port above " + fromPort); + } + + public int findFreePort() + { + return getNextAvailable(10000); + } + + /** + * Set a System property for duration of this test only. The tearDown will + * guarantee to reset the property to its previous value after the test + * completes. + * + * @param property The property to set + * @param value the value to set it to, if null, the property will be cleared + */ + protected void setTestSystemProperty(final String property, final String value) + { + if (!_propertiesSetForTest.containsKey(property)) + { + // Record the current value so we can revert it later. + _propertiesSetForTest.put(property, System.getProperty(property)); + } + + if (value == null) + { + System.clearProperty(property); + } + else + { + System.setProperty(property, value); + } + + _logger.info("Set system property \"" + property + "\" to: \"" + value + "\""); + } + + /** + * Restore the System property values that were set by this test run. + */ + protected void revertTestSystemProperties() + { + if(!_propertiesSetForTest.isEmpty()) + { + _logger.debug("reverting " + _propertiesSetForTest.size() + " test properties"); + for (String key : _propertiesSetForTest.keySet()) + { + String value = _propertiesSetForTest.get(key); + if (value != null) + { + System.setProperty(key, value); + } + else + { + System.clearProperty(key); + } + } + + _propertiesSetForTest.clear(); + } + } + + /** + * Adjust the VMs Log4j Settings just for this test run + * + * @param logger the logger to change + * @param level the level to set + */ + protected void setLoggerLevel(Logger logger, Level level) + { + assertNotNull("Cannot set level of null logger", logger); + assertNotNull("Cannot set Logger("+logger.getName()+") to null level.",level); + + if (!_loggerLevelSetForTest.containsKey(logger)) + { + // Record the current value so we can revert it later. + _loggerLevelSetForTest.put(logger, logger.getLevel()); + } + + logger.setLevel(level); + } + + /** + * Restore the logging levels defined by this test. + */ + protected void revertLoggingLevels() + { + for (Logger logger : _loggerLevelSetForTest.keySet()) + { + logger.setLevel(_loggerLevelSetForTest.get(logger)); + } + + _loggerLevelSetForTest.clear(); + } + + protected void tearDown() throws java.lang.Exception + { + _logger.info("========== tearDown " + _testName + " =========="); + revertTestSystemProperties(); + revertLoggingLevels(); + } + + protected void setUp() throws Exception + { + _testName = getClass().getSimpleName() + "." + getName(); + _logger.info("========== start " + _testName + " =========="); + } + + protected String getTestName() + { + return _testName; + } +} diff --git a/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java new file mode 100644 index 0000000000..d04413f06f --- /dev/null +++ b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java @@ -0,0 +1,233 @@ +/* + * + * 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.test.utils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import java.io.FileOutputStream; + +import junit.framework.TestCase; + +/** + * Utility methods intended to be used in tests that manipulate files + */ +public class TestFileUtils +{ + private static final String SYSTEM_TMP_DIR = System.getProperty("java.io.tmpdir"); + private static final String SUFFIX = "tmp"; + + /** + * Create and return a temporary directory that will be deleted on exit. + */ + public static File createTestDirectory() + { + String dirNameStem = TestFileUtils.class.getSimpleName() + "-testDir"; + return createTestDirectory(dirNameStem, true); + } + + /** + * Creates an empty directory with a name like /tmp/dirNameStem-12345678 + */ + public static File createTestDirectory(String dirNameStem, boolean deleteOnExit) + { + File testDir = new File(SYSTEM_TMP_DIR, dirNameStem + "-" + System.currentTimeMillis()); + if (testDir.exists()) + { + delete(testDir, true); + } + + testDir.mkdirs(); + + if (deleteOnExit) + { + testDir.deleteOnExit(); + } + + return testDir; + } + + public static File createTempFile(TestCase testcase) + { + return createTempFile(testcase, SUFFIX); + } + + public static File createTempFile(TestCase testcase, String suffix) + { + String prefix = testcase.getClass().getSimpleName() + "-" + testcase.getName(); + + File tmpFile; + try + { + tmpFile = File.createTempFile(prefix, suffix); + tmpFile.deleteOnExit(); + } + catch (IOException e) + { + throw new RuntimeException("Cannot create temporary file with prefix " + prefix + " and suffix " + SUFFIX, e); + } + + return tmpFile; + } + + /** + * Creates a temporary file from the resource name given, using the resource name as the file suffix. + * + * This is required because the tests use the jar files as their class path. + */ + public static File createTempFileFromResource(TestCase testCase, String resourceName) + { + File dst = createTempFile(testCase, resourceName); + InputStream in = testCase.getClass().getResourceAsStream(resourceName); + try + { + copy(in, dst); + } + catch (Exception e) + { + throw new RuntimeException("Cannot copy resource " + resourceName + + " to temp file " + dst.getAbsolutePath(), e); + } + dst.deleteOnExit(); + return dst; + } + + /** + * Creates a temporary file for given test with given suffix in file name. + * The given content is stored in the file using UTF-8 encoding. + */ + public static File createTempFile(TestCase testcase, String suffix, String content) + { + File file = createTempFile(testcase, suffix); + if (content != null) + { + FileOutputStream fos = null; + try + { + fos = new FileOutputStream(file); + fos.write(content.getBytes("UTF-8")); + fos.flush(); + } + catch (Exception e) + { + throw new RuntimeException("Cannot add the content into temp file " + file.getAbsolutePath(), e); + } + finally + { + if (fos != null) + { + try + { + fos.close(); + } + catch (IOException e) + { + throw new RuntimeException("Cannot close output stream into temp file " + file.getAbsolutePath(), e); + } + } + } + } + return file; + } + + /** + * Delete a given file/directory, + * A directory will always require the recursive flag to be set. + * if a directory is specified and recursive set then delete the whole tree + * + * @param file the File object to start at + * @param recursive boolean to recurse if a directory is specified. + * + * @return <code>true</code> if and only if the file or directory is + * successfully deleted; <code>false</code> otherwise + */ + public static boolean delete(File file, boolean recursive) + { + boolean success = true; + + if (file.isDirectory()) + { + if (recursive) + { + File[] files = file.listFiles(); + + // This can occur if the file is deleted outside the JVM + if (files == null) + { + return false; + } + + for (int i = 0; i < files.length; i++) + { + success = delete(files[i], true) && success; + } + + return success && file.delete(); + } + + return false; + } + + return file.delete(); + } + + /** + * Copies the specified InputStream to the specified destination file. If the destination file does not exist, + * it is created. + * + * @param in The InputStream + * @param dst The destination file name. + * @throws IOException + */ + public static void copy(InputStream in, File dst) throws IOException + { + try + { + if (!dst.exists()) + { + dst.createNewFile(); + } + + OutputStream out = new FileOutputStream(dst); + + try + { + // Transfer bytes from in to out + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) + { + out.write(buf, 0, len); + } + } + finally + { + out.close(); + } + } + finally + { + in.close(); + } + } +} diff --git a/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java new file mode 100644 index 0000000000..c48f164d98 --- /dev/null +++ b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java @@ -0,0 +1,37 @@ +/* + * 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.test.utils; + +public interface TestSSLConstants +{ + String KEYSTORE = "test-profiles/test_resources/ssl/java_client_keystore.jks"; + String UNTRUSTED_KEYSTORE = "test-profiles/test_resources/ssl/java_client_untrusted_keystore.jks"; + String KEYSTORE_PASSWORD = "password"; + String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks"; + String TRUSTSTORE_PASSWORD = "password"; + + String BROKER_KEYSTORE = "test-profiles/test_resources/ssl/java_broker_keystore.jks"; + String BROKER_KEYSTORE_PASSWORD = "password"; + + String BROKER_PEERSTORE = "test-profiles/test_resources/ssl/java_broker_peerstore.jks"; + String BROKER_PEERSTORE_PASSWORD = "password"; + + String BROKER_TRUSTSTORE = "test-profiles/test_resources/ssl/java_broker_truststore.jks"; + String BROKER_TRUSTSTORE_PASSWORD = "password"; +} |
