/* * Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The * University of Hong Kong (HKU). All Rights Reserved. * * This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1] * * [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */ package hk.hku.cecid.piazza.commons.swallow; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Properties; import org.junit.Ignore; import org.junit.Test; import org.junit.Assert; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import static org.hamcrest.CoreMatchers.*; import hk.hku.cecid.piazza.commons.swallow.ShutdownHookEmailModule; import hk.hku.cecid.piazza.commons.swallow.ShutdownHookEmailThread; import hk.hku.cecid.piazza.commons.test.ModuleTest; import hk.hku.cecid.piazza.commons.util.Instance; import hk.hku.cecid.piazza.commons.util.StringUtilities; /** * The <code>ShutdownHookEmailModuleUnitTest</code> is unit test of <code>ShutdownHookEmailModule</code>. * * @author Twinsen Tsang * @version 1.0.0 * @since JDK5.0, H2O 0908 */ @RunWith(Parameterized.class) public class ShutdownHookEmailModuleUnitTest extends ModuleTest<ShutdownHookEmailModule> { public static final String [] MODULE_DESCRIPTORS = { "shutdown.hook.email.module.def.xml", "shutdown.hook.email.module.rand.xml", }; @SuppressWarnings("unchecked") @Parameters public static Collection getModuleDescriptionSet() { List<Object[]> parameters = new ArrayList<Object[]>(); for (int i = 0; i < MODULE_DESCRIPTORS.length; i++) { parameters.add(new Object[]{MODULE_DESCRIPTORS[i]}); } return parameters; } private String moduleDescriptor; /* (non-JAVADOC) * @see hk.hku.cecid.piazza.commons.test.ModuleTest#getModuleDescription() */ @Override public String getModuleDescription() { return moduleDescriptor; } /* (non-JAVADOC) * @see hk.hku.cecid.piazza.commons.test.ModuleTest#initAtOnce() */ @Override public boolean initAtOnce() { return true; } /** * Create an instance of parameterized (parameter=module descriptor) ShutdownHookEmailModuleUnitTest. * * @param moduleDescriptor The parameterized module descriptor. */ public ShutdownHookEmailModuleUnitTest(String moduleDescriptor) { this.moduleDescriptor = moduleDescriptor; } /** * Test whether {@link ShutdownHookEmailModule#getThread()} always return non null value. */ @Test public void testGetThread() { Assert.assertNotNull("The worker is always not-null", super.getTestingTarget().getThread()); } /** * Test whether the thread from {@link ShutdownHookEmailModule#getThread()} is registered inside the runtime shutdown hook. */ @Test public void testShutdownHookRegisteredToRuntime() throws Throwable { Assert.assertTrue( "The mail shutdown hook has not been registered to runtime", Runtime.getRuntime().removeShutdownHook(this.getTestingTarget().getThread())); } /** * This test has not implemented yet because it is not a automated test case (it is for debugging purpose only). */ @Test @Ignore public void testStop() { super.getTestingTarget().stop(); } public static class CreateShudownHookWorkerAssertionThread extends Thread { private Properties p; private Thread shutdownThread; public CreateShudownHookWorkerAssertionThread(Properties assertionProperties, Thread shutdownThread) { this.p = assertionProperties; this.shutdownThread = shutdownThread; } public void run() { Assert.assertThat("Email shutdown hook must be instance of ShutdownHookEmailThread.", shutdownThread, instanceOf(ShutdownHookEmailThread.class)); final String host = p.getProperty("host"); final String protocol = p.getProperty("protocol", "smtp"); final String username = p.getProperty("username"); final String password = p.getProperty("password"); final String from = p.getProperty("from", "commonDaemon@cecid.hku.hk"); final String tos = p.getProperty("to"); final String ccs = p.getProperty("cc"); final String subject = p.getProperty("subject", ShutdownHookEmailThread.DEFAULT_SHUTDOWN_MAIL_SUBJECT); final boolean verbose = StringUtilities.parseBoolean(p.getProperty("verbose"), false); ShutdownHookEmailThread shutdownEmailThread = (ShutdownHookEmailThread) shutdownThread; Assert.assertEquals("Protocol does not as expect", protocol, shutdownEmailThread.getProtocol()); Assert.assertEquals("Host does not as expect" , host , shutdownEmailThread.getHost()); Assert.assertEquals("Username does not as expect", username, shutdownEmailThread.getUsername()); Assert.assertEquals("Password does not as expect", password, shutdownEmailThread.getPassword()); Assert.assertEquals("'From' does not as expect" , from , shutdownEmailThread.getFrom()); Assert.assertEquals("'Tos' does not as expect" , tos , shutdownEmailThread.getTos()); Assert.assertEquals("'CCs' does not as expect" , ccs , shutdownEmailThread.getCcs()); Assert.assertEquals("Subject does not as expect" , subject , shutdownEmailThread.getSubject()); Assert.assertEquals("Verbose flag not equal" , verbose , shutdownEmailThread.getIsVerbose()); } } /** * Test whether the {@link ShutdownHookEmailModule#createShutdownHookWorker()} able to wire up * all properties from the module descriptor and it is an instance of ShutdownHookEmailThread. * * Note that the assertion actually take place in a helper class called CreateShudownHookWorkerAssertionThread. * It is essential because the ShutdownHook worker thread is loaded through a clone of current class loader * and therefore the class only appear in that domain. */ @Test public void testCreateShutdownHookWorker() throws Throwable { ShutdownHookEmailModule m = super.getTestingTarget(); final Properties p = m.getParameters(); final Thread shutdownThread = m.createShutdownHookWorker(); final ClassLoader shutdownThreadCL = shutdownThread.getClass().getClassLoader(); /* * Create the helper thread which is in the same domain to the shutdown hook worker. */ Instance ins = new Instance( CreateShudownHookWorkerAssertionThread.class.getName(), shutdownThreadCL, new Class[] {Properties.class, Thread.class}, new Object[]{p, shutdownThread}); Thread helperThread = (Thread) ins.getObject(); /* * Run the helper and assert the properties are wired properly. */ helperThread.setContextClassLoader(shutdownThreadCL); helperThread.run(); } /** * This test has not implemented yet because the mail subject is subject to change. */ @Test @Ignore public void testOnCreateMailNotificationSubject() throws Throwable { } /** * This test has not implemented yet because the mail subject is subject to change. */ @Test @Ignore public void testOnCreateMailNotificationBody() throws Throwable { } /* (non-JAVADOC) * @see hk.hku.cecid.piazza.commons.test.UnitTest#tearDown() */ @Override public void tearDown() throws Exception { super.tearDown(); /* * Stop the module so there is no alert email deliver (suppress some annoying exception) */ ShutdownHookEmailModule m = this.getTestingTarget(); if (m != null) m.stop(); } }