diff --git a/app/cli/src/main/scala/org/bitcoins/cli/Cli.scala b/app/cli/src/main/scala/org/bitcoins/cli/Cli.scala index 4ee51db5fe..d4c5bff5bf 100644 --- a/app/cli/src/main/scala/org/bitcoins/cli/Cli.scala +++ b/app/cli/src/main/scala/org/bitcoins/cli/Cli.scala @@ -9,7 +9,7 @@ object Cli extends App { import System.err.{println => printerr} try { - ConsoleCli.exec(args.toVector: _*) match { + ConsoleCli.exec(args.toVector) match { case Success(output) => println(output) case Failure(err) => printerr(err.getMessage) diff --git a/app/cli/src/main/scala/org/bitcoins/cli/ConsoleCli.scala b/app/cli/src/main/scala/org/bitcoins/cli/ConsoleCli.scala index 2cb1636de4..755806a06e 100644 --- a/app/cli/src/main/scala/org/bitcoins/cli/ConsoleCli.scala +++ b/app/cli/src/main/scala/org/bitcoins/cli/ConsoleCli.scala @@ -1491,8 +1491,8 @@ object ConsoleCli { ) } - def exec(args: String*): Try[String] = { - val config = OParser.parse(parser, args.toVector, Config()) match { + def exec(args: Vector[String]): Try[String] = { + val config = OParser.parse(parser, args, Config()) match { case None => sys.exit(1) case Some(conf) => conf } diff --git a/app/server-test/src/test/scala/org/bitcoins/server/BitcoinSServerMainBitcoindTest.scala b/app/server-test/src/test/scala/org/bitcoins/server/BitcoinSServerMainBitcoindTest.scala new file mode 100644 index 0000000000..f9919e8ec7 --- /dev/null +++ b/app/server-test/src/test/scala/org/bitcoins/server/BitcoinSServerMainBitcoindTest.scala @@ -0,0 +1,43 @@ +package org.bitcoins.server + +import org.bitcoins.cli.{CliCommand, Config, ConsoleCli} +import org.bitcoins.commons.util.ServerArgParser +import org.bitcoins.testkit.fixtures.BitcoinSAppConfigBitcoinFixtureNotStarted + +/** Test starting bitcoin-s with bitcoind as the backend for app */ +class BitcoinSServerMainBitcoindTest + extends BitcoinSAppConfigBitcoinFixtureNotStarted { + + behavior of "BitcoinSServerMain" + + it must "start our app server with bitcoind as a backend" in { + config: BitcoinSAppConfig => + val server = new BitcoinSServerMain(ServerArgParser.empty)(system, config) + + val cliConfig = Config(rpcPortOpt = Some(config.rpcPort)) + + for { + _ <- server.start() + // Await RPC server started + _ <- BitcoinSServer.startedF + + info = ConsoleCli.exec(CliCommand.WalletInfo, cliConfig) + balance = ConsoleCli.exec(CliCommand.GetBalance(isSats = true), + cliConfig) + addr = ConsoleCli.exec(CliCommand.GetNewAddress(labelOpt = None), + cliConfig) + blockHash = ConsoleCli.exec(CliCommand.GetBestBlockHash, cliConfig) + } yield { + assert(info.isSuccess) + assert(balance.isSuccess) + assert(balance.get == "0 sats") + assert(addr.isSuccess) + assert(blockHash.isSuccess) + } + } + + override def afterAll(): Unit = { + super.afterAll() + BitcoinSServer.reset() + } +} diff --git a/app/server-test/src/test/scala/org/bitcoins/server/BitcoinSServerMainBitcoindTorTest.scala b/app/server-test/src/test/scala/org/bitcoins/server/BitcoinSServerMainBitcoindTorTest.scala new file mode 100644 index 0000000000..fbf69d063a --- /dev/null +++ b/app/server-test/src/test/scala/org/bitcoins/server/BitcoinSServerMainBitcoindTorTest.scala @@ -0,0 +1,46 @@ +package org.bitcoins.server + +import org.bitcoins.cli.{CliCommand, Config, ConsoleCli} +import org.bitcoins.commons.util.ServerArgParser +import org.bitcoins.testkit.fixtures.BitcoinSAppConfigBitcoinFixtureNotStarted +import org.bitcoins.testkit.tor.CachedTor + +/** Test starting bitcoin-s with bitcoind as the backend for app */ +class BitcoinSServerMainBitcoindTorTest + extends BitcoinSAppConfigBitcoinFixtureNotStarted + with CachedTor { + + behavior of "BitcoinSServerMain" + + it must "start our app server with bitcoind as a backend with tor" in { + config: BitcoinSAppConfig => + val server = new BitcoinSServerMain(ServerArgParser.empty)(system, config) + + val cliConfig: Config = Config(rpcPortOpt = Some(config.rpcPort)) + + for { + _ <- torF + _ <- server.start() + // Await RPC server started + _ <- BitcoinSServer.startedF + + info = ConsoleCli.exec(CliCommand.WalletInfo, cliConfig) + balance = ConsoleCli.exec(CliCommand.GetBalance(isSats = true), + cliConfig) + addr = ConsoleCli.exec(CliCommand.GetNewAddress(labelOpt = None), + cliConfig) + blockHash = ConsoleCli.exec(CliCommand.GetBestBlockHash, cliConfig) + } yield { + assert(info.isSuccess) + assert(balance.isSuccess) + assert(balance.get == "0 sats") + assert(addr.isSuccess) + assert(blockHash.isSuccess) + } + } + + override def afterAll(): Unit = { + super.afterAll() + BitcoinSServer.reset() + } +} diff --git a/app/server/src/main/scala/org/bitcoins/server/BitcoinSServerMain.scala b/app/server/src/main/scala/org/bitcoins/server/BitcoinSServerMain.scala index a237355c02..98b47f6ff1 100644 --- a/app/server/src/main/scala/org/bitcoins/server/BitcoinSServerMain.scala +++ b/app/server/src/main/scala/org/bitcoins/server/BitcoinSServerMain.scala @@ -445,7 +445,7 @@ object BitcoinSServerMain extends BitcoinSAppScalaDaemon { } object BitcoinSServer { - private[server] val startedFP = Promise[Future[Http.ServerBinding]]() + private[server] var startedFP = Promise[Future[Http.ServerBinding]]() /** Allows the above server to be bundled with other projects. * @@ -457,4 +457,8 @@ object BitcoinSServer { * been initialized. */ val startedF: Future[Http.ServerBinding] = startedFP.future.flatten + + def reset(): Unit = { + startedFP = Promise[Future[Http.ServerBinding]]() + } } diff --git a/build.sbt b/build.sbt index a5d846fd8e..0446243463 100644 --- a/build.sbt +++ b/build.sbt @@ -398,9 +398,11 @@ lazy val appServerTest = project .in(file("app/server-test")) .settings(CommonSettings.testSettings: _*) .settings(libraryDependencies ++= Deps.walletServerTest) + .settings(parallelExecution := false) .dependsOn( appServer, - testkit + testkit, + cli ) lazy val cli = project diff --git a/testkit/src/main/scala/org/bitcoins/testkit/fixtures/BitcoinSAppConfigFixture.scala b/testkit/src/main/scala/org/bitcoins/testkit/fixtures/BitcoinSAppConfigFixture.scala new file mode 100644 index 0000000000..5f0cbb644c --- /dev/null +++ b/testkit/src/main/scala/org/bitcoins/testkit/fixtures/BitcoinSAppConfigFixture.scala @@ -0,0 +1,81 @@ +package org.bitcoins.testkit.fixtures + +import com.typesafe.config.{Config, ConfigFactory} +import org.bitcoins.rpc.config.BitcoindInstance +import org.bitcoins.rpc.util.RpcUtil +import org.bitcoins.server.BitcoinSAppConfig +import org.bitcoins.testkit.rpc.CachedBitcoindNewest +import org.bitcoins.testkit.util.TorUtil +import org.bitcoins.testkit.{BitcoinSTestAppConfig, EmbeddedPg} +import org.scalatest.FutureOutcome + +import scala.concurrent.Future + +sealed trait BitcoinSAppConfigFixture extends BitcoinSFixture with EmbeddedPg { + override type FixtureParam = BitcoinSAppConfig + + override def afterAll(): Unit = { + super[EmbeddedPg].afterAll() + super[BitcoinSFixture].afterAll() + } +} + +/** Makes a bitcoin-s app config with proper bitcoind credentials + * and bitcoin-s.node.mode=bitcoind to use bitcoin as the backend + * + * The [[BitcoinSAppConfig]] is not started + */ +trait BitcoinSAppConfigBitcoinFixtureNotStarted + extends BitcoinSAppConfigFixture + with CachedBitcoindNewest { + + override type FixtureParam = BitcoinSAppConfig + + override def withFixture(test: OneArgAsyncTest): FutureOutcome = { + val builder: () => Future[BitcoinSAppConfig] = () => { + for { + bitcoind <- cachedBitcoindWithFundsF + datadir = bitcoind.instance.datadir + conf = buildConfig(bitcoind.instance) + bitcoinSAppConfig = BitcoinSAppConfig(datadir.toPath, conf) + } yield bitcoinSAppConfig + } + + val destroyF: BitcoinSAppConfig => Future[Unit] = { appConfig => + val stopF = appConfig + .stop() + .map(_ => BitcoinSTestAppConfig.deleteAppConfig(appConfig)) + .map(_ => ()) + stopF + } + + makeDependentFixture(builder, destroyF)(test) + } + + /** Builds a configuration with the proper bitcoind credentials and bitcoin-s node mode set to bitcoind + * and sets tor config + */ + private def buildConfig(instance: BitcoindInstance): Config = { + val configStr = + s""" + |bitcoin-s.bitcoind-rpc.rpcuser="${instance.authCredentials.username}" + |bitcoin-s.bitcoind-rpc.rpcpassword="${instance.authCredentials.password}" + |bitcoin-s.bitcoind-rpc.rpcbind="${instance.rpcUri.getHost}" + |bitcoin-s.bitcoind-rpc.rpcport="${instance.rpcUri.getPort}" + |bitcoin-s.bitcoind-rpc.isRemote=true + |bitcoin-s.bitcoind-rpc.version="${instance.getVersion}" + |bitcoin-s.node.mode=bitcoind + |bitcoin-s.tor.enabled=${TorUtil.torEnabled} + |bitcoin-s.proxy.enabled=${TorUtil.torEnabled} + |bitcoin-s.dlcnode.listen = "0.0.0.0:${RpcUtil.randomPort}" + |bitcoin-s.server.rpcport = ${RpcUtil.randomPort} + |""".stripMargin + + ConfigFactory.parseString(configStr) + } + + override def afterAll(): Unit = { + super[CachedBitcoindNewest].afterAll() + super[BitcoinSAppConfigFixture].afterAll() + } +} diff --git a/testkit/src/main/scala/org/bitcoins/testkit/rpc/BitcoindFixtures.scala b/testkit/src/main/scala/org/bitcoins/testkit/rpc/BitcoindFixtures.scala index 2205f8711a..7e8b965bdc 100644 --- a/testkit/src/main/scala/org/bitcoins/testkit/rpc/BitcoindFixtures.scala +++ b/testkit/src/main/scala/org/bitcoins/testkit/rpc/BitcoindFixtures.scala @@ -189,6 +189,27 @@ trait BitcoindFixturesFundedCachedV21 } } +trait BitcoindFixturesFundedCachedNewest + extends BitcoinSAsyncFixtureTest + with BitcoindFixturesFundedCached + with CachedBitcoindNewest { + override type FixtureParam = BitcoindRpcClient + + override def withFixture(test: OneArgAsyncTest): FutureOutcome = { + val f: Future[Outcome] = for { + bitcoind <- cachedBitcoindWithFundsF + futOutcome = withNewestFundedBitcoindCached(test, bitcoind) + fut <- futOutcome.toFuture + } yield fut + new FutureOutcome(f) + } + + override def afterAll(): Unit = { + super[CachedBitcoindNewest].afterAll() + super[BitcoinSAsyncFixtureTest].afterAll() + } +} + /** Bitcoind fixtures with two cached bitcoind that are connected via p2p */ trait BitcoindFixturesCachedPair[T <: BitcoindRpcClient] extends BitcoindFixturesCached