From cdcc75dd2a5bf2adf4f98bf789688f70d1a2bd33 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 27 Apr 2017 11:27:29 -0700 Subject: [PATCH] Plugins: Add support for platform specific plugins (#24265) This commit adds support for plugins having a platform specific variant. It also adds unit tests for all official and maven urls. --- .../org/elasticsearch/plugins/Platforms.java | 3 +- .../plugins/InstallPluginCommand.java | 74 +++++++-- .../plugins/InstallPluginCommandTests.java | 146 ++++++++++++------ 3 files changed, 163 insertions(+), 60 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/plugins/Platforms.java b/core/src/main/java/org/elasticsearch/plugins/Platforms.java index 62bb32a4e9a..91af58ebec4 100644 --- a/core/src/main/java/org/elasticsearch/plugins/Platforms.java +++ b/core/src/main/java/org/elasticsearch/plugins/Platforms.java @@ -30,8 +30,7 @@ import java.util.Locale; public class Platforms { private static final String PROGRAM_NAME = Constants.WINDOWS ? "controller.exe" : "controller"; - private static final String PLATFORM_NAME = - Platforms.platformName(Constants.OS_NAME, Constants.OS_ARCH); + public static final String PLATFORM_NAME = Platforms.platformName(Constants.OS_NAME, Constants.OS_ARCH); private Platforms() {} diff --git a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java index afe4593e627..dd7e39f7c79 100644 --- a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java +++ b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java @@ -41,6 +41,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; @@ -214,18 +215,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand { /** Downloads the plugin and returns the file it was downloaded to. */ private Path download(Terminal terminal, String pluginId, Path tmpDir) throws Exception { if (OFFICIAL_PLUGINS.contains(pluginId)) { - final String version = Version.CURRENT.toString(); - final String url; - final String stagingHash = System.getProperty(PROPERTY_STAGING_ID); - if (stagingHash != null) { - url = String.format(Locale.ROOT, - "https://staging.elastic.co/%3$s-%1$s/downloads/elasticsearch-plugins/%2$s/%2$s-%3$s.zip", - stagingHash, pluginId, version); - } else { - url = String.format(Locale.ROOT, - "https://artifacts.elastic.co/downloads/elasticsearch-plugins/%1$s/%1$s-%2$s.zip", - pluginId, version); - } + final String url = getElasticUrl(terminal, getStagingHash(), Version.CURRENT, pluginId, Platforms.PLATFORM_NAME); terminal.println("-> Downloading " + pluginId + " from elastic"); return downloadZipAndChecksum(terminal, url, tmpDir); } @@ -233,8 +223,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand { // now try as maven coordinates, a valid URL would only have a colon and slash String[] coordinates = pluginId.split(":"); if (coordinates.length == 3 && pluginId.contains("/") == false) { - String mavenUrl = String.format(Locale.ROOT, "https://repo1.maven.org/maven2/%1$s/%2$s/%3$s/%2$s-%3$s.zip", - coordinates[0].replace(".", "/") /* groupId */, coordinates[1] /* artifactId */, coordinates[2] /* version */); + String mavenUrl = getMavenUrl(terminal, coordinates, Platforms.PLATFORM_NAME); terminal.println("-> Downloading " + pluginId + " from maven central"); return downloadZipAndChecksum(terminal, mavenUrl, tmpDir); } @@ -253,6 +242,60 @@ class InstallPluginCommand extends EnvironmentAwareCommand { return downloadZip(terminal, pluginId, tmpDir); } + // pkg private so tests can override + String getStagingHash() { + return System.getProperty(PROPERTY_STAGING_ID); + } + + /** Returns the url for an official elasticsearch plugin. */ + private String getElasticUrl(Terminal terminal, String stagingHash, Version version, + String pluginId, String platform) throws IOException { + final String baseUrl; + if (stagingHash != null) { + baseUrl = String.format(Locale.ROOT, + "https://staging.elastic.co/%s-%s/downloads/elasticsearch-plugins/%s", version, stagingHash, pluginId); + } else { + baseUrl = String.format(Locale.ROOT, + "https://artifacts.elastic.co/downloads/elasticsearch-plugins/%s", pluginId); + } + final String platformUrl = String.format(Locale.ROOT, "%s/%s-%s-%s.zip", baseUrl, pluginId, platform, version); + if (urlExists(terminal, platformUrl)) { + return platformUrl; + } + return String.format(Locale.ROOT, "%s/%s-%s.zip", baseUrl, pluginId, version); + } + + /** Returns the url for an elasticsearch plugin in maven. */ + private String getMavenUrl(Terminal terminal, String[] coordinates, String platform) throws IOException { + final String groupId = coordinates[0].replace(".", "/"); + final String artifactId = coordinates[1]; + final String version = coordinates[2]; + final String baseUrl = String.format(Locale.ROOT, "https://repo1.maven.org/maven2/%s/%s/%s", groupId, artifactId, version); + final String platformUrl = String.format(Locale.ROOT, "%s/%s-%s-%s.zip", baseUrl, artifactId, platform, version); + if (urlExists(terminal, platformUrl)) { + return platformUrl; + } + return String.format(Locale.ROOT, "%s/%s-%s.zip", baseUrl, artifactId, version); + } + + /** + * Returns {@code true} if the given url exists, and {@code false} otherwise. + * + * The given url must be {@code https} and existing means a {@code HEAD} request returns 200. + */ + // pkg private for tests to manipulate + @SuppressForbidden(reason = "Make HEAD request using URLConnection.connect()") + boolean urlExists(Terminal terminal, String urlString) throws IOException { + terminal.println(VERBOSE, "Checking if url exists: " + urlString); + URL url = new URL(urlString); + assert "https".equals(url.getProtocol()) : "Only http urls can be checked"; + HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer"); + urlConnection.setRequestMethod("HEAD"); + urlConnection.connect(); + return urlConnection.getResponseCode() == 200; + } + /** Returns all the official plugin names that look similar to pluginId. **/ private List checkMisspelledPlugin(String pluginId) { LevensteinDistance ld = new LevensteinDistance(); @@ -318,8 +361,9 @@ class InstallPluginCommand extends EnvironmentAwareCommand { } /** Downloads a zip from the url, as well as a SHA1 checksum, and checks the checksum. */ + // pkg private for tests @SuppressForbidden(reason = "We use openStream to download plugins") - private Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir) throws Exception { + Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir) throws Exception { Path zip = downloadZip(terminal, urlString, tmpDir); pathsToDeleteOnShutdown.add(zip); URL checksumUrl = new URL(urlString + ".sha1"); diff --git a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java index a70b8a8d3d4..57dfec30807 100644 --- a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java +++ b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java @@ -52,6 +52,7 @@ import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; @@ -77,6 +78,14 @@ import static org.hamcrest.Matchers.not; @LuceneTestCase.SuppressFileSystems("*") public class InstallPluginCommandTests extends ESTestCase { + private static InstallPluginCommand SKIP_JARHELL_COMMAND = new InstallPluginCommand() { + @Override + void jarHellCheck(Path candidate, Path pluginsDir) throws Exception { + // no jarhell check + } + }; + private static InstallPluginCommand DEFAULT_COMMAND = new InstallPluginCommand(); + private final Function temp; private final FileSystem fs; @@ -164,7 +173,7 @@ public class InstallPluginCommandTests extends ESTestCase { } } - static String writeZip(Path structure, String prefix) throws IOException { + static Path writeZip(Path structure, String prefix) throws IOException { Path zip = createTempDir().resolve(structure.getFileName() + ".zip"); try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(zip))) { Files.walkFileTree(structure, new SimpleFileVisitor() { @@ -177,15 +186,15 @@ public class InstallPluginCommandTests extends ESTestCase { } }); } - return zip.toUri().toURL().toString(); + return zip; } /** creates a plugin .zip and returns the url for testing */ - static String createPlugin(String name, Path structure) throws IOException { - return createPlugin(name, structure, false); + static String createPluginUrl(String name, Path structure) throws IOException { + return createPlugin(name, structure, false).toUri().toURL().toString(); } - static String createPlugin(String name, Path structure, boolean createSecurityPolicyFile) throws IOException { + static Path createPlugin(String name, Path structure, boolean createSecurityPolicyFile) throws IOException { PluginTestUtil.writeProperties(structure, "description", "fake desc", "name", name, @@ -202,20 +211,13 @@ public class InstallPluginCommandTests extends ESTestCase { } static MockTerminal installPlugin(String pluginUrl, Path home) throws Exception { - return installPlugin(pluginUrl, home, false); + return installPlugin(pluginUrl, home, SKIP_JARHELL_COMMAND); } - static MockTerminal installPlugin(String pluginUrl, Path home, boolean jarHellCheck) throws Exception { + static MockTerminal installPlugin(String pluginUrl, Path home, InstallPluginCommand command) throws Exception { Environment env = new Environment(Settings.builder().put("path.home", home).build()); MockTerminal terminal = new MockTerminal(); - new InstallPluginCommand() { - @Override - void jarHellCheck(Path candidate, Path pluginsDir) throws Exception { - if (jarHellCheck) { - super.jarHellCheck(candidate, pluginsDir); - } - } - }.execute(terminal, pluginUrl, true, env); + command.execute(terminal, pluginUrl, true, env); return terminal; } @@ -315,7 +317,7 @@ public class InstallPluginCommandTests extends ESTestCase { public void testSomethingWorks() throws Exception { Tuple env = createEnv(fs, temp); Path pluginDir = createPluginDir(temp); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); installPlugin(pluginZip, env.v1()); assertPlugin("fake", pluginDir, env.v2()); } @@ -323,7 +325,7 @@ public class InstallPluginCommandTests extends ESTestCase { public void testSpaceInUrl() throws Exception { Tuple env = createEnv(fs, temp); Path pluginDir = createPluginDir(temp); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); Path pluginZipWithSpaces = createTempFile("foo bar", ".zip"); try (InputStream in = FileSystemUtils.openFileURLStream(new URL(pluginZip))) { Files.copy(in, pluginZipWithSpaces, StandardCopyOption.REPLACE_EXISTING); @@ -351,7 +353,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path pluginDir = createPluginDir(temp); try (PosixPermissionsResetter pluginsAttrs = new PosixPermissionsResetter(env.v2().pluginsFile())) { pluginsAttrs.setPermissions(new HashSet<>()); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); IOException e = expectThrows(IOException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains(env.v2().pluginsFile().toString())); } @@ -361,7 +363,7 @@ public class InstallPluginCommandTests extends ESTestCase { public void testBuiltinModule() throws Exception { Tuple env = createEnv(fs, temp); Path pluginDir = createPluginDir(temp); - String pluginZip = createPlugin("lang-painless", pluginDir); + String pluginZip = createPluginUrl("lang-painless", pluginDir); UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains("is a system module")); assertInstallCleaned(env.v2()); @@ -373,8 +375,9 @@ public class InstallPluginCommandTests extends ESTestCase { Tuple environment = createEnv(fs, temp); Path pluginDirectory = createPluginDir(temp); writeJar(pluginDirectory.resolve("other.jar"), "FakePlugin"); - String pluginZip = createPlugin("fake", pluginDirectory); // adds plugin.jar with FakePlugin - IllegalStateException e = expectThrows(IllegalStateException.class, () -> installPlugin(pluginZip, environment.v1(), true)); + String pluginZip = createPluginUrl("fake", pluginDirectory); // adds plugin.jar with FakePlugin + IllegalStateException e = expectThrows(IllegalStateException.class, + () -> installPlugin(pluginZip, environment.v1(), DEFAULT_COMMAND)); assertTrue(e.getMessage(), e.getMessage().contains("jar hell")); assertInstallCleaned(environment.v2()); } @@ -383,10 +386,10 @@ public class InstallPluginCommandTests extends ESTestCase { Tuple env = createEnv(fs, temp); // these both share the same FakePlugin class Path pluginDir1 = createPluginDir(temp); - String pluginZip1 = createPlugin("fake1", pluginDir1); + String pluginZip1 = createPluginUrl("fake1", pluginDir1); installPlugin(pluginZip1, env.v1()); Path pluginDir2 = createPluginDir(temp); - String pluginZip2 = createPlugin("fake2", pluginDir2); + String pluginZip2 = createPluginUrl("fake2", pluginDir2); installPlugin(pluginZip2, env.v1()); assertPlugin("fake1", pluginDir1, env.v2()); assertPlugin("fake2", pluginDir2, env.v2()); @@ -395,7 +398,7 @@ public class InstallPluginCommandTests extends ESTestCase { public void testExistingPlugin() throws Exception { Tuple env = createEnv(fs, temp); Path pluginDir = createPluginDir(temp); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); installPlugin(pluginZip, env.v1()); UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains("already exists")); @@ -408,7 +411,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path binDir = pluginDir.resolve("bin"); Files.createDirectory(binDir); Files.createFile(binDir.resolve("somescript")); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); installPlugin(pluginZip, env.v1()); assertPlugin("fake", pluginDir, env.v2()); } @@ -418,7 +421,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path pluginDir = createPluginDir(temp); Path binDir = pluginDir.resolve("bin"); Files.createFile(binDir); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains("not a directory")); assertInstallCleaned(env.v2()); @@ -430,7 +433,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path dirInBinDir = pluginDir.resolve("bin").resolve("foo"); Files.createDirectories(dirInBinDir); Files.createFile(dirInBinDir.resolve("somescript")); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains("Directories not allowed in bin dir for plugin")); assertInstallCleaned(env.v2()); @@ -442,7 +445,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path binDir = pluginDir.resolve("bin"); Files.createDirectory(binDir); Files.createFile(binDir.resolve("somescript")); - String pluginZip = createPlugin("elasticsearch", pluginDir); + String pluginZip = createPluginUrl("elasticsearch", pluginDir); FileAlreadyExistsException e = expectThrows(FileAlreadyExistsException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains(env.v2().binFile().resolve("elasticsearch").toString())); assertInstallCleaned(env.v2()); @@ -455,7 +458,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path binDir = pluginDir.resolve("bin"); Files.createDirectory(binDir); Files.createFile(binDir.resolve("somescript")); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); try (PosixPermissionsResetter binAttrs = new PosixPermissionsResetter(env.v2().binFile())) { Set perms = binAttrs.getCopyPermissions(); // make sure at least one execute perm is missing, so we know we forced it during installation @@ -480,7 +483,7 @@ public class InstallPluginCommandTests extends ESTestCase { assertFalse(sourcePerms.contains(PosixFilePermission.OWNER_EXECUTE)); assertFalse(sourcePerms.contains(PosixFilePermission.GROUP_EXECUTE)); assertFalse(sourcePerms.contains(PosixFilePermission.OTHERS_EXECUTE)); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); installPlugin(pluginZip, env.v1()); assertPlugin("fake", pluginDir, env.v2()); // check that the installed program has execute permissions, even though the one added to the plugin didn't @@ -500,7 +503,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path configDir = pluginDir.resolve("config"); Files.createDirectory(configDir); Files.createFile(configDir.resolve("custom.yaml")); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); installPlugin(pluginZip, env.v1()); assertPlugin("fake", pluginDir, env.v2()); } @@ -515,7 +518,7 @@ public class InstallPluginCommandTests extends ESTestCase { Files.createDirectory(configDir); Files.write(configDir.resolve("custom.yaml"), "new config".getBytes(StandardCharsets.UTF_8)); Files.createFile(configDir.resolve("other.yaml")); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); installPlugin(pluginZip, env.v1()); assertPlugin("fake", pluginDir, env.v2()); List configLines = Files.readAllLines(envConfigDir.resolve("custom.yaml"), StandardCharsets.UTF_8); @@ -529,7 +532,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path pluginDir = createPluginDir(temp); Path configDir = pluginDir.resolve("config"); Files.createFile(configDir); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains("not a directory")); assertInstallCleaned(env.v2()); @@ -541,7 +544,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path dirInConfigDir = pluginDir.resolve("config").resolve("foo"); Files.createDirectories(dirInConfigDir); Files.createFile(dirInConfigDir.resolve("myconfig.yml")); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains("Directories not allowed in config dir for plugin")); assertInstallCleaned(env.v2()); @@ -553,7 +556,7 @@ public class InstallPluginCommandTests extends ESTestCase { Path configDir = pluginDir.resolve("config"); Files.createDirectory(configDir); Files.createFile(configDir.resolve("myconfig.yml")); - String pluginZip = createPlugin("elasticsearch.yml", pluginDir); + String pluginZip = createPluginUrl("elasticsearch.yml", pluginDir); FileAlreadyExistsException e = expectThrows(FileAlreadyExistsException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains(env.v2().configFile().resolve("elasticsearch.yml").toString())); assertInstallCleaned(env.v2()); @@ -563,7 +566,7 @@ public class InstallPluginCommandTests extends ESTestCase { Tuple env = createEnv(fs, temp); Path pluginDir = createPluginDir(temp); Files.createFile(pluginDir.resolve("fake.yml")); - String pluginZip = writeZip(pluginDir, "elasticsearch"); + String pluginZip = writeZip(pluginDir, "elasticsearch").toUri().toURL().toString(); NoSuchFileException e = expectThrows(NoSuchFileException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains("plugin-descriptor.properties")); assertInstallCleaned(env.v2()); @@ -573,7 +576,7 @@ public class InstallPluginCommandTests extends ESTestCase { Tuple env = createEnv(fs, temp); Path pluginDir = createPluginDir(temp); Files.createFile(pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES)); - String pluginZip = writeZip(pluginDir, null); + String pluginZip = writeZip(pluginDir, null).toUri().toURL().toString(); UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1())); assertTrue(e.getMessage(), e.getMessage().contains("`elasticsearch` directory is missing in the plugin zip")); assertInstallCleaned(env.v2()); @@ -666,9 +669,10 @@ public class InstallPluginCommandTests extends ESTestCase { public void testPluginAlreadyInstalled() throws Exception { Tuple env = createEnv(fs, temp); Path pluginDir = createPluginDir(temp); - String pluginZip = createPlugin("fake", pluginDir); + String pluginZip = createPluginUrl("fake", pluginDir); installPlugin(pluginZip, env.v1()); - final UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1(), randomBoolean())); + final UserException e = expectThrows(UserException.class, + () -> installPlugin(pluginZip, env.v1(), randomFrom(SKIP_JARHELL_COMMAND, DEFAULT_COMMAND))); assertThat( e.getMessage(), equalTo("plugin directory [" + env.v2().pluginsFile().resolve("fake") + "] already exists; " + @@ -679,15 +683,71 @@ public class InstallPluginCommandTests extends ESTestCase { Tuple env = createEnv(fs, temp); Path pluginDir = createPluginDir(temp); // if batch is enabled, we also want to add a security policy - String pluginZip = createPlugin("fake", pluginDir, isBatch); + String pluginZip = createPlugin("fake", pluginDir, isBatch).toUri().toURL().toString(); + SKIP_JARHELL_COMMAND.execute(terminal, pluginZip, isBatch, env.v2()); + } - new InstallPluginCommand() { + public void assertInstallPluginFromUrl(String pluginId, String name, String url, String stagingHash) throws Exception { + Tuple env = createEnv(fs, temp); + Path pluginDir = createPluginDir(temp); + Path pluginZip = createPlugin(name, pluginDir, false); + InstallPluginCommand command = new InstallPluginCommand() { + @Override + Path downloadZipAndChecksum(Terminal terminal, String urlString, Path tmpDir) throws Exception { + assertEquals(url, urlString); + Path downloadedPath = tmpDir.resolve("downloaded.zip"); + Files.copy(pluginZip, downloadedPath); + return downloadedPath; + } + @Override + boolean urlExists(Terminal terminal, String urlString) throws IOException { + return urlString.equals(url); + } + @Override + String getStagingHash() { + return stagingHash; + } @Override void jarHellCheck(Path candidate, Path pluginsDir) throws Exception { + // no jarhell check } - }.execute(terminal, pluginZip, isBatch, env.v2()); + }; + installPlugin(pluginId, env.v1(), command); + assertPlugin(name, pluginDir, env.v2()); + } + + public void testOfficalPlugin() throws Exception { + String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + Version.CURRENT + ".zip"; + assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null); + } + + public void testOfficalPluginStaging() throws Exception { + String url = "https://staging.elastic.co/" + Version.CURRENT + "-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + + Version.CURRENT + ".zip"; + assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123"); + } + + public void testOfficalPlatformPlugin() throws Exception { + String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + Platforms.PLATFORM_NAME + + "-" + Version.CURRENT + ".zip"; + assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null); + } + + public void testOfficalPlatformPluginStaging() throws Exception { + String url = "https://staging.elastic.co/" + Version.CURRENT + "-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + + Platforms.PLATFORM_NAME + "-"+ Version.CURRENT + ".zip"; + assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123"); + } + + public void testMavenPlugin() throws Exception { + String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-1.0.0.zip"; + assertInstallPluginFromUrl("mygroup:myplugin:1.0.0", "myplugin", url, null); + } + + public void testMavenPlatformPlugin() throws Exception { + String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-" + Platforms.PLATFORM_NAME + "-1.0.0.zip"; + assertInstallPluginFromUrl("mygroup:myplugin:1.0.0", "myplugin", url, null); } // TODO: test checksum (need maven/official below) - // TODO: test maven, official, and staging install...need tests with fixtures... }