diff --git a/appengine-plugins-core/pom.xml b/appengine-plugins-core/pom.xml
index 96bdae8bd..c8310aa4f 100644
--- a/appengine-plugins-core/pom.xml
+++ b/appengine-plugins-core/pom.xml
@@ -59,7 +59,7 @@
UTF-8
- com.google.cloud.tools.appengine.operations.DevServerTest,com.google.cloud.tools.appengine.operations.cloudsdk.serialization.AppEngineDeployResult,com.google.cloud.tools.io.FilePermissionsTest,com.google.cloud.tools.managedcloudsdk.install.InstallerFactoryTest,com.google.cloud.tools.appengine.AppEngineDescriptorTest,com.google.cloud.tools.appengine.operations.cloudsdk.serialization.CloudSdkVersionTest,com.google.cloud.tools.appengine.operations.GenRepoInfoFileTest,com.google.cloud.tools.appengine.operations.DeploymentTest,com.google.cloud.tools.appengine.operations.AuthTest,com.google.cloud.tools.appengine.configuration.RunConfigurationTest
+ com.google.cloud.tools.appengine.operations.DevServerJava8Test,com.google.cloud.tools.appengine.operations.DevServerJava9OrAboveTest,com.google.cloud.tools.appengine.operations.cloudsdk.serialization.AppEngineDeployResult,com.google.cloud.tools.io.FilePermissionsTest,com.google.cloud.tools.managedcloudsdk.install.InstallerFactoryTest,com.google.cloud.tools.appengine.AppEngineDescriptorTest,com.google.cloud.tools.appengine.operations.cloudsdk.serialization.CloudSdkVersionTest,com.google.cloud.tools.appengine.operations.GenRepoInfoFileTest,com.google.cloud.tools.appengine.operations.DeploymentTest,com.google.cloud.tools.appengine.operations.AuthTest,com.google.cloud.tools.appengine.configuration.RunConfigurationTest
diff --git a/appengine-plugins-core/src/main/java/com/google/cloud/tools/appengine/operations/DevServer.java b/appengine-plugins-core/src/main/java/com/google/cloud/tools/appengine/operations/DevServer.java
index 0531432ff..393fb9f3d 100644
--- a/appengine-plugins-core/src/main/java/com/google/cloud/tools/appengine/operations/DevServer.java
+++ b/appengine-plugins-core/src/main/java/com/google/cloud/tools/appengine/operations/DevServer.java
@@ -16,6 +16,8 @@
package com.google.cloud.tools.appengine.operations;
+import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;
+
import com.google.cloud.tools.appengine.AppEngineDescriptor;
import com.google.cloud.tools.appengine.AppEngineException;
import com.google.cloud.tools.appengine.configuration.RunConfiguration;
@@ -80,6 +82,16 @@ public void run(RunConfiguration config) throws AppEngineException {
jvmArguments.addAll(config.getJvmFlags());
}
+ if (!JAVA_SPECIFICATION_VERSION.value().equals("1.8")) {
+ // Due to JPMS restrictions, Java11 or later need more flags:
+ jvmArguments.add("--add-opens");
+ jvmArguments.add("java.base/java.net=ALL-UNNAMED");
+ jvmArguments.add("--add-opens");
+ jvmArguments.add("java.base/sun.net.www.protocol.http=ALL-UNNAMED");
+ jvmArguments.add("--add-opens");
+ jvmArguments.add("java.base/sun.net.www.protocol.https=ALL-UNNAMED");
+ }
+
arguments.addAll(DevAppServerArgs.get("default_gcs_bucket", config.getDefaultGcsBucketName()));
arguments.addAll(DevAppServerArgs.get("application", config.getProjectId()));
diff --git a/appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerTest.java b/appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerJava8Test.java
similarity index 97%
rename from appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerTest.java
rename to appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerJava8Test.java
index f0f8f5929..dc6124fe7 100644
--- a/appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerTest.java
+++ b/appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerJava8Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Google LLC.
+ * Copyright 2016-2022 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
package com.google.cloud.tools.appengine.operations;
+import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
@@ -39,6 +41,7 @@
import java.util.logging.LogRecord;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -49,7 +52,7 @@
/** Unit tests for {@link DevServer}. */
@RunWith(MockitoJUnitRunner.class)
-public class DevServerTest {
+public class DevServerJava8Test {
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
private Path fakeJavaSdkHome;
@@ -74,6 +77,12 @@ public class DevServerTest {
private final Map expectedJava8Environment =
ImmutableMap.of("GAE_ENV", "localdev", "GAE_RUNTIME", "java8");
+ @BeforeClass
+ public static void disableIfJavaVersionAbove8() {
+ assumeTrue(
+ "DevServerTestJava8 requires Java 8", JAVA_SPECIFICATION_VERSION.value().equals("1.8"));
+ }
+
@Before
public void setUp() throws IOException {
devServer = Mockito.spy(new DevServer(sdk, devAppServerRunner));
diff --git a/appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerJava9OrAboveTest.java b/appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerJava9OrAboveTest.java
new file mode 100644
index 000000000..9079343c2
--- /dev/null
+++ b/appengine-plugins-core/src/test/java/com/google/cloud/tools/appengine/operations/DevServerJava9OrAboveTest.java
@@ -0,0 +1,587 @@
+/*
+ * Copyright 2016-2022 Google LLC.
+ *
+ * Licensed 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 com.google.cloud.tools.appengine.operations;
+
+import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import com.google.cloud.tools.appengine.AppEngineException;
+import com.google.cloud.tools.appengine.configuration.RunConfiguration;
+import com.google.cloud.tools.appengine.configuration.StopConfiguration;
+import com.google.cloud.tools.appengine.operations.cloudsdk.process.ProcessHandlerException;
+import com.google.cloud.tools.test.utils.LogStoringHandler;
+import com.google.cloud.tools.test.utils.SpyVerifier;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+/** Unit tests for {@link DevServer}. */
+@RunWith(MockitoJUnitRunner.class)
+public class DevServerJava9OrAboveTest {
+
+ @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
+ private Path fakeJavaSdkHome;
+
+ private LogStoringHandler testHandler;
+ @Mock private CloudSdk sdk;
+ @Mock private DevAppServerRunner devAppServerRunner;
+
+ private DevServer devServer;
+
+ private final Path java8Service = Paths.get("src/test/resources/projects/EmptyStandard8Project");
+ private final Path java7Service = Paths.get("src/test/resources/projects/EmptyStandard7Project");
+
+ private final Path java8Service1EnvVars =
+ Paths.get("src/test/resources/projects/Standard8Project1EnvironmentVariables");
+ private final Path java8Service2EnvVars =
+ Paths.get("src/test/resources/projects/Standard8Project2EnvironmentVariables");
+
+ // Environment variables included in running the dev server for Java 7/8 runtimes.
+ private final Map expectedJava7Environment =
+ ImmutableMap.of("GAE_ENV", "localdev", "GAE_RUNTIME", "java7");
+ private final Map expectedJava8Environment =
+ ImmutableMap.of("GAE_ENV", "localdev", "GAE_RUNTIME", "java8");
+
+ @BeforeClass
+ public static void disableIfJavaVersion8() {
+ // CI does not run with anything below 8, so equals is safe.
+ assumeTrue(
+ "DevServerTestJava8 requires Java 9 or above",
+ !JAVA_SPECIFICATION_VERSION.value().equals("1.8"));
+ }
+
+ @Before
+ public void setUp() throws IOException {
+ devServer = Mockito.spy(new DevServer(sdk, devAppServerRunner));
+ fakeJavaSdkHome = temporaryFolder.newFolder("java-sdk").toPath();
+
+ Mockito.when(sdk.getAppEngineSdkForJavaPath()).thenReturn(fakeJavaSdkHome);
+
+ testHandler = LogStoringHandler.getForLogger(DevServer.class.getName());
+ }
+
+ @Test
+ public void testStop_allFlags() {
+ StopConfiguration configuration =
+ StopConfiguration.builder().host("alt-local-host").port(7777).build();
+ try {
+ devServer.stop(configuration);
+ Assert.fail();
+ } catch (AppEngineException ex) {
+ Assert.assertEquals(
+ "Error connecting to http://alt-local-host:7777/_ah/admin/quit", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testStop_defaultAdminHost() {
+ StopConfiguration configuration = StopConfiguration.builder().port(7777).build();
+ try {
+ devServer.stop(configuration);
+ Assert.fail();
+ } catch (AppEngineException ex) {
+ Assert.assertEquals(
+ "Error connecting to http://localhost:7777/_ah/admin/quit", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNullSdk() {
+ try {
+ new DevServer(null, devAppServerRunner);
+ Assert.fail("Allowed null SDK");
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ new DevServer(sdk, null);
+ Assert.fail("Allowed null runner");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ @Test
+ public void testPrepareCommand_allFlags() throws Exception {
+
+ RunConfiguration configuration =
+ Mockito.spy(
+ RunConfiguration.builder(ImmutableList.of(java8Service))
+ .host("host")
+ .port(8090)
+ .jvmFlags(ImmutableList.of("-Dflag1", "-Dflag2"))
+ .defaultGcsBucketName("buckets")
+ .environment(null)
+ .automaticRestart(true)
+ .projectId("my-project")
+ .environment(ImmutableMap.of("ENV_NAME", "ENV_VAL"))
+ .additionalArguments(Arrays.asList("--ARG1", "--ARG2"))
+ .build());
+
+ SpyVerifier.newVerifier(configuration).verifyAllValuesNotNull();
+
+ List expectedFlags =
+ ImmutableList.of(
+ "--address=host",
+ "--port=8090",
+ "--default_gcs_bucket=buckets",
+ "--application=my-project",
+ "--allow_remote_shutdown",
+ "--disable_update_check",
+ "--ARG1",
+ "--ARG2",
+ "--no_java_agent",
+ java8Service.toString());
+
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "-Dappengine.fullscan.seconds=1",
+ "-Dflag1",
+ "-Dflag2",
+ "--add-opens",
+ "java.base/java.net=ALL-UNNAMED",
+ "--add-opens",
+ "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens",
+ "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-Duse_jetty9_runtime=true",
+ "-D--enable_all_permissions=true");
+
+ // Not us immutable map, it enforces order
+ Map expectedEnvironment =
+ ImmutableMap.builder()
+ .putAll(expectedJava8Environment)
+ .put("ENV_NAME", "ENV_VAL")
+ .build();
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner, times(1))
+ .run(
+ expectedJvmArgs,
+ expectedFlags,
+ expectedEnvironment,
+ java8Service /* workingDirectory */);
+
+ SpyVerifier.newVerifier(configuration)
+ .verifyDeclaredGetters(
+ ImmutableMap.of("getServices", 7, "getJavaHomeDir", 2, "getJvmFlags", 2));
+ }
+
+ @Test
+ public void testPrepareCommand_booleanFlags()
+ throws AppEngineException, ProcessHandlerException, IOException {
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java8Service)).build();
+
+ List expectedFlags =
+ ImmutableList.of(
+ "--allow_remote_shutdown",
+ "--disable_update_check",
+ "--no_java_agent",
+ java8Service.toString());
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "--add-opens", "java.base/java.net=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-Duse_jetty9_runtime=true", "-D--enable_all_permissions=true");
+ devServer.run(configuration);
+ verify(devAppServerRunner, times(1))
+ .run(
+ expectedJvmArgs,
+ expectedFlags,
+ expectedJava8Environment,
+ java8Service /* workingDirectory */);
+ }
+
+ @Test
+ public void testPrepareCommand_noFlags()
+ throws AppEngineException, ProcessHandlerException, IOException {
+
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java8Service)).build();
+
+ List expectedFlags =
+ ImmutableList.of(
+ "--allow_remote_shutdown",
+ "--disable_update_check",
+ "--no_java_agent",
+ java8Service.toString());
+
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "--add-opens", "java.base/java.net=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-Duse_jetty9_runtime=true", "-D--enable_all_permissions=true");
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner, times(1))
+ .run(
+ expectedJvmArgs,
+ expectedFlags,
+ expectedJava8Environment,
+ java8Service /* workingDirectory */);
+ }
+
+ @Test
+ public void testPrepareCommand_noFlagsJava7()
+ throws AppEngineException, ProcessHandlerException, IOException {
+
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java7Service)).build();
+
+ List expectedFlags =
+ ImmutableList.of(
+ "--allow_remote_shutdown", "--disable_update_check", java7Service.toString());
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "--add-opens",
+ "java.base/java.net=ALL-UNNAMED",
+ "--add-opens",
+ "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens",
+ "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-javaagent:"
+ + fakeJavaSdkHome.resolve("agent/appengine-agent.jar").toAbsolutePath().toString());
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner, times(1))
+ .run(
+ expectedJvmArgs,
+ expectedFlags,
+ expectedJava7Environment,
+ java7Service /* workingDirectory */);
+ }
+
+ @Test
+ public void testPrepareCommand_noFlagsMultiModule()
+ throws AppEngineException, ProcessHandlerException, IOException {
+
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java7Service, java8Service)).build();
+
+ List expectedFlags =
+ ImmutableList.of(
+ "--allow_remote_shutdown",
+ "--disable_update_check",
+ "--no_java_agent",
+ java7Service.toString(),
+ java8Service.toString());
+
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "--add-opens", "java.base/java.net=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-Duse_jetty9_runtime=true", "-D--enable_all_permissions=true");
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner, times(1))
+ .run(expectedJvmArgs, expectedFlags, expectedJava8Environment, null /* workingDirectory */);
+ }
+
+ @Test
+ public void testPrepareCommand_appEngineWebXmlEnvironmentVariables()
+ throws AppEngineException, ProcessHandlerException, IOException {
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java8Service1EnvVars)).build();
+
+ List expectedFlags =
+ ImmutableList.of(
+ "--allow_remote_shutdown",
+ "--disable_update_check",
+ "--no_java_agent",
+ java8Service1EnvVars.toString());
+
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "--add-opens", "java.base/java.net=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-Duse_jetty9_runtime=true", "-D--enable_all_permissions=true");
+
+ Map expectedConfigurationEnvironment =
+ ImmutableMap.of("key1", "val1", "key2", "val2");
+ Map expectedEnvironment =
+ ImmutableMap.builder()
+ .putAll(expectedConfigurationEnvironment)
+ .putAll(expectedJava8Environment)
+ .build();
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner, times(1))
+ .run(
+ expectedJvmArgs,
+ expectedFlags,
+ expectedEnvironment,
+ java8Service1EnvVars /* workingDirectory */);
+ }
+
+ @Test
+ public void testPrepareCommand_multipleServicesDuplicateAppEngineWebXmlEnvironmentVariables()
+ throws AppEngineException, ProcessHandlerException, IOException {
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java8Service1EnvVars, java8Service2EnvVars))
+ .build();
+
+ List expectedFlags =
+ ImmutableList.of(
+ "--allow_remote_shutdown",
+ "--disable_update_check",
+ "--no_java_agent",
+ java8Service1EnvVars.toString(),
+ java8Service2EnvVars.toString());
+
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "--add-opens", "java.base/java.net=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-Duse_jetty9_runtime=true", "-D--enable_all_permissions=true");
+
+ Map expectedConfigurationEnvironment =
+ ImmutableMap.of("key1", "val1", "keya", "vala", "key2", "duplicated-key", "keyc", "valc");
+ Map expectedEnvironment =
+ ImmutableMap.builder()
+ .putAll(expectedConfigurationEnvironment)
+ .putAll(expectedJava8Environment)
+ .build();
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner, times(1))
+ .run(expectedJvmArgs, expectedFlags, expectedEnvironment, null /* workingDirectory */);
+ }
+
+ @Test
+ public void testPrepareCommand_clientSuppliedEnvironmentVariables()
+ throws AppEngineException, ProcessHandlerException, IOException {
+ Map clientEnvironmentVariables =
+ ImmutableMap.of("mykey1", "myval1", "mykey2", "myval2");
+
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java7Service))
+ .environment(clientEnvironmentVariables)
+ .build();
+
+ Map expectedEnvironment =
+ ImmutableMap.builder()
+ .putAll(expectedJava7Environment)
+ .putAll(clientEnvironmentVariables)
+ .build();
+ List expectedFlags =
+ ImmutableList.of(
+ "--allow_remote_shutdown", "--disable_update_check", java7Service.toString());
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "--add-opens",
+ "java.base/java.net=ALL-UNNAMED",
+ "--add-opens",
+ "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens",
+ "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-javaagent:"
+ + fakeJavaSdkHome.resolve("agent/appengine-agent.jar").toAbsolutePath().toString());
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner, times(1))
+ .run(
+ expectedJvmArgs,
+ expectedFlags,
+ expectedEnvironment,
+ java7Service /* workingDirectory */);
+ }
+
+ @Test
+ public void testPrepareCommand_clientSuppliedAndAppEngineWebXmlEnvironmentVariables()
+ throws AppEngineException, ProcessHandlerException, IOException {
+ Map clientEnvironmentVariables =
+ ImmutableMap.of("mykey1", "myval1", "mykey2", "myval2");
+
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java8Service1EnvVars))
+ .environment(clientEnvironmentVariables)
+ .build();
+
+ List expectedFlags =
+ ImmutableList.of(
+ "--allow_remote_shutdown",
+ "--disable_update_check",
+ "--no_java_agent",
+ java8Service1EnvVars.toString());
+
+ List expectedJvmArgs =
+ ImmutableList.of(
+ "--add-opens", "java.base/java.net=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.http=ALL-UNNAMED",
+ "--add-opens", "java.base/sun.net.www.protocol.https=ALL-UNNAMED",
+ "-Duse_jetty9_runtime=true", "-D--enable_all_permissions=true");
+
+ Map appEngineEnvironment = ImmutableMap.of("key1", "val1", "key2", "val2");
+ Map expectedEnvironment =
+ ImmutableMap.builder()
+ .putAll(appEngineEnvironment)
+ .putAll(expectedJava8Environment)
+ .putAll(clientEnvironmentVariables)
+ .build();
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner, times(1))
+ .run(
+ expectedJvmArgs,
+ expectedFlags,
+ expectedEnvironment,
+ java8Service1EnvVars /* workingDirectory */);
+ }
+
+ @Test
+ public void testCheckAndWarnIgnored_withSetValue() {
+ devServer.checkAndWarnIgnored(new Object(), "testName");
+
+ Assert.assertEquals(1, testHandler.getLogs().size());
+
+ LogRecord logRecord = testHandler.getLogs().get(0);
+ Assert.assertEquals(
+ "testName only applies to Dev Appserver v2 and will be ignored by Dev Appserver v1",
+ logRecord.getMessage());
+ Assert.assertEquals(Level.WARNING, logRecord.getLevel());
+ }
+
+ @Test
+ public void testCheckAndWarnIgnored_withUnsetValue() {
+ devServer.checkAndWarnIgnored(null, "testName");
+
+ Assert.assertEquals(0, testHandler.getLogs().size());
+ }
+
+ @Test
+ public void testDetermineJavaRuntime_noWarningsJava7() throws AppEngineException {
+ Assert.assertTrue(devServer.isSandboxEnforced(ImmutableList.of(java7Service)));
+ Assert.assertEquals(0, testHandler.getLogs().size());
+ }
+
+ @Test
+ public void testDetermineJavaRuntime_noWarningsJava7Multiple() throws AppEngineException {
+ Assert.assertTrue(devServer.isSandboxEnforced(ImmutableList.of(java7Service, java7Service)));
+ Assert.assertEquals(0, testHandler.getLogs().size());
+ }
+
+ @Test
+ public void testDetermineJavaRuntime_noWarningsJava8() throws AppEngineException {
+ Assert.assertFalse(devServer.isSandboxEnforced(ImmutableList.of(java8Service)));
+ Assert.assertEquals(0, testHandler.getLogs().size());
+ }
+
+ @Test
+ public void testDetermineJavaRuntime_noWarningsJava8Multiple() throws AppEngineException {
+ Assert.assertFalse(devServer.isSandboxEnforced(ImmutableList.of(java8Service, java8Service)));
+ Assert.assertEquals(0, testHandler.getLogs().size());
+ }
+
+ @Test
+ public void testDetermineJavaRuntime_mixedModeWarning() throws AppEngineException {
+
+ Assert.assertFalse(devServer.isSandboxEnforced(ImmutableList.of(java8Service, java7Service)));
+ Assert.assertEquals(1, testHandler.getLogs().size());
+
+ LogRecord logRecord = testHandler.getLogs().get(0);
+ Assert.assertEquals(
+ "Mixed runtimes detected, will not enforce sandbox restrictions.", logRecord.getMessage());
+ Assert.assertEquals(Level.WARNING, logRecord.getLevel());
+ }
+
+ @Test
+ public void testWorkingDirectory_fallbackIfOneProject()
+ throws ProcessHandlerException, AppEngineException, IOException {
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java8Service)).build();
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner).run(any(), any(), any(), eq(java8Service) /* workingDirectory */);
+ }
+
+ @Test
+ public void testWorkingDirectory_noFallbackIfManyProjects()
+ throws ProcessHandlerException, AppEngineException, IOException {
+ RunConfiguration configuration =
+ RunConfiguration.builder(ImmutableList.of(java8Service, java8Service)).build();
+
+ devServer.run(configuration);
+
+ verify(devAppServerRunner).run(any(), any(), any(), eq(null) /* workingDirectory */);
+ }
+
+ @Test
+ public void testGetLocalAppEngineEnvironmentVariables_java7() {
+ Map environment = DevServer.getLocalAppEngineEnvironmentVariables("java7");
+ Assert.assertEquals(expectedJava7Environment, environment);
+ }
+
+ @Test
+ public void testGetLocalAppEngineEnvironmentVariables_java8() {
+ Map environment = DevServer.getLocalAppEngineEnvironmentVariables("java8");
+ Assert.assertEquals(expectedJava8Environment, environment);
+ }
+
+ @Test
+ public void testGetLocalAppEngineEnvironmentVariables_other() {
+ Map environment =
+ DevServer.getLocalAppEngineEnvironmentVariables("some_other_runtime");
+ Map expectedEnvironment =
+ ImmutableMap.of("GAE_ENV", "localdev", "GAE_RUNTIME", "some_other_runtime");
+ Assert.assertEquals(expectedEnvironment, environment);
+ }
+
+ @Test
+ public void testGetGaeRuntimeJava_isJava8() {
+ Assert.assertEquals("java8", DevServer.getGaeRuntimeJava(true));
+ }
+
+ @Test
+ public void testGetGaeRuntimeJava_isNotJava8() {
+ Assert.assertEquals("java7", DevServer.getGaeRuntimeJava(false));
+ }
+}