Java tutorial
/* * Weblounge: Web Content Management System * Copyright (c) 2003 - 2011 The Weblounge Team * http://entwinemedia.com/weblounge * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package ch.entwine.weblounge.kernel.command; import ch.entwine.weblounge.common.impl.util.WebloungeDateFormat; import ch.entwine.weblounge.common.impl.util.config.ConfigurationUtils; import ch.entwine.weblounge.common.site.Environment; import ch.entwine.weblounge.common.site.Site; import ch.entwine.weblounge.testing.IntegrationTest; import org.apache.commons.lang.StringUtils; import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Dictionary; import java.util.Hashtable; import java.util.List; /** * OSGi shell command implementation for the test harness. */ public final class TestCommand { /** Logger */ private static final Logger logger = LoggerFactory.getLogger(TestCommand.class); /** The tests */ private final List<IntegrationTest> tests = new ArrayList<IntegrationTest>(); /** The current environment */ private Environment environment = null; /** Comparator used to get the test suite in order */ private static final IntegrationTestComparator testComparator = new IntegrationTestComparator(); /** * Callback for OSGi's declarative services component activation. * * @param context * the component context * @throws Exception * if component activation fails */ void activate(ComponentContext context) { BundleContext bundleContext = context.getBundleContext(); logger.debug("Registering test commands"); Dictionary<String, Object> commands = new Hashtable<String, Object>(); commands.put("osgi.command.scope", "weblounge"); commands.put("osgi.command.function", new String[] { "lt", "test", "tests" }); bundleContext.registerService(getClass().getName(), this, commands); } /** * Adds <code>test</code> to the list of integration tests. This method will * usually be called as a result of on {@link IntegrationTest} being published * in the OSGi service registry. * * @param test * the test implementation */ void addIntegrationTest(IntegrationTest test) { if (!tests.contains(test)) { tests.add(test); Collections.sort(tests, testComparator); logger.debug("Installing {}", test.getName()); } } /** * Removes <code>test</code> from the list of integration tests. This method * will usually be called as a result of on {@link IntegrationTest} * disappearing from the OSGi service registry. * * @param test * the test to remove */ void removeIntegrationTest(IntegrationTest test) { tests.remove(test); logger.debug("Removed {}", test.getName()); } /** * Command signature that allows to do * <ul> * <li><code>test list</code></li> * <li><code>test all</code></li> * <li><code>test <id></li> * </ul> * * @param args * the list of arguments to this command */ public void test(String[] args) { if (args.length == 0) { list(); return; } else if (args.length == 1) { if ("list".equals(args[0])) { list(); } else if ("all".equals(args[0])) { if (environment == null) { System.out.println("Environment is still unknown"); return; } executeAll(tests); } else { if (environment == null) { System.out.println("Environment is still unknown"); return; } String id = args[0]; // Look up the test IntegrationTest test = null; try { int testIndex = Integer.parseInt(id); test = tests.get(testIndex - 1); List<IntegrationTest> tests = new ArrayList<IntegrationTest>(); tests.add(test); executeAll(tests); } catch (NumberFormatException e) { System.out.println("Unknown test: " + id); return; } catch (IndexOutOfBoundsException e) { System.out.println("Unknown test: " + id + " Please choose between [1.." + tests.size() + "]"); return; } } } else { printUsage(); } } /** * OSGi callback to set the environment. * * @param environment * the environment */ void setEnvironment(Environment environment) { this.environment = environment; } /** * Prints a list of currently registered tests. */ private void list() { // Are there any tests? if (tests.size() == 0) { System.out.println("No tests found"); return; } // Memorize the group String currentGroup = ""; // Display the test list for (int i = 0; i < tests.size(); i++) { IntegrationTest test = tests.get(i); String group = StringUtils.trimToEmpty(test.getGroup()); if ("".equals(group)) group = "DEFAULT"; if (!group.equals(currentGroup)) { System.out.println(""); System.out.println(group); System.out.println(" ID|Name"); currentGroup = group; } StringBuffer buf = new StringBuffer(); System.out.format("%5s", Integer.toString(i + 1)); buf.append("|"); buf.append(test.getName()); System.out.println(buf.toString()); } System.out.println(""); } /** * Prints the command usage to the commandline. */ private void printUsage() { System.out.println(" Usage:"); System.out.println(" test list"); System.out.println(" test all"); System.out.println(" test <id>"); } /** * Executes all registered tests. */ private void executeAll(List<IntegrationTest> tests) { List<IntegrationTest> succeeded = new ArrayList<IntegrationTest>(); List<IntegrationTest> failed = new ArrayList<IntegrationTest>(); // Print the test header Date startDate = new Date(); logger.info("------------------------------------------------------------------------"); logger.info("Running Integration Tests"); logger.info("------------------------------------------------------------------------"); logger.info("Tests: " + tests.size()); logger.info("Started at: " + WebloungeDateFormat.formatStatic(startDate)); // Execute the tests for (IntegrationTest test : tests) { if (execute(test)) succeeded.add(test); else failed.add(test); } Date endDate = new Date(); long time = endDate.getTime() - startDate.getTime(); String testcount = Integer.toString(tests.size()); // Print the summary logger.info(" "); logger.info(" "); logger.info("------------------------------------------------------------------------"); logger.info("Test Summary:"); logger.info("------------------------------------------------------------------------"); for (IntegrationTest test : tests) { StringBuffer buf = new StringBuffer(); // Test number int pos = 0; for (int i = 0; i < this.tests.size(); i++) { if (this.tests.get(i) == test) { pos = i + 1; break; } } // Test number String num = Integer.toString(pos); for (int i = num.length(); i < testcount.length(); i++) buf.append(" "); buf.append(num); buf.append(" "); // Test name buf.append(test.getName()); buf.append(" "); int testNameLenght = buf.length(); if (succeeded.contains(test)) { for (int i = 0; i < 64 - testNameLenght; i++) buf.append("."); buf.append(" SUCCESS"); } else { for (int i = 0; i < 64 - testNameLenght; i++) buf.append("."); buf.append(" FAILURE"); } logger.info(buf.toString()); pos++; } logger.info("------------------------------------------------------------------------"); logger.info("------------------------------------------------------------------------"); if (failed.size() == 0) logger.info("SUCCESS: " + succeeded.size() + " TEST" + (succeeded.size() > 1 ? "S" : "") + " PASSED"); else logger.info("FAILURE: " + failed.size() + " TEST" + (succeeded.size() > 1 ? "S" : "") + " FAILED"); logger.info("------------------------------------------------------------------------"); logger.info("Total time: " + ConfigurationUtils.toHumanReadableDuration(time)); logger.info("Finished at: " + WebloungeDateFormat.formatStatic(endDate)); logger.info("------------------------------------------------------------------------"); } /** * Executes a single integration test and returns <code>true</code> if the * test passed, <code>false</code> otherwise. * * @param test * the test to run * @return <code>true</code> if the test passed */ private boolean execute(IntegrationTest test) { logger.info(""); logger.info("------------------------------------------------------------------------"); logger.info("Running test '" + test + "'"); logger.info("------------------------------------------------------------------------"); try { Site site = test.getSite(); if (site == null) { logger.warn("Test {} has no site associated", test.getName()); return false; } test.init(environment); test.execute(test.getSite().getHostname(environment).toExternalForm()); logger.info("Test '" + test + "' succeeded"); return true; } catch (Throwable t) { logger.warn("Test '" + test + "' failed: {}", t.getMessage(), t); return false; } } /** * Helper class used to sort the integration tests. */ private static final class IntegrationTestComparator implements Comparator<IntegrationTest> { /** * Creates a new comparator. */ IntegrationTestComparator() { // Nothing to do here. } /** * {@inheritDoc} * * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ public int compare(IntegrationTest test, IntegrationTest otherTest) { // Sort by test group String testGroup = StringUtils.trimToEmpty(test.getGroup()); String otherTestGroup = StringUtils.trimToEmpty(otherTest.getGroup()); int groupComparison = testGroup.compareTo(otherTestGroup); if (groupComparison != 0) { if (IntegrationTest.WEBLOUNGE_CONTENT_TEST_GROUP.equals(testGroup)) return -1; else if (IntegrationTest.WEBLOUNGE_ENDPOINT_TEST_GROUP.equals(otherTestGroup)) return -1; else if (IntegrationTest.WEBLOUNGE_CONTENT_TEST_GROUP.equals(otherTestGroup)) return 1; else if (IntegrationTest.WEBLOUNGE_ENDPOINT_TEST_GROUP.equals(otherTestGroup)) return 1; return groupComparison; } // Sort by order Integer testOrder = Integer.valueOf(test.getExecutionOrder()); Integer otherTestOrder = Integer.valueOf(otherTest.getExecutionOrder()); int orderComparison = testOrder.compareTo(otherTestOrder); if (orderComparison != 0) return orderComparison; return test.getName().compareTo(otherTest.getName()); } } }