6464import java .io .BufferedReader ;
6565import java .io .ByteArrayInputStream ;
6666import java .io .ByteArrayOutputStream ;
67+ import java .io .FileNotFoundException ;
6768import java .io .IOException ;
6869import java .io .InputStream ;
6970import java .io .StringReader ;
9394import java .security .NoSuchProviderException ;
9495import java .util .ArrayList ;
9596import java .util .Arrays ;
97+ import java .util .Collections ;
9698import java .util .Date ;
9799import java .util .HashSet ;
98100import java .util .List ;
@@ -280,9 +282,17 @@ void installPlugin(String pluginUrl, Path home) throws Exception {
280282 installPlugin (pluginUrl , home , skipJarHellCommand );
281283 }
282284
285+ void installPlugins (final List <String > pluginUrls , final Path home ) throws Exception {
286+ installPlugins (pluginUrls , home , skipJarHellCommand );
287+ }
288+
283289 void installPlugin (String pluginUrl , Path home , InstallPluginCommand command ) throws Exception {
284- Environment env = TestEnvironment .newEnvironment (Settings .builder ().put ("path.home" , home ).build ());
285- command .execute (terminal , pluginUrl , false , env );
290+ installPlugins (pluginUrl == null ? Collections .emptyList () : Collections .singletonList (pluginUrl ), home , command );
291+ }
292+
293+ void installPlugins (final List <String > pluginUrls , final Path home , final InstallPluginCommand command ) throws Exception {
294+ final Environment env = TestEnvironment .newEnvironment (Settings .builder ().put ("path.home" , home ).build ());
295+ command .execute (terminal , pluginUrls , false , env );
286296 }
287297
288298 void assertPlugin (String name , Path original , Environment env ) throws IOException {
@@ -382,7 +392,7 @@ void assertInstallCleaned(Environment env) throws IOException {
382392 public void testMissingPluginId () throws IOException {
383393 final Tuple <Path , Environment > env = createEnv (fs , temp );
384394 final UserException e = expectThrows (UserException .class , () -> installPlugin (null , env .v1 ()));
385- assertTrue (e .getMessage (), e .getMessage ().contains ("plugin id is required" ));
395+ assertTrue (e .getMessage (), e .getMessage ().contains ("at least one plugin id is required" ));
386396 }
387397
388398 public void testSomethingWorks () throws Exception {
@@ -393,6 +403,38 @@ public void testSomethingWorks() throws Exception {
393403 assertPlugin ("fake" , pluginDir , env .v2 ());
394404 }
395405
406+ public void testMultipleWorks () throws Exception {
407+ Tuple <Path , Environment > env = createEnv (fs , temp );
408+ Path pluginDir = createPluginDir (temp );
409+ String fake1PluginZip = createPluginUrl ("fake1" , pluginDir );
410+ String fake2PluginZip = createPluginUrl ("fake2" , pluginDir );
411+ installPlugins (Arrays .asList (fake1PluginZip , fake2PluginZip ), env .v1 ());
412+ assertPlugin ("fake1" , pluginDir , env .v2 ());
413+ assertPlugin ("fake2" , pluginDir , env .v2 ());
414+ }
415+
416+ public void testDuplicateInstall () throws Exception {
417+ Tuple <Path , Environment > env = createEnv (fs , temp );
418+ Path pluginDir = createPluginDir (temp );
419+ String pluginZip = createPluginUrl ("fake" , pluginDir );
420+ final UserException e = expectThrows (UserException .class , () -> installPlugins (Arrays .asList (pluginZip , pluginZip ), env .v1 ()));
421+ assertThat (e , hasToString (containsString ("duplicate plugin id [" + pluginZip + "]" )));
422+ }
423+
424+ public void testTransaction () throws Exception {
425+ Tuple <Path , Environment > env = createEnv (fs , temp );
426+ Path pluginDir = createPluginDir (temp );
427+ String pluginZip = createPluginUrl ("fake" , pluginDir );
428+ final FileNotFoundException e = expectThrows (
429+ FileNotFoundException .class ,
430+ () -> installPlugins (Arrays .asList (pluginZip , pluginZip + "does-not-exist" ), env .v1 ()));
431+ assertThat (e , hasToString (containsString ("does-not-exist" )));
432+ final Path fakeInstallPath = env .v2 ().pluginsFile ().resolve ("fake" );
433+ // fake should have been removed when the file not found exception occurred
434+ assertFalse (Files .exists (fakeInstallPath ));
435+ assertInstallCleaned (env .v2 ());
436+ }
437+
396438 public void testInstallFailsIfPreviouslyRemovedPluginFailed () throws Exception {
397439 Tuple <Path , Environment > env = createEnv (fs , temp );
398440 Path pluginDir = createPluginDir (temp );
@@ -769,7 +811,8 @@ Build.Flavor buildFlavor() {
769811 };
770812
771813 final Environment environment = createEnv (fs , temp ).v2 ();
772- final T exception = expectThrows (clazz , () -> flavorCommand .execute (terminal , "x-pack" , false , environment ));
814+ final T exception =
815+ expectThrows (clazz , () -> flavorCommand .execute (terminal , Collections .singletonList ("x-pack" ), false , environment ));
773816 assertThat (exception , hasToString (containsString (expectedMessage )));
774817 }
775818
@@ -830,7 +873,7 @@ private void installPlugin(MockTerminal terminal, boolean isBatch) throws Except
830873 writePluginSecurityPolicy (pluginDir , "setFactory" );
831874 }
832875 String pluginZip = createPlugin ("fake" , pluginDir ).toUri ().toURL ().toString ();
833- skipJarHellCommand .execute (terminal , pluginZip , isBatch , env .v2 ());
876+ skipJarHellCommand .execute (terminal , Collections . singletonList ( pluginZip ) , isBatch , env .v2 ());
834877 }
835878
836879 void assertInstallPluginFromUrl (
0 commit comments