contractcourt: use t.Run in TestHtlcTimeoutResolver

Along the way we refactor the test to eliminate some unnecessary line
length.
This commit is contained in:
Olaoluwa Osuntokun
2024-09-06 18:19:49 -07:00
committed by Oliver Gugger
parent 906fa0b7b8
commit 941590d384

View File

@@ -69,11 +69,31 @@ func (m *mockWitnessBeacon) AddPreimages(preimages ...lntypes.Preimage) error {
return nil return nil
} }
// TestHtlcTimeoutResolver tests that the timeout resolver properly handles all type htlcTimeoutTestCase struct {
// variations of possible local+remote spends. // name is a human readable description of the test case.
func TestHtlcTimeoutResolver(t *testing.T) { name string
t.Parallel()
// remoteCommit denotes if the commitment broadcast was the remote
// commitment or not.
remoteCommit bool
// timeout denotes if the HTLC should be let timeout, or if the "remote"
// party should sweep it on-chain. This also affects what type of
// resolution message we expect.
timeout bool
// txToBroadcast is a function closure that should generate the
// transaction that should spend the HTLC output. Test authors can use
// this to customize the witness used when spending to trigger various
// redemption cases.
txToBroadcast func() (*wire.MsgTx, error)
// outcome is the resolver outcome that we expect to be reported once
// the contract is fully resolved.
outcome channeldb.ResolverOutcome
}
func genHtlcTimeoutTestCases() []htlcTimeoutTestCase {
fakePreimageBytes := bytes.Repeat([]byte{1}, lntypes.HashSize) fakePreimageBytes := bytes.Repeat([]byte{1}, lntypes.HashSize)
var ( var (
@@ -105,29 +125,7 @@ func TestHtlcTimeoutResolver(t *testing.T) {
}, },
} }
testCases := []struct { return []htlcTimeoutTestCase{
// name is a human readable description of the test case.
name string
// remoteCommit denotes if the commitment broadcast was the
// remote commitment or not.
remoteCommit bool
// timeout denotes if the HTLC should be let timeout, or if the
// "remote" party should sweep it on-chain. This also affects
// what type of resolution message we expect.
timeout bool
// txToBroadcast is a function closure that should generate the
// transaction that should spend the HTLC output. Test authors
// can use this to customize the witness used when spending to
// trigger various redemption cases.
txToBroadcast func() (*wire.MsgTx, error)
// outcome is the resolver outcome that we expect to be reported
// once the contract is fully resolved.
outcome channeldb.ResolverOutcome
}{
// Remote commitment is broadcast, we time out the HTLC on // Remote commitment is broadcast, we time out the HTLC on
// chain, and should expect a fail HTLC resolution. // chain, and should expect a fail HTLC resolution.
{ {
@@ -149,7 +147,8 @@ func TestHtlcTimeoutResolver(t *testing.T) {
// immediately if the witness is already set // immediately if the witness is already set
// correctly. // correctly.
if reflect.DeepEqual( if reflect.DeepEqual(
templateTx.TxIn[0].Witness, witness, templateTx.TxIn[0].Witness,
witness,
) { ) {
return templateTx, nil return templateTx, nil
@@ -219,7 +218,8 @@ func TestHtlcTimeoutResolver(t *testing.T) {
// immediately if the witness is already set // immediately if the witness is already set
// correctly. // correctly.
if reflect.DeepEqual( if reflect.DeepEqual(
templateTx.TxIn[0].Witness, witness, templateTx.TxIn[0].Witness,
witness,
) { ) {
return templateTx, nil return templateTx, nil
@@ -253,7 +253,8 @@ func TestHtlcTimeoutResolver(t *testing.T) {
// immediately if the witness is already set // immediately if the witness is already set
// correctly. // correctly.
if reflect.DeepEqual( if reflect.DeepEqual(
templateTx.TxIn[0].Witness, witness, templateTx.TxIn[0].Witness,
witness,
) { ) {
return templateTx, nil return templateTx, nil
@@ -265,17 +266,25 @@ func TestHtlcTimeoutResolver(t *testing.T) {
outcome: channeldb.ResolverOutcomeClaimed, outcome: channeldb.ResolverOutcomeClaimed,
}, },
} }
}
func testHtlcTimeoutResolver(t *testing.T, testCase htlcTimeoutTestCase) {
fakePreimageBytes := bytes.Repeat([]byte{1}, lntypes.HashSize)
var fakePreimage lntypes.Preimage
fakeSignDesc := &input.SignDescriptor{
Output: &wire.TxOut{},
}
copy(fakePreimage[:], fakePreimageBytes)
notifier := &mock.ChainNotifier{ notifier := &mock.ChainNotifier{
EpochChan: make(chan *chainntnfs.BlockEpoch), EpochChan: make(chan *chainntnfs.BlockEpoch),
SpendChan: make(chan *chainntnfs.SpendDetail), SpendChan: make(chan *chainntnfs.SpendDetail),
ConfChan: make(chan *chainntnfs.TxConfirmation), ConfChan: make(chan *chainntnfs.TxConfirmation),
} }
witnessBeacon := newMockWitnessBeacon() witnessBeacon := newMockWitnessBeacon()
for _, testCase := range testCases {
t.Logf("Running test case: %v", testCase.name)
checkPointChan := make(chan struct{}, 1) checkPointChan := make(chan struct{}, 1)
incubateChan := make(chan struct{}, 1) incubateChan := make(chan struct{}, 1)
resolutionChan := make(chan ResolutionMsg, 1) resolutionChan := make(chan ResolutionMsg, 1)
@@ -289,8 +298,8 @@ func TestHtlcTimeoutResolver(t *testing.T) {
IncubateOutputs: func(wire.OutPoint, IncubateOutputs: func(wire.OutPoint,
fn.Option[lnwallet.OutgoingHtlcResolution], fn.Option[lnwallet.OutgoingHtlcResolution],
fn.Option[lnwallet.IncomingHtlcResolution], fn.Option[lnwallet.IncomingHtlcResolution],
uint32, fn.Option[int32]) error { uint32, fn.Option[int32],
) error {
incubateChan <- struct{}{} incubateChan <- struct{}{}
return nil return nil
}, },
@@ -305,13 +314,14 @@ func TestHtlcTimeoutResolver(t *testing.T) {
return nil return nil
}, },
Budget: *DefaultBudgetConfig(), Budget: *DefaultBudgetConfig(),
QueryIncomingCircuit: func(circuit models.CircuitKey) *models.CircuitKey { QueryIncomingCircuit: func(circuit models.CircuitKey,
) *models.CircuitKey {
return nil return nil
}, },
}, },
PutResolverReport: func(_ kvdb.RwTx, PutResolverReport: func(_ kvdb.RwTx,
_ *channeldb.ResolverReport) error { _ *channeldb.ResolverReport,
) error {
return nil return nil
}, },
} }
@@ -319,8 +329,8 @@ func TestHtlcTimeoutResolver(t *testing.T) {
cfg := ResolverConfig{ cfg := ResolverConfig{
ChannelArbitratorConfig: chainCfg, ChannelArbitratorConfig: chainCfg,
Checkpoint: func(_ ContractResolver, Checkpoint: func(_ ContractResolver,
reports ...*channeldb.ResolverReport) error { reports ...*channeldb.ResolverReport,
) error {
checkPointChan <- struct{}{} checkPointChan <- struct{}{}
// Send all of our reports into the channel. // Send all of our reports into the channel.
@@ -381,7 +391,7 @@ func TestHtlcTimeoutResolver(t *testing.T) {
} }
}() }()
// At the output isn't yet in the nursery, we expect that we // As the output isn't yet in the nursery, we expect that we
// should receive an incubation request. // should receive an incubation request.
select { select {
case <-incubateChan: case <-incubateChan:
@@ -503,6 +513,19 @@ func TestHtlcTimeoutResolver(t *testing.T) {
t.Fatalf("resolver should be marked as resolved") t.Fatalf("resolver should be marked as resolved")
} }
} }
// TestHtlcTimeoutResolver tests that the timeout resolver properly handles all
// variations of possible local+remote spends.
func TestHtlcTimeoutResolver(t *testing.T) {
t.Parallel()
testCases := genHtlcTimeoutTestCases()
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
testHtlcTimeoutResolver(t, testCase)
})
}
} }
// NOTE: the following tests essentially checks many of the same scenarios as // NOTE: the following tests essentially checks many of the same scenarios as
@@ -545,6 +568,7 @@ func TestHtlcTimeoutSingleStage(t *testing.T) {
// by the nursery. // by the nursery.
preCheckpoint: func(ctx *htlcResolverTestContext, preCheckpoint: func(ctx *htlcResolverTestContext,
_ bool) error { _ bool) error {
// The nursery will create and publish a sweep // The nursery will create and publish a sweep
// tx. // tx.
ctx.notifier.SpendChan <- &chainntnfs.SpendDetail{ ctx.notifier.SpendChan <- &chainntnfs.SpendDetail{
@@ -653,6 +677,7 @@ func TestHtlcTimeoutSecondStage(t *testing.T) {
// that our sweep succeeded. // that our sweep succeeded.
preCheckpoint: func(ctx *htlcResolverTestContext, preCheckpoint: func(ctx *htlcResolverTestContext,
_ bool) error { _ bool) error {
// The nursery will publish the timeout tx. // The nursery will publish the timeout tx.
ctx.notifier.SpendChan <- &chainntnfs.SpendDetail{ ctx.notifier.SpendChan <- &chainntnfs.SpendDetail{
SpendingTx: timeoutTx, SpendingTx: timeoutTx,
@@ -1296,7 +1321,9 @@ func TestHtlcTimeoutSecondStageSweeperRemoteSpend(t *testing.T) {
} }
func testHtlcTimeout(t *testing.T, resolution lnwallet.OutgoingHtlcResolution, func testHtlcTimeout(t *testing.T, resolution lnwallet.OutgoingHtlcResolution,
checkpoints []checkpoint) { checkpoints []checkpoint,
) {
t.Helper()
defer timeout()() defer timeout()()