|
@@ -18,17 +18,18 @@
|
|
|
*/
|
|
|
package org.elasticsearch.plugins;
|
|
|
|
|
|
+import com.google.common.base.Joiner;
|
|
|
import com.google.common.base.Predicate;
|
|
|
import org.apache.http.impl.client.HttpClients;
|
|
|
-import org.apache.lucene.util.IOUtils;
|
|
|
import org.apache.lucene.util.LuceneTestCase;
|
|
|
import org.elasticsearch.ElasticsearchException;
|
|
|
-import org.elasticsearch.ElasticsearchTimeoutException;
|
|
|
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
|
|
|
import org.elasticsearch.action.admin.cluster.node.info.PluginInfo;
|
|
|
+import org.elasticsearch.common.cli.CliTool;
|
|
|
+import org.elasticsearch.common.cli.CliToolTestCase.CaptureOutputTerminal;
|
|
|
import org.elasticsearch.common.collect.Tuple;
|
|
|
+import org.elasticsearch.common.io.Streams;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
-import org.elasticsearch.common.unit.TimeValue;
|
|
|
import org.elasticsearch.env.Environment;
|
|
|
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
|
|
import org.elasticsearch.rest.RestStatus;
|
|
@@ -37,6 +38,8 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
|
|
import org.elasticsearch.test.junit.annotations.Network;
|
|
|
import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
|
|
|
import org.elasticsearch.test.rest.client.http.HttpResponse;
|
|
|
+import org.junit.After;
|
|
|
+import org.junit.Before;
|
|
|
import org.junit.Test;
|
|
|
|
|
|
import java.io.IOException;
|
|
@@ -46,14 +49,16 @@ import java.nio.file.Path;
|
|
|
import java.nio.file.attribute.PosixFileAttributeView;
|
|
|
import java.nio.file.attribute.PosixFileAttributes;
|
|
|
import java.nio.file.attribute.PosixFilePermission;
|
|
|
+import java.util.Locale;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
+import static org.elasticsearch.common.cli.CliTool.ExitStatus.USAGE;
|
|
|
+import static org.elasticsearch.common.cli.CliToolTestCase.args;
|
|
|
import static org.elasticsearch.common.io.FileSystemUtilsTests.assertFileContent;
|
|
|
+import static org.elasticsearch.common.settings.Settings.settingsBuilder;
|
|
|
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
|
|
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertDirectoryExists;
|
|
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertFileExists;
|
|
|
-import static org.hamcrest.CoreMatchers.is;
|
|
|
-import static org.hamcrest.CoreMatchers.not;
|
|
|
import static org.hamcrest.Matchers.*;
|
|
|
|
|
|
@ClusterScope(scope = Scope.TEST, numDataNodes = 0, transportClientRatio = 0.0)
|
|
@@ -62,20 +67,50 @@ import static org.hamcrest.Matchers.*;
|
|
|
// if its in your classpath, then do not use plugins!!!!!!
|
|
|
public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
|
|
|
- @Test(expected = IllegalArgumentException.class)
|
|
|
- public void testDownloadAndExtract_NullName_ThrowsException() throws IOException {
|
|
|
- pluginManager(getPluginUrlForResource("plugin_single_folder.zip")).downloadAndExtract(null);
|
|
|
+ private Tuple<Settings, Environment> initialSettings;
|
|
|
+ private CaptureOutputTerminal terminal = new CaptureOutputTerminal();
|
|
|
+
|
|
|
+ @Before
|
|
|
+ public void setup() throws Exception {
|
|
|
+ initialSettings = buildInitialSettings();
|
|
|
+ System.setProperty("es.default.path.home", initialSettings.v1().get("path.home"));
|
|
|
+ try {
|
|
|
+ Files.createDirectories(initialSettings.v2().pluginsFile());
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ Path binDir = initialSettings.v2().homeFile().resolve("bin");
|
|
|
+ if (!Files.exists(binDir)) {
|
|
|
+ Files.createDirectories(binDir);
|
|
|
+ }
|
|
|
+ Path configDir = initialSettings.v2().configFile();
|
|
|
+ if (!Files.exists(configDir)) {
|
|
|
+ Files.createDirectories(configDir);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @After
|
|
|
+ public void clearPathHome() {
|
|
|
+ System.clearProperty("es.default.path.home");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testThatPluginNameMustBeSupplied() throws IOException {
|
|
|
+ String pluginUrl = getPluginUrlForResource("plugin_single_folder.zip");
|
|
|
+ assertStatus("install --url " + pluginUrl, USAGE);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
public void testLocalPluginInstallSingleFolder() throws Exception {
|
|
|
//When we have only a folder in top-level (no files either) we remove that folder while extracting
|
|
|
String pluginName = "plugin-test";
|
|
|
- Tuple<Settings, Environment> initialSettings = buildInitialSettings();
|
|
|
- downloadAndExtract(pluginName, initialSettings, getPluginUrlForResource("plugin_single_folder.zip"));
|
|
|
+ String pluginUrl = getPluginUrlForResource("plugin_single_folder.zip");
|
|
|
+ String installCommand = String.format(Locale.ROOT, "install %s --url %s", pluginName, pluginUrl);
|
|
|
+ assertStatusOk(installCommand);
|
|
|
|
|
|
internalCluster().startNode(initialSettings.v1());
|
|
|
-
|
|
|
assertPluginLoaded(pluginName);
|
|
|
assertPluginAvailable(pluginName);
|
|
|
}
|
|
@@ -83,45 +118,30 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
@Test
|
|
|
public void testLocalPluginInstallWithBinAndConfig() throws Exception {
|
|
|
String pluginName = "plugin-test";
|
|
|
- Tuple<Settings, Environment> initialSettings = buildInitialSettings();
|
|
|
Environment env = initialSettings.v2();
|
|
|
Path binDir = env.homeFile().resolve("bin");
|
|
|
- if (!Files.exists(binDir)) {
|
|
|
- Files.createDirectories(binDir);
|
|
|
- }
|
|
|
Path pluginBinDir = binDir.resolve(pluginName);
|
|
|
- Path configDir = env.configFile();
|
|
|
- if (!Files.exists(configDir)) {
|
|
|
- Files.createDirectories(configDir);
|
|
|
- }
|
|
|
- Path pluginConfigDir =configDir.resolve(pluginName);
|
|
|
- try {
|
|
|
-
|
|
|
- PluginManager pluginManager = pluginManager(getPluginUrlForResource("plugin_with_bin_and_config.zip"), initialSettings);
|
|
|
-
|
|
|
- pluginManager.downloadAndExtract(pluginName);
|
|
|
-
|
|
|
- Path[] plugins = pluginManager.getListInstalledPlugins();
|
|
|
-
|
|
|
- assertThat(plugins, arrayWithSize(1));
|
|
|
- assertDirectoryExists(pluginBinDir);
|
|
|
- assertDirectoryExists(pluginConfigDir);
|
|
|
- Path toolFile = pluginBinDir.resolve("tool");
|
|
|
- assertFileExists(toolFile);
|
|
|
|
|
|
- // check that the file is marked executable, without actually checking that we can execute it.
|
|
|
- PosixFileAttributeView view = Files.getFileAttributeView(toolFile, PosixFileAttributeView.class);
|
|
|
- // the view might be null, on e.g. windows, there is nothing to check there!
|
|
|
- if (view != null) {
|
|
|
- PosixFileAttributes attributes = view.readAttributes();
|
|
|
- assertTrue("unexpected permissions: " + attributes.permissions(),
|
|
|
- attributes.permissions().contains(PosixFilePermission.OWNER_EXECUTE));
|
|
|
- assertTrue("unexpected permissions: " + attributes.permissions(),
|
|
|
- attributes.permissions().contains(PosixFilePermission.OWNER_READ));
|
|
|
- }
|
|
|
- } finally {
|
|
|
- // we need to clean up the copied dirs
|
|
|
- IOUtils.rm(pluginBinDir, pluginConfigDir);
|
|
|
+ Path pluginConfigDir = env.configFile().resolve(pluginName);
|
|
|
+ String pluginUrl = getPluginUrlForResource("plugin_with_bin_and_config.zip");
|
|
|
+ assertStatusOk("install " + pluginName + " --url " + pluginUrl + " --verbose");
|
|
|
+
|
|
|
+ terminal.getTerminalOutput().clear();
|
|
|
+ assertStatusOk("list");
|
|
|
+ assertThat(terminal.getTerminalOutput(), hasItem(containsString(pluginName)));
|
|
|
+
|
|
|
+ assertDirectoryExists(pluginBinDir);
|
|
|
+ assertDirectoryExists(pluginConfigDir);
|
|
|
+ Path toolFile = pluginBinDir.resolve("tool");
|
|
|
+ assertFileExists(toolFile);
|
|
|
+
|
|
|
+ // check that the file is marked executable, without actually checking that we can execute it.
|
|
|
+ PosixFileAttributeView view = Files.getFileAttributeView(toolFile, PosixFileAttributeView.class);
|
|
|
+ // the view might be null, on e.g. windows, there is nothing to check there!
|
|
|
+ if (view != null) {
|
|
|
+ PosixFileAttributes attributes = view.readAttributes();
|
|
|
+ assertThat(attributes.permissions(), hasItem(PosixFilePermission.OWNER_EXECUTE));
|
|
|
+ assertThat(attributes.permissions(), hasItem(PosixFilePermission.OWNER_READ));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -131,102 +151,76 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
@Test
|
|
|
public void testLocalPluginInstallWithBinAndConfigInAlreadyExistingConfigDir_7890() throws Exception {
|
|
|
String pluginName = "plugin-test";
|
|
|
- Tuple<Settings, Environment> initialSettings = buildInitialSettings();
|
|
|
Environment env = initialSettings.v2();
|
|
|
-
|
|
|
- Path configDir = env.configFile();
|
|
|
- if (!Files.exists(configDir)) {
|
|
|
- Files.createDirectories(configDir);
|
|
|
- }
|
|
|
- Path pluginConfigDir = configDir.resolve(pluginName);
|
|
|
-
|
|
|
- try {
|
|
|
- PluginManager pluginManager = pluginManager(getPluginUrlForResource("plugin_with_config_v1.zip"), initialSettings);
|
|
|
- pluginManager.downloadAndExtract(pluginName);
|
|
|
-
|
|
|
- Path[] plugins = pluginManager.getListInstalledPlugins();
|
|
|
- assertThat(plugins, arrayWithSize(1));
|
|
|
-
|
|
|
- /*
|
|
|
- First time, our plugin contains:
|
|
|
- - config/test.txt (version1)
|
|
|
- */
|
|
|
- assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
-
|
|
|
- // We now remove the plugin
|
|
|
- pluginManager.removePlugin(pluginName);
|
|
|
- // We should still have test.txt
|
|
|
- assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
-
|
|
|
- // Installing a new plugin version
|
|
|
- /*
|
|
|
- Second time, our plugin contains:
|
|
|
- - config/test.txt (version2)
|
|
|
- - config/dir/testdir.txt (version1)
|
|
|
- - config/dir/subdir/testsubdir.txt (version1)
|
|
|
- */
|
|
|
- pluginManager = pluginManager(getPluginUrlForResource("plugin_with_config_v2.zip"), initialSettings);
|
|
|
- pluginManager.downloadAndExtract(pluginName);
|
|
|
-
|
|
|
- assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "test.txt.new", "version2\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/testdir.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/subdir/testsubdir.txt", "version1\n");
|
|
|
-
|
|
|
- // Removing
|
|
|
- pluginManager.removePlugin(pluginName);
|
|
|
- assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "test.txt.new", "version2\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/testdir.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/subdir/testsubdir.txt", "version1\n");
|
|
|
-
|
|
|
- // Installing a new plugin version
|
|
|
- /*
|
|
|
- Third time, our plugin contains:
|
|
|
- - config/test.txt (version3)
|
|
|
- - config/test2.txt (version1)
|
|
|
- - config/dir/testdir.txt (version2)
|
|
|
- - config/dir/testdir2.txt (version1)
|
|
|
- - config/dir/subdir/testsubdir.txt (version2)
|
|
|
- */
|
|
|
- pluginManager = pluginManager(getPluginUrlForResource("plugin_with_config_v3.zip"), initialSettings);
|
|
|
- pluginManager.downloadAndExtract(pluginName);
|
|
|
-
|
|
|
- assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "test2.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "test.txt.new", "version3\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/testdir.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/testdir.txt.new", "version2\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/testdir2.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/subdir/testsubdir.txt", "version1\n");
|
|
|
- assertFileContent(pluginConfigDir, "dir/subdir/testsubdir.txt.new", "version2\n");
|
|
|
- } finally {
|
|
|
- // we need to clean up the copied dirs
|
|
|
- IOUtils.rm(pluginConfigDir);
|
|
|
- }
|
|
|
+ Path pluginConfigDir = env.configFile().resolve(pluginName);
|
|
|
+
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_with_config_v1.zip")));
|
|
|
+
|
|
|
+ /*
|
|
|
+ First time, our plugin contains:
|
|
|
+ - config/test.txt (version1)
|
|
|
+ */
|
|
|
+ assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
+
|
|
|
+ // We now remove the plugin
|
|
|
+ assertStatusOk("remove " + pluginName);
|
|
|
+
|
|
|
+ // We should still have test.txt
|
|
|
+ assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
+
|
|
|
+ // Installing a new plugin version
|
|
|
+ /*
|
|
|
+ Second time, our plugin contains:
|
|
|
+ - config/test.txt (version2)
|
|
|
+ - config/dir/testdir.txt (version1)
|
|
|
+ - config/dir/subdir/testsubdir.txt (version1)
|
|
|
+ */
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_with_config_v2.zip")));
|
|
|
+
|
|
|
+ assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "test.txt.new", "version2\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/testdir.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/subdir/testsubdir.txt", "version1\n");
|
|
|
+
|
|
|
+ // Removing
|
|
|
+ assertStatusOk("remove " + pluginName);
|
|
|
+ assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "test.txt.new", "version2\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/testdir.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/subdir/testsubdir.txt", "version1\n");
|
|
|
+
|
|
|
+ // Installing a new plugin version
|
|
|
+ /*
|
|
|
+ Third time, our plugin contains:
|
|
|
+ - config/test.txt (version3)
|
|
|
+ - config/test2.txt (version1)
|
|
|
+ - config/dir/testdir.txt (version2)
|
|
|
+ - config/dir/testdir2.txt (version1)
|
|
|
+ - config/dir/subdir/testsubdir.txt (version2)
|
|
|
+ */
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_with_config_v3.zip")));
|
|
|
+
|
|
|
+ assertFileContent(pluginConfigDir, "test.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "test2.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "test.txt.new", "version3\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/testdir.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/testdir.txt.new", "version2\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/testdir2.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/subdir/testsubdir.txt", "version1\n");
|
|
|
+ assertFileContent(pluginConfigDir, "dir/subdir/testsubdir.txt.new", "version2\n");
|
|
|
}
|
|
|
|
|
|
// For #7152
|
|
|
@Test
|
|
|
public void testLocalPluginInstallWithBinOnly_7152() throws Exception {
|
|
|
String pluginName = "plugin-test";
|
|
|
- Tuple<Settings, Environment> initialSettings = buildInitialSettings();
|
|
|
Environment env = initialSettings.v2();
|
|
|
Path binDir = env.homeFile().resolve("bin");
|
|
|
- if (!Files.exists(binDir)) {
|
|
|
- Files.createDirectories(binDir);
|
|
|
- }
|
|
|
Path pluginBinDir = binDir.resolve(pluginName);
|
|
|
- try {
|
|
|
- PluginManager pluginManager = pluginManager(getPluginUrlForResource("plugin_with_bin_only.zip"), initialSettings);
|
|
|
- pluginManager.downloadAndExtract(pluginName);
|
|
|
- Path[] plugins = pluginManager.getListInstalledPlugins();
|
|
|
- assertThat(plugins.length, is(1));
|
|
|
- assertDirectoryExists(pluginBinDir);
|
|
|
- } finally {
|
|
|
- // we need to clean up the copied dirs
|
|
|
- IOUtils.rm(pluginBinDir);
|
|
|
- }
|
|
|
+
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_with_bin_only.zip")));
|
|
|
+ assertThatPluginIsListed(pluginName);
|
|
|
+ assertDirectoryExists(pluginBinDir);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
@@ -234,8 +228,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
//When we have only a folder in top-level (no files either) but it's called _site, we make it work
|
|
|
//we can either remove the folder while extracting and then re-add it manually or just leave it as it is
|
|
|
String pluginName = "plugin-test";
|
|
|
- Tuple<Settings, Environment> initialSettings = buildInitialSettings();
|
|
|
- downloadAndExtract(pluginName, initialSettings, getPluginUrlForResource("plugin_folder_site.zip"));
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_folder_site.zip")));
|
|
|
|
|
|
internalCluster().startNode(initialSettings.v1());
|
|
|
|
|
@@ -247,8 +240,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
public void testLocalPluginWithoutFolders() throws Exception {
|
|
|
//When we don't have folders at all in the top-level, but only files, we don't modify anything
|
|
|
String pluginName = "plugin-test";
|
|
|
- Tuple<Settings, Environment> initialSettings = buildInitialSettings();
|
|
|
- downloadAndExtract(pluginName, initialSettings, getPluginUrlForResource("plugin_without_folders.zip"));
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_without_folders.zip")));
|
|
|
|
|
|
internalCluster().startNode(initialSettings.v1());
|
|
|
|
|
@@ -260,8 +252,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
public void testLocalPluginFolderAndFile() throws Exception {
|
|
|
//When we have a single top-level folder but also files in the top-level, we don't modify anything
|
|
|
String pluginName = "plugin-test";
|
|
|
- Tuple<Settings, Environment> initialSettings = buildInitialSettings();
|
|
|
- downloadAndExtract(pluginName, initialSettings, getPluginUrlForResource("plugin_folder_file.zip"));
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_folder_file.zip")));
|
|
|
|
|
|
internalCluster().startNode(initialSettings.v1());
|
|
|
|
|
@@ -269,37 +260,13 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
assertPluginAvailable(pluginName);
|
|
|
}
|
|
|
|
|
|
- @Test(expected = IllegalArgumentException.class)
|
|
|
- public void testSitePluginWithSourceThrows() throws Exception {
|
|
|
+ @Test
|
|
|
+ public void testSitePluginWithSourceDoesNotInstall() throws Exception {
|
|
|
String pluginName = "plugin-with-source";
|
|
|
- downloadAndExtract(pluginName, buildInitialSettings(), getPluginUrlForResource("plugin_with_sourcefiles.zip"));
|
|
|
- }
|
|
|
-
|
|
|
- private PluginManager pluginManager(String pluginUrl) throws IOException {
|
|
|
- return pluginManager(pluginUrl, buildInitialSettings());
|
|
|
- }
|
|
|
-
|
|
|
- private Tuple<Settings, Environment> buildInitialSettings() throws IOException {
|
|
|
- Settings settings = Settings.settingsBuilder()
|
|
|
- .put("discovery.zen.ping.multicast.enabled", false)
|
|
|
- .put("http.enabled", true)
|
|
|
- .put("path.home", createTempDir()).build();
|
|
|
- return InternalSettingsPreparer.prepareSettings(settings, false);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * We build a plugin manager instance which wait only for 30 seconds before
|
|
|
- * raising an ElasticsearchTimeoutException
|
|
|
- */
|
|
|
- private PluginManager pluginManager(String pluginUrl, Tuple<Settings, Environment> initialSettings) throws IOException {
|
|
|
- if (!Files.exists(initialSettings.v2().pluginsFile())) {
|
|
|
- Files.createDirectories(initialSettings.v2().pluginsFile());
|
|
|
- }
|
|
|
- return new PluginManager(initialSettings.v2(), pluginUrl, PluginManager.OutputMode.VERBOSE, TimeValue.timeValueSeconds(30));
|
|
|
- }
|
|
|
-
|
|
|
- private void downloadAndExtract(String pluginName, Tuple<Settings, Environment> initialSettings, String pluginUrl) throws IOException {
|
|
|
- pluginManager(pluginUrl, initialSettings).downloadAndExtract(pluginName);
|
|
|
+ String cmd = String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_with_sourcefiles.zip"));
|
|
|
+ int status = new PluginManagerCliParser(terminal).execute(args(cmd));
|
|
|
+ assertThat(status, is(USAGE.status()));
|
|
|
+ assertThat(terminal.getTerminalOutput(), hasItem(containsString("Plugin installation assumed to be site plugin, but contains source code, aborting installation")));
|
|
|
}
|
|
|
|
|
|
private void assertPluginLoaded(String pluginName) {
|
|
@@ -352,61 +319,44 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
|
|
|
@Test
|
|
|
public void testListInstalledEmpty() throws IOException {
|
|
|
- Path[] plugins = pluginManager(null).getListInstalledPlugins();
|
|
|
- assertThat(plugins, notNullValue());
|
|
|
- assertThat(plugins.length, is(0));
|
|
|
+ assertStatusOk("list");
|
|
|
+ assertThat(terminal.getTerminalOutput(), hasItem(containsString("No plugin detected")));
|
|
|
}
|
|
|
|
|
|
- @Test(expected = IOException.class)
|
|
|
- public void testInstallPluginNull() throws IOException {
|
|
|
- pluginManager(null).downloadAndExtract("plugin-test");
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
@Test
|
|
|
public void testInstallPlugin() throws IOException {
|
|
|
- PluginManager pluginManager = pluginManager(getPluginUrlForResource("plugin_with_classfile.zip"));
|
|
|
-
|
|
|
- pluginManager.downloadAndExtract("plugin-classfile");
|
|
|
- Path[] plugins = pluginManager.getListInstalledPlugins();
|
|
|
- assertThat(plugins, notNullValue());
|
|
|
- assertThat(plugins.length, is(1));
|
|
|
+ String pluginName = "plugin-classfile";
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_with_classfile.zip")));
|
|
|
+ assertThatPluginIsListed("plugin-classfile");
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
public void testInstallSitePlugin() throws IOException {
|
|
|
- Tuple<Settings, Environment> initialSettings = buildInitialSettings();
|
|
|
- PluginManager pluginManager = pluginManager(getPluginUrlForResource("plugin_without_folders.zip"), initialSettings);
|
|
|
-
|
|
|
- pluginManager.downloadAndExtract("plugin-site");
|
|
|
- Path[] plugins = pluginManager.getListInstalledPlugins();
|
|
|
- assertThat(plugins, notNullValue());
|
|
|
- assertThat(plugins.length, is(1));
|
|
|
-
|
|
|
+ String pluginName = "plugin-site";
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginName, getPluginUrlForResource("plugin_without_folders.zip")));
|
|
|
+ assertThatPluginIsListed(pluginName);
|
|
|
// We want to check that Plugin Manager moves content to _site
|
|
|
assertFileExists(initialSettings.v2().pluginsFile().resolve("plugin-site/_site"));
|
|
|
}
|
|
|
|
|
|
|
|
|
- private void singlePluginInstallAndRemove(String pluginShortName, String pluginCoordinates) throws IOException {
|
|
|
- logger.info("--> trying to download and install [{}]", pluginShortName);
|
|
|
- PluginManager pluginManager = pluginManager(pluginCoordinates);
|
|
|
- try {
|
|
|
- pluginManager.downloadAndExtract(pluginShortName);
|
|
|
- Path[] plugins = pluginManager.getListInstalledPlugins();
|
|
|
- assertThat(plugins, notNullValue());
|
|
|
- assertThat(plugins.length, is(1));
|
|
|
-
|
|
|
- // We remove it
|
|
|
- pluginManager.removePlugin(pluginShortName);
|
|
|
- plugins = pluginManager.getListInstalledPlugins();
|
|
|
- assertThat(plugins, notNullValue());
|
|
|
- assertThat(plugins.length, is(0));
|
|
|
- } catch (IOException e) {
|
|
|
- logger.warn("--> IOException raised while downloading plugin [{}]. Skipping test.", e, pluginShortName);
|
|
|
- } catch (ElasticsearchTimeoutException e) {
|
|
|
- logger.warn("--> timeout exception raised while downloading plugin [{}]. Skipping test.", pluginShortName);
|
|
|
+ private void singlePluginInstallAndRemove(String pluginDescriptor, String pluginName, String pluginCoordinates) throws IOException {
|
|
|
+ logger.info("--> trying to download and install [{}]", pluginDescriptor);
|
|
|
+ if (pluginCoordinates == null) {
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --verbose", pluginDescriptor));
|
|
|
+ } else {
|
|
|
+ assertStatusOk(String.format(Locale.ROOT, "install %s --url %s --verbose", pluginDescriptor, pluginCoordinates));
|
|
|
}
|
|
|
+ assertThatPluginIsListed(pluginName);
|
|
|
+
|
|
|
+ terminal.getTerminalOutput().clear();
|
|
|
+ assertStatusOk("remove " + pluginDescriptor);
|
|
|
+ assertThat(terminal.getTerminalOutput(), hasItem(containsString("Removing " + pluginDescriptor)));
|
|
|
+
|
|
|
+ // not listed anymore
|
|
|
+ terminal.getTerminalOutput().clear();
|
|
|
+ assertStatusOk("list");
|
|
|
+ assertThat(terminal.getTerminalOutput(), not(hasItem(containsString(pluginName))));
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -420,7 +370,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
@AwaitsFix(bugUrl = "fails with jar hell failures - http://build-us-00.elastic.co/job/es_core_master_oracle_6/519/testReport/")
|
|
|
public void testInstallPluginWithElasticsearchDownloadService() throws IOException {
|
|
|
assumeTrue("download.elastic.co is accessible", isDownloadServiceWorking("download.elastic.co", 80, "/elasticsearch/ci-test.txt"));
|
|
|
- singlePluginInstallAndRemove("elasticsearch/elasticsearch-transport-thrift/2.4.0", null);
|
|
|
+ singlePluginInstallAndRemove("elasticsearch/elasticsearch-transport-thrift/2.4.0", "elasticsearch-transport-thrift", null);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -435,7 +385,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
public void testInstallPluginWithMavenCentral() throws IOException {
|
|
|
assumeTrue("search.maven.org is accessible", isDownloadServiceWorking("search.maven.org", 80, "/"));
|
|
|
assumeTrue("repo1.maven.org is accessible", isDownloadServiceWorking("repo1.maven.org", 443, "/maven2/org/elasticsearch/elasticsearch-transport-thrift/2.4.0/elasticsearch-transport-thrift-2.4.0.pom"));
|
|
|
- singlePluginInstallAndRemove("org.elasticsearch/elasticsearch-transport-thrift/2.4.0", null);
|
|
|
+ singlePluginInstallAndRemove("org.elasticsearch/elasticsearch-transport-thrift/2.4.0", "elasticsearch-transport-thrift", null);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -448,7 +398,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
@Network
|
|
|
public void testInstallPluginWithGithub() throws IOException {
|
|
|
assumeTrue("github.com is accessible", isDownloadServiceWorking("github.com", 443, "/"));
|
|
|
- singlePluginInstallAndRemove("elasticsearch/kibana", null);
|
|
|
+ singlePluginInstallAndRemove("elasticsearch/kibana", "kibana", null);
|
|
|
}
|
|
|
|
|
|
private boolean isDownloadServiceWorking(String host, int port, String resource) {
|
|
@@ -469,48 +419,38 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
@Test
|
|
|
public void testRemovePlugin() throws Exception {
|
|
|
// We want to remove plugin with plugin short name
|
|
|
- singlePluginInstallAndRemove("plugintest", getPluginUrlForResource("plugin_without_folders.zip"));
|
|
|
+ singlePluginInstallAndRemove("plugintest", "plugintest", getPluginUrlForResource("plugin_without_folders.zip"));
|
|
|
|
|
|
// We want to remove plugin with groupid/artifactid/version form
|
|
|
- singlePluginInstallAndRemove("groupid/plugintest/1.0.0", getPluginUrlForResource("plugin_without_folders.zip"));
|
|
|
+ singlePluginInstallAndRemove("groupid/plugintest/1.0.0", "plugintest", getPluginUrlForResource("plugin_without_folders.zip"));
|
|
|
|
|
|
// We want to remove plugin with groupid/artifactid form
|
|
|
- singlePluginInstallAndRemove("groupid/plugintest", getPluginUrlForResource("plugin_without_folders.zip"));
|
|
|
+ singlePluginInstallAndRemove("groupid/plugintest", "plugintest", getPluginUrlForResource("plugin_without_folders.zip"));
|
|
|
}
|
|
|
|
|
|
- @Test(expected = IllegalArgumentException.class)
|
|
|
+ @Test
|
|
|
public void testRemovePlugin_NullName_ThrowsException() throws IOException {
|
|
|
- pluginManager(getPluginUrlForResource("plugin_single_folder.zip")).removePlugin(null);
|
|
|
+ int status = new PluginManagerCliParser(terminal).execute(args("remove "));
|
|
|
+ assertThat("Terminal output was: " + terminal.getTerminalOutput(), status, is(USAGE.status()));
|
|
|
}
|
|
|
|
|
|
- @Test(expected = IllegalArgumentException.class)
|
|
|
+ @Test
|
|
|
public void testRemovePluginWithURLForm() throws Exception {
|
|
|
- PluginManager pluginManager = pluginManager(null);
|
|
|
- pluginManager.removePlugin("file://whatever");
|
|
|
+ int status = new PluginManagerCliParser(terminal).execute(args("remove file://whatever"));
|
|
|
+ assertThat(terminal.getTerminalOutput(), hasItem(containsString("Illegal plugin name")));
|
|
|
+ assertThat("Terminal output was: " + terminal.getTerminalOutput(), status, is(USAGE.status()));
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void testForbiddenPluginName_ThrowsException() throws IOException {
|
|
|
- runTestWithForbiddenName(null);
|
|
|
- runTestWithForbiddenName("");
|
|
|
- runTestWithForbiddenName("elasticsearch");
|
|
|
- runTestWithForbiddenName("elasticsearch.bat");
|
|
|
- runTestWithForbiddenName("elasticsearch.in.sh");
|
|
|
- runTestWithForbiddenName("plugin");
|
|
|
- runTestWithForbiddenName("plugin.bat");
|
|
|
- runTestWithForbiddenName("service.bat");
|
|
|
- runTestWithForbiddenName("ELASTICSEARCH");
|
|
|
- runTestWithForbiddenName("ELASTICSEARCH.IN.SH");
|
|
|
- }
|
|
|
-
|
|
|
- private void runTestWithForbiddenName(String name) throws IOException {
|
|
|
- try {
|
|
|
- pluginManager(null).removePlugin(name);
|
|
|
- fail("this plugin name [" + name +
|
|
|
- "] should not be allowed");
|
|
|
- } catch (IllegalArgumentException e) {
|
|
|
- // We expect that error
|
|
|
- }
|
|
|
+ public void testForbiddenPluginNames() throws IOException {
|
|
|
+ assertStatus("remove elasticsearch", USAGE);
|
|
|
+ assertStatus("remove elasticsearch.bat", USAGE);
|
|
|
+ assertStatus("remove elasticsearch.in.sh", USAGE);
|
|
|
+ assertStatus("remove plugin", USAGE);
|
|
|
+ assertStatus("remove plugin.bat", USAGE);
|
|
|
+ assertStatus("remove service.bat", USAGE);
|
|
|
+ assertStatus("remove ELASTICSEARCH", USAGE);
|
|
|
+ assertStatus("remove ELASTICSEARCH.IN.SH", USAGE);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
@@ -535,6 +475,33 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void testHelpWorks() throws IOException {
|
|
|
+ assertStatusOk("--help");
|
|
|
+ assertHelp("/org/elasticsearch/plugins/plugin.help");
|
|
|
+
|
|
|
+ terminal.getTerminalOutput().clear();
|
|
|
+ assertStatusOk("install -h");
|
|
|
+ assertHelp("/org/elasticsearch/plugins/plugin-install.help");
|
|
|
+ for (String plugin : PluginManager.OFFICIAL_PLUGINS) {
|
|
|
+ assertThat(terminal.getTerminalOutput(), hasItem(containsString(plugin)));
|
|
|
+ }
|
|
|
+
|
|
|
+ terminal.getTerminalOutput().clear();
|
|
|
+ assertStatusOk("remove --help");
|
|
|
+ assertHelp("/org/elasticsearch/plugins/plugin-remove.help");
|
|
|
+
|
|
|
+ terminal.getTerminalOutput().clear();
|
|
|
+ assertStatusOk("list -h");
|
|
|
+ assertHelp("/org/elasticsearch/plugins/plugin-list.help");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void assertHelp(String classPath) throws IOException {
|
|
|
+ String expectedDocs = Streams.copyToStringFromClasspath(classPath);
|
|
|
+ String returnedDocs = Joiner.on("").join(terminal.getTerminalOutput());
|
|
|
+ assertThat(returnedDocs.trim(), is(expectedDocs.trim()));
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Retrieve a URL string that represents the resource with the given {@code resourceName}.
|
|
|
* @param resourceName The resource name relative to {@link PluginManagerTests}.
|
|
@@ -546,4 +513,28 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
|
|
|
|
|
|
return "file://" + uri.getPath();
|
|
|
}
|
|
|
+
|
|
|
+ private Tuple<Settings, Environment> buildInitialSettings() throws IOException {
|
|
|
+ Settings settings = settingsBuilder()
|
|
|
+ .put("discovery.zen.ping.multicast.enabled", false)
|
|
|
+ .put("http.enabled", true)
|
|
|
+ .put("path.home", createTempDir()).build();
|
|
|
+ return InternalSettingsPreparer.prepareSettings(settings, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void assertStatusOk(String command) {
|
|
|
+ assertStatus(command, CliTool.ExitStatus.OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void assertStatus(String command, CliTool.ExitStatus exitStatus) {
|
|
|
+ int status = new PluginManagerCliParser(terminal).execute(args(command));
|
|
|
+ assertThat("Terminal output was: " + terminal.getTerminalOutput(), status, is(exitStatus.status()));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void assertThatPluginIsListed(String pluginName) {
|
|
|
+ terminal.getTerminalOutput().clear();
|
|
|
+ assertStatusOk("list");
|
|
|
+ String message = String.format(Locale.ROOT, "Terminal output was: %s", terminal.getTerminalOutput());
|
|
|
+ assertThat(message, terminal.getTerminalOutput(), hasItem(containsString(pluginName)));
|
|
|
+ }
|
|
|
}
|