Kaushik Das
Kaushik Das

Reputation: 119

vertx unit test not executing, timeout exception

I have the below simple retry class. This class will retry a given promise for a couple no of times(retryCount), with a given delay(delay), if it succeeds within the retry count, it passes, else it fails.

public class SimpleRetry {

  private final Vertx vertx;

  public SimpleRetry(Vertx vertx) {
    this.vertx = vertx;
  }

  
  public <T> Promise<T> retryWithDelay(Promise<T> promise, int retryCount, int delay, TimeUnit unit) {
    log.debug("Retrying operation with : " + retryCount + " retry count and delay of " + delay);
    return execute(promise, retryCount, delay, unit);
  }


  private <T> Promise<T> execute(Promise<T> promise, int count, int delay, TimeUnit unit) {
    Promise<T> newPromise = Promise.promise();
    if (count > 0) {
      promise.future().onComplete(handler -> {
        if (handler.succeeded()) {
          log.debug("Retry operation successful");
          newPromise.complete(handler.result());
        } else {
          log.debug("Operation failed, hence retrying again..");
          if (delay > 0) {
            vertx.setTimer(unit.toMillis(delay), id -> execute(promise, count - 1, delay, unit));
          } else {
            execute(promise, count - 1, delay, unit);
          }
        }
      });
    } else {
      log.debug("Retry count exceeded, hence failing the promise..");
      newPromise.fail("Retry count exceeded!.");
    }
    return newPromise;
  }

Wrote the below test case to test it. But it doesn't get executed. instead it times out.

@RunWith(VertxUnitRunner.class)
public class SimpleRetryTests {

  private SimpleRetry simpleRetry;
  private Vertx vertx;
  private static int count;

  @Before
  public void setUp(TestContext context){
    vertx = Vertx.vertx();
    simpleRetry = new SimpleRetry(vertx);
    count = 0;
    context.asyncAssertSuccess();
  }

  @Test
  public void testSimpleRetryWhichPassesOnFirstTry(TestContext context){
    final Async async = context.async();
    simpleRetry.retryWithDelay(dummyPromise(1), 10, 10, TimeUnit.MILLISECONDS)
        .future().onSuccess(res -> {
      System.out.println("Promise completed");
      context.asyncAssertSuccess();
      async.complete();
    }).onFailure(ex -> {
      System.out.println("Promise failed : " + ex);
      context.asyncAssertFailure();
      async.complete();
    });
  }

  //A dummy promise which only passes when called 5 times.
  private Promise<Void> dummyPromise(int passCount){
    Promise<Void> promise = Promise.promise();
    vertx.setTimer(10, id->{
      count++;
      if(count == passCount) {
        promise.complete();
      } else {
        promise.fail("Error!!");
      }
    });
    return promise;
  }

  @After
  public void tearDown(TestContext context){
    simpleRetry = null;
    vertx.close(context.asyncAssertSuccess());
  }
}

What am I doing wrong? Thanks in advance.

Upvotes: 1

Views: 576

Answers (1)

taygetos
taygetos

Reputation: 3040

You are misusing the context.asyncAssertSuccess() and context.asyncAssertFailure() it will halt your code, e.g your setUp function will never exit. Take them out and your test is going to run through.

Upvotes: 1

Related Questions