From 1f617b77fd77d09f327b909d2302f2f4efc6e0a5 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 29 Sep 2015 17:14:32 -0700 Subject: [PATCH] choose port for LocalGcdHelper dynamically --- .../datastore/DatastoreOptionsTest.java | 5 +- .../gcloud/datastore/DatastoreTest.java | 7 +-- .../gcloud/datastore/LocalGcdHelper.java | 53 ++++++++++++------- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index e7dc71c50ff6..8a0d52aec9c8 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -34,6 +34,7 @@ public class DatastoreOptionsTest { private static final String PROJECT_ID = "project_id"; + private static final int PORT = LocalGcdHelper.findOpenPort(); private DatastoreRpcFactory datastoreRpcFactory; private DatastoreRpc datastoreRpc; private DatastoreOptions.Builder options; @@ -46,7 +47,7 @@ public void setUp() throws IOException, InterruptedException { .normalizeDataset(false) .serviceRpcFactory(datastoreRpcFactory) .projectId(PROJECT_ID) - .host("http://localhost:" + LocalGcdHelper.PORT); + .host("http://localhost:" + PORT); EasyMock.expect(datastoreRpcFactory.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(datastoreRpc) .anyTimes(); @@ -60,7 +61,7 @@ public void testProjectId() throws Exception { @Test public void testHost() throws Exception { - assertEquals("http://localhost:" + LocalGcdHelper.PORT, options.build().host()); + assertEquals("http://localhost:" + PORT, options.build().host()); } @Test diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 156f9684f8ba..2c7e8f987cb1 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -101,11 +101,12 @@ public class DatastoreTest { private Datastore datastore; private static LocalGcdHelper gcdHelper; + private static final int PORT = LocalGcdHelper.findOpenPort(); @BeforeClass public static void beforeClass() throws IOException, InterruptedException { - if (!LocalGcdHelper.isActive(PROJECT_ID)) { - gcdHelper = LocalGcdHelper.start(PROJECT_ID); + if (!LocalGcdHelper.isActive(PROJECT_ID, PORT)) { + gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT); } } @@ -113,7 +114,7 @@ public static void beforeClass() throws IOException, InterruptedException { public void setUp() throws IOException, InterruptedException { options = DatastoreOptions.builder() .projectId(PROJECT_ID) - .host("http://localhost:" + LocalGcdHelper.PORT) + .host("http://localhost:" + PORT) .build(); datastore = DatastoreFactory.instance().get(options); StructuredQuery query = Query.keyQueryBuilder().build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 888fd2157d3a..a78797bb88e4 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -35,6 +35,7 @@ import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.MalformedURLException; +import java.net.ServerSocket; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; @@ -68,9 +69,10 @@ public class LocalGcdHelper { private final String projectId; private Path gcdPath; private ProcessStreamReader processReader; + private final int port; public static final String DEFAULT_PROJECT_ID = "projectid1"; - public static final int PORT = 8080; + private static final int DEFAULT_PORT = 8080; private static final String GCD_VERSION = "v1beta2"; private static final String GCD_BUILD = "rev1-2.1.2b"; private static final String GCD_BASENAME = "gcd-" + GCD_VERSION + "-" + GCD_BUILD; @@ -94,6 +96,17 @@ public class LocalGcdHelper { } } + public static int findOpenPort() { + int port; + try (ServerSocket temp_socket = new ServerSocket(0)) { + port = temp_socket.getLocalPort(); + temp_socket.close(); + } catch (IOException e) { + port = DEFAULT_PORT; + } + return port; + } + private static Path installedGcdPath() { String gcloudExecutableName; if (isWindows()) { @@ -283,8 +296,9 @@ public static CommandWrapper create() { } } - public LocalGcdHelper(String projectId) { + public LocalGcdHelper(String projectId, int port) { this.projectId = projectId; + this.port = port; } /** @@ -297,7 +311,7 @@ public LocalGcdHelper(String projectId) { */ public void start() throws IOException, InterruptedException { // send a quick request in case we have a hanging process from a previous run - sendQuitRequest(); + sendQuitRequest(port); // Each run is associated with its own folder that is deleted once test completes. gcdPath = Files.createTempDirectory("gcd"); File gcdFolder = gcdPath.toFile(); @@ -379,13 +393,12 @@ private void startGcd(Path executablePath) throws IOException, InterruptedExcept if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Starting datastore emulator for the project: {0}", projectId); } - Process startProcess = - CommandWrapper.create() - .command(gcdAbsolutePath.toString(), "start", "--testing", "--allow_remote_shutdown", - projectId) - .directory(gcdPath) - .redirectErrorStream() - .start(); + Process startProcess = CommandWrapper.create() + .command(gcdAbsolutePath.toString(), "start", "--testing", "--allow_remote_shutdown", + "--port=" + Integer.toString(port), projectId) + .directory(gcdPath) + .redirectErrorStream() + .start(); processReader = ProcessStreamReader.start(startProcess, "Dev App Server is now running"); } @@ -419,9 +432,9 @@ private static void extractFile(ZipInputStream zipIn, File filePath) throws IOEx } } - public static void sendQuitRequest() { + public static void sendQuitRequest(int port) { try { - URL url = new URL("http", "localhost", PORT, "/_ah/admin/quit"); + URL url = new URL("http", "localhost", port, "/_ah/admin/quit"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("POST"); con.setDoOutput(true); @@ -439,7 +452,7 @@ public static void sendQuitRequest() { } public void stop() throws IOException, InterruptedException { - sendQuitRequest(); + sendQuitRequest(port); if (processReader != null) { processReader.terminate(); } @@ -468,8 +481,8 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO }); } - public static LocalGcdHelper start(String projectId) throws IOException, InterruptedException { - LocalGcdHelper helper = new LocalGcdHelper(projectId); + public static LocalGcdHelper start(String projectId, int port) throws IOException, InterruptedException { + LocalGcdHelper helper = new LocalGcdHelper(projectId, port); helper.start(); return helper; } @@ -478,15 +491,15 @@ public static void main(String... args) throws IOException, InterruptedException if (args.length == 1) { switch (args[0]) { case "START": - if (!isActive(DEFAULT_PROJECT_ID)) { - LocalGcdHelper helper = start(DEFAULT_PROJECT_ID); + if (!isActive(DEFAULT_PROJECT_ID, DEFAULT_PORT)) { + LocalGcdHelper helper = start(DEFAULT_PROJECT_ID, DEFAULT_PORT); try (FileWriter writer = new FileWriter(".local_gcd_helper")) { writer.write(helper.gcdPath.toAbsolutePath().toString()); } } return; case "STOP": - sendQuitRequest(); + sendQuitRequest(DEFAULT_PORT); File file = new File(".local_gcd_helper"); if (file.exists()) { try (BufferedReader reader = new BufferedReader(new FileReader(file))) { @@ -503,9 +516,9 @@ public static void main(String... args) throws IOException, InterruptedException throw new RuntimeException("expecting only START | STOP"); } - public static boolean isActive(String projectId) { + public static boolean isActive(String projectId, int port) { try { - StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); + StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(port); urlBuilder.append("/datastore/v1beta2/datasets/").append(projectId).append("/lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader =