mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-22 22:36:34 +01:00
Start refactoring testkit to allow for specifying a different binary … (#2325)
* Start refactoring testkit to allow for specifying a different binary directory than the sbt default * Fix BitcoindRpcTestUtil * Add BitcoindRpcTestClient
This commit is contained in:
parent
097398499a
commit
7df02c4198
16 changed files with 405 additions and 159 deletions
|
@ -3,7 +3,6 @@ package org.bitcoins.rpc
|
||||||
import java.io.{File, PrintWriter}
|
import java.io.{File, PrintWriter}
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.file.{Files, Path}
|
import java.nio.file.{Files, Path}
|
||||||
|
|
||||||
import akka.stream.StreamTcpException
|
import akka.stream.StreamTcpException
|
||||||
import org.bitcoins.core.config.RegTest
|
import org.bitcoins.core.config.RegTest
|
||||||
import org.bitcoins.core.currency.Bitcoins
|
import org.bitcoins.core.currency.Bitcoins
|
||||||
|
@ -16,7 +15,7 @@ import org.bitcoins.rpc.config.{
|
||||||
import org.bitcoins.rpc.util.RpcUtil
|
import org.bitcoins.rpc.util.RpcUtil
|
||||||
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
||||||
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil.newestBitcoindBinary
|
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil.newestBitcoindBinary
|
||||||
import org.bitcoins.testkit.util.BitcoindRpcTest
|
import org.bitcoins.testkit.util.{BitcoindRpcTest, FileUtil}
|
||||||
import org.scalatest.compatible.Assertion
|
import org.scalatest.compatible.Assertion
|
||||||
|
|
||||||
import scala.concurrent.Future
|
import scala.concurrent.Future
|
||||||
|
@ -66,7 +65,7 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
||||||
|rpcport=${RpcUtil.randomPort}
|
|rpcport=${RpcUtil.randomPort}
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
|
|
||||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
val conf = BitcoindConfig(confStr, FileUtil.tmpDir())
|
||||||
val instance = BitcoindInstance.fromConfig(conf, newestBitcoindBinary)
|
val instance = BitcoindInstance.fromConfig(conf, newestBitcoindBinary)
|
||||||
assert(
|
assert(
|
||||||
instance.authCredentials
|
instance.authCredentials
|
||||||
|
@ -86,7 +85,7 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
||||||
|rpcport=${RpcUtil.randomPort}
|
|rpcport=${RpcUtil.randomPort}
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
|
|
||||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
val conf = BitcoindConfig(confStr, FileUtil.tmpDir())
|
||||||
val instance = BitcoindInstance.fromConfig(conf, newestBitcoindBinary)
|
val instance = BitcoindInstance.fromConfig(conf, newestBitcoindBinary)
|
||||||
assert(
|
assert(
|
||||||
instance.authCredentials
|
instance.authCredentials
|
||||||
|
@ -113,7 +112,7 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
||||||
|rpcport=${RpcUtil.randomPort}
|
|rpcport=${RpcUtil.randomPort}
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
|
|
||||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
val conf = BitcoindConfig(confStr, FileUtil.tmpDir())
|
||||||
val authCredentials =
|
val authCredentials =
|
||||||
BitcoindAuthCredentials.PasswordBased(username = "bitcoin-s",
|
BitcoindAuthCredentials.PasswordBased(username = "bitcoin-s",
|
||||||
password = "strong_password")
|
password = "strong_password")
|
||||||
|
|
|
@ -24,8 +24,8 @@ class BlockchainRpcTest extends BitcoindRpcTest {
|
||||||
case (_, _) =>
|
case (_, _) =>
|
||||||
val pruneClient =
|
val pruneClient =
|
||||||
BitcoindRpcClient.withActorSystem(
|
BitcoindRpcClient.withActorSystem(
|
||||||
BitcoindRpcTestUtil.instance(pruneMode = true,
|
BitcoindRpcTestUtil
|
||||||
versionOpt = Some(BitcoindVersion.V17)))
|
.instance(pruneMode = true, versionOpt = Some(BitcoindVersion.V17)))
|
||||||
|
|
||||||
clientAccum += pruneClient
|
clientAccum += pruneClient
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.bitcoins.rpc.config
|
package org.bitcoins.rpc.config
|
||||||
|
|
||||||
import org.bitcoins.testkit.util.BitcoinSUnitTest
|
import org.bitcoins.testkit.util.{BitcoinSUnitTest, FileUtil}
|
||||||
import org.bitcoins.rpc.config.BitcoindAuthCredentials.CookieBased
|
import org.bitcoins.rpc.config.BitcoindAuthCredentials.CookieBased
|
||||||
import org.bitcoins.rpc.config.BitcoindAuthCredentials.PasswordBased
|
import org.bitcoins.rpc.config.BitcoindAuthCredentials.PasswordBased
|
||||||
import org.bitcoins.core.config.RegTest
|
import org.bitcoins.core.config.RegTest
|
||||||
|
@ -11,7 +11,7 @@ class BitcoindAuthCredentialsTest extends BitcoinSUnitTest {
|
||||||
val confStr = """
|
val confStr = """
|
||||||
|regtest=1
|
|regtest=1
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
val conf = BitcoindConfig(confStr, FileUtil.tmpDir())
|
||||||
val auth = BitcoindAuthCredentials.fromConfig(conf)
|
val auth = BitcoindAuthCredentials.fromConfig(conf)
|
||||||
val cookie = auth match {
|
val cookie = auth match {
|
||||||
case cookie: CookieBased => cookie
|
case cookie: CookieBased => cookie
|
||||||
|
@ -29,7 +29,7 @@ class BitcoindAuthCredentialsTest extends BitcoinSUnitTest {
|
||||||
|rpcuser=foo
|
|rpcuser=foo
|
||||||
|rpcpassword=bar
|
|rpcpassword=bar
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
val conf = BitcoindConfig(confStr, FileUtil.tmpDir())
|
||||||
val auth = BitcoindAuthCredentials.fromConfig(conf)
|
val auth = BitcoindAuthCredentials.fromConfig(conf)
|
||||||
|
|
||||||
val pass = auth match {
|
val pass = auth match {
|
||||||
|
@ -49,7 +49,7 @@ class BitcoindAuthCredentialsTest extends BitcoinSUnitTest {
|
||||||
|rpcpassword=bar
|
|rpcpassword=bar
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
|
|
||||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
val conf = BitcoindConfig(confStr, FileUtil.tmpDir())
|
||||||
BitcoindAuthCredentials.fromConfig(conf) match {
|
BitcoindAuthCredentials.fromConfig(conf) match {
|
||||||
case _: CookieBased => fail
|
case _: CookieBased => fail
|
||||||
case PasswordBased(username, password) =>
|
case PasswordBased(username, password) =>
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
package org.bitcoins.rpc.config
|
package org.bitcoins.rpc.config
|
||||||
|
|
||||||
import org.bitcoins.testkit.util.BitcoinSUnitTest
|
import org.bitcoins.core.config.{MainNet, RegTest, TestNet3}
|
||||||
import org.bitcoins.core.config.RegTest
|
|
||||||
import org.bitcoins.core.config.TestNet3
|
|
||||||
import org.bitcoins.core.config.MainNet
|
|
||||||
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
||||||
import org.bitcoins.testkit.util.BitcoindRpcTest
|
import org.bitcoins.testkit.util.{BitcoinSUnitTest, FileUtil}
|
||||||
|
|
||||||
class BitcoindConfigTest extends BitcoinSUnitTest {
|
class BitcoindConfigTest extends BitcoinSUnitTest {
|
||||||
|
|
||||||
def tmpDir = BitcoindRpcTestUtil.tmpDir()
|
def tmpDir = FileUtil.tmpDir()
|
||||||
it must "have to/fromString symmetry" in {
|
it must "have to/fromString symmetry" in {
|
||||||
val conf = BitcoindRpcTestUtil.standardConfig
|
val conf = BitcoindRpcTestUtil.standardConfig
|
||||||
val confStr = conf.toWriteableString
|
val confStr = conf.toWriteableString
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.bitcoins.eclair.rpc
|
||||||
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
import org.bitcoins.commons.jsonmodels.eclair._
|
import org.bitcoins.commons.jsonmodels.eclair._
|
||||||
import org.bitcoins.core.config.RegTest
|
import org.bitcoins.core.config.RegTest
|
||||||
import org.bitcoins.core.currency.{CurrencyUnits, Satoshis}
|
import org.bitcoins.core.currency.{CurrencyUnits, Satoshis}
|
||||||
|
@ -29,7 +28,7 @@ import org.bitcoins.rpc.util.AsyncUtil
|
||||||
import org.bitcoins.testkit.async.TestAsyncUtil
|
import org.bitcoins.testkit.async.TestAsyncUtil
|
||||||
import org.bitcoins.testkit.eclair.rpc.{EclairNodes4, EclairRpcTestUtil}
|
import org.bitcoins.testkit.eclair.rpc.{EclairNodes4, EclairRpcTestUtil}
|
||||||
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
||||||
import org.bitcoins.testkit.util.BitcoinSAsyncTest
|
import org.bitcoins.testkit.util.{BitcoinSAsyncTest, EclairRpcTestClient}
|
||||||
import org.scalatest.Assertion
|
import org.scalatest.Assertion
|
||||||
|
|
||||||
import scala.concurrent._
|
import scala.concurrent._
|
||||||
|
@ -37,10 +36,10 @@ import scala.concurrent.duration.{DurationInt, _}
|
||||||
|
|
||||||
class EclairRpcClientTest extends BitcoinSAsyncTest {
|
class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||||
|
|
||||||
private val dirExists = Files.exists(EclairRpcTestUtil.binaryDirectory)
|
private val dirExists = Files.exists(EclairRpcTestClient.sbtBinaryDirectory)
|
||||||
|
|
||||||
private val hasContents = dirExists && Files
|
private val hasContents = dirExists && Files
|
||||||
.list(EclairRpcTestUtil.binaryDirectory)
|
.list(EclairRpcTestClient.sbtBinaryDirectory)
|
||||||
.toArray()
|
.toArray()
|
||||||
.nonEmpty
|
.nonEmpty
|
||||||
|
|
||||||
|
@ -50,7 +49,7 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||||
printerr(s"Run 'sbt downloadEclair' to fetch needed binaries")
|
printerr(s"Run 'sbt downloadEclair' to fetch needed binaries")
|
||||||
sys.error {
|
sys.error {
|
||||||
val msg =
|
val msg =
|
||||||
s""""Eclair binary directory (${BitcoindRpcTestUtil.binaryDirectory}) is empty.
|
s""""Eclair binary directory (${EclairRpcTestClient.sbtBinaryDirectory}) is empty.
|
||||||
|Run 'sbt downloadEclair' to fetch needed binaries""".stripMargin
|
|Run 'sbt downloadEclair' to fetch needed binaries""".stripMargin
|
||||||
msg
|
msg
|
||||||
}
|
}
|
||||||
|
@ -407,14 +406,12 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "be able to start and shutdown a node" in {
|
it should "be able to start and shutdown a node" in {
|
||||||
|
val eclairTestClient =
|
||||||
|
EclairRpcTestClient.fromSbtDownload(eclairVersionOpt = None,
|
||||||
|
eclairCommitOpt = None,
|
||||||
|
bitcoindRpcClientOpt = None)
|
||||||
for {
|
for {
|
||||||
bitcoind <- EclairRpcTestUtil.startedBitcoindRpcClient()
|
eclair <- eclairTestClient.start()
|
||||||
eclair <- {
|
|
||||||
val server = EclairRpcTestUtil.eclairInstance(bitcoind)
|
|
||||||
val eclair =
|
|
||||||
new EclairRpcClient(server, EclairRpcTestUtil.binary(None, None))
|
|
||||||
eclair.start().map(_ => eclair)
|
|
||||||
}
|
|
||||||
_ <- TestAsyncUtil.retryUntilSatisfiedF(conditionF =
|
_ <- TestAsyncUtil.retryUntilSatisfiedF(conditionF =
|
||||||
() => eclair.isStarted(),
|
() => eclair.isStarted(),
|
||||||
interval = 1.second,
|
interval = 1.second,
|
||||||
|
@ -542,7 +539,9 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||||
|
|
||||||
val badClientF =
|
val badClientF =
|
||||||
badInstanceF.map(
|
badInstanceF.map(
|
||||||
new EclairRpcClient(_, EclairRpcTestUtil.binary(None, None)))
|
new EclairRpcClient(_,
|
||||||
|
Some(
|
||||||
|
EclairRpcTestClient.sbtBinaryDirectory.toFile)))
|
||||||
|
|
||||||
badClientF.flatMap { badClient =>
|
badClientF.flatMap { badClient =>
|
||||||
recoverToSucceededIf[RuntimeException](badClient.getInfo)
|
recoverToSucceededIf[RuntimeException](badClient.getInfo)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.bitcoins.testkit.chain
|
package org.bitcoins.testkit.chain
|
||||||
|
|
||||||
import java.net.InetSocketAddress
|
import java.net.InetSocketAddress
|
||||||
|
|
||||||
import akka.actor.ActorSystem
|
import akka.actor.ActorSystem
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import org.bitcoins.chain.ChainVerificationLogger
|
import org.bitcoins.chain.ChainVerificationLogger
|
||||||
|
@ -24,6 +23,7 @@ import org.bitcoins.testkit.chain.fixture._
|
||||||
import org.bitcoins.testkit.fixtures.BitcoinSFixture
|
import org.bitcoins.testkit.fixtures.BitcoinSFixture
|
||||||
import org.bitcoins.testkit.node.CachedChainAppConfig
|
import org.bitcoins.testkit.node.CachedChainAppConfig
|
||||||
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
||||||
|
|
||||||
import org.bitcoins.testkit.util.ScalaTestUtil
|
import org.bitcoins.testkit.util.ScalaTestUtil
|
||||||
import org.bitcoins.testkit.{chain, BitcoinSTestAppConfig}
|
import org.bitcoins.testkit.{chain, BitcoinSTestAppConfig}
|
||||||
import org.bitcoins.zmq.ZMQSubscriber
|
import org.bitcoins.zmq.ZMQSubscriber
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package org.bitcoins.testkit.eclair.rpc
|
package org.bitcoins.testkit.eclair.rpc
|
||||||
|
|
||||||
import java.io.{File, PrintWriter}
|
|
||||||
import java.net.URI
|
|
||||||
import java.nio.file.Files
|
|
||||||
|
|
||||||
import akka.actor.ActorSystem
|
import akka.actor.ActorSystem
|
||||||
import com.typesafe.config.{Config, ConfigFactory}
|
import com.typesafe.config.{Config, ConfigFactory}
|
||||||
import org.bitcoins.commons.jsonmodels.eclair.{
|
import org.bitcoins.commons.jsonmodels.eclair.{
|
||||||
|
@ -13,7 +9,6 @@ import org.bitcoins.commons.jsonmodels.eclair.{
|
||||||
PaymentId
|
PaymentId
|
||||||
}
|
}
|
||||||
import org.bitcoins.core.compat.JavaConverters._
|
import org.bitcoins.core.compat.JavaConverters._
|
||||||
import org.bitcoins.core.config.RegTest
|
|
||||||
import org.bitcoins.core.currency.{CurrencyUnit, Satoshis}
|
import org.bitcoins.core.currency.{CurrencyUnit, Satoshis}
|
||||||
import org.bitcoins.core.protocol.ln.channel.{
|
import org.bitcoins.core.protocol.ln.channel.{
|
||||||
ChannelId,
|
ChannelId,
|
||||||
|
@ -32,8 +27,11 @@ import org.bitcoins.rpc.config.{BitcoindAuthCredentials, BitcoindInstance}
|
||||||
import org.bitcoins.rpc.util.RpcUtil
|
import org.bitcoins.rpc.util.RpcUtil
|
||||||
import org.bitcoins.testkit.async.TestAsyncUtil
|
import org.bitcoins.testkit.async.TestAsyncUtil
|
||||||
import org.bitcoins.testkit.rpc.{BitcoindRpcTestUtil, TestRpcUtil}
|
import org.bitcoins.testkit.rpc.{BitcoindRpcTestUtil, TestRpcUtil}
|
||||||
import org.bitcoins.testkit.util.TestkitBinaries
|
import org.bitcoins.testkit.util.{EclairRpcTestClient, FileUtil}
|
||||||
|
|
||||||
|
import java.io.{File, PrintWriter}
|
||||||
|
import java.net.URI
|
||||||
|
import java.nio.file.Path
|
||||||
import scala.concurrent.duration.{DurationInt, FiniteDuration}
|
import scala.concurrent.duration.{DurationInt, FiniteDuration}
|
||||||
import scala.concurrent.{ExecutionContext, Future}
|
import scala.concurrent.{ExecutionContext, Future}
|
||||||
import scala.reflect.ClassTag
|
import scala.reflect.ClassTag
|
||||||
|
@ -51,42 +49,11 @@ import scala.util.{Failure, Success}
|
||||||
*/
|
*/
|
||||||
trait EclairRpcTestUtil extends BitcoinSLogger {
|
trait EclairRpcTestUtil extends BitcoinSLogger {
|
||||||
|
|
||||||
/** Directory where sbt downloads Eclair binaries */
|
|
||||||
private[bitcoins] val binaryDirectory =
|
|
||||||
TestkitBinaries.baseBinaryDirectory.resolve("eclair")
|
|
||||||
|
|
||||||
/** Path to Jar downloaded by Eclair, if it exists */
|
|
||||||
private[bitcoins] def binary(
|
|
||||||
eclairVersionOpt: Option[String],
|
|
||||||
eclairCommitOpt: Option[String]): Option[File] = {
|
|
||||||
val path = binaryDirectory
|
|
||||||
.resolve(eclairVersionOpt.getOrElse(EclairRpcClient.version))
|
|
||||||
.resolve(
|
|
||||||
s"eclair-node-${EclairRpcClient.version}-${eclairCommitOpt.getOrElse(EclairRpcClient.commit)}")
|
|
||||||
.resolve("bin")
|
|
||||||
.resolve(
|
|
||||||
if (sys.props("os.name").toLowerCase.contains("windows"))
|
|
||||||
"eclair-node.bat"
|
|
||||||
else
|
|
||||||
"eclair-node.sh")
|
|
||||||
|
|
||||||
if (Files.exists(path)) {
|
|
||||||
Some(path.toFile)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def randomDirName: String =
|
|
||||||
0.until(5).map(_ => scala.util.Random.alphanumeric.head).mkString
|
|
||||||
|
|
||||||
def randomEclairDatadir(): File =
|
def randomEclairDatadir(): File =
|
||||||
new File(s"/tmp/eclair-test/${randomDirName}/.eclair/")
|
new File(s"/tmp/eclair-test/${FileUtil.randomDirName}/.eclair/")
|
||||||
|
|
||||||
def cannonicalDatadir = new File(s"${System.getenv("HOME")}/.reg_eclair/")
|
def cannonicalDatadir = new File(s"${System.getenv("HOME")}/.reg_eclair/")
|
||||||
|
|
||||||
lazy val network = RegTest
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a best effort to get a 0.16 bitcoind instance
|
* Makes a best effort to get a 0.16 bitcoind instance
|
||||||
*/
|
*/
|
||||||
|
@ -204,39 +171,25 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
||||||
eclairVersionOpt: Option[String] = None,
|
eclairVersionOpt: Option[String] = None,
|
||||||
eclairCommitOpt: Option[String] = None)(implicit
|
eclairCommitOpt: Option[String] = None)(implicit
|
||||||
system: ActorSystem): Future[EclairRpcClient] = {
|
system: ActorSystem): Future[EclairRpcClient] = {
|
||||||
import system.dispatcher
|
val eclairRpcTestClient = EclairRpcTestClient.fromSbtDownload(
|
||||||
val bitcoindRpcF: Future[BitcoindRpcClient] = {
|
eclairVersionOpt = eclairVersionOpt,
|
||||||
if (bitcoindRpcOpt.isDefined) {
|
eclairCommitOpt = eclairCommitOpt,
|
||||||
Future.successful(bitcoindRpcOpt.get)
|
bitcoindRpcClientOpt = bitcoindRpcOpt)
|
||||||
} else {
|
|
||||||
EclairRpcTestUtil.startedBitcoindRpcClient()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val randInstanceF = bitcoindRpcF.map(randomEclairInstance(_))
|
eclairRpcTestClient.start()
|
||||||
val eclairRpcF = randInstanceF.map(i =>
|
|
||||||
new EclairRpcClient(i, binary(eclairVersionOpt, eclairCommitOpt)))
|
|
||||||
|
|
||||||
val startedF = eclairRpcF.flatMap(_.start())
|
|
||||||
|
|
||||||
startedF.flatMap(_ => eclairRpcF)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def cannonicalEclairClient(
|
def cannonicalEclairClient(
|
||||||
eclairVersionOpt: Option[String] = None,
|
eclairVersionOpt: Option[String] = None,
|
||||||
eclairCommitOpt: Option[String] = None)(implicit
|
eclairCommitOpt: Option[String] = None,
|
||||||
|
binaryDirectory: Path = EclairRpcTestClient.sbtBinaryDirectory)(implicit
|
||||||
system: ActorSystem): EclairRpcClient = {
|
system: ActorSystem): EclairRpcClient = {
|
||||||
val inst = cannonicalEclairInstance()
|
val inst = cannonicalEclairInstance()
|
||||||
new EclairRpcClient(inst, binary(eclairVersionOpt, eclairCommitOpt))
|
new EclairRpcClient(inst,
|
||||||
}
|
EclairRpcTestClient.getBinary(
|
||||||
|
eclairVersionOpt = eclairVersionOpt,
|
||||||
def deleteTmpDir(dir: File): Boolean = {
|
eclairCommitOpt = eclairCommitOpt,
|
||||||
if (!dir.isDirectory) {
|
binaryDirectory = binaryDirectory))
|
||||||
dir.delete()
|
|
||||||
} else {
|
|
||||||
dir.listFiles().foreach(deleteTmpDir)
|
|
||||||
dir.delete()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -542,7 +495,8 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
||||||
eclairVersionOpt1: Option[String] = None,
|
eclairVersionOpt1: Option[String] = None,
|
||||||
eclairCommitOpt1: Option[String] = None,
|
eclairCommitOpt1: Option[String] = None,
|
||||||
eclairVersionOpt2: Option[String] = None,
|
eclairVersionOpt2: Option[String] = None,
|
||||||
eclairCommitOpt2: Option[String] = None)(implicit
|
eclairCommitOpt2: Option[String] = None,
|
||||||
|
binaryDirectory: Path = EclairRpcTestClient.sbtBinaryDirectory)(implicit
|
||||||
system: ActorSystem): Future[(EclairRpcClient, EclairRpcClient)] = {
|
system: ActorSystem): Future[(EclairRpcClient, EclairRpcClient)] = {
|
||||||
import system.dispatcher
|
import system.dispatcher
|
||||||
val bitcoindRpcClientF: Future[BitcoindRpcClient] = {
|
val bitcoindRpcClientF: Future[BitcoindRpcClient] = {
|
||||||
|
@ -561,14 +515,20 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
||||||
|
|
||||||
val clientF = e1InstanceF.flatMap { e1 =>
|
val clientF = e1InstanceF.flatMap { e1 =>
|
||||||
val e =
|
val e =
|
||||||
new EclairRpcClient(e1, binary(eclairVersionOpt1, eclairCommitOpt1))
|
new EclairRpcClient(e1,
|
||||||
|
EclairRpcTestClient.getBinary(eclairVersionOpt1,
|
||||||
|
eclairCommitOpt1,
|
||||||
|
binaryDirectory))
|
||||||
logger.debug(
|
logger.debug(
|
||||||
s"Temp eclair directory created ${e.getDaemon.authCredentials.datadir}")
|
s"Temp eclair directory created ${e.getDaemon.authCredentials.datadir}")
|
||||||
e.start().map(_ => e)
|
e.start().map(_ => e)
|
||||||
}
|
}
|
||||||
val otherClientF = e2InstanceF.flatMap { e2 =>
|
val otherClientF = e2InstanceF.flatMap { e2 =>
|
||||||
val e =
|
val e =
|
||||||
new EclairRpcClient(e2, binary(eclairVersionOpt2, eclairCommitOpt2))
|
new EclairRpcClient(e2,
|
||||||
|
EclairRpcTestClient.getBinary(eclairVersionOpt2,
|
||||||
|
eclairCommitOpt2,
|
||||||
|
binaryDirectory))
|
||||||
logger.debug(
|
logger.debug(
|
||||||
s"Temp eclair directory created ${e.getDaemon.authCredentials.datadir}")
|
s"Temp eclair directory created ${e.getDaemon.authCredentials.datadir}")
|
||||||
e.start().map(_ => e)
|
e.start().map(_ => e)
|
||||||
|
@ -805,16 +765,19 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
||||||
senderEclairCommit: Option[String],
|
senderEclairCommit: Option[String],
|
||||||
networkSize: Int,
|
networkSize: Int,
|
||||||
channelAmount: MilliSatoshis,
|
channelAmount: MilliSatoshis,
|
||||||
logbackXml: Option[String])(implicit
|
logbackXml: Option[String],
|
||||||
|
binaryDirectory: Path = EclairRpcTestClient.sbtBinaryDirectory)(implicit
|
||||||
system: ActorSystem): Future[EclairNetwork] = {
|
system: ActorSystem): Future[EclairNetwork] = {
|
||||||
import system.dispatcher
|
import system.dispatcher
|
||||||
for {
|
for {
|
||||||
bitcoind <- startedBitcoindRpcClient()
|
bitcoind <- startedBitcoindRpcClient()
|
||||||
testEclairInstance =
|
testEclairInstance =
|
||||||
EclairRpcTestUtil.eclairInstance(bitcoind, logbackXml = logbackXml)
|
EclairRpcTestUtil.eclairInstance(bitcoind, logbackXml = logbackXml)
|
||||||
testEclairNode = new EclairRpcClient(
|
testEclairNode = new EclairRpcClient(testEclairInstance,
|
||||||
testEclairInstance,
|
EclairRpcTestClient.getBinary(
|
||||||
binary(testEclairVersion, testEclairCommit))
|
testEclairVersion,
|
||||||
|
testEclairCommit,
|
||||||
|
binaryDirectory))
|
||||||
_ <- testEclairNode.start()
|
_ <- testEclairNode.start()
|
||||||
_ <- awaitEclairInSync(testEclairNode, bitcoind)
|
_ <- awaitEclairInSync(testEclairNode, bitcoind)
|
||||||
networkEclairInstances =
|
networkEclairInstances =
|
||||||
|
@ -826,7 +789,9 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
||||||
logbackXml = logbackXml))
|
logbackXml = logbackXml))
|
||||||
networkEclairNodes = networkEclairInstances.map(
|
networkEclairNodes = networkEclairInstances.map(
|
||||||
new EclairRpcClient(_,
|
new EclairRpcClient(_,
|
||||||
binary(senderEclairVersion, senderEclairCommit)))
|
EclairRpcTestClient.getBinary(senderEclairVersion,
|
||||||
|
senderEclairCommit,
|
||||||
|
binaryDirectory)))
|
||||||
_ <- Future.sequence(networkEclairNodes.map(_.start()))
|
_ <- Future.sequence(networkEclairNodes.map(_.start()))
|
||||||
_ <- Future.sequence(
|
_ <- Future.sequence(
|
||||||
networkEclairNodes.map(awaitEclairInSync(_, bitcoind)))
|
networkEclairNodes.map(awaitEclairInSync(_, bitcoind)))
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.bitcoins.testkit.fixtures
|
||||||
import akka.actor.ActorSystem
|
import akka.actor.ActorSystem
|
||||||
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||||
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
||||||
|
|
||||||
import org.bitcoins.testkit.util.BitcoinSAsyncFixtureTest
|
import org.bitcoins.testkit.util.BitcoinSAsyncFixtureTest
|
||||||
import org.scalatest._
|
import org.scalatest._
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@ package org.bitcoins.testkit.rpc
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.file.{Files, Path, Paths}
|
import java.nio.file.{Files, Path}
|
||||||
|
|
||||||
import akka.actor.ActorSystem
|
import akka.actor.ActorSystem
|
||||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddNodeArgument
|
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddNodeArgument
|
||||||
import org.bitcoins.commons.jsonmodels.bitcoind.{
|
import org.bitcoins.commons.jsonmodels.bitcoind.{
|
||||||
|
@ -44,10 +43,9 @@ import org.bitcoins.rpc.config.{
|
||||||
ZmqConfig
|
ZmqConfig
|
||||||
}
|
}
|
||||||
import org.bitcoins.rpc.util.{AsyncUtil, RpcUtil}
|
import org.bitcoins.rpc.util.{AsyncUtil, RpcUtil}
|
||||||
import org.bitcoins.testkit.util.{FileUtil, TestkitBinaries}
|
import org.bitcoins.testkit.util.{BitcoindRpcTestClient, FileUtil}
|
||||||
import org.bitcoins.util.ListUtil
|
import org.bitcoins.util.ListUtil
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
|
||||||
import scala.collection.immutable.Map
|
import scala.collection.immutable.Map
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.concurrent._
|
import scala.concurrent._
|
||||||
|
@ -57,26 +55,11 @@ import scala.util._
|
||||||
//noinspection AccessorLikeMethodIsEmptyParen
|
//noinspection AccessorLikeMethodIsEmptyParen
|
||||||
trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
||||||
|
|
||||||
|
lazy val network: RegTest.type = RegTest
|
||||||
|
|
||||||
type RpcClientAccum =
|
type RpcClientAccum =
|
||||||
mutable.Builder[BitcoindRpcClient, Vector[BitcoindRpcClient]]
|
mutable.Builder[BitcoindRpcClient, Vector[BitcoindRpcClient]]
|
||||||
|
|
||||||
@tailrec
|
|
||||||
private def randomDirName: String = {
|
|
||||||
val dirname = 0.until(5).map(_ => Random.alphanumeric.head).mkString
|
|
||||||
val dir = new File(dirname)
|
|
||||||
if (!dir.exists()) {
|
|
||||||
dirname
|
|
||||||
} else {
|
|
||||||
randomDirName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def tmpDir(): File = {
|
|
||||||
val f = Paths.get(Properties.tmpDir, randomDirName).toFile
|
|
||||||
f.mkdirs()
|
|
||||||
f
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard config used for testing purposes
|
* Standard config used for testing purposes
|
||||||
*/
|
*/
|
||||||
|
@ -94,7 +77,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
||||||
zmqPort: Int,
|
zmqPort: Int,
|
||||||
pruneMode: Boolean,
|
pruneMode: Boolean,
|
||||||
blockFilterIndex: Boolean = false): BitcoindConfig = {
|
blockFilterIndex: Boolean = false): BitcoindConfig = {
|
||||||
val pass = randomDirName
|
val pass = FileUtil.randomDirName
|
||||||
val username = "random_user_name"
|
val username = "random_user_name"
|
||||||
val conf = s"""
|
val conf = s"""
|
||||||
|regtest=1
|
|regtest=1
|
||||||
|
@ -123,7 +106,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
else
|
else
|
||||||
conf
|
conf
|
||||||
BitcoindConfig(config = config, datadir = BitcoindRpcTestUtil.tmpDir())
|
BitcoindConfig(config = config, datadir = FileUtil.tmpDir())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,19 +129,14 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
||||||
written
|
written
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val network: RegTest.type = RegTest
|
|
||||||
|
|
||||||
/** The directory that sbt downloads bitcoind binaries into */
|
|
||||||
private[bitcoins] val binaryDirectory = {
|
|
||||||
TestkitBinaries.baseBinaryDirectory.resolve("bitcoind")
|
|
||||||
}
|
|
||||||
|
|
||||||
def newestBitcoindBinary: File = getBinary(BitcoindVersion.newest)
|
def newestBitcoindBinary: File = getBinary(BitcoindVersion.newest)
|
||||||
|
|
||||||
def getBinary(version: BitcoindVersion): File =
|
def getBinary(
|
||||||
|
version: BitcoindVersion,
|
||||||
|
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory): File =
|
||||||
version match {
|
version match {
|
||||||
// default to newest version
|
// default to newest version
|
||||||
case Unknown => getBinary(BitcoindVersion.newest)
|
case Unknown => getBinary(BitcoindVersion.newest, binaryDirectory)
|
||||||
case known @ (Experimental | V16 | V17 | V18 | V19 | V20) =>
|
case known @ (Experimental | V16 | V17 | V18 | V19 | V20) =>
|
||||||
val fileList = Files
|
val fileList = Files
|
||||||
.list(binaryDirectory)
|
.list(binaryDirectory)
|
||||||
|
@ -200,7 +178,9 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
||||||
rpcPort: Int = RpcUtil.randomPort,
|
rpcPort: Int = RpcUtil.randomPort,
|
||||||
zmqPort: Int = RpcUtil.randomPort,
|
zmqPort: Int = RpcUtil.randomPort,
|
||||||
pruneMode: Boolean = false,
|
pruneMode: Boolean = false,
|
||||||
versionOpt: Option[BitcoindVersion] = None): BitcoindInstance = {
|
versionOpt: Option[BitcoindVersion] = None,
|
||||||
|
binaryDirectory: Path =
|
||||||
|
BitcoindRpcTestClient.sbtBinaryDirectory): BitcoindInstance = {
|
||||||
val uri = new URI("http://localhost:" + port)
|
val uri = new URI("http://localhost:" + port)
|
||||||
val rpcUri = new URI("http://localhost:" + rpcPort)
|
val rpcUri = new URI("http://localhost:" + rpcPort)
|
||||||
val hasNeutrinoSupport = versionOpt match {
|
val hasNeutrinoSupport = versionOpt match {
|
||||||
|
@ -220,7 +200,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
||||||
val binary: File = versionOpt match {
|
val binary: File = versionOpt match {
|
||||||
case Some(version) => getBinary(version)
|
case Some(version) => getBinary(version)
|
||||||
case None =>
|
case None =>
|
||||||
if (Files.exists(BitcoindRpcTestUtil.binaryDirectory)) {
|
if (Files.exists(binaryDirectory)) {
|
||||||
newestBitcoindBinary
|
newestBitcoindBinary
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
@ -244,73 +224,138 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
||||||
port: Int = RpcUtil.randomPort,
|
port: Int = RpcUtil.randomPort,
|
||||||
rpcPort: Int = RpcUtil.randomPort,
|
rpcPort: Int = RpcUtil.randomPort,
|
||||||
zmqPort: Int = RpcUtil.randomPort,
|
zmqPort: Int = RpcUtil.randomPort,
|
||||||
pruneMode: Boolean = false
|
pruneMode: Boolean = false,
|
||||||
|
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory
|
||||||
): BitcoindInstance =
|
): BitcoindInstance =
|
||||||
instance(port = port,
|
instance(port = port,
|
||||||
rpcPort = rpcPort,
|
rpcPort = rpcPort,
|
||||||
zmqPort = zmqPort,
|
zmqPort = zmqPort,
|
||||||
pruneMode = pruneMode,
|
pruneMode = pruneMode,
|
||||||
versionOpt = Some(BitcoindVersion.V16))
|
versionOpt = Some(BitcoindVersion.V16),
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
|
||||||
def v17Instance(
|
def v17Instance(
|
||||||
port: Int = RpcUtil.randomPort,
|
port: Int = RpcUtil.randomPort,
|
||||||
rpcPort: Int = RpcUtil.randomPort,
|
rpcPort: Int = RpcUtil.randomPort,
|
||||||
zmqPort: Int = RpcUtil.randomPort,
|
zmqPort: Int = RpcUtil.randomPort,
|
||||||
pruneMode: Boolean = false
|
pruneMode: Boolean = false,
|
||||||
|
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory
|
||||||
): BitcoindInstance =
|
): BitcoindInstance =
|
||||||
instance(port = port,
|
instance(port = port,
|
||||||
rpcPort = rpcPort,
|
rpcPort = rpcPort,
|
||||||
zmqPort = zmqPort,
|
zmqPort = zmqPort,
|
||||||
pruneMode = pruneMode,
|
pruneMode = pruneMode,
|
||||||
versionOpt = Some(BitcoindVersion.V17))
|
versionOpt = Some(BitcoindVersion.V17),
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
|
||||||
def v18Instance(
|
def v18Instance(
|
||||||
port: Int = RpcUtil.randomPort,
|
port: Int = RpcUtil.randomPort,
|
||||||
rpcPort: Int = RpcUtil.randomPort,
|
rpcPort: Int = RpcUtil.randomPort,
|
||||||
zmqPort: Int = RpcUtil.randomPort,
|
zmqPort: Int = RpcUtil.randomPort,
|
||||||
pruneMode: Boolean = false
|
pruneMode: Boolean = false,
|
||||||
|
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory
|
||||||
): BitcoindInstance =
|
): BitcoindInstance =
|
||||||
instance(port = port,
|
instance(port = port,
|
||||||
rpcPort = rpcPort,
|
rpcPort = rpcPort,
|
||||||
zmqPort = zmqPort,
|
zmqPort = zmqPort,
|
||||||
pruneMode = pruneMode,
|
pruneMode = pruneMode,
|
||||||
versionOpt = Some(BitcoindVersion.V18))
|
versionOpt = Some(BitcoindVersion.V18),
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
|
||||||
def v19Instance(
|
def v19Instance(
|
||||||
port: Int = RpcUtil.randomPort,
|
port: Int = RpcUtil.randomPort,
|
||||||
rpcPort: Int = RpcUtil.randomPort,
|
rpcPort: Int = RpcUtil.randomPort,
|
||||||
zmqPort: Int = RpcUtil.randomPort,
|
zmqPort: Int = RpcUtil.randomPort,
|
||||||
pruneMode: Boolean = false
|
pruneMode: Boolean = false,
|
||||||
|
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory
|
||||||
): BitcoindInstance =
|
): BitcoindInstance =
|
||||||
instance(port = port,
|
instance(port = port,
|
||||||
rpcPort = rpcPort,
|
rpcPort = rpcPort,
|
||||||
zmqPort = zmqPort,
|
zmqPort = zmqPort,
|
||||||
pruneMode = pruneMode,
|
pruneMode = pruneMode,
|
||||||
versionOpt = Some(BitcoindVersion.V19))
|
versionOpt = Some(BitcoindVersion.V19),
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
|
||||||
def v20Instance(
|
def v20Instance(
|
||||||
port: Int = RpcUtil.randomPort,
|
port: Int = RpcUtil.randomPort,
|
||||||
rpcPort: Int = RpcUtil.randomPort,
|
rpcPort: Int = RpcUtil.randomPort,
|
||||||
zmqPort: Int = RpcUtil.randomPort,
|
zmqPort: Int = RpcUtil.randomPort,
|
||||||
pruneMode: Boolean = false
|
pruneMode: Boolean = false,
|
||||||
|
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory
|
||||||
): BitcoindInstance =
|
): BitcoindInstance =
|
||||||
instance(port = port,
|
instance(port = port,
|
||||||
rpcPort = rpcPort,
|
rpcPort = rpcPort,
|
||||||
zmqPort = zmqPort,
|
zmqPort = zmqPort,
|
||||||
pruneMode = pruneMode,
|
pruneMode = pruneMode,
|
||||||
versionOpt = Some(BitcoindVersion.V20))
|
versionOpt = Some(BitcoindVersion.V20),
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
|
||||||
def vExperimentalInstance(
|
def vExperimentalInstance(
|
||||||
port: Int = RpcUtil.randomPort,
|
port: Int = RpcUtil.randomPort,
|
||||||
rpcPort: Int = RpcUtil.randomPort,
|
rpcPort: Int = RpcUtil.randomPort,
|
||||||
zmqPort: Int = RpcUtil.randomPort,
|
zmqPort: Int = RpcUtil.randomPort,
|
||||||
pruneMode: Boolean = false
|
pruneMode: Boolean = false,
|
||||||
|
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory
|
||||||
): BitcoindInstance =
|
): BitcoindInstance =
|
||||||
instance(port = port,
|
instance(port = port,
|
||||||
rpcPort = rpcPort,
|
rpcPort = rpcPort,
|
||||||
zmqPort = zmqPort,
|
zmqPort = zmqPort,
|
||||||
pruneMode = pruneMode,
|
pruneMode = pruneMode,
|
||||||
versionOpt = Some(BitcoindVersion.Experimental))
|
versionOpt = Some(BitcoindVersion.Experimental),
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
|
||||||
|
/** Gets an instance of bitcoind with the given version */
|
||||||
|
def getInstance(
|
||||||
|
bitcoindVersion: BitcoindVersion,
|
||||||
|
port: Int = RpcUtil.randomPort,
|
||||||
|
rpcPort: Int = RpcUtil.randomPort,
|
||||||
|
zmqPort: Int = RpcUtil.randomPort,
|
||||||
|
pruneMode: Boolean = false,
|
||||||
|
binaryDirectory: Path =
|
||||||
|
BitcoindRpcTestClient.sbtBinaryDirectory): BitcoindInstance = {
|
||||||
|
bitcoindVersion match {
|
||||||
|
case BitcoindVersion.V16 =>
|
||||||
|
BitcoindRpcTestUtil.v16Instance(port,
|
||||||
|
rpcPort,
|
||||||
|
zmqPort,
|
||||||
|
pruneMode,
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
case BitcoindVersion.V17 =>
|
||||||
|
BitcoindRpcTestUtil.v17Instance(port,
|
||||||
|
rpcPort,
|
||||||
|
zmqPort,
|
||||||
|
pruneMode,
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
case BitcoindVersion.V18 =>
|
||||||
|
BitcoindRpcTestUtil.v18Instance(port,
|
||||||
|
rpcPort,
|
||||||
|
zmqPort,
|
||||||
|
pruneMode,
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
case BitcoindVersion.V19 =>
|
||||||
|
BitcoindRpcTestUtil.v19Instance(port,
|
||||||
|
rpcPort,
|
||||||
|
zmqPort,
|
||||||
|
pruneMode,
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
case BitcoindVersion.V20 =>
|
||||||
|
BitcoindRpcTestUtil.v20Instance(port,
|
||||||
|
rpcPort,
|
||||||
|
zmqPort,
|
||||||
|
pruneMode,
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
case BitcoindVersion.Experimental =>
|
||||||
|
BitcoindRpcTestUtil.vExperimentalInstance(port,
|
||||||
|
rpcPort,
|
||||||
|
zmqPort,
|
||||||
|
pruneMode,
|
||||||
|
binaryDirectory =
|
||||||
|
binaryDirectory)
|
||||||
|
case BitcoindVersion.Unknown =>
|
||||||
|
sys.error(
|
||||||
|
s"Could not create a bitcoind version with version=${BitcoindVersion.Unknown}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def startServers(servers: Vector[BitcoindRpcClient])(implicit
|
def startServers(servers: Vector[BitcoindRpcClient])(implicit
|
||||||
ec: ExecutionContext): Future[Unit] = {
|
ec: ExecutionContext): Future[Unit] = {
|
||||||
|
@ -1023,7 +1068,7 @@ object BitcoindRpcTestUtil extends BitcoindRpcTestUtil {
|
||||||
/**
|
/**
|
||||||
* Used for long running async tasks
|
* Used for long running async tasks
|
||||||
*/
|
*/
|
||||||
private val DEFAULT_LONG_INTERVAL = {
|
val DEFAULT_LONG_INTERVAL = {
|
||||||
if (EnvUtil.isMac && EnvUtil.isCI) 10.seconds
|
if (EnvUtil.isMac && EnvUtil.isCI) 10.seconds
|
||||||
else 3.seconds
|
else 3.seconds
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.bitcoins.testkit.util
|
package org.bitcoins.testkit.util
|
||||||
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
||||||
import org.bitcoins.core.config.NetworkParameters
|
import org.bitcoins.core.config.NetworkParameters
|
||||||
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
||||||
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
||||||
|
@ -10,10 +9,11 @@ import scala.collection.mutable
|
||||||
|
|
||||||
abstract class BitcoindRpcTest extends BitcoinSAsyncTest {
|
abstract class BitcoindRpcTest extends BitcoinSAsyncTest {
|
||||||
|
|
||||||
private val dirExists = Files.exists(BitcoindRpcTestUtil.binaryDirectory)
|
private val dirExists =
|
||||||
|
Files.exists(BitcoindRpcTestClient.sbtBinaryDirectory)
|
||||||
|
|
||||||
private val hasContents = dirExists && Files
|
private val hasContents = dirExists && Files
|
||||||
.list(BitcoindRpcTestUtil.binaryDirectory)
|
.list(BitcoindRpcTestClient.sbtBinaryDirectory)
|
||||||
.toArray()
|
.toArray()
|
||||||
.nonEmpty
|
.nonEmpty
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ abstract class BitcoindRpcTest extends BitcoinSAsyncTest {
|
||||||
printerr(s"Run 'sbt downloadBitcoind' to fetch needed binaries")
|
printerr(s"Run 'sbt downloadBitcoind' to fetch needed binaries")
|
||||||
sys.error {
|
sys.error {
|
||||||
val msg =
|
val msg =
|
||||||
s""""bitcoind binary directory (${BitcoindRpcTestUtil.binaryDirectory}) is empty.
|
s""""bitcoind binary directory (${BitcoindRpcTestClient.sbtBinaryDirectory}) is empty.
|
||||||
|Run 'sbt downloadBitcoind' to fetch needed binaries""".stripMargin
|
|Run 'sbt downloadBitcoind' to fetch needed binaries""".stripMargin
|
||||||
msg
|
msg
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package org.bitcoins.testkit.util
|
||||||
|
|
||||||
|
import akka.actor.ActorSystem
|
||||||
|
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||||
|
import org.bitcoins.rpc.config.BitcoindInstance
|
||||||
|
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
||||||
|
|
||||||
|
import java.nio.file.{Files, Path}
|
||||||
|
import scala.concurrent.Future
|
||||||
|
|
||||||
|
/** Helper class to start a bitcoind client with the given binary */
|
||||||
|
case class BitcoindRpcTestClient(
|
||||||
|
override val binary: Path,
|
||||||
|
version: BitcoindVersion)(implicit system: ActorSystem)
|
||||||
|
extends RpcBinaryUtil[BitcoindRpcClient] {
|
||||||
|
require(Files.exists(binary),
|
||||||
|
s"Path did not exist! got=${binary.toAbsolutePath.toString}")
|
||||||
|
import system.dispatcher
|
||||||
|
|
||||||
|
private lazy val bitcoindInstance: BitcoindInstance = {
|
||||||
|
BitcoindRpcTestUtil.getInstance(bitcoindVersion = version,
|
||||||
|
binaryDirectory = binaryDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Cached client. This is defined if start() has been called
|
||||||
|
* else None
|
||||||
|
*/
|
||||||
|
private var clientOpt: Option[BitcoindRpcClient] = None
|
||||||
|
|
||||||
|
override def start(): Future[BitcoindRpcClient] = {
|
||||||
|
clientOpt match {
|
||||||
|
case Some(client) => Future.successful(client)
|
||||||
|
case None =>
|
||||||
|
val clientF =
|
||||||
|
BitcoindRpcTestUtil.startedBitcoindRpcClient(bitcoindInstance)
|
||||||
|
clientF.map { c =>
|
||||||
|
clientOpt = Some(c)
|
||||||
|
c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def stop(): Future[BitcoindRpcClient] = {
|
||||||
|
clientOpt match {
|
||||||
|
case Some(cli) => cli.stop()
|
||||||
|
case None =>
|
||||||
|
Future.failed(
|
||||||
|
new RuntimeException(s"BitcoindRpcClient was not defined!"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object BitcoindRpcTestClient extends SbtBinaryFactory {
|
||||||
|
|
||||||
|
override val sbtBinaryDirectory: Path =
|
||||||
|
TestkitBinaries.baseBinaryDirectory.resolve("bitcoind")
|
||||||
|
|
||||||
|
def fromSbtDownload(bitcoindVersion: BitcoindVersion)(implicit
|
||||||
|
system: ActorSystem): BitcoindRpcTestClient = {
|
||||||
|
val binary =
|
||||||
|
BitcoindRpcTestUtil.getBinary(bitcoindVersion, sbtBinaryDirectory)
|
||||||
|
BitcoindRpcTestClient(binary.toPath, bitcoindVersion)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
package org.bitcoins.testkit.util
|
||||||
|
|
||||||
|
import akka.actor.ActorSystem
|
||||||
|
import org.bitcoins.eclair.rpc.client.EclairRpcClient
|
||||||
|
import org.bitcoins.eclair.rpc.config.EclairInstance
|
||||||
|
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
||||||
|
import org.bitcoins.testkit.eclair.rpc.EclairRpcTestUtil
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.{Files, Path}
|
||||||
|
import scala.concurrent.Future
|
||||||
|
|
||||||
|
/** Helper class to start a eclair client with the given binary */
|
||||||
|
case class EclairRpcTestClient(
|
||||||
|
override val binary: Path,
|
||||||
|
bitcoindRpcClientOpt: Option[BitcoindRpcClient])(implicit
|
||||||
|
system: ActorSystem)
|
||||||
|
extends RpcBinaryUtil[EclairRpcClient] {
|
||||||
|
require(Files.exists(binary),
|
||||||
|
s"Path did not exist! got=${binary.toAbsolutePath.toString}")
|
||||||
|
import system.dispatcher
|
||||||
|
|
||||||
|
private lazy val bitcoindRpcClientF: Future[BitcoindRpcClient] = {
|
||||||
|
bitcoindRpcClientOpt match {
|
||||||
|
case Some(bitcoindRpcClient) => Future.successful(bitcoindRpcClient)
|
||||||
|
case None =>
|
||||||
|
EclairRpcTestUtil.startedBitcoindRpcClient()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy val eclairInstanceF: Future[EclairInstance] = {
|
||||||
|
bitcoindRpcClientF.map { bitcoind =>
|
||||||
|
EclairRpcTestUtil.eclairInstance(bitcoind, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy val eclairRpcClientF: Future[EclairRpcClient] = {
|
||||||
|
eclairInstanceF.map(new EclairRpcClient(_, Some(binary.toFile)))
|
||||||
|
}
|
||||||
|
|
||||||
|
override def start(): Future[EclairRpcClient] = {
|
||||||
|
//should we start bitcoind rpc client here too?
|
||||||
|
for {
|
||||||
|
rpcClient <- eclairRpcClientF
|
||||||
|
started <- rpcClient.start()
|
||||||
|
} yield started
|
||||||
|
}
|
||||||
|
|
||||||
|
override def stop(): Future[EclairRpcClient] = {
|
||||||
|
//should we stop bitcoind rpc client here too?
|
||||||
|
for {
|
||||||
|
rpcClient <- eclairRpcClientF
|
||||||
|
stopped <- rpcClient.stop()
|
||||||
|
} yield stopped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object EclairRpcTestClient extends SbtBinaryFactory {
|
||||||
|
|
||||||
|
/** Directory where sbt downloads Eclair binaries */
|
||||||
|
override val sbtBinaryDirectory: Path =
|
||||||
|
TestkitBinaries.baseBinaryDirectory.resolve("eclair")
|
||||||
|
|
||||||
|
def fromSbtDownloadOpt(
|
||||||
|
eclairVersionOpt: Option[String],
|
||||||
|
eclairCommitOpt: Option[String],
|
||||||
|
bitcoindRpcClientOpt: Option[BitcoindRpcClient])(implicit
|
||||||
|
system: ActorSystem): Option[EclairRpcTestClient] = {
|
||||||
|
val fileOpt =
|
||||||
|
getBinary(eclairVersionOpt = eclairVersionOpt,
|
||||||
|
eclairCommitOpt = eclairCommitOpt,
|
||||||
|
binaryDirectory = sbtBinaryDirectory)
|
||||||
|
|
||||||
|
fileOpt.map(f =>
|
||||||
|
EclairRpcTestClient(binary = f.toPath, bitcoindRpcClientOpt))
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromSbtDownload(
|
||||||
|
eclairVersionOpt: Option[String],
|
||||||
|
eclairCommitOpt: Option[String],
|
||||||
|
bitcoindRpcClientOpt: Option[BitcoindRpcClient])(implicit
|
||||||
|
system: ActorSystem): EclairRpcTestClient = {
|
||||||
|
val eclairOpt = fromSbtDownloadOpt(eclairVersionOpt = eclairCommitOpt,
|
||||||
|
eclairCommitOpt = eclairCommitOpt,
|
||||||
|
bitcoindRpcClientOpt =
|
||||||
|
bitcoindRpcClientOpt)
|
||||||
|
eclairOpt match {
|
||||||
|
case Some(client) => client
|
||||||
|
case None =>
|
||||||
|
sys.error(
|
||||||
|
s"Could not find eclair that was downloaded by sbt " +
|
||||||
|
s"with version=$eclairVersionOpt " +
|
||||||
|
s"commit=$eclairCommitOpt at " +
|
||||||
|
s"path=${sbtBinaryDirectory.toAbsolutePath.toString}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Path to Jar downloaded by Eclair, if it exists */
|
||||||
|
def getBinary(
|
||||||
|
eclairVersionOpt: Option[String],
|
||||||
|
eclairCommitOpt: Option[String],
|
||||||
|
binaryDirectory: Path): Option[File] = {
|
||||||
|
val path = binaryDirectory
|
||||||
|
.resolve(eclairVersionOpt.getOrElse(EclairRpcClient.version))
|
||||||
|
.resolve(
|
||||||
|
s"eclair-node-${EclairRpcClient.version}-${eclairCommitOpt.getOrElse(EclairRpcClient.commit)}")
|
||||||
|
.resolve("bin")
|
||||||
|
.resolve(
|
||||||
|
if (sys.props("os.name").toLowerCase.contains("windows"))
|
||||||
|
"eclair-node.bat"
|
||||||
|
else
|
||||||
|
"eclair-node.sh")
|
||||||
|
|
||||||
|
if (Files.exists(path)) {
|
||||||
|
Some(path.toFile)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
package org.bitcoins.testkit.util
|
package org.bitcoins.testkit.util
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.{Path, Paths}
|
||||||
|
|
||||||
import org.bitcoins.core.util.BitcoinSLogger
|
import org.bitcoins.core.util.BitcoinSLogger
|
||||||
|
|
||||||
import scala.util.Properties
|
import scala.annotation.tailrec
|
||||||
|
import scala.util.{Properties, Random}
|
||||||
|
|
||||||
object FileUtil extends BitcoinSLogger {
|
object FileUtil extends BitcoinSLogger {
|
||||||
|
|
||||||
|
@ -38,4 +38,21 @@ object FileUtil extends BitcoinSLogger {
|
||||||
def deleteTmpDir(path: Path): Boolean = {
|
def deleteTmpDir(path: Path): Boolean = {
|
||||||
deleteTmpDir(path.toFile)
|
deleteTmpDir(path.toFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@tailrec
|
||||||
|
final def randomDirName: String = {
|
||||||
|
val dirname = 0.until(5).map(_ => Random.alphanumeric.head).mkString
|
||||||
|
val dir = new File(dirname)
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dirname
|
||||||
|
} else {
|
||||||
|
randomDirName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def tmpDir(): File = {
|
||||||
|
val f = Paths.get(Properties.tmpDir, FileUtil.randomDirName).toFile
|
||||||
|
f.mkdirs()
|
||||||
|
f
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.bitcoins.testkit.util
|
||||||
|
|
||||||
|
import org.bitcoins.core.config.RegTest
|
||||||
|
import org.bitcoins.core.util.{BitcoinSLogger, StartStopAsync}
|
||||||
|
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
/** A utility trait for handling binaries like bitcoind/eclair.
|
||||||
|
* All common utility methods should go in this trait
|
||||||
|
*/
|
||||||
|
trait RpcBinaryUtil[T] extends StartStopAsync[T] with BitcoinSLogger {
|
||||||
|
|
||||||
|
/** The path to the binary, an example is
|
||||||
|
* '/home/suredbits/.bitcoin-s/binaries/bitcoind/bitcoin-0.20.1/bin/bitcoind'
|
||||||
|
* or
|
||||||
|
* '/home/suredbits/.bitcoin-s/binaries/eclair/0.4.1/eclair-node-0.4.1-e5fb281/bin/eclair-node.sh'
|
||||||
|
*/
|
||||||
|
def binary: Path
|
||||||
|
|
||||||
|
def binaryDirectory: Path = binary.getParent
|
||||||
|
|
||||||
|
lazy val network = RegTest
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package org.bitcoins.testkit.util
|
||||||
|
|
||||||
|
trait SbtBinaryFactory {
|
||||||
|
|
||||||
|
/** The path where binaries are stored by sbt */
|
||||||
|
def sbtBinaryDirectory: java.nio.file.Path
|
||||||
|
}
|
|
@ -6,12 +6,19 @@ import scala.util.Properties
|
||||||
|
|
||||||
object TestkitBinaries {
|
object TestkitBinaries {
|
||||||
|
|
||||||
|
private val base: Path = Paths.get(".bitcoin-s", "binaries")
|
||||||
|
|
||||||
/** The base directory where binaries needed in tests
|
/** The base directory where binaries needed in tests
|
||||||
* are located.
|
* are located.
|
||||||
*/
|
*/
|
||||||
lazy val baseBinaryDirectory: Path = {
|
lazy val baseBinaryDirectory: Path = {
|
||||||
val home = Paths.get(Properties.userHome, ".bitcoin-s", "binaries")
|
val home = Paths.get(Properties.userHome)
|
||||||
home
|
fromRoot(home)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gives you an arbitrary root path, and then tacks on .bitcoin-s/binaries/ onto the end of it
|
||||||
|
*/
|
||||||
|
def fromRoot(path: Path): Path = {
|
||||||
|
path.resolve(base)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue