// Copyright 2015 Michel Kraemer // // 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 de.undercouch.vertx.lang.typescript; import java.io.IOException; import java.net.ConnectException; import java.net.ServerSocket; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import io.vertx.core.AsyncResult; import io.vertx.core.DeploymentOptions; import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpClientRequest; import io.vertx.core.json.JsonObject; import io.vertx.ext.unit.Async; import io.vertx.ext.unit.TestContext; import io.vertx.ext.unit.junit.RunTestOnContext; import io.vertx.ext.unit.junit.Timeout; import io.vertx.ext.unit.junit.VertxUnitRunnerWithParametersFactory; /** * Tests various verticles written in TypeScript * @author Michel Kraemer */ @RunWith(Parameterized.class) @Parameterized.UseParametersRunnerFactory(VertxUnitRunnerWithParametersFactory.class) public class TypeScriptVerticleTest extends MultipleCompilerTestBase { @Rule public RunTestOnContext runTestOnContext = new RunTestOnContext(); @Rule public Timeout globalTimeout = Timeout.seconds(60 * 10); // 10 minutes (for the really slow CI server) @BeforeClass public static void setUpClass() { System.setProperty(TypeScriptVerticleFactory.PROP_NAME_SHARE_COMPILER, "true"); } public TypeScriptVerticleTest(Compiler compiler) { super(compiler); } /** * Gets a free socket port * @return the port * @throws IOException if the port could not be determined */ private static int getAvailablePort() throws IOException { ServerSocket s = null; try { s = new ServerSocket(0); return s.getLocalPort(); } finally { if (s != null) { s.close(); } } } private void makeRequest(HttpClient client, int port, int retries, int delay, Handler<AsyncResult<Buffer>> handler) { Vertx vertx = runTestOnContext.vertx(); HttpClientRequest request = client.get(port, "localhost", "/", response -> response.bodyHandler(buffer -> handler.handle(Future.succeededFuture(buffer)))); request.exceptionHandler(t -> { if (retries > 0 && t instanceof ConnectException) { vertx.setTimer(delay, l -> makeRequest(client, port, retries - 1, delay, handler)); } else { handler.handle(Future.failedFuture(t)); } }); request.end(); } private void doTest(String verticle, String message, TestContext context) throws IOException { Async async = context.async(); int port = getAvailablePort(); JsonObject config = new JsonObject().put("port", port); DeploymentOptions options = new DeploymentOptions().setConfig(config); Vertx vertx = runTestOnContext.vertx(); vertx.deployVerticle(verticle, options, context.asyncAssertSuccess(deploymentID -> { HttpClient client = vertx.createHttpClient(); // retry for 30 seconds and give the verticle a chance to launch the server makeRequest(client, port, 30, 1000, context.asyncAssertSuccess(buffer -> { context.assertEquals(message, buffer.toString()); vertx.undeploy(deploymentID, context.asyncAssertSuccess(r -> async.complete())); client.close(); })); })); } /** * Tests if a simple HTTP server can be deployed. Relies on the current * working directory being the project's root. * @throws Exception if something goes wrong */ @Test public void simpleServer(TestContext context) throws Exception { doTest("src/test/resources/simpleServer.ts", "Hello", context); } /** * Tests if a simple HTTP server using routing can be deployed. Relies on * the current working directory being the project's root. * @throws Exception if something goes wrong */ @Test public void routingServer(TestContext context) throws Exception { doTest("src/test/resources/routingServer.ts", "Hello Routing", context); } /** * Tests if a simple HTTP server using modules can be deployed. Relies on * the current working directory being the project's root. * @throws Exception if something goes wrong */ @Test public void moduleServer(TestContext context) throws Exception { doTest("src/test/resources/moduleServer.ts", "Hello Module", context); } }