/*************************GO-LICENSE-START*********************************
* Copyright 2015 ThoughtWorks, Inc.
*
* Licensed 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.
*************************GO-LICENSE-END***********************************/
package com.thoughtworks.go.agent;
import com.thoughtworks.go.plugin.infra.PluginManager;
import com.thoughtworks.go.plugin.infra.monitor.DefaultPluginJarLocationMonitor;
import com.thoughtworks.go.util.SystemEnvironment;
import com.thoughtworks.go.util.TestFileUtil;
import com.thoughtworks.go.util.ZipBuilder;
import com.thoughtworks.go.util.ZipUtil;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.io.File;
import java.io.IOException;
import static com.thoughtworks.go.agent.launcher.DownloadableFile.AGENT_PLUGINS;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;
/* Some parts are mocked, as in AgentPluginsInitializerTest, but the file system (through ZipUtil) is not. */
@RunWith(MockitoJUnitRunner.class)
public class AgentPluginsInitializerIntegrationTest {
@Mock
private PluginManager pluginManager;
@Mock
private DefaultPluginJarLocationMonitor pluginJarLocationMonitor;
@Mock
private SystemEnvironment systemEnvironment;
private File directoryForUnzippedPlugins;
private AgentPluginsInitializer agentPluginsInitializer;
@Before
public void setUp() throws Exception {
agentPluginsInitializer = new AgentPluginsInitializer(pluginManager, pluginJarLocationMonitor, new ZipUtil(), systemEnvironment);
directoryForUnzippedPlugins = setupUnzippedPluginsDirectoryStructure();
when(systemEnvironment.get(SystemEnvironment.AGENT_PLUGINS_PATH)).thenReturn(directoryForUnzippedPlugins.getAbsolutePath());
}
@After
public void tearDown() throws Exception {
cleanupAgentPluginsFile();
TestFileUtil.cleanTempFiles();
}
@Test
public void shouldRemoveExistingBundledPluginsBeforeInitializingNewPlugins() throws Exception {
File existingBundledPlugin = new File(directoryForUnzippedPlugins, "bundled/existing-plugin-1.jar");
setupAgentsPluginFile().withBundledPlugin("new-plugin-1.jar", "SOME-PLUGIN-CONTENT").done();
FileUtils.writeStringToFile(existingBundledPlugin, "OLD-CONTENT");
agentPluginsInitializer.onApplicationEvent(null);
assertThat(existingBundledPlugin.exists(), is(false));
assertThat(new File(directoryForUnzippedPlugins, "bundled/new-plugin-1.jar").exists(), is(true));
}
@Test
public void shouldReplaceExistingBundledPluginsWithNewPluginsOfSameName() throws Exception {
File bundledPlugin = new File(directoryForUnzippedPlugins, "bundled/plugin-1.jar");
setupAgentsPluginFile().withBundledPlugin("plugin-1.jar", "SOME-NEW-CONTENT").done();
FileUtils.writeStringToFile(bundledPlugin, "OLD-CONTENT");
agentPluginsInitializer.onApplicationEvent(null);
assertThat(bundledPlugin.exists(), is(true));
assertThat(FileUtils.readFileToString(bundledPlugin), is("SOME-NEW-CONTENT"));
}
@Test
public void shouldRemoveExistingExternalPluginsBeforeInitializingNewPlugins() throws Exception {
File existingExternalPlugin = new File(directoryForUnzippedPlugins, "external/existing-plugin-1.jar");
setupAgentsPluginFile().withExternalPlugin("new-plugin-1.jar", "SOME-PLUGIN-CONTENT").done();
FileUtils.writeStringToFile(existingExternalPlugin, "OLD-CONTENT");
agentPluginsInitializer.onApplicationEvent(null);
assertThat(existingExternalPlugin.exists(), is(false));
assertThat(new File(directoryForUnzippedPlugins, "external/new-plugin-1.jar").exists(), is(true));
}
@Test
public void shouldReplaceExistingExternalPluginsWithNewPluginsOfSameName() throws Exception {
File externalPlugin = new File(directoryForUnzippedPlugins, "external/plugin-1.jar");
setupAgentsPluginFile().withExternalPlugin("plugin-1.jar", "SOME-NEW-CONTENT").done();
FileUtils.writeStringToFile(externalPlugin, "OLD-CONTENT");
agentPluginsInitializer.onApplicationEvent(null);
assertThat(externalPlugin.exists(), is(true));
assertThat(FileUtils.readFileToString(externalPlugin), is("SOME-NEW-CONTENT"));
}
@Test
public void shouldRemoveAnExistingPluginWhenItHasBeenRemovedFromTheServerSide() throws Exception {
File existingExternalPlugin = new File(directoryForUnzippedPlugins, "external/plugin-1.jar");
setupAgentsPluginFile().done();
FileUtils.writeStringToFile(existingExternalPlugin, "OLD-CONTENT");
agentPluginsInitializer.onApplicationEvent(null);
assertThat(existingExternalPlugin.exists(), is(false));
}
private File setupUnzippedPluginsDirectoryStructure() throws IOException {
File dir = TestFileUtil.createTempFolder("unzipped-plugins");
FileUtils.forceMkdir(new File(dir, "bundled"));
FileUtils.forceMkdir(new File(dir, "external"));
return dir;
}
private SetupOfAgentPluginsFile setupAgentsPluginFile() throws IOException {
return new SetupOfAgentPluginsFile(AGENT_PLUGINS.getLocalFile());
}
private void cleanupAgentPluginsFile() throws IOException {
FileUtils.deleteQuietly(AGENT_PLUGINS.getLocalFile());
}
private class SetupOfAgentPluginsFile {
private final File bundledPluginsDir;
private final File externalPluginsDir;
private final ZipUtil zipUtil;
private final File dummyFileSoZipFileIsNotEmpty;
private File pluginsZipFile;
public SetupOfAgentPluginsFile(File pluginsZipFile) throws IOException {
this.pluginsZipFile = pluginsZipFile;
this.bundledPluginsDir = TestFileUtil.createTempFolder("bundled");
this.externalPluginsDir = TestFileUtil.createTempFolder("external");
this.dummyFileSoZipFileIsNotEmpty = TestFileUtil.createTempFile("dummy.txt");
this.zipUtil = new ZipUtil();
}
public SetupOfAgentPluginsFile withBundledPlugin(String pluginFileName, String pluginFileContent) throws IOException {
FileUtils.writeStringToFile(new File(bundledPluginsDir, pluginFileName), pluginFileContent);
return this;
}
public SetupOfAgentPluginsFile withExternalPlugin(String pluginFileName, String pluginFileContent) throws IOException {
FileUtils.writeStringToFile(new File(externalPluginsDir, pluginFileName), pluginFileContent);
return this;
}
public File done() throws IOException {
ZipBuilder zipBuilder = zipUtil.zipContentsOfMultipleFolders(pluginsZipFile, true);
zipBuilder.add("bundled", bundledPluginsDir).add("external", externalPluginsDir).add("dummy.txt", dummyFileSoZipFileIsNotEmpty).done();
return pluginsZipFile;
}
}
}