Oliver Shaw
Oliver Shaw

Reputation: 5422

Vert.x Async Testing

I'm new to vert.x. I'm trying to run some basic tests and benchmarks etc to evaluate the framework (so I'm probably doing lots wrong!)

One thing I'm interested is the performance costs of running 'controller' level tests. I set up a test that should repeatedly spin up and tear down a httpclient.

@Repeat(100)
@Test
public void testMyApplication(TestContext context) {

    final Async async = context.async(1);
    vertx.createHttpClient().getNow(8080, "localhost", "/",
            response -> {
                response.handler(body -> {
                    context.assertTrue(body.toString().contains("Hello"));
                    context.assertEquals(200, response.statusCode());
                    async.complete();
                });
            });
    async.awaitSuccess();
}

However this will occasionally fail with.

SEVERE: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:8080

What's a better way to spin up multiple clients and ensure the tests run in order or with some controlled parallelism?

Upvotes: 1

Views: 2029

Answers (2)

Oliver Shaw
Oliver Shaw

Reputation: 5422

OK,

What's happening here is that that due to the async calls then there are occasions where a new test can be started before async.complete is called. Hence there is already a test server running on port 8080.

The solution is to use pass a port in via config and to use a random one in the tests.

      server.requestHandler(router::accept)
          .listen(
                  config().getInteger("http.port", 8080),
      ...

And the test becomes

@Before
public void setUp(TestContext context) throws Exception {
    ServerSocket socket = new ServerSocket(0);
    port = socket.getLocalPort();
    socket.close();

    DeploymentOptions options = new DeploymentOptions()
            .setConfig(new JsonObject().put("http.port", port)
            );
    vertx = Vertx.vertx();
    vertx.deployVerticle(HelloVerticle.class.getName(), options,
            context.asyncAssertSuccess());
}
...

@Repeat(100)
@Test
public void testMyApplication(TestContext context) {

    final Async async = context.async();
    vertx.createHttpClient().getNow(port, "localhost", "/",
            response -> {
                response.handler(body -> {
                    context.assertTrue(body.toString().contains("Hello"));
                    context.assertEquals(200, response.statusCode());
                    async.complete();
                });
            });
}

This blog post helped a lot http://vertx.io/blog/vert-x-application-configuration/

Upvotes: 7

Niraj Chauhan
Niraj Chauhan

Reputation: 7900

The error says that Connection refused, which means no server is running at port 8080. In your test case you need start some server at port 8080.

@RunWith(VertxUnitRunner.class)
public class VertxText {
    Vertx vertx;
    HttpServer server;

    @Before
    public void before(TestContext context) {
        vertx = Vertx.vertx();
        server =
                vertx.createHttpServer().requestHandler(req -> req.response().end("Hello")).
                        listen(8080, context.asyncAssertSuccess());
    }

    @After
    public void after(TestContext context) {
        vertx.close(context.asyncAssertSuccess());
    }

    @Repeat(100)
    @Test
    public void testMyApplication(TestContext context) {
        final Async async = context.async(1);
        vertx.createHttpClient().getNow(8080, "localhost", "/",
                response -> {
                    response.handler(body -> {
                        context.assertTrue(body.toString().contains("Hello"));
                        context.assertEquals(200, response.statusCode());
                        async.complete();
                    });
                });
        async.awaitSuccess();
    }
}

In the before, where server is getting initialized you will have to pass your request handler which will test your routes.

Upvotes: 1

Related Questions