Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can not set up clustered Vert.x environment from my JUnit test

I have a junit test where I would like to set up a clustered vert.x environment. It works fine if I run the code in the setUp method from the public static void main() method but not if it is run from the setUpmethod.
The public void handle(AsyncResult<Vertx> res) method is never invoked! Why?

@RunWith(VertxUnitRunner.class)
public class TestMyStuff {
    private Vertx vertx;

    @Before
    public void setUp(TestContext context) throws IOException {

        ClusterManager mgr = new HazelcastClusterManager();
        VertxOptions options = new VertxOptions().setClusterManager(mgr);
        Vertx.clusteredVertx(options, new Handler<AsyncResult<Vertx>>() {
            @Override
            public void handle(AsyncResult<Vertx> res) {
                if(res.succeeded()) {
                    vertx = res.result();

                    DeploymentOptions options = new DeploymentOptions()
                            .setConfig(new JsonObject().put("http.port", 8080)
                            );
                    vertx.deployVerticle(MyWebService.class.getName(), options, context.asyncAssertSuccess());
                    System.out.println("SUCCESS");
                } else {
                    System.out.println("FAILED");
                }
            }
        });
    }

    @Test
    public void printSomething(TestContext context) {
        System.out.println("Print from method printSomething()");
    }

"Print from method printSomething()" is beeing written but not "SUCCESS" or "FAILED" from the handle() method.

Why does not it work in the setUp method but from main()?

like image 613
Rox Avatar asked Dec 10 '25 09:12

Rox


2 Answers

VertX does have its own function to handle multithreading and Asynchronous request.

Just use Async class in your Test function:

   @Test
   public void printSomething(TestContext context) {
        Async async = context.async();
        System.out.println("Print from method printSomething()");
        async.complete();     
   }

Hope it helps some body in future.

like image 141
Crawler Avatar answered Dec 11 '25 22:12

Crawler


The test isn't set up properly due to the asynchronous behaviour of VertX:

  • The code inside @Before is starting VertX in an asynchronous way with Vertx.clusteredVertx(), but it simply doesn't have time to even start VertX
  • The printSomething() method starts right after the clusteredVertx() call (without a running VertX), the test itself ends immediately so JUnit stops the whole test process, killing the not-even-started VertX

I have encountered this issue as well some time ago, so what you should do in this situation?

You should set up VertX properly and wait in your test method to finish the setup. I could accomplish this with a waiting-kind-of mechanism, using the Awaitility (https://github.com/jayway/awaitility).

The main points

  • set up a variable to wait for the setup of vertx
  • in the handler of the clusteredVertx call, set the variable to true
  • and finally, wait for this variable to be set in the test method

I

@RunWith(VertxUnitRunner.class) 
public class TestMyStuff {
   private Vertx vertx;

   final AtomicBoolean loaded = new AtomicBoolean(false);

   @Before
   public void setUp(TestContext context) throws IOException {
    ClusterManager mgr = new HazelcastClusterManager();
    VertxOptions options = new VertxOptions().setClusterManager(mgr);
    Vertx.clusteredVertx(options, new Handler<AsyncResult<Vertx>>() {
        @Override
        public void handle(AsyncResult<Vertx> res) {
            if (res.succeeded()) {
                vertx = res.result();

                DeploymentOptions options = new DeploymentOptions()
                        .setConfig(new JsonObject().put("http.port", 8080)
                        );
                //vertx.deployVerticle(MyWebService.class.getName(), options, context.asyncAssertSuccess());
                System.out.println("SUCCESS");
                loaded.set(true);
            } else {
                System.out.println("FAILED");
            }
         }
       });
   }

   @Test
   public void printSomething(TestContext context) {


    Awaitility.waitAtMost(Duration.ONE_MINUTE).await().untilTrue(loaded);
    System.out.println("Print from method printSomething()");
   }
}

I hope this helps to understand the main point, so you can find any other workaround as well!

like image 29
gabowsky Avatar answered Dec 11 '25 22:12

gabowsky