@@ -10,6 +10,7 @@ import (
1010
1111 "github.com/lightninglabs/aperture/l402"
1212 "github.com/lightninglabs/loop/swapserverrpc"
13+ "github.com/lightningnetwork/lnd/lntypes"
1314 "github.com/stretchr/testify/require"
1415 "google.golang.org/grpc"
1516 "google.golang.org/grpc/metadata"
@@ -111,7 +112,9 @@ func TestManager_ReservationNotification(t *testing.T) {
111112 Client : mockClient ,
112113 CurrentToken : func () (* l402.Token , error ) {
113114 // Simulate successful fetching of L402
114- return nil , nil
115+ return & l402.Token {
116+ Preimage : lntypes.Preimage {1 , 2 , 3 },
117+ }, nil
115118 },
116119 })
117120
@@ -208,7 +211,10 @@ func TestManager_Backoff(t *testing.T) {
208211 mgr := NewManager (& Config {
209212 Client : mockClient ,
210213 CurrentToken : func () (* l402.Token , error ) {
211- return & l402.Token {}, nil
214+ // Simulate successful fetching of L402
215+ return & l402.Token {
216+ Preimage : lntypes.Preimage {1 , 2 , 3 },
217+ }, nil
212218 },
213219 })
214220
@@ -233,7 +239,7 @@ func TestManager_Backoff(t *testing.T) {
233239 // - Attempt #3: ~3 seconds after that etc.
234240 time .Sleep (5 * time .Second )
235241
236- // Cancel the contedt to stop the manager.
242+ // Cancel the context to stop the manager.
237243 cancel ()
238244 wg .Wait ()
239245
@@ -297,7 +303,10 @@ func TestManager_MinAliveConnTime(t *testing.T) {
297303 Client : mockClient ,
298304 MinAliveConnTime : minAlive ,
299305 CurrentToken : func () (* l402.Token , error ) {
300- return & l402.Token {}, nil
306+ // Simulate successful fetching of L402
307+ return & l402.Token {
308+ Preimage : lntypes.Preimage {1 , 2 , 3 },
309+ }, nil
301310 },
302311 })
303312
@@ -345,3 +354,76 @@ func TestManager_MinAliveConnTime(t *testing.T) {
345354 "Second attempt should occur ~2s after the first" ,
346355 )
347356}
357+
358+ func TestManager_Backoff_Pending_Token (t * testing.T ) {
359+ t .Parallel ()
360+
361+ // We'll tolerate a bit of jitter in the timing checks.
362+ const tolerance = 300 * time .Millisecond
363+
364+ recvChan := make (chan * swapserverrpc.SubscribeNotificationsResponse )
365+ recvErrChan := make (chan error )
366+
367+ mockStream := & mockSubscribeNotificationsClient {
368+ recvChan : recvChan ,
369+ recvErrChan : recvErrChan ,
370+ }
371+
372+ // Create a new mock client that will fail to subscribe.
373+ mockClient := & mockNotificationsClient {
374+ mockStream : mockStream ,
375+ // subscribeErr stays nil => would succeed on each call.
376+ }
377+
378+ var tokenCalls []time.Time
379+ // Manager with a successful CurrentToken so that it always tries
380+ // to subscribe.
381+ mgr := NewManager (& Config {
382+ Client : mockClient ,
383+ CurrentToken : func () (* l402.Token , error ) {
384+ tokenCalls = append (tokenCalls , time .Now ())
385+ if len (tokenCalls ) < 3 {
386+ // Simulate a pending token.
387+ return & l402.Token {}, nil
388+ }
389+
390+ // Simulate successful fetching of L402
391+ return & l402.Token {
392+ Preimage : lntypes.Preimage {1 , 2 , 3 },
393+ }, nil
394+ },
395+ })
396+
397+ // Run the manager in a background goroutine.
398+ ctx , cancel := context .WithCancel (context .Background ())
399+ defer cancel ()
400+
401+ var wg sync.WaitGroup
402+ wg .Add (1 )
403+ go func () {
404+ defer wg .Done ()
405+ // We ignore the returned error because the Manager returns
406+ // nil on context cancel.
407+ _ = mgr .Run (ctx )
408+ }()
409+
410+ // Wait long enough to see at least 3 token calls, so we can see that
411+ // we'll indeed backoff when the token is pending.
412+ time .Sleep (5 * time .Second )
413+
414+ // Signal EOF so the subscription stops.
415+ close (recvChan )
416+
417+ // Cancel the context to stop the manager.
418+ cancel ()
419+ wg .Wait ()
420+
421+ // Expect exactly 3 token calls.
422+ require .Equal (t , 3 , len (tokenCalls ))
423+
424+ require .InDeltaf (
425+ t , 3 * time .Second , tokenCalls [2 ].Sub (tokenCalls [0 ]),
426+ float64 (tolerance ),
427+ "Expected to backoff for at ~3 seconds due to pending token" ,
428+ )
429+ }
0 commit comments