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);
    }
  }
  @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));
  }
  @Test
  public void testInstallSitePlugin() throws IOException {
    PluginManager pluginManager =
        pluginManager(getPluginUrlForResource("plugin_without_folders.zip"));

    pluginManager.downloadAndExtract("plugin-site");
    Path[] plugins = pluginManager.getListInstalledPlugins();
    assertThat(plugins, notNullValue());
    assertThat(plugins.length, is(1));

    // We want to check that Plugin Manager moves content to _site
    String pluginDir = PLUGIN_DIR.concat("/plugin-site/_site");
    assertFileExists(Paths.get(pluginDir));
  }
  @Test
  public void testLocalPluginInstallWithBinAndConfig() throws Exception {
    String pluginName = "plugin-test";
    Tuple<Settings, Environment> initialSettings =
        InternalSettingsPreparer.prepareSettings(
            ImmutableSettings.settingsBuilder().build(), false);
    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));
      }
    } finally {
      // we need to clean up the copied dirs
      IOUtils.rm(pluginBinDir, pluginConfigDir);
    }
  }
 // For #7152
 @Test
 public void testLocalPluginInstallWithBinOnly_7152() throws Exception {
   String pluginName = "plugin-test";
   Tuple<Settings, Environment> initialSettings =
       InternalSettingsPreparer.prepareSettings(
           ImmutableSettings.settingsBuilder().build(), false);
   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);
   }
 }
 @Test(expected = ElasticsearchIllegalArgumentException.class)
 public void testRemovePluginWithURLForm() throws Exception {
   PluginManager pluginManager = pluginManager(null);
   pluginManager.removePlugin("file://whatever");
 }
  /** Test for #7890 */
  @Test
  public void testLocalPluginInstallWithBinAndConfigInAlreadyExistingConfigDir_7890()
      throws Exception {
    String pluginName = "plugin-test";
    Tuple<Settings, Environment> initialSettings =
        InternalSettingsPreparer.prepareSettings(
            ImmutableSettings.settingsBuilder().build(), false);
    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);
    }
  }