diff --git a/appengine-plugins-core/pom.xml b/appengine-plugins-core/pom.xml index 77eb4e9a5..24b00fe2e 100644 --- a/appengine-plugins-core/pom.xml +++ b/appengine-plugins-core/pom.xml @@ -17,7 +17,7 @@ Google LLC - http://www.google.com + https://www.google.com @@ -67,7 +67,7 @@ com.google.guava guava - 28.1-jre + 28.2-jre org.yaml diff --git a/appengine-plugins-core/src/main/java/com/google/cloud/tools/managedcloudsdk/command/AsyncByteConsumer.java b/appengine-plugins-core/src/main/java/com/google/cloud/tools/managedcloudsdk/command/AsyncByteConsumer.java index 1da8b5519..5a44cf4dc 100644 --- a/appengine-plugins-core/src/main/java/com/google/cloud/tools/managedcloudsdk/command/AsyncByteConsumer.java +++ b/appengine-plugins-core/src/main/java/com/google/cloud/tools/managedcloudsdk/command/AsyncByteConsumer.java @@ -59,9 +59,10 @@ class AsyncByteConsumer implements AsyncStreamSaver { @Override public void handleStream(final InputStream inputStream) { if (executorService.isShutdown()) { - throw new IllegalStateException("Cannot re-use " + this.getClass().getName()); + throw new IllegalStateException("Cannot reuse " + this.getClass().getName()); } - result.setFuture(executorService.submit(() -> consumeBytes(inputStream))); + ListenableFuture submit = executorService.submit(() -> consumeBytes(inputStream)); + result.setFuture(submit); executorService.shutdown(); } diff --git a/appengine-plugins-core/src/test/java/com/google/cloud/tools/managedcloudsdk/command/AsyncByteConsumerTest.java b/appengine-plugins-core/src/test/java/com/google/cloud/tools/managedcloudsdk/command/AsyncByteConsumerTest.java index 2546ab6a5..ed027bb47 100644 --- a/appengine-plugins-core/src/test/java/com/google/cloud/tools/managedcloudsdk/command/AsyncByteConsumerTest.java +++ b/appengine-plugins-core/src/test/java/com/google/cloud/tools/managedcloudsdk/command/AsyncByteConsumerTest.java @@ -17,11 +17,12 @@ package com.google.cloud.tools.managedcloudsdk.command; import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.SettableFuture; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,42 +38,50 @@ public class AsyncByteConsumerTest { private final InputStream fakeInputStream = new ByteArrayInputStream(TEST_STRING.getBytes(StandardCharsets.UTF_8)); - @Mock private ListeningExecutorService mockExecutorService; + @Mock private ExecutorService executorService; @Mock private ByteHandler mockByteHandler; @Mock private InputStream mockInputStream; - @Mock private SettableFuture mockFuture; + + private SettableFuture future = SettableFuture.create(); @Test public void testHandleStream() { - Mockito.when(mockExecutorService.isShutdown()).thenReturn(false); + Mockito.when(executorService.isShutdown()).thenReturn(false); + + ListeningExecutorService listeningExecutorService = + MoreExecutors.listeningDecorator(executorService); - new AsyncByteConsumer(mockByteHandler, mockExecutorService, mockFuture) - .handleStream(mockInputStream); + AsyncByteConsumer consumer = + new AsyncByteConsumer(mockByteHandler, listeningExecutorService, future); + consumer.handleStream(mockInputStream); - Mockito.verify(mockExecutorService).isShutdown(); - Mockito.verify(mockExecutorService).submit(Mockito.>any()); - Mockito.verify(mockExecutorService).shutdown(); - Mockito.verifyNoMoreInteractions(mockExecutorService); + Mockito.verify(executorService).isShutdown(); + Mockito.verify(executorService).execute(Mockito.any()); + Mockito.verify(executorService).shutdown(); + Mockito.verifyNoMoreInteractions(executorService); } @Test public void testHandleStream_failIfReused() { - Mockito.when(mockExecutorService.isShutdown()).thenReturn(true); + Mockito.when(executorService.isShutdown()).thenReturn(true); + ListeningExecutorService listeningExecutorService = + MoreExecutors.listeningDecorator(executorService); try { - new AsyncByteConsumer(mockByteHandler, mockExecutorService, mockFuture) + new AsyncByteConsumer(mockByteHandler, listeningExecutorService, future) .handleStream(mockInputStream); Assert.fail("IllegalStateException expected but not thrown"); } catch (IllegalStateException ex) { // pass - Assert.assertEquals("Cannot re-use " + AsyncByteConsumer.class.getName(), ex.getMessage()); + Assert.assertEquals("Cannot reuse " + AsyncByteConsumer.class.getName(), ex.getMessage()); } } @Test public void testConsumeBytes() throws Exception { - - new AsyncByteConsumer(mockByteHandler, mockExecutorService, mockFuture) + ListeningExecutorService listeningExecutorService = + MoreExecutors.listeningDecorator(executorService); + new AsyncByteConsumer(mockByteHandler, listeningExecutorService, future) .consumeBytes(fakeInputStream); ArgumentCaptor bytes = ArgumentCaptor.forClass(byte[].class); diff --git a/appengine-plugins-core/src/test/java/com/google/cloud/tools/managedcloudsdk/command/CommandCallerTest.java b/appengine-plugins-core/src/test/java/com/google/cloud/tools/managedcloudsdk/command/CommandCallerTest.java index 3a60116e7..3c657046d 100644 --- a/appengine-plugins-core/src/test/java/com/google/cloud/tools/managedcloudsdk/command/CommandCallerTest.java +++ b/appengine-plugins-core/src/test/java/com/google/cloud/tools/managedcloudsdk/command/CommandCallerTest.java @@ -18,7 +18,8 @@ import com.google.cloud.tools.managedcloudsdk.process.ProcessExecutor; import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.AbstractFuture; +import com.google.common.util.concurrent.SettableFuture; import java.io.IOException; import java.nio.file.Path; import java.util.Arrays; @@ -45,9 +46,9 @@ public class CommandCallerTest { @Mock private AsyncStreamSaver mockStdoutSaver; @Mock private AsyncStreamSaver mockStderrSaver; @Mock private AsyncStreamSaverFactory mockStreamSaverFactory; - @Mock private ListenableFuture mockStdout; - @Mock private ListenableFuture mockStderr; + private final SettableFuture mockStdout = SettableFuture.create(); + private final SettableFuture mockStderr = SettableFuture.create(); private List fakeCommand; private Path fakeWorkingDirectory; private Map fakeEnvironment; @@ -73,8 +74,9 @@ public void setUp() throws IOException, InterruptedException, ExecutionException .thenReturn(0); Mockito.when(mockStdoutSaver.getResult()).thenReturn(mockStdout); Mockito.when(mockStderrSaver.getResult()).thenReturn(mockStderr); - Mockito.when(mockStdout.get()).thenReturn("stdout"); - Mockito.when(mockStderr.get()).thenReturn("stderr"); + + mockStdout.set("stdout"); + mockStderr.set("stderr"); testCommandCaller = new CommandCaller(() -> mockProcessExecutor, mockStreamSaverFactory); } @@ -143,7 +145,15 @@ public void testCall_ioException() public void testCall_interruptedExceptionPassthrough() throws CommandExecutionException, CommandExitException, ExecutionException, InterruptedException, IOException { - Mockito.when(mockStdout.get()).thenThrow(InterruptedException.class); + + AbstractFuture future = + new AbstractFuture() { + @Override + public String get() throws InterruptedException { + throw new InterruptedException(); + } + }; + Mockito.when(mockStdoutSaver.getResult()).thenReturn(future); try { testCommandCaller.call(fakeCommand, fakeWorkingDirectory, fakeEnvironment);