/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.
*/
package org.elasticsearch.plugins;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Locale;
import java.util.stream.Collectors;
import org.apache.lucene.util.LuceneTestCase;
import org.elasticsearch.Version;
import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.MockTerminal;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.test.ESTestCase;
import org.junit.Before;
@LuceneTestCase.SuppressFileSystems("*")
public class ListPluginsCommandTests extends ESTestCase {
private Path home;
private Environment env;
@Before
public void setUp() throws Exception {
super.setUp();
home = createTempDir();
Files.createDirectories(home.resolve("plugins"));
Settings settings = Settings.builder()
.put("path.home", home)
.build();
env = new Environment(settings);
}
static MockTerminal listPlugins(Path home) throws Exception {
return listPlugins(home, new String[0]);
}
static MockTerminal listPlugins(Path home, String[] args) throws Exception {
String[] argsAndHome = new String[args.length + 1];
System.arraycopy(args, 0, argsAndHome, 0, args.length);
argsAndHome[args.length] = "-Epath.home=" + home;
MockTerminal terminal = new MockTerminal();
int status = new ListPluginsCommand() {
@Override
protected boolean addShutdownHook() {
return false;
}
}.main(argsAndHome, terminal);
assertEquals(ExitCodes.OK, status);
return terminal;
}
private static String buildMultiline(String... args){
return Arrays.stream(args).collect(Collectors.joining("\n", "", "\n"));
}
private static void buildFakePlugin(
final Environment env,
final String description,
final String name,
final String classname) throws IOException {
buildFakePlugin(env, description, name, classname, false);
}
private static void buildFakePlugin(
final Environment env,
final String description,
final String name,
final String classname,
final boolean hasNativeController) throws IOException {
PluginTestUtil.writeProperties(
env.pluginsFile().resolve(name),
"description", description,
"name", name,
"version", "1.0",
"elasticsearch.version", Version.CURRENT.toString(),
"java.version", System.getProperty("java.specification.version"),
"classname", classname,
"has.native.controller", Boolean.toString(hasNativeController));
}
public void testPluginsDirMissing() throws Exception {
Files.delete(env.pluginsFile());
IOException e = expectThrows(IOException.class, () -> listPlugins(home));
assertEquals("Plugins directory missing: " + env.pluginsFile(), e.getMessage());
}
public void testNoPlugins() throws Exception {
MockTerminal terminal = listPlugins(home);
assertTrue(terminal.getOutput(), terminal.getOutput().isEmpty());
}
public void testOnePlugin() throws Exception {
buildFakePlugin(env, "fake desc", "fake", "org.fake");
MockTerminal terminal = listPlugins(home);
assertEquals(buildMultiline("fake"), terminal.getOutput());
}
public void testTwoPlugins() throws Exception {
buildFakePlugin(env, "fake desc", "fake1", "org.fake");
buildFakePlugin(env, "fake desc 2", "fake2", "org.fake");
MockTerminal terminal = listPlugins(home);
assertEquals(buildMultiline("fake1", "fake2"), terminal.getOutput());
}
public void testPluginWithVerbose() throws Exception {
buildFakePlugin(env, "fake desc", "fake_plugin", "org.fake");
String[] params = { "-v" };
MockTerminal terminal = listPlugins(home, params);
assertEquals(
buildMultiline(
"Plugins directory: " + env.pluginsFile(),
"fake_plugin",
"- Plugin information:",
"Name: fake_plugin",
"Description: fake desc",
"Version: 1.0",
"Native Controller: false",
" * Classname: org.fake"),
terminal.getOutput());
}
public void testPluginWithNativeController() throws Exception {
buildFakePlugin(env, "fake desc 1", "fake_plugin1", "org.fake", true);
String[] params = { "-v" };
MockTerminal terminal = listPlugins(home, params);
assertEquals(
buildMultiline(
"Plugins directory: " + env.pluginsFile(),
"fake_plugin1",
"- Plugin information:",
"Name: fake_plugin1",
"Description: fake desc 1",
"Version: 1.0",
"Native Controller: true",
" * Classname: org.fake"),
terminal.getOutput());
}
public void testPluginWithVerboseMultiplePlugins() throws Exception {
buildFakePlugin(env, "fake desc 1", "fake_plugin1", "org.fake");
buildFakePlugin(env, "fake desc 2", "fake_plugin2", "org.fake2");
String[] params = { "-v" };
MockTerminal terminal = listPlugins(home, params);
assertEquals(
buildMultiline(
"Plugins directory: " + env.pluginsFile(),
"fake_plugin1",
"- Plugin information:",
"Name: fake_plugin1",
"Description: fake desc 1",
"Version: 1.0",
"Native Controller: false",
" * Classname: org.fake",
"fake_plugin2",
"- Plugin information:",
"Name: fake_plugin2",
"Description: fake desc 2",
"Version: 1.0",
"Native Controller: false",
" * Classname: org.fake2"),
terminal.getOutput());
}
public void testPluginWithoutVerboseMultiplePlugins() throws Exception {
buildFakePlugin(env, "fake desc 1", "fake_plugin1", "org.fake");
buildFakePlugin(env, "fake desc 2", "fake_plugin2", "org.fake2");
MockTerminal terminal = listPlugins(home, new String[0]);
String output = terminal.getOutput();
assertEquals(buildMultiline("fake_plugin1", "fake_plugin2"), output);
}
public void testPluginWithoutDescriptorFile() throws Exception{
final Path pluginDir = env.pluginsFile().resolve("fake1");
Files.createDirectories(pluginDir);
NoSuchFileException e = expectThrows(NoSuchFileException.class, () -> listPlugins(home));
assertEquals(pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES).toString(), e.getFile());
}
public void testPluginWithWrongDescriptorFile() throws Exception{
final Path pluginDir = env.pluginsFile().resolve("fake1");
PluginTestUtil.writeProperties(pluginDir, "description", "fake desc");
IllegalArgumentException e = expectThrows(
IllegalArgumentException.class,
() -> listPlugins(home));
final Path descriptorPath = pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES);
assertEquals(
"property [name] is missing in [" + descriptorPath.toString() + "]",
e.getMessage());
}
public void testExistingIncompatiblePlugin() throws Exception {
PluginTestUtil.writeProperties(env.pluginsFile().resolve("fake_plugin1"),
"description", "fake desc 1",
"name", "fake_plugin1",
"version", "1.0",
"elasticsearch.version", Version.fromString("1.0.0").toString(),
"java.version", System.getProperty("java.specification.version"),
"classname", "org.fake1");
buildFakePlugin(env, "fake desc 2", "fake_plugin2", "org.fake2");
MockTerminal terminal = listPlugins(home);
final String message = String.format(Locale.ROOT,
"plugin [%s] is incompatible with version [%s]; was designed for version [%s]",
"fake_plugin1",
Version.CURRENT.toString(),
"1.0.0");
assertEquals(
"fake_plugin1\n" + "WARNING: " + message + "\n" + "fake_plugin2\n",
terminal.getOutput());
String[] params = {"-s"};
terminal = listPlugins(home, params);
assertEquals("fake_plugin1\nfake_plugin2\n", terminal.getOutput());
}
}