citrus
citrus copied to clipboard
StackOverflowError when using many SequenceBefore / SequenceAfter
Description: When having many SequenceBefore / SequenceAfter (e.g. 'TestRunnerBeforeTestSupport') the application context cannot be created because of an StackOverflowError.
Citrus Version 2.7.8 2.7.9-SNAPSHOT
Expected behavior Application Context should have been initialized and tests should run.
Actual behavior Application crashes with 'StackOverflowError'
Test case sample Testclass:
package stackoverflow;
import com.consol.citrus.annotations.CitrusTest;
import com.consol.citrus.dsl.testng.TestNGCitrusTestRunner;
import org.testng.annotations.Test;
@Test
public class StackOverflowIT extends TestNGCitrusTestRunner {
@CitrusTest
public void testStackOverflowIT() {
echo("this is a test");
}
}
Fixture:
package stackoverflow;
import com.consol.citrus.dsl.runner.TestRunner;
import com.consol.citrus.dsl.runner.TestRunnerBeforeTestSupport;
public class Fixture extends TestRunnerBeforeTestSupport {
public void beforeTest(TestRunner runner) {
runner.echo("beforeTest");
}
}
Configuration:
package stackoverflow;
import org.springframework.context.annotation.Bean;
public class Configuration {
@Bean
public Fixture beforeTest_0() {
return new Fixture();
}
@Bean
public Fixture beforeTest_1() {
return new Fixture();
}
@Bean
public Fixture beforeTest_2() {
return new Fixture();
}
...
The 'real' range is from 0 to 999. Leaving out everything between 3 and 996 because this would make this example unreadable.
...
@Bean
public Fixture beforeTest_997() {
return new Fixture();
}
@Bean
public Fixture beforeTest_998() {
return new Fixture();
}
@Bean
public Fixture beforeTest_999() {
return new Fixture();
}
}
Cause:
It seems as if this is caused by the fact that 'afterPropertiesSet' method of 'TestRunnerBeforeTestSupport' class creates a new DefaultTestRunner which itsself calls 'applicationContext.getBeansOfType(SequenceBeforeTest.class)' in its constructor. As a result all not-yet initialized Beans of type 'SequenceBeforeTest' get initialized, which also includes calling 'afterPropertiesSet'.
Because of this a very large call stack gets created that eventually gets too big - StackOverflowError.
Hi!
I'll have a look at this and will try to reconstruct it on my side. I'll also have a look at the root cause proposal.
Nevertheless, creating 1000 TestRunnerBeforeTestSupport
beans seams a little bit too much for a single test suite. I have a feeling that this could be optimized.
One option could be to review the test suite setup and separate different concerns into different suites with different configuration. Another option could be to review the implementation of the Fixture
classes.
BR, Sven
Hi!
I investigated the issue and agree, that the cascading initialization of the SequenceBeforeTest
beans is not ideal for your use case. To change this, we'd have to rethink the way these beans are initialized. A possible solution would be to initialize them in a sequential order.
Nevertheless, Citrus was not designed with the intent to handle 1000 TestRunnerBeforeTestSupport
beans at once. As I don't know any details about your project, I can't say whether this could be optimized or provide you any hint how you would optimize this.
Concerning the priority from a projects perspective: From my knowledge, this is the first time someone ran into this limitation after more that 10 years. I've also checked the 10 :+1: reactions to this issue. As I reviewed the accounts behind this reactions, I found out, that all accounts share the same community. Therefore, the amount of up-votes is not representative for the Citrus community in general but for this specific subset. That's why this is a low priority enhancement from my perspective.
BR, Sven