spring-cloud-task
spring-cloud-task copied to clipboard
JdbcTaskExecutionDaoTests needs to clear(truncate) tables between each test
On some machines with faster processors this this test fails, because data from a previous run is still present in the datastore used by the test. This is being expressed with the following exception:
15:15:10.265 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@1ad4e testClass = Jdb
cTaskExecutionDaoTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2f0c2b93 testClass = JdbcTaskEx
ecutionDaoTests, locations = '{}', classes = '{class org.springframework.cloud.task.configuration.TestConfiguration, class org.springframework.boot.autoconfigure.jdbc.EmbeddedDataS
ourceConfiguration, class org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySo
urceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7f7af971, org.springfram
ework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@65b66b08, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@
0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFact
ory$Customizer@499ef98e], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]], attributes = map['org.springframework.test.cont
ext.support.DependencyInjectionTestExecutionListener.reinjectDependencies' -> true]], class annotated with @DirtiesContext [false] with mode [null].
Tests run: 21, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.909 sec <<< FAILURE!
testFindAllDefaultSort(org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDaoTests) Time elapsed: 0.019 sec <<< FAILURE!
java.lang.AssertionError: expected:<3> but was:<4>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)
at org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDaoTests.getPageIterator(JdbcTaskExecutionDaoTests.java:208)
at org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDaoTests.testFindAllDefaultSort(JdbcTaskExecutionDaoTests.java:158)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
If we're using an in memory database, why doesn't @DirtiesContext work?
@jvalkeal Also noticed when running this TestClass alone, there are no failures. Only when run with other classes. I noticed that TaskConfiguration is the only commonality between this test and others.
I'm trying to debug this. I see from where the the wrong value is coming from but the trouble is that individual test runs on, is just that when I run full set. This means that I can't easily debug this on sts. Hopefully this is just a regression in tests as otherwise it has to come down from a spring data, or some other crap.
Good thing is that I can't get this to fail just by running ./mvnw clean package -pl spring-cloud-task-core -Dtest=JdbcTaskExecutionDaoTests, just ./mvnw clean package -pl spring-cloud-task-core fails.
Right I was able to isolate what's causing this. Locally with maven build I'm able to see same failure if I run SimpleSingleTaskAutoConfigurationWithDataSourceTests together with JdbcTaskExecutionDaoTests.
./mvnw clean package -pl spring-cloud-task-core -Dtest="JdbcTaskExecutionDaoTests,SimpleSingleTaskAutoConfigurationWithDataSourceTests"
Running just JdbcTaskExecutionDaoTests doesn't fail.
./mvnw clean package -pl spring-cloud-task-core -Dtest="JdbcTaskExecutionDaoTests"
I added some logging to org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDaoTests.getPageIterator(int, int, Sort) to see what is a 4th task execution and it showed:
XXX task TaskExecution{executionId=4, parentExecutionId=null, exitCode=null, taskName='FOO1', startTime=2018-10-30 10:17:09.611, endTime=null, exitMessage='null', externalExecutionId='externalC', errorMessage='null', arguments=[]}
XXX task TaskExecution{executionId=3, parentExecutionId=null, exitCode=null, taskName='FOO2', startTime=2018-10-30 10:17:09.61, endTime=null, exitMessage='null', externalExecutionId='externalB', errorMessage='null', arguments=[]}
XXX task TaskExecution{executionId=2, parentExecutionId=null, exitCode=null, taskName='FOO3', startTime=2018-10-30 10:17:09.608, endTime=null, exitMessage='null', externalExecutionId='externalA', errorMessage='null', arguments=[]}
XXX task TaskExecution{executionId=1, parentExecutionId=null, exitCode=null, taskName='org.springframework.context.support.GenericApplicationContext@2cf0deac', startTime=2018-10-30 10:17:08.729, endTime=null, exitMessage='null', externalExecutionId='null', errorMessage='null', arguments=[]}
Usual suspect is a task with name org.springframework.context.support.GenericApplicationContext@2cf0deac.
Then looking build logs for that:
10:17:08.731 [main] DEBUG org.springframework.cloud.task.repository.support.SimpleTaskRepository - Creating: TaskExecution{executionId=0, parentExecutionId=null, exitCode=null, taskName='org.springframework.context.support.GenericApplicationContext@2cf0deac', startTime=Tue Oct 30 10:17:08 GMT 2018, endTime=null, exitMessage='null', externalExecutionId='null', errorMessage='null', arguments=[]}
10:17:08.755 [lock-leadership-1] INFO org.springframework.integration.leader.DefaultCandidate - DefaultCandidate{role=org.springframework.context.support.GenericApplicationContext@2cf0deac, id=1} has been granted leadership; context: LockContext{role=org.springframework.context.support.GenericApplicationContext@2cf0deac, id=1, isLeader=true}
As SimpleSingleTaskAutoConfigurationWithDataSourceTests seem to enable some locking functionality which then explains why not running SimpleSingleTaskAutoConfigurationWithDataSourceTests makes tests to pass.
Btw, you should mark BaseTaskExecutionDaoTestCases as abstract as it cannot be run as is. Had to make it abstract able to run all tests in STS which naturally didn't fail. So this is some kind of race condition when I run tests from command line.
SimpleSingleTaskAutoConfigurationWithDataSourceTests verifies that the Configuration for the singleInstanceTaskListener is working properly. (The singleInstanceTaskListener prevents a task from starting if another task with the same name is running. This is implemented by SI's LogRegistry. ) I'm curious if a @DirtiesContext would resolve the issue, since it seems like the EmbeddedDataSourceConfiguration is bleeding over.
Is this issue still valid? It seems likely to me that the root cause of this issue is (or was) non-unique names for the embedded databases. The tests import Spring Boot's EmbeddedDataSourceConfiguration, and with Spring Boot 2.3 they flipped the default for spring.datasource.generate-unique-name from false to true (https://github.com/spring-projects/spring-boot/issues/16747).
Issue resolved in testing.