BitcoinTxBuilderTest Hang (#901)

* Fix hanging bug in BitcoinTxBuilderTest

* Added forAllAsync to BitcoinSAsyncTest
This commit is contained in:
Nadav Kohen 2019-12-02 12:04:58 -07:00 committed by Chris Stewart
parent c7a8a8eadf
commit 3183f17ce2
2 changed files with 123 additions and 15 deletions

View file

@ -14,7 +14,7 @@ import org.bitcoins.testkit.core.gen.{
ScriptGenerators,
TransactionGenerators
}
import org.bitcoins.core.number.{Int64, UInt32}
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.script._
import org.bitcoins.core.protocol.transaction._
import org.bitcoins.core.script.crypto.HashType
@ -32,9 +32,9 @@ import org.bitcoins.core.script.interpreter.ScriptInterpreter
import org.bitcoins.core.wallet.builder.BitcoinTxBuilder.UTXOMap
import org.bitcoins.testkit.Implicits._
import org.bitcoins.testkit.util.BitcoinSAsyncTest
import org.scalatest.Assertion
import scala.concurrent.Await
import scala.concurrent.duration.DurationInt
import scala.concurrent.Future
class BitcoinTxBuilderTest extends BitcoinSAsyncTest {
val tc = TransactionConstants
@ -454,9 +454,9 @@ class BitcoinTxBuilderTest extends BitcoinSAsyncTest {
.suchThat(_._1.nonEmpty)
it must "sign a mix of spks in a tx and then have it verified" in {
forAll(outputGen,
ScriptGenerators.scriptPubKey,
ChainParamsGenerator.bitcoinNetworkParams) {
forAllAsync(outputGen,
ScriptGenerators.scriptPubKey,
ChainParamsGenerator.bitcoinNetworkParams) {
case ((creditingTxsInfo, destinations), changeSPK, network) =>
val fee = SatoshisPerVirtualByte(Satoshis(1000))
val builder = BitcoinTxBuilder(destinations,
@ -464,15 +464,18 @@ class BitcoinTxBuilderTest extends BitcoinSAsyncTest {
fee,
changeSPK._1,
network)
val tx = Await.result(builder.flatMap(_.sign), 10.seconds)
assert(verifyScript(tx, creditingTxsInfo))
val txF = builder.flatMap(_.sign)
txF.map { tx =>
assert(verifyScript(tx, creditingTxsInfo))
}
}
}
it must "sign a mix of p2sh/p2wsh in a tx and then have it verified" in {
forAll(outputGen,
ScriptGenerators.scriptPubKey,
ChainParamsGenerator.bitcoinNetworkParams) {
forAllAsync(outputGen,
ScriptGenerators.scriptPubKey,
ChainParamsGenerator.bitcoinNetworkParams) {
case ((creditingTxsInfo, destinations), changeSPK, network) =>
val fee = SatoshisPerByte(Satoshis(1000))
val builder = BitcoinTxBuilder(destinations,
@ -480,8 +483,11 @@ class BitcoinTxBuilderTest extends BitcoinSAsyncTest {
fee,
changeSPK._1,
network)
val tx = Await.result(builder.flatMap(_.sign), 10.seconds)
assert(verifyScript(tx, creditingTxsInfo))
val txF = builder.flatMap(_.sign)
txF.map { tx =>
assert(verifyScript(tx, creditingTxsInfo))
}
}
}
}

View file

@ -6,14 +6,14 @@ import akka.util.Timeout
import org.bitcoins.core.config.{NetworkParameters, RegTest}
import org.bitcoins.core.protocol.blockchain.ChainParams
import org.bitcoins.core.util.BitcoinSLogger
import org.scalacheck.Shrink
import org.scalacheck.{Gen, Shrink}
import org.scalactic.anyvals.PosInt
import org.scalatest._
import org.scalatest.concurrent.AsyncTimeLimitedTests
import org.scalatest.time.Span
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import scala.concurrent.ExecutionContext
import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration.DurationInt
/** This is a base trait in bitcoin-s for async tests
@ -90,6 +90,108 @@ trait BaseAsyncTest
def generatorDrivenConfigNewCode: PropertyCheckConfiguration = {
customGenDrivenConfig(BitcoinSUnitTest.NEW_CODE_EXECUTIONS)
}
def sequenceTestRuns(
testRunFs: scala.collection.mutable.Builder[
Future[Assertion],
Vector[Future[Assertion]]]): Future[Assertion] = {
val testRunsF: Future[Vector[Assertion]] =
Future.sequence(testRunFs.result())
testRunsF.map(_.reduce((_, testRun) => testRun))
}
def forAllAsync[A](gen: Gen[A])(
func: A => Future[Assertion]): Future[Assertion] = {
val testRunFs = Vector.newBuilder[Future[Assertion]]
forAll(gen) { input =>
testRunFs.+=(func(input))
succeed
}
sequenceTestRuns(testRunFs)
}
def forAllAsync[A, B](genA: Gen[A], genB: Gen[B])(
func: (A, B) => Future[Assertion]): Future[Assertion] = {
val testRunFs = Vector.newBuilder[Future[Assertion]]
forAll(genA, genB) {
case (inputA, inputB) =>
testRunFs.+=(func(inputA, inputB))
succeed
}
sequenceTestRuns(testRunFs)
}
def forAllAsync[A, B, C](genA: Gen[A], genB: Gen[B], genC: Gen[C])(
func: (A, B, C) => Future[Assertion]): Future[Assertion] = {
val testRunFs = Vector.newBuilder[Future[Assertion]]
forAll(genA, genB, genC) {
case (inputA, inputB, inputC) =>
testRunFs.+=(func(inputA, inputB, inputC))
succeed
}
sequenceTestRuns(testRunFs)
}
def forAllAsync[A, B, C, D](
genA: Gen[A],
genB: Gen[B],
genC: Gen[C],
genD: Gen[D])(
func: (A, B, C, D) => Future[Assertion]): Future[Assertion] = {
val testRunFs = Vector.newBuilder[Future[Assertion]]
forAll(genA, genB, genC, genD) {
case (inputA, inputB, inputC, inputD) =>
testRunFs.+=(func(inputA, inputB, inputC, inputD))
succeed
}
sequenceTestRuns(testRunFs)
}
def forAllAsync[A, B, C, D, E](
genA: Gen[A],
genB: Gen[B],
genC: Gen[C],
genD: Gen[D],
genE: Gen[E])(
func: (A, B, C, D, E) => Future[Assertion]): Future[Assertion] = {
val testRunFs = Vector.newBuilder[Future[Assertion]]
forAll(genA, genB, genC, genD, genE) {
case (inputA, inputB, inputC, inputD, inputE) =>
testRunFs.+=(func(inputA, inputB, inputC, inputD, inputE))
succeed
}
sequenceTestRuns(testRunFs)
}
def forAllAsync[A, B, C, D, E, F](
genA: Gen[A],
genB: Gen[B],
genC: Gen[C],
genD: Gen[D],
genE: Gen[E],
genF: Gen[F])(
func: (A, B, C, D, E, F) => Future[Assertion]): Future[Assertion] = {
val testRunFs = Vector.newBuilder[Future[Assertion]]
forAll(genA, genB, genC, genD, genE, genF) {
case (inputA, inputB, inputC, inputD, inputE, inputF) =>
testRunFs.+=(func(inputA, inputB, inputC, inputD, inputE, inputF))
succeed
}
sequenceTestRuns(testRunFs)
}
}
/** A trait that uses [[AsyncFlatSpec]] to execute tests