Define a proper base class for fixture tests#2286
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2286 +/- ##
==========================================
- Coverage 84.40% 84.36% -0.04%
==========================================
Files 194 194
Lines 14411 14419 +8
Branches 567 581 +14
==========================================
+ Hits 12163 12164 +1
- Misses 2248 2255 +7
|
t-bast
left a comment
There was a problem hiding this comment.
I like the direction in which we're going with that change, and I'm happy to merge that PR and start using these new fixtures for new code, but before migrating old code or removing ChannelStateTestHelperMethods we should really integrate dual-funding which touches those a lot, otherwise we'll make a complex set of PRs even more complex to integrate!
| override def makeFundingTx(pubkeyScript: ByteVector, amount: Satoshi, feeRatePerKw: FeeratePerKw)(implicit ec: ExecutionContext): Future[MakeFundingTxResponse] = { | ||
| val tx = DummyOnChainWallet.makeDummyFundingTx(pubkeyScript, amount) | ||
| funded += (tx.fundingTx.txid -> tx.fundingTx) | ||
| Future.successful(tx) |
There was a problem hiding this comment.
I'm making many changes to these test helpers in #2275, if you plan on making more changes here in follow-up PRs we should probably do it after dual-funding to minimize conflicts.
There was a problem hiding this comment.
Gotcha, I don't plan to make more changes so we should be fine. Dealing with the mempool/blockchain is one of the trickiest parts, because they need to be shared among various MinimalNodeFixture. I have explored several approaches and am still not 100% happy.
In particular, there are two ways of confirming channels: MinimalNodeFixture.confirmChannel and MinimalNodeFixture.autoConfirmLocalChannels. I think the latter (based on autopilot) is nicer when you don't need fine-grained control, but the core issue of having access to the actual transaction remains. For example, note that we pass a reference to alice's wallet for bob's autopilot:
Maybe with dual-funding this will be a tad simpler since both sides know the full tx?
The edit: On 2nd thought, maybe better to wait for the akka typed migration before revamping the channel tests. |
| * Created by PM on 11/03/2020. | ||
| */ | ||
| class PeerConnection(keyPair: KeyPair, conf: PeerConnection.Conf, switchboard: ActorRef, router: ActorRef) extends FSMDiagnosticActorLogging[PeerConnection.State, PeerConnection.Data] { | ||
| class PeerConnection(keyPair: KeyPair, conf: PeerConnection.Conf, switchboard: ActorRef, router: ActorRef) extends FSMDiagnosticActorLogging[PeerConnection.State, PeerConnection.Data] with Stash { |
There was a problem hiding this comment.
Another pretty good reason not to use TestActorRef is that it is not compatible with Stash (https://stackoverflow.com/a/18377939).
Stash allows us to nicely handle race conditions between messages, instead of delaying them, which creates other race conditions (which is exactly what happened in my attempted fix 2632be3).
| } | ||
| d.transport ! localInit | ||
| startSingleTimer(INIT_TIMER, InitTimeout, conf.initTimeout) | ||
| unstashAll() // unstash remote init if it already arrived |
There was a problem hiding this comment.
NB: I'm only unstashing right before we are ready to process the remote init.
If we can delay the migration of the channel tests just after we do dual funding, that would be great :) |
Agreed, done in fb2e439. |
The circular dependency to TestKitBaseClass/TestKitBase was really weird, we had: - NormalStateSpec -> TestKitBaseClass -> ChannelStateTestsBase - ChannelStateTestsBase -> ChannelStateTestsHelperMethods - ChannelStateTestsHelperMethods -> TestKitBase
Triple equals allows customizing the equality method, but we never use that. Detailed errors (which is what we were looking for) are provided by mixing in scalatest's `Assertions` and using the regular `assert(x==y)` syntax. The `Assertions` trait is already mixed in by default in all scalatest suites.
pm47
left a comment
There was a problem hiding this comment.
I did some cleanup which shouldn't impact your dual-funding tests.
| bob2blockchain.expectMsgType[WatchFundingDeeplyBuried] | ||
| awaitCond(alice.stateName == NORMAL) | ||
| awaitCond(bob.stateName == NORMAL) | ||
| eventually(assert(alice.stateName == NORMAL)) |
There was a problem hiding this comment.
Before:
assertion failed: timeout 149050696200 nanoseconds expired:
java.lang.AssertionError: assertion failed: timeout 149050696200 nanoseconds expired:
After:
The code passed to eventually never returned normally. Attempted 9 times over 161.3674 milliseconds. Last failure message: NORMAL did not equal CLOSED.
ScalaTestFailureLocation: fr.acinq.eclair.channel.states.ChannelStateTestsHelperMethods at (ChannelStateTestsHelperMethods.scala:245)
Expected :CLOSED.
Actual :The code passed to eventually never returned normally. Attempted 9 times over 161.3674 milliseconds. Last failure message: NORMAL
No comment!
This PR does two main things:
FixtureSpecbase class for tests that involve a fixture. See the scaladoc for more info.The existing testWaitForOpenChannelStateSpechas been migrated as an example. The diff is small but we separate clearly the fixtures from the test framework. There is duplication for now, but the goal is forChannelStateTestsHelperMethodsto disappear.integration.basic. They are based onMinimalNodeFixture, which is a full setup for a node with real actors, except the bitcoin part (watcher/wallet) which is mocked. They are much lighter than our previous integration tests, which allow us to keep each test individual, as opposed to having all tests of the same suite depend on each other. We can define more complex fixtures with any number of nodes.Also updated scalatest version and fixed a few issues.