Skip to content

Commit

Permalink
JT400 tests can not be run in parallel #6018
Browse files Browse the repository at this point in the history
  • Loading branch information
JiriOndrusek authored and jamesnetherton committed Apr 23, 2024
1 parent 3539d6b commit 90df987
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 236 deletions.
47 changes: 25 additions & 22 deletions integration-tests/jt400/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,31 @@ CRTDTAQ DTAQ(LIBRARY/TESTKEYED) SEQ(*KEYED) KEYLEN(20) MAXLEN(100)
CRTDTAQ DTAQ(LIBRARY/TESTLIFO) SEQ(*LIFO) MAXLEN(100)
```

==== Synchronization for parallel executions

The tests do not work by default for parallel executions.
For parallel scenario, the locking file has to be provided.

You can create such file by running

```
QSH CMD('touch #file_lock_path')
for example QSH CMD('touch /home/#username/cq_jt400_lock')
```

How to provide a locking file:

```
export JT400_LOCK_FILE=#file_lock_path
```

or for Windows:

```
$Env:JT400_LOCK_FILE="#file_lock_path"
```
*If locking file is not provided, tests may fail their executions in parallel mode*

==== Using different object names

If your test object names are different from the default ones, you can override default values via environmental variable
Expand All @@ -109,27 +134,5 @@ $Env:JT400_LIFO_QUEUE="#lifoqueue_if_not_TESTLIFO.DTAQe"
$Env:JT400_KEYED_QUEUE="#lkeyedqueue_if_not_TESTKEYED.DTAQ"
$Env:JT400_MESSAGE_QUEUE="#messagequeue_if_not_TESTMSGQ.MSGQ"
$Env:JT400_MESSAGE_REPLYTO_QUEUE="#messagequeueinquiry_if_not_REPLYMSGQ.MSGQ"
$Env:JT400_USER_SPACE="#userspace_if_not_PROGCALL"
```

=== Clear queues after unexpected failures

If tests finishes without unexpected failure, tests are taking care of clearing the data.
In some cases data might stay written into the real server if test fails unexpectedly.
This state should might alter following executions.

To force full clear (of each queue) can be achieved by add ing parameter
```
-Dcq.jt400.clear-all=true
```
Be aware that with `-Dcq.jt400.clear-all=true`, the tests can not successfully finish in parallel run.

Usage of clear queues parameter is *strongly* suggested during development


==== Parallel runs and locking

Simple locking mechanism is implemented for the test to allow parallel executions.

Whenever test is started, new entry is written into keyed data queue `JT400_KEYED_QUEUE` with the key `cq.jt400.global-lock` and entry is removed after the run.
Tests are able to clear this lock even if previous execution fails unexpectedly.
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
#quarkus.test.flat-class-path = ${quarkus.test.flat-class-path}

# workaround for mocked tests, should be solvable by excluding mocked java files from compilation of skip-mock-tests profile
# I can not make it work though, but to not block the native support by this, I'm setting flat path to true for all tests
quarkus.test.flat-class-path = true

#jt400 server connection information
cq.jt400.url=${JT400_URL:system}
cq.jt400.username=${JT400_USERNAME:username}
Expand All @@ -31,4 +25,6 @@ cq.jt400.user-space=${JT400_USER_SPACE:PROGCALL}
cq.jt400.message-queue=${JT400_MESSAGE_QUEUE:TESTMSGQ.MSGQ}
cq.jt400.message-replyto-queue=${JT400_MESSAGE_REPLYTO_QUEUE:REPLYMSGQ.MSGQ}
cq.jt400.keyed-queue=${JT400_KEYED_QUEUE:TESTKEYED.DTAQ}
cq.jt400.lifo-queue=${JT400_LIFO_QUEUE:TESTLIFO.DTAQ}
cq.jt400.lifo-queue=${JT400_LIFO_QUEUE:TESTLIFO.DTAQ}

cq.jt400.lock-file=${JT400_LOCK_FILE}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.awaitility.Awaitility;
import org.hamcrest.Matchers;
import org.jboss.logging.Logger;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
Expand All @@ -41,33 +40,42 @@ public class Jt400Test {

private final int MSG_LENGTH = 20;
//tests may be executed in parallel, therefore the timeout is a little bigger in case the test has to wait for another one
private final int WAIT_IN_SECONDS = 20;
private static final int WAIT_IN_SECONDS = 30;

@BeforeAll
public static void beforeAll() throws Exception {
//lock execution
getClientHelper().lock();

//for development purposes
// logQueues();

//lock execution
Jt400TestResource.CLIENT_HELPER.lock();
}

@AfterAll
public static void afterAll() throws Exception {
getClientHelper().unlock();
//clear al data in advance to be sure that there is no data in the queues
//it is not possible to clear data after the run because of CPF2451 Message queue REPLYMSGQ is allocated to another job
//wait is required also because of CPF2451, usually takes ~20 seconds to release connections to a reply queue
Awaitility.await().pollInterval(1, TimeUnit.SECONDS).atMost(WAIT_IN_SECONDS, TimeUnit.SECONDS).until(
() -> {
try {
return getClientHelper().clear();
} catch (Exception e) {
LOGGER.debug("Clear failed because of: " + e.getMessage());
return false;
}
},
Matchers.is(true));
}

private static void logQueues() throws Exception {
StringBuilder sb = new StringBuilder("\n");
sb.append("**********************************************************");
sb.append("************************************************************");
sb.append(getClientHelper().dumpQueues());
sb.append("\n**********************************************************\n");
LOGGER.info(sb.toString());
}

@Test
public void testDataQueue() {
LOGGER.debug("** testDataQueue() ** has started ");
LOGGER.debug("**** testDataQueue() ** has started ");

String msg = RandomStringUtils.randomAlphanumeric(MSG_LENGTH).toLowerCase(Locale.ROOT);
String answer = "Hello From DQ: " + msg;
Expand All @@ -91,7 +99,7 @@ public void testDataQueue() {

@Test
public void testDataQueueBinary() throws Exception {
LOGGER.debug("** testDataQueueBinary() ** has started ");
LOGGER.debug("**** testDataQueueBinary() ** has started ");
String msg = RandomStringUtils.randomAlphanumeric(MSG_LENGTH).toLowerCase(Locale.ROOT);
String answer = "Hello (bin) " + msg;

Expand All @@ -118,7 +126,7 @@ public void testDataQueueBinary() throws Exception {

@Test
public void testKeyedDataQueue() {
LOGGER.debug("** testKeyedDataQueue() ** has started ");
LOGGER.debug("**** testKeyedDataQueue() ** has started ");
String msg1 = RandomStringUtils.randomAlphanumeric(MSG_LENGTH).toLowerCase(Locale.ROOT);
String msg2 = RandomStringUtils.randomAlphanumeric(MSG_LENGTH).toLowerCase(Locale.ROOT);
String answer1 = "Hello From KDQ: " + msg1;
Expand Down Expand Up @@ -170,7 +178,7 @@ public void testKeyedDataQueue() {

@Test
public void testMessageQueue() throws Exception {
LOGGER.debug("** testMessageQueue() ** has started ");
LOGGER.debug("**** testMessageQueue() ** has started ");
//write
String msg = RandomStringUtils.randomAlphanumeric(MSG_LENGTH).toLowerCase(Locale.ROOT);
String answer = "Hello from MQ: " + msg;
Expand Down Expand Up @@ -205,19 +213,20 @@ public void testMessageQueue() throws Exception {

@Test
public void testInquiryMessageQueue() throws Exception {
LOGGER.debug("** testInquiryMessageQueue() **: has started ");
LOGGER.debug("**** testInquiryMessageQueue() **: has started ");

String msg = RandomStringUtils.randomAlphanumeric(10).toLowerCase(Locale.ROOT);
String replyMsg = "reply to: " + msg;

LOGGER.debug("testInquiryMessageQueue: writing " + msg);
getClientHelper().registerForRemoval(Jt400TestResource.RESOURCE_TYPE.replyToQueueu, msg);
getClientHelper().registerForRemoval(Jt400TestResource.RESOURCE_TYPE.replyToQueueu, replyMsg);

//sending a message using the same client as component
getClientHelper().sendInquiry(msg);

LOGGER.debug("testInquiryMessageQueue: message " + msg + " written via client");
//register deletion of the message in case some following task fails
QueuedMessage queuedMessage = getClientHelper().peekReplyToQueueMessage(msg);
if (queuedMessage != null) {
getClientHelper().registerForRemoval(Jt400TestResource.RESOURCE_TYPE.replyToQueueu, queuedMessage.getKey());
LOGGER.debug("testInquiryMessageQueue: message confirmed by peek: " + msg);
}

Expand All @@ -227,6 +236,7 @@ public void testInquiryMessageQueue() throws Exception {
.post("/jt400/inquiryMessageSetExpected")
.then()
.statusCode(204);

//start route before sending message (and wait for start)
Awaitility.await().atMost(WAIT_IN_SECONDS, TimeUnit.SECONDS).until(
() -> RestAssured.get("/jt400/route/start/inquiryRoute")
Expand All @@ -237,7 +247,7 @@ public void testInquiryMessageQueue() throws Exception {
LOGGER.debug("testInquiryMessageQueue: inquiry route started");

//await to be processed
Awaitility.await().pollInterval(1, TimeUnit.SECONDS).atMost(20, TimeUnit.SECONDS).until(
Awaitility.await().pollInterval(1, TimeUnit.SECONDS).atMost(WAIT_IN_SECONDS, TimeUnit.SECONDS).until(
() -> RestAssured.get("/jt400/inquiryMessageProcessed")
.then()
.statusCode(200)
Expand Down
Loading

0 comments on commit 90df987

Please sign in to comment.