Description
Pulsar tests regularly succeed locally, but after submitting a Pull Request to merge changes into master, some of the tests (usually < 3 at a time) will randomly fail.
Examples include, but are not limited to:
In CI - CPP, Python Tests / cpp-tests:
In CI - Unit - Brokers:
In CI - Unit - Flaky:
In CI - Unit - Proxy:
In CI - Integration - Function State:
In CI - Unit - Adapters:
Regarding org.apache.pulsar.client.api.SimpleProducerConsumerTest.setup, I found an interesting exception message:
org.apache.pulsar.client.api.SimpleProducerConsumerTest.setup(org.apache.pulsar.client.api.SimpleProducerConsumerTest)
165[ERROR] Run 1: SimpleProducerConsumerTest.setup:108->MockedPulsarServiceBaseTest.internalSetup:107->MockedPulsarServiceBaseTest.init:144->MockedPulsarServiceBaseTest.startBroker:195->MockedPulsarServiceBaseTest.startBroker:218 禄 WrongTypeOfReturnValue
This message suggests that there's a race condition in the testing framework (or our use of it).
Perhaps there are known concurrency bugs in some of the versions of the test libraries we are using.
Each time the tests are run (e.g. for PR #6031), different tests fail. There seems to be no consistency to them at all.
There is also a risk that there are concurrency bugs in the actual framework that only appear in certain environments. If this is the case, then these bugs could result in instability for certain users in production environments.
Expected behavior
Tests should not randomly fail when run by Jenkins or the Github CI Action test runner after submitting a Pull Request. These random failures significantly slow down the rate of being able to merge PRs and raise the possibility of other potential risks.
Do we ever have cases where multiple threads are stubbing/verifying a shared mock?
@merlimat Do you have any theories about what could be happening? It looks like you've spent a decent amount of time in a lot of these tests.
@sijie I added a lot of detail about the different exceptions that are appearing.
I noticed that there are many tests (including at least two of the tests above) that use this block of code that involves a Thread.sleep, which is often an anti-pattern in tests.
In MockedPulsarServiceBaseTest.java:
public static boolean retryStrategically(Predicate<Void> predicate, int retryCount, long intSleepTimeInMillis)
throws Exception {
for (int i = 0; i < retryCount; i++) {
if (predicate.test(null) || i == (retryCount - 1)) {
return true;
}
Thread.sleep(intSleepTimeInMillis + (intSleepTimeInMillis * i));
}
return false;
}
At least these two tests (referenced above) use retryStrategically:
org.apache.pulsar.client.kafka.test.KafkaProducerSimpleConsumerTest
org.apache.pulsar.functions.worker.PulsarFunctionE2ESecurityTest
After discovering quite a few closed issues involving intermittent tests, I realized that almost all of them involved race conditions or concurrency issues involving shared state.
So, I'll start looking at these failing tests in greater depth individually.
I'm hoping that some common causes will emerge, but so far, it looks like each one of the solved intermittent tests has been a unique case.
Thanks @devinbost for the great help
I found an interesting study that examined common causes of Flaky tests: http://mir.cs.illinois.edu/~qluo2/fse14LuoHEM.pdf
Most helpful comment
After discovering quite a few closed issues involving intermittent tests, I realized that almost all of them involved race conditions or concurrency issues involving shared state.
So, I'll start looking at these failing tests in greater depth individually.
I'm hoping that some common causes will emerge, but so far, it looks like each one of the solved intermittent tests has been a unique case.