Search code examples
javajboss-arquillian

Multiple threads in Arquillain


I am writing a test that uses some client side logic and some server side logic. In the client side, I make a REST call to some webservice which manipulates the data and stores it in a JMS queue. I later make a JMS call to see what was written to the JMS topic, and am getting some surprising results.

Here is the interesting portion of the test code that defines this issue:

@Test
@OperateOnDeployment("my-deployable")
public void testMessageInTopic() throws Exception {
    // make a rest call with the minimal request
    makeRequest(getMyXmlAsString());

    // compare the message with the one sent to the topic
    connection = factory.createConnection();
    final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    final MessageConsumer consumer = session.createConsumer(topic);
    connection.start();

    System.out.println("### listening for a response");
    final TextMessage receivedMessage = (TextMessage) consumer.receive();
    final String expectedString = "sampleFromTest"

    final String receivedText = receivedMessage.getText();
    System.out.println("### got this message " + receivedText);
    assertEquals("the message in the received topic is the same", expectedString, receivedText);
    System.out.println("#### the message was as expected");
}

The makeRequest(final String data) method does the following:

public makeRequest(final String data) {
    final String url = getAppEndpoint("http://localhost:8080/doit");
    final ClientRequest req= new ClientRequest(url);
    req.header(HttpHeaderNames.CONTENT_TYPE, MediaType.TEXT_PLAIN);
    req.body(MediaType.TEXT_PLAIN, data);
    response = req.post(MyResponse.class);
}

When observing the logs, here are the messages I get in order:

09:38:59,448 INFO  [stdout] (pool-2-thread-1) ### got this message sampleFromTest
09:38:59,448 INFO  [stdout] (pool-2-thread-1) #### the message was as expected
09:38:59,488 INFO  [stdout] (pool-2-thread-2) ### listening for a response

It's obvious that embedded tests and client side tests combined do not play nice, as threading becomes an issue. I can potentially circumvent this issue by making the rest call in my @Before test method, or by injecting the webservice and programmatically hitting it with a request. However, as my interest lies in testing the full integration path, mixing client and server requests seems like a good idea. My question is then, is it possible to run a scenario where we make a client side request and parse data received by the container?


Solution

  • Turns out that I was getting this discrepancy because I was calling the jms receive() method without adding an explicit wait. Hence, the above output was correct:

    09:38:59,448 INFO  [stdout] (pool-2-thread-1) ### got this message sampleFromTest
    09:38:59,448 INFO  [stdout] (pool-2-thread-1) #### the message was as expected
    09:38:59,488 INFO  [stdout] (pool-2-thread-2) ### listening for a response
    

    To solve my issue, I did something like this to add an explicit, synchronous wait before executing more code:

    final TextMessage message = (TextMessage) consumer.receive(15000);
    

    This way, after a message is written, I wait for up to 15 sec for it to trickle back down. While I could never prove that

    ### listening for a response
    

    never occurred before

    09:38:59,448
    

    in the original issue, applying this approach indeed solves the problem.