spring-cloud-task icon indicating copy to clipboard operation
spring-cloud-task copied to clipboard

JdbcTaskExecutionDaoTests needs to clear(truncate) tables between each test

Open cppwfs opened this issue 7 years ago • 6 comments
trafficstars

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)

cppwfs avatar Oct 26 '18 14:10 cppwfs

If we're using an in memory database, why doesn't @DirtiesContext work?

mminella avatar Oct 26 '18 15:10 mminella

@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.

cppwfs avatar Oct 26 '18 15:10 cppwfs

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.

jvalkeal avatar Oct 26 '18 15:10 jvalkeal

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.

jvalkeal avatar Oct 30 '18 11:10 jvalkeal

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.

cppwfs avatar Oct 30 '18 13:10 cppwfs

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).

hpoettker avatar Jul 04 '21 19:07 hpoettker

Issue resolved in testing.

cppwfs avatar Jan 04 '24 14:01 cppwfs