两次运行sbt测试套件会导致找不到jdbc Driver错误

时间:2018-06-13 20:59:39

标签: java scala sqlite jdbc sbt

我第一次运行依赖于测试套件传递的jdbc sql lite驱动程序的测试套件。如果我再次尝试运行测试套件,则测试失败,因为没有为数据库找到合适的驱动程序。这是控制台会话:

> > test-only *EclairTest*
15:56:27.386 TKD [EclairTest-akka.actor.default-dispatcher-14] ERROR a.h.i.engine.client.PoolMasterActor - connection pool for PoolGateway(hcps = HostConnectionPoolSetup(localhost,18332,ConnectionPoolSetup(ConnectionPoolSettings(4,0,5,32,1,30 seconds,ClientConnectionSettings(Some(User-Agent: akka-http/10.1.1),10 seconds,1 minute,512,None,WebSocketSettings(<function0>,ping,Duration.Inf,<function0>),List(),ParserSettings(2048,16,64,64,8192,64,8388608,256,1048576,Strict,RFC6265,true,Full,Error,Map(If-Range -> 0, If-Modified-Since -> 0, If-Unmodified-Since -> 0, default -> 12, Content-MD5 -> 0, Date -> 0, If-Match -> 0, If-None-Match -> 0, User-Agent -> 32),false,true,<function1>,<function1>,<function2>),None,TCPTransport),New,1 second),akka.http.scaladsl.HttpConnectionContext$@5fb80e0c,akka.event.MarkerLoggingAdapter@7da2ada2))) has shut down unexpectedly
[ERROR] [06/13/2018 15:56:27.404] [EclairTest-akka.actor.default-dispatcher-4] [akka.actor.ActorSystemImpl(EclairTest)] exception while executing timer task
[info] EclairTest:
[info] EclairTest
[info] - should connect to a running eclair instance
[info] ScalaTest
[info] Run completed in 3 seconds, 2 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 5 s, completed Jun 13, 2018 3:56:27 PM

> test-only *EclairTest*
[info] EclairTest:
[info] com.suredbits.api.ln.EclairTest *** ABORTED ***
[info]   java.sql.SQLException: No suitable driver found for jdbc:sqlite:/home/chris/.eclair/regtest/eclair.sqlite
[info]   at java.sql.DriverManager.getConnection(DriverManager.java:689)
[info]   at java.sql.DriverManager.getConnection(DriverManager.java:270)
[info]   at fr.acinq.eclair.NodeParams$.makeNodeParams(NodeParams.scala:136)
[info]   at fr.acinq.eclair.Setup.<init>(Setup.scala:71)
[info]   at com.suredbits.api.ln.EclairTest.<init>(EclairTest.scala:20)
[info]   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[info]   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[info]   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[info]   at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[info]   at java.lang.Class.newInstance(Class.java:442)
[info]   ...
[info] ScalaTest
[info] Run completed in 589 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 0, aborted 1
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0
[info] *** 1 SUITE ABORTED ***
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
[error] Error during tests:
[error]         com.suredbits.api.ln.EclairTest
[error] (api/test:testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 1 s, completed Jun 13, 2018 3:56:31 PM

这对我来说似乎非常古怪。您认为可能导致此问题的原因是什么?如果我关闭sbt并重新启动,我会看到相同的行为。

测试如下:

class EclairTest extends TestKit(ActorSystem("EclairTest")) with FlatSpecLike with BeforeAndAfterAll {

  implicit val dispatcher = system.dispatcher

  behavior of "EclairTest"

  //assumes eclair is running
  val datadir = new File("/home/chris/.eclair")
  val setup = new Setup(
    datadir = datadir,
    actorSystem = system
  )
  val params = setup.nodeParams
  val kitF: Future[Kit] = setup.bootstrap

  it should "connect to a running eclair instance" in {
    val balance: Future[fr.acinq.bitcoin.Satoshi] = kitF.flatMap(_.wallet.getBalance)
    balance.map(b => assert(b.toLong >= 0))
  }

  override def afterAll: Unit = {
    TestKit.shutdownActorSystem(system)
  }
}

并且依赖项被捆绑到另一个依赖项中,但我还使用

显式地包含了sqlite
val hikari = ("com.typesafe.slick" %% "slick-hikaricp" % V.slickV).exclude("org.slf4j","slf4j-api")
val slick = "com.typesafe.slick" %% "slick" % V.slickV withSources() withJavadoc()
val dbcp = "commons-dbcp" % "commons-dbcp" % "1.4"
val postgresql = "org.postgresql" % "postgresql" % "9.4.1210"
val sqlite = "org.xerial" % "sqlite-jdbc" % V.sqliteV

lazy val api = project
      .in(file("."))
      .enablePlugins()
      .settings(
        mainClass := Some("com.suredbits.api.Main"), 
        fork in test := true,
        resolvers += Resolver.sonatypeRepo("releases"),  
        resolvers += Resolver.mavenLocal,
        libraryDependencies ++= Deps.api
      )

这里定义了开源项目和开源项目的pom.xml文件:https://github.com/ACINQ/eclair/blob/master/eclair-core/pom.xml#L175-L179

1 个答案:

答案 0 :(得分:2)

Eclair 库中声明数据库的Setup.bootstrap方法似乎依赖于 JVM 退出后清理它,并且似乎没有提供允许您在测试结束时手动执行此操作的机制。 (如果有这样的机制,使用它也可以解决这个问题。)

默认情况下,测试在 SBT 构建实例运行的同一 JVM 中运行,因此当您执行第一次测试时声明的资源仍然存在第二次运行测试。除此之外,在第二次和后续运行中,他们无法声明数据库资源,因为它们已被声明。

添加:

fork in Test := true

到你的 SBT 版本,你强迫每个测试实例在它自己的 JVM 实例中运行,所以每次都可以重新开始。