001/** 002 * Copyright 2005-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kew.plugin; 017 018import static org.junit.Assert.assertEquals; 019import static org.junit.Assert.assertFalse; 020import static org.junit.Assert.assertNotNull; 021import static org.junit.Assert.assertTrue; 022 023import java.io.File; 024 025import javax.xml.namespace.QName; 026 027import org.apache.commons.io.FileUtils; 028import org.junit.Test; 029import org.kuali.rice.core.api.config.CoreConfigHelper; 030import org.kuali.rice.kew.test.KEWTestCase; 031import org.kuali.rice.kew.test.TestUtilities; 032 033 034/** 035 * Tests the HotDeployer and Reloader which handle hot deployment and hot reloading 036 * of Plugins. 037 * 038 * @author Kuali Rice Team (rice.collab@kuali.org) 039 */ 040public class HotDeployTest extends KEWTestCase { 041 042 private File pluginDir; 043 044 @Override 045 public void setUp() throws Exception { 046 super.setUp(); 047 TestUtilities.initializePluginDirectories(); 048 this.pluginDir = TestUtilities.getPluginsDirectory(); 049 } 050 051 @Override 052 public void tearDown() throws Exception { 053 super.tearDown(); 054 TestUtilities.cleanupPluginDirectories(); 055 } 056 057 @Test public void testHotDeploy() throws Exception { 058 // Grab the ServerPluginRegistry 059 PluginRegistry theRegistry = PluginUtils.getPluginRegistry(); 060 assertNotNull("PluginRegistry should exist.", theRegistry); 061 assertTrue(theRegistry instanceof ServerPluginRegistry); 062 ServerPluginRegistry registry = (ServerPluginRegistry)theRegistry; 063 064 // Let's shut down the asynchronous reloader and hot deployer because we want to do this synchronously. 065 HotDeployer hotDeployer = registry.getHotDeployer(); 066 Reloader reloader = registry.getReloader(); 067 registry.stopHotDeployer(); 068 registry.stopReloader(); 069 070 // Assert that there are currently no plugins 071 assertEquals("There should be no plugins.", 0, registry.getPluginEnvironments().size()); 072 assertEquals("Resource loader should have no children.", 0, registry.getResourceLoaders().size()); 073 074 // query the hot deployer directly about it's added and removed plugins 075 assertEquals("There should be no plugins added.", 0, hotDeployer.getAddedPlugins().size()); 076 assertEquals("There should be no plugins removed.", 0, hotDeployer.getRemovedPlugins().size()); 077 hotDeployer.run(); 078 assertEquals("There should still be no plugins.", 0, registry.getPluginEnvironments().size()); 079 080 // now let's copy a plugin over and run the hot deployer 081 String pluginZipFileLocation = getBaseDir() + "/src/test/resources/org/kuali/rice/kew/plugin/ziptest.zip"; 082 File pluginZipFile = new File(pluginZipFileLocation); 083 assertTrue("Plugin file '" + pluginZipFileLocation + "' should exist", pluginZipFile.exists()); 084 assertTrue("Plugin file '" + pluginZipFileLocation + "' should be a file", pluginZipFile.isFile()); 085 FileUtils.copyFileToDirectory(pluginZipFile, pluginDir); 086 087 assertEquals("There should be one plugin added.", 1, hotDeployer.getAddedPlugins().size()); 088 assertEquals("There should be no plugins removed.", 0, hotDeployer.getRemovedPlugins().size()); 089 090 hotDeployer.run(); 091 092 // the plugin should have been hot deployed 093 assertEquals("Plugin should have been hot deployed.", 1, registry.getPluginEnvironments().size()); 094 095 // check added plugins again, it should now indicate no new added plugins 096 assertEquals("There should be no plugins added.", 0, hotDeployer.getAddedPlugins().size()); 097 assertEquals("There should be no plugins removed.", 0, hotDeployer.getRemovedPlugins().size()); 098 099 // verify that the resource loading and the registry are sane and properly set up with the new plugin 100 assertEquals("Resource loader should have 1 plugin child.", 1, registry.getResourceLoaders().size()); 101 Plugin plugin = (Plugin)registry.getResourceLoaders().get(0); 102 assertEquals("Plugin has wrong name.", new QName(CoreConfigHelper.getApplicationId(), "ziptest"), plugin.getName()); 103 assertTrue("Plugin should be started.", plugin.isStarted()); 104 assertEquals("Plugin in resource loader and environment should be the same.", plugin, registry.getPluginEnvironment(plugin.getName().getLocalPart()).getPlugin()); 105 106 // The reloader should have a reference to the environment 107 assertEquals("Reloader should have a reference to environment.", 1, reloader.getReloadables().size()); 108 109 // now remove the plugin and ensure that it goes away 110 FileUtils.forceDelete(new File(pluginDir, "ziptest.zip")); 111 assertEquals("There should be no plugins added.", 0, hotDeployer.getAddedPlugins().size()); 112 assertEquals("There should be one plugin removed.", 1, hotDeployer.getRemovedPlugins().size()); 113 hotDeployer.run(); 114 115 // verify that the resource loading and the registry no longer contain the plugin 116 assertEquals("No plugins should be deployed.", 0, registry.getPluginEnvironments().size()); 117 assertEquals("Resource loader should have 0 plugin children.", 0, registry.getResourceLoaders().size()); 118 119 // also assert that the reloader no longer has a reference to the environment 120 assertEquals("Reloader should no longer have reference to environment.", 0, reloader.getReloadables().size()); 121 122 } 123 124 @Test public void testReloader() throws Exception { 125 // Grab the ServerPluginRegistry 126 PluginRegistry theRegistry = PluginUtils.getPluginRegistry(); 127 assertNotNull("PluginRegistry should exist.", theRegistry); 128 assertTrue(theRegistry instanceof ServerPluginRegistry); 129 ServerPluginRegistry registry = (ServerPluginRegistry)theRegistry; 130 131 // Let's shut down the asynchronous reloader and hot deployer because we want to do this synchronously. 132 HotDeployer hotDeployer = registry.getHotDeployer(); 133 Reloader reloader = registry.getReloader(); 134 registry.stopHotDeployer(); 135 registry.stopReloader(); 136 137 // Assert that there are currently no plugins 138 assertEquals("There should be no plugins.", 0, registry.getPluginEnvironments().size()); 139 assertEquals("Resource loader should have no children.", 0, registry.getResourceLoaders().size()); 140 141 // now let's copy a plugin over and run the hot deployer 142 String pluginZipFileLocation = getBaseDir() + "/src/test/resources/org/kuali/rice/kew/plugin/ziptest.zip"; 143 File pluginZipFile = new File(pluginZipFileLocation); 144 assertTrue("Plugin file '" + pluginZipFileLocation + "' should exist", pluginZipFile.exists()); 145 assertTrue("Plugin file '" + pluginZipFileLocation + "' should be a file", pluginZipFile.isFile()); 146 FileUtils.copyFileToDirectory(pluginZipFile, pluginDir); 147 148 // update pluginZipFile to point to the copy 149 pluginZipFile = new File(pluginDir, pluginZipFile.getName()); 150 assertTrue(pluginZipFile.exists()); 151 152 // execute a hot deploy 153 hotDeployer.run(); 154 155 // the plugin should have been hot deployed 156 assertEquals("Plugin should have been hot deployed.", 1, registry.getPluginEnvironments().size()); 157 assertEquals("Resource loader should have 1 plugin child.", 1, registry.getResourceLoaders().size()); 158 PluginEnvironment environment = registry.getPluginEnvironments().get(0); 159 Plugin plugin = environment.getPlugin(); 160 assertTrue(environment.isReloadable()); 161 assertFalse(environment.isReloadNeeded()); 162 163 // let's attempt to execute a Reload 164 reloader.run(); 165 166 // a reload should not have occurred here since nothing was updated 167 assertTrue("Original plugin should still be running.", plugin.isStarted()); 168 assertEquals("Plugin should not have changed.", plugin, registry.getPluginEnvironments().get(0).getPlugin()); 169 170 // touch the plugin file and then reload 171 FileUtils.touch(pluginZipFile); 172 assertTrue("A reload should be needed now.", environment.isReloadNeeded()); 173 reloader.run(); 174 175 // the original plugin should now be stopped 176 assertTrue("original plugin should be stopped.", !plugin.isStarted()); 177 assertEquals("There should only be one Plugin.", 1, registry.getResourceLoaders().size()); 178 179 PluginEnvironment newPluginEnvironment = registry.getPluginEnvironments().get(0); 180 Plugin newPlugin = newPluginEnvironment.getPlugin(); 181 assertEquals("There should still only be one environment.", 1, registry.getPluginEnvironments().size()); 182 assertEquals("The plugin environments should still be the same.", environment, registry.getPluginEnvironments().get(0)); 183 184 assertFalse("The old and new plugins should be different.", newPlugin.equals(plugin)); 185 186 // verify that the resource loader was updated 187 assertEquals("The resource loaders should have been updated with the new plugin.", newPlugin, registry.getResourceLoaders().get(0)); 188 189 } 190 191 192}