db代码中的自动JUnit测试错误,在手动运行时不会

时间:2015-09-09 00:10:14

标签: oracle junit4 spring-jdbc bamboo springjunit4classrunner

我有一套JUnit测试,当用完STS / Eclipse时可以工作,但是使用Jacoco从Bamboo运行时不起作用。当我们使用Cobertura运行Jenkins的测试时,它曾经工作过。当我说工作时,我的意思是测试错误,特别是触摸我们的SQL数据库(Oracle)的测试。不接触数据库的测试没有错误。我们现在也使用比以前更好/更快的硬件,因此可能就是这样。我们现在也运行Java 8而不是7.但就像我说的那样,测试从STS / Eclipse运行良好。我们一次改变了很多东西,所以我对这可能做到的事情感到有点失落。

错误特别是“在递归SQL级别1 ORA-01000超出最大打开游标时发生错误”。

我们使用Springsource Framework,ojdbc6和ucp,并且错误发生在以下堆栈跟踪中:

    org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL []; SQL state [60000]; error code [604]; ORA-00604: error occurred at recursive SQL level 1 ORA-01000: maximum open cursors exceeded; nested exception is java.sql.SQLException: ORA-00604: error occurred at rcursive SLQ level 1 ORA-01000: maximum open cursors exceeded
    at
    org.springframework.jdbc.support.AbstractFallbackSLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
    at
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at
    org.springframework.jdbc.core.JdbcTemplate.execute (JdbcTemplate.java:660)
    at
    mycompany.db.StatementManager.execute(StatementManager.java:183)
    at
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at
    org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at
    com.sun.proxy.$Proxy27.execute(Unknown Source)
    at
    mycompany.db.SomeDbCode.clear(SomeDbCode.java:48)
    at
    ........more AOP layers that are irrelevant ....
    mycompany.db.TestSomeDb.setup(TestSomeDb.java:115) //this runs before each set of unit tests to truncate the tables to pristine state with a @Before
    at
    ..... layers up to the runner ...
    at 
    org.springframework.test.context.junit4.SpringJUnit4ClassRnner.run (SpringJUnit4ClassRunner.java:163)
    Caused by: java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
    ORA-01000: maximum open cursors exceeded
    at 
    oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
    at
    oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
    at
    oracle.jdbc.driver.T4C80all.processError(T4C80all.java:802)
    at
    oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
    at 
    oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
    at
    oracle.jdbc.driver.T4C80all.do0ALL(T4C80all.java:521)
    at
    oracle.jdbc.driver.T4CPreparedStatement.do0all8(T4CPreparedStatement.java:205)
    at
    oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1008)
    at
    oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
    at
    oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449)
    at
    oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3530)
    at
    oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
    at
    oracle.ucp.jdbc.proxy.StatementProxyFactory.invoke(StatementProxyFactory.java:230)
    at
    oracle.ucp.jdbc.proxy.StatementProxyFactory.invoke(StatementProxyFactory.java:124)
    at
    com.sun.proxy.$Proxy113.executeUpdate(Unknown Source)
    at 
    mycompany.db.StatementManager$ExecuteFiller.doInPreparedStatment(StatementManager.java:44)
    at
    org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:644)

这就是所有人试图打电话的方式:

TRUNCATE TABLE sometablename

我认为我已经找到了根本原因,但还不是解决问题的最佳方法(对想法持开放态度)。

每组测试都会打开一些游标。随着这组测试的完成,Spring开始清理游标。但随后下一类测试启动并开始打开新游标。我正在观看“开放游标”号码通过运行查询来增加正弦曲线 How to find Current open Cursors in Oracle。 显然我的旧硬件速度太快,清理速度比增长速度快,但是新的东西最终会达到300的限制(所以在某些时候团队中的其他人意识到默认的50太少了,不过当然那里没有关于300如何被确定为正确的文档,以及该错误之后的任何测试都出现了该错误。

我试图减轻的事情: 使用@AfterClass方法为数据库提供一个名为TouchesDatabase的超类的所有测试,该方法可以休眠10秒。
这实际上修复了除我的一个测试之外的所有测试,但它也使构建需要两倍的构建时间。

所以我想,好吧,显然有些测试会比其他测试打开更多的游标,所以我会查询有多少游标是打开的,如果它超过100,我会再睡一秒钟。不幸的是,似乎我正在使用的光标查询(可能必须尝试不同的一个)是过度计算事物或做一些奇怪的事情,因为它似乎需要更长时间才能降低100个光标以下而不仅仅是平坦的10秒睡眠。当我不得不离开这一天它就像第3或第4分析测试课程(30岁以上)并且已经运行了30分钟,所以我会在早上看一看,但显然不理想。 / p>

如果我找不到更好的游标查询,那么我将开始检查每个测试,看看是否有更聪明的方法来做那里的事情。我们对生产应用程序没有任何问题,顺便说一句,只是测试。

0 个答案:

没有答案