Commit b1188c27 authored by Asier Lostalé's avatar Asier Lostalé
Browse files

fixes BUG-46159: unstable DalLockingTest.lockedObjectShouldAllowChildrenCreation

This tests executes 2 threads:

  - T1: acquires a lock on an AlertRule and keeps running for a while
    (200ms)
  - T2: is executed after the lock is aquiered and inserts a recipient
    for the rule with the lock

The tests asserts T2 completes before than T1, ensuring in PG the lock
is a FOR UPDATE NO KEY which allows insertions in child tables even
there is a lock in the parent. It assumes T2 completes faster than the
200ms T1 waits after the lock is acquired.

In certain cases, it is possible T2 to take more than 200ms to do
complete the instertion. In these cases T1 will finish before T2 making
the test fail.

This commit fixes the problem by removing the fixed 200ms wait in T1
replacing it with a latch to wait for T2 to complete (or fail if it
takes more than 10s, which never should be the case).

On top:
  - It adds some timing information to the logs
  - fixes a typo in waitUntil method name
parent fc84808b
......@@ -11,7 +11,7 @@
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2018 Openbravo SLU
* All portions are Copyright (C) 2018-2021 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
......@@ -118,13 +118,18 @@ public class DalLockingTest extends OBBaseTest {
public void lockedObjectShouldAllowChildrenCreation()
throws InterruptedException, ExecutionException {
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch t2completes = new CountDownLatch(1);
List<Callable<Void>> threads = Arrays.asList( //
doWithDAL(() -> acquireLock(latch), "T1", 200), //
doWithDAL(() -> {
acquireLock(latch);
waitUntil(t2completes);
}, "T1", 0), //
doWithDAL(() -> {
AlertRecipient recipient = OBProvider.getInstance().get(AlertRecipient.class);
recipient.setRole(OBContext.getOBContext().getRole());
recipient.setAlertRule(getTestingAlertRule());
OBDal.getInstance().save(recipient);
t2completes.countDown();
}, "T2", latch));
executeAndGetResults(threads);
......@@ -144,7 +149,7 @@ public class DalLockingTest extends OBBaseTest {
AlertRule ar = getTestingAlertRule();
originalName.append(ar.getName());
gotRule.countDown();
waitUnitl(ruleModified);
waitUntil(ruleModified);
lockedName.append(OBDal.getInstance().getObjectLockForNoKeyUpdate(ar).getName());
}, "T1", 50), //
doWithDAL(() -> {
......@@ -191,10 +196,18 @@ public class DalLockingTest extends OBBaseTest {
long waitAfter) {
return () -> {
boolean errorOccurred = false;
long tWaitBefore = -1;
long tCompletion = -1;
try {
OBContext.setAdminMode(true);
waitUnitl(waitEvent);
tWaitBefore = System.currentTimeMillis();
waitUntil(waitEvent);
tWaitBefore = System.currentTimeMillis() - tWaitBefore;
tCompletion = System.currentTimeMillis();
r.run();
tCompletion = System.currentTimeMillis() - tCompletion;
TimeUnit.MILLISECONDS.sleep(waitAfter);
return null;
} catch (Exception e) {
......@@ -204,7 +217,9 @@ public class DalLockingTest extends OBBaseTest {
throw new OBException(e);
} finally {
synchronized (executionOrder) {
log.info("Completed thread {}", name);
log.info(
"Completed thread {}. Timings - wait before: {} - execution: {} - wait after: {}",
name, tWaitBefore, tCompletion, waitAfter);
executionOrder.add(name);
}
if (!errorOccurred) {
......@@ -243,7 +258,7 @@ public class DalLockingTest extends OBBaseTest {
return OBDal.getInstance().get(AlertRule.class, testingRuleId);
}
private void waitUnitl(CountDownLatch event) {
private void waitUntil(CountDownLatch event) {
if (event == null) {
return;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment