0

STS/Eclipse から実行すると機能する JUnit テストのスイートがありますが、Jacoco を使用して Bamboo から実行すると機能しません。Cobertura を使用して Jenkins からテストを実行していたとき、これは機能していました。私が仕事と言うとき、私はテストがエラーになっていることを意味します.それは特に私たちのSQLデータベース(Oracle)に触れるテストです. データベースに触れないテストにはエラーはありません。また、以前よりも優れた/高速なハードウェアを使用しているため、それが原因かもしれません. また、現在 Java 7 ではなく 8 を実行しています。しかし、前述したように、テストは STS/Eclipse から正常に実行されます。一度に多くのことを変更したので、何がこれを行っているのか少し途方に暮れています.

エラーは、具体的には「再帰 SQL レベル 1 ORA-01000 でエラーが発生しました。開いているカーソルの最大数を超えました」です。

Springsource Framework、ojdbc6、および ucp を使用しており、次のスタック トレースでエラーが発生します。

    org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; 分類されていない SQL の SQLException []; SQL 状態 [60000]; エラーコード [604]; ORA-00604: 再帰的 SQL レベル 1 でエラーが発生しました ORA-01000: 開いているカーソルの最大数を超えました。ネストされた例外は java.sql.SQLException です: ORA-00604: rcursive SLQ レベル 1 でエラーが発生しました ORA-01000: 開いているカーソルの最大数を超えました
    で
    org.springframework.jdbc.support.AbstractFallbackSLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
    で
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    で
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    で
    org.springframework.jdbc.core.JdbcTemplate.execute (JdbcTemplate.java:660)
    で
    mycompany.db.StatementManager.execute(StatementManager.java:183)
    で
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    で
    org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    で
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    で
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    で
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    で
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    で
    com.sun.proxy.$Proxy27.execute (不明なソース)
    で
    mycompany.db.SomeDbCode.clear(SomeDbCode.java:48)
    で
    ........関係のない AOP レイヤーが増える ....
    mycompany.db.TestSomeDb.setup(TestSomeDb.java:115) //これは、ユニット テストの各セットの前に実行され、@Before を使用してテーブルを元の状態に切り捨てます
    で
    ..... ランナーまでのレイヤー...
    で
    org.springframework.test.context.junit4.SpringJUnit4ClassRnner.run (SpringJUnit4ClassRunner.java:163)
    原因: java.sql.SQLException: ORA-00604: 再帰 SQL レベル 1 でエラーが発生しました
    ORA-01000: 開いているカーソルの最大数を超えました
    で
    oracle.jdbc.driver.T4CTTIOer.processError(T4CTTIOer.java:439)
    で
    oracle.jdbc.driver.T4CTTIOer.processError(T4CTTIOer.java:395)
    で
    oracle.jdbc.driver.T4C80all.processError(T4C80all.java:802)
    で
    oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
    で
    oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
    で
    oracle.jdbc.driver.T4C80all.do0ALL(T4C80all.java:521)
    で
    oracle.jdbc.driver.T4CPreparedStatement.do0all8(T4CPreparedStatement.java:205)
    で
    oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1008)
    で
    oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
    で
    oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449)
    で
    oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3530)
    で
    oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
    で
    oracle.ucp.jdbc.proxy.StatementProxyFactory.invoke(StatementProxyFactory.java:230)
    で
    oracle.ucp.jdbc.proxy.StatementProxyFactory.invoke(StatementProxyFactory.java:124)
    で
    com.sun.proxy.$Proxy113.executeUpdate(不明なソース)
    で
    mycompany.db.StatementManager$ExecuteFiller.doInPreparedStatment(StatementManager.java:44)
    で
    org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:644)

ちなみに、これはすべて呼び出しを試みたものです:

TRUNCATE TABLE sometablename

根本的な原因を突き止めたと思いますが、それを修正するための最良の方法はまだありません(アイデアは自由です)。

テストの各セットは、いくつかのカーソルを開きます。その一連のテストの実行が終了すると、Spring はカーソルのクリーンアップを開始します。しかしその後、次のクラスのテストが開始され、新しいカーソルが開かれ始めます。How to find Current open Cursors in Oracleというクエリを実行して、「開いているカーソル」の数が正弦波状に増加するのを見ていました 。どうやら私の古いハードウェアは非常に遅かったため、クリーンアップは成長よりも速く行われましたが、新しいものでは最終的に 300 の制限に達しました (そのため、チームの他の誰かがデフォルトの 50 が少なすぎることに気づきました。 300 がどのように正しいと判断されたかについてのドキュメントはありません)、そのエラーの後のすべてのテストはそのエラーで終了します。

私が軽減しようとしたこと: データベースに触れるすべてのテストに、10 秒間スリープする @AfterClass メソッドを持つ TouchesDatabase というスーパークラスを与えます。
これにより、実際には1つを除くすべてのテストが修正されましたが、ビルドに2倍の時間がかかりました.

明らかに、一部のテストでは他のカーソルよりも多くのカーソルが開かれているので、10 秒間実行する代わりに、開いているカーソルの数をクエリし、100 を超える場合はもう 1 秒間スリープします。残念ながら、私が使用しているカーソル クエリ (別のものを試す必要があるかもしれません) は、10 秒のフラット スリープよりも 100 カーソルを下回るのにさらに時間がかかるように見えるため、物事を過大評価しているか、奇妙なことをしているようです。私がその日に出発しなければならなかったとき、それは 3 番目または 4 番目の db テスト クラス (30 のうち) のように実行され、すでに 30 分間実行されていたので、朝に見てみますが、明らかに理想的ではありません。

カーソルに対するより適切なクエリが見つからない場合は、各テストの調査を開始して、よりスマートな方法があるかどうかを確認します。テストだけで、実稼働アプリケーションに問題はありませんでした。

4

0 に答える 0