Skip to content

Commit 7962f54

Browse files
committed
looprpc: add test for ListSwaps pagination and filtering
1 parent 8b758d1 commit 7962f54

File tree

1 file changed

+274
-0
lines changed

1 file changed

+274
-0
lines changed

loopd/swapclient_server_test.go

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@ import (
44
"context"
55
"os"
66
"testing"
7+
"time"
78

89
"github.com/btcsuite/btcd/btcutil"
910
"github.com/btcsuite/btcd/chaincfg"
1011
"github.com/btcsuite/btclog/v2"
1112
"github.com/lightninglabs/lndclient"
1213
"github.com/lightninglabs/loop"
1314
"github.com/lightninglabs/loop/labels"
15+
"github.com/lightninglabs/loop/loopdb"
1416
"github.com/lightninglabs/loop/looprpc"
17+
"github.com/lightninglabs/loop/swap"
1518
mock_lnd "github.com/lightninglabs/loop/test"
19+
"github.com/lightningnetwork/lnd/lntypes"
1620
"github.com/lightningnetwork/lnd/lnwire"
1721
"github.com/lightningnetwork/lnd/routing/route"
1822
"github.com/stretchr/testify/require"
@@ -595,3 +599,273 @@ func TestHasBandwidth(t *testing.T) {
595599
})
596600
}
597601
}
602+
603+
// TestListSwapsFilterAndPagination tests the filtering and
604+
// paging of the ListSwaps command.
605+
func TestListSwapsFilterAndPagination(t *testing.T) {
606+
// Create a set of test swaps of various types which contain the minimal
607+
// viable amount of info to successfully be run through marshallSwap.
608+
swapInOrder0 := loop.SwapInfo{
609+
SwapStateData: loopdb.SwapStateData{
610+
State: loopdb.StateInitiated,
611+
Cost: loopdb.SwapCost{},
612+
},
613+
SwapContract: loopdb.SwapContract{
614+
InitiationTime: time.Now().Add(time.Duration(0)),
615+
},
616+
LastUpdate: time.Now(),
617+
SwapHash: lntypes.Hash{1},
618+
SwapType: swap.Type(swap.TypeIn),
619+
HtlcAddressP2WSH: testnetAddr,
620+
HtlcAddressP2TR: testnetAddr,
621+
}
622+
623+
swapOutOrder1 := loop.SwapInfo{
624+
SwapStateData: loopdb.SwapStateData{
625+
State: loopdb.StateInitiated,
626+
Cost: loopdb.SwapCost{},
627+
},
628+
SwapContract: loopdb.SwapContract{
629+
InitiationTime: time.Now().Add(time.Duration(50)),
630+
},
631+
LastUpdate: time.Now(),
632+
SwapHash: lntypes.Hash{2},
633+
SwapType: swap.Type(swap.TypeOut),
634+
HtlcAddressP2WSH: testnetAddr,
635+
HtlcAddressP2TR: testnetAddr,
636+
}
637+
638+
swapOutOrder2 := loop.SwapInfo{
639+
SwapStateData: loopdb.SwapStateData{
640+
State: loopdb.StateInitiated,
641+
Cost: loopdb.SwapCost{},
642+
},
643+
SwapContract: loopdb.SwapContract{
644+
InitiationTime: time.Now().Add(time.Duration(100)),
645+
},
646+
LastUpdate: time.Now(),
647+
SwapHash: lntypes.Hash{3},
648+
SwapType: swap.Type(swap.TypeOut),
649+
HtlcAddressP2WSH: testnetAddr,
650+
HtlcAddressP2TR: testnetAddr,
651+
}
652+
653+
mockSwaps := []loop.SwapInfo{swapInOrder0, swapOutOrder1, swapOutOrder2}
654+
655+
tests := []struct {
656+
name string
657+
// Define the mock swaps that will be stored in the mock client.
658+
mockSwaps []loop.SwapInfo
659+
req *looprpc.ListSwapsRequest
660+
expectedReturnedSwaps []lntypes.Hash
661+
expectedFirstIdx uint64
662+
expectedLastIdx uint64
663+
expectedFilteredTotalCount uint64
664+
}{
665+
{
666+
name: "fetch all swaps no pagination",
667+
mockSwaps: mockSwaps,
668+
req: &looprpc.ListSwapsRequest{},
669+
expectedReturnedSwaps: []lntypes.Hash{
670+
swapOutOrder2.SwapHash,
671+
swapOutOrder1.SwapHash,
672+
swapInOrder0.SwapHash,
673+
},
674+
expectedFirstIdx: 0,
675+
expectedLastIdx: 2,
676+
expectedFilteredTotalCount: 3,
677+
},
678+
{
679+
name: "fetch all swaps no pagination alt-order1",
680+
mockSwaps: []loop.SwapInfo{swapOutOrder1, swapInOrder0, swapOutOrder2},
681+
req: &looprpc.ListSwapsRequest{},
682+
expectedReturnedSwaps: []lntypes.Hash{
683+
swapOutOrder2.SwapHash,
684+
swapOutOrder1.SwapHash,
685+
swapInOrder0.SwapHash,
686+
},
687+
expectedFirstIdx: 0,
688+
expectedLastIdx: 2,
689+
expectedFilteredTotalCount: 3,
690+
},
691+
{
692+
name: "fetch all swaps no pagination alt-order2",
693+
mockSwaps: []loop.SwapInfo{swapOutOrder2, swapOutOrder1, swapInOrder0},
694+
req: &looprpc.ListSwapsRequest{},
695+
expectedReturnedSwaps: []lntypes.Hash{
696+
swapOutOrder2.SwapHash,
697+
swapOutOrder1.SwapHash,
698+
swapInOrder0.SwapHash,
699+
},
700+
expectedFirstIdx: 0,
701+
expectedLastIdx: 2,
702+
expectedFilteredTotalCount: 3,
703+
},
704+
{
705+
name: "fetch swaps-ins no pagination",
706+
mockSwaps: mockSwaps,
707+
req: &looprpc.ListSwapsRequest{
708+
ListSwapFilter: &looprpc.ListSwapsFilter{
709+
SwapType: looprpc.ListSwapsFilter_LOOP_IN},
710+
},
711+
expectedReturnedSwaps: []lntypes.Hash{
712+
swapInOrder0.SwapHash,
713+
},
714+
expectedFirstIdx: 0,
715+
expectedLastIdx: 0,
716+
expectedFilteredTotalCount: 1,
717+
},
718+
{
719+
name: "fetch swaps-outs no pagination",
720+
mockSwaps: mockSwaps,
721+
req: &looprpc.ListSwapsRequest{
722+
ListSwapFilter: &looprpc.ListSwapsFilter{
723+
SwapType: looprpc.ListSwapsFilter_LOOP_OUT,
724+
},
725+
},
726+
expectedReturnedSwaps: []lntypes.Hash{
727+
swapOutOrder2.SwapHash,
728+
swapOutOrder1.SwapHash,
729+
},
730+
expectedFirstIdx: 0,
731+
expectedLastIdx: 1,
732+
expectedFilteredTotalCount: 2,
733+
},
734+
{
735+
name: "fetch swaps-outs increment start_index",
736+
mockSwaps: mockSwaps,
737+
req: &looprpc.ListSwapsRequest{
738+
ListSwapFilter: &looprpc.ListSwapsFilter{
739+
SwapType: looprpc.ListSwapsFilter_LOOP_OUT,
740+
},
741+
IndexOffset: 1,
742+
},
743+
expectedReturnedSwaps: []lntypes.Hash{
744+
swapOutOrder1.SwapHash,
745+
},
746+
expectedFirstIdx: 1,
747+
expectedLastIdx: 1,
748+
expectedFilteredTotalCount: 2,
749+
},
750+
{
751+
name: "fetch all swaps set swap limit",
752+
mockSwaps: mockSwaps,
753+
req: &looprpc.ListSwapsRequest{
754+
MaxSwaps: 2,
755+
},
756+
expectedReturnedSwaps: []lntypes.Hash{
757+
swapOutOrder2.SwapHash,
758+
swapOutOrder1.SwapHash,
759+
},
760+
expectedFirstIdx: 0,
761+
expectedLastIdx: 1,
762+
expectedFilteredTotalCount: 3,
763+
},
764+
{
765+
name: "fetch all swaps set swap limit set start index",
766+
mockSwaps: mockSwaps,
767+
req: &looprpc.ListSwapsRequest{
768+
IndexOffset: 1,
769+
MaxSwaps: 1,
770+
},
771+
expectedReturnedSwaps: []lntypes.Hash{
772+
swapOutOrder1.SwapHash,
773+
},
774+
expectedFirstIdx: 1,
775+
expectedLastIdx: 1,
776+
expectedFilteredTotalCount: 3,
777+
},
778+
{
779+
name: "fetch all swaps set start index out of bounds",
780+
mockSwaps: mockSwaps,
781+
req: &looprpc.ListSwapsRequest{
782+
IndexOffset: 5,
783+
},
784+
expectedReturnedSwaps: []lntypes.Hash{},
785+
expectedFirstIdx: 5,
786+
expectedLastIdx: 0,
787+
expectedFilteredTotalCount: 3,
788+
},
789+
{
790+
name: "fetch all swaps set limit to 0",
791+
mockSwaps: mockSwaps,
792+
req: &looprpc.ListSwapsRequest{
793+
MaxSwaps: 0,
794+
},
795+
expectedReturnedSwaps: []lntypes.Hash{
796+
swapOutOrder2.SwapHash,
797+
swapOutOrder1.SwapHash,
798+
swapInOrder0.SwapHash,
799+
},
800+
expectedLastIdx: 2,
801+
expectedFilteredTotalCount: 3,
802+
},
803+
}
804+
805+
for _, test := range tests {
806+
t.Run(test.name, func(t *testing.T) {
807+
t.Parallel()
808+
809+
// Create the swap client server with our mock client.
810+
server := &swapClientServer{
811+
swaps: make(map[lntypes.Hash]loop.SwapInfo),
812+
}
813+
814+
// Populate the server's swap cache with our mock swaps.
815+
for _, swap := range test.mockSwaps {
816+
server.swaps[swap.SwapHash] = swap
817+
}
818+
819+
// Call the ListSwaps method.
820+
resp, err := server.ListSwaps(context.Background(), test.req)
821+
require.NoError(t, err)
822+
823+
require.Len(
824+
t,
825+
resp.Swaps,
826+
len(test.expectedReturnedSwaps),
827+
"incorrect returned count",
828+
)
829+
830+
require.Equal(
831+
t,
832+
test.expectedFirstIdx,
833+
resp.FirstIndexOffset,
834+
"incorrect first index",
835+
)
836+
837+
require.Equal(
838+
t,
839+
test.expectedLastIdx,
840+
resp.LastIndexOffset,
841+
"incorrect last index",
842+
)
843+
844+
require.Equal(
845+
t,
846+
test.expectedFilteredTotalCount,
847+
resp.TotalFilteredSwaps,
848+
"incorrect total",
849+
)
850+
851+
// Subtest function to check consistent iteration order.
852+
swapOrderCheck := func(
853+
hashes []lntypes.Hash,
854+
swaps *looprpc.ListSwapsResponse) {
855+
for idx, aswap := range swaps.Swaps {
856+
newhash, err := lntypes.MakeHash(aswap.GetIdBytes())
857+
require.NoError(t, err)
858+
require.Equal(
859+
t,
860+
hashes[idx],
861+
newhash,
862+
"iteration order mismatch",
863+
)
864+
865+
}
866+
867+
}
868+
swapOrderCheck(test.expectedReturnedSwaps, resp)
869+
})
870+
}
871+
}

0 commit comments

Comments
 (0)