@@ -146,7 +146,10 @@ func TestTelemetry_Funder_Run(t *testing.T) {
146146 ProgramIDFunc : func () solana.PublicKey { return solana.PublicKey {} },
147147 }
148148
149- var transferAmount uint64
149+ var (
150+ transferAmount uint64
151+ mu sync.Mutex
152+ )
150153
151154 sol := & mockSolana {
152155 GetBalanceFunc : func (ctx context.Context , pubkey solana.PublicKey , _ solanarpc.CommitmentType ) (* solanarpc.GetBalanceResult , error ) {
@@ -175,7 +178,10 @@ func TestTelemetry_Funder_Run(t *testing.T) {
175178 require .Equal (t , devicePK , to )
176179 require .Equal (t , 5 * solana .LAMPORTS_PER_SOL , amount )
177180
181+ mu .Lock ()
178182 transferAmount = amount
183+ mu .Unlock ()
184+
179185 tracker .mark ("transfer" )
180186 cancel ()
181187 return solana.Signature {}, nil
@@ -197,7 +203,11 @@ func TestTelemetry_Funder_Run(t *testing.T) {
197203
198204 tracker .wait (t , 200 * time .Millisecond )
199205
200- require .Equal (t , 5 * solana .LAMPORTS_PER_SOL , transferAmount )
206+ mu .Lock ()
207+ got := transferAmount
208+ mu .Unlock ()
209+
210+ require .Equal (t , 5 * solana .LAMPORTS_PER_SOL , got )
201211 })
202212
203213 t .Run ("no top up when device balance is above min" , func (t * testing.T ) {
@@ -602,6 +612,7 @@ func TestTelemetry_Funder_Run(t *testing.T) {
602612
603613 tracker .wait (t , 200 * time .Millisecond )
604614 })
615+
605616 t .Run ("handles multiple devices with mixed balances" , func (t * testing.T ) {
606617 t .Parallel ()
607618
@@ -639,6 +650,7 @@ func TestTelemetry_Funder_Run(t *testing.T) {
639650 var (
640651 transferTo solana.PublicKey
641652 deviceLowBalanceCalls atomic.Int32
653+ mu sync.Mutex
642654 )
643655
644656 sol := & mockSolana {
@@ -651,7 +663,6 @@ func TestTelemetry_Funder_Run(t *testing.T) {
651663 return & solanarpc.GetBalanceResult {Value : 5 * solana .LAMPORTS_PER_SOL }, nil
652664 case deviceLow :
653665 tracker .mark ("device-low" )
654- // Simulate balance increasing after the first poll in waitForBalance
655666 if deviceLowBalanceCalls .Add (1 ) >= 2 {
656667 return & solanarpc.GetBalanceResult {Value : 5 * solana .LAMPORTS_PER_SOL }, nil
657668 }
@@ -677,7 +688,10 @@ func TestTelemetry_Funder_Run(t *testing.T) {
677688 require .Equal (t , deviceLow , to )
678689 require .Equal (t , 5 * solana .LAMPORTS_PER_SOL , amount )
679690
691+ mu .Lock ()
680692 transferTo = to
693+ mu .Unlock ()
694+
681695 tracker .mark ("transfer" )
682696 return solana.Signature {}, nil
683697 },
@@ -698,7 +712,10 @@ func TestTelemetry_Funder_Run(t *testing.T) {
698712 tracker .wait (t , 500 * time .Millisecond )
699713 cancel ()
700714
701- require .Equal (t , deviceLow , transferTo , "should only transfer to underfunded device" )
715+ mu .Lock ()
716+ got := transferTo
717+ mu .Unlock ()
718+ require .Equal (t , deviceLow , got , "should only transfer to underfunded device" )
702719 })
703720
704721 t .Run ("skips devices with zero MetricsPublisherPubKey" , func (t * testing.T ) {
@@ -781,7 +798,6 @@ func TestTelemetry_Funder_Run(t *testing.T) {
781798 ctx , cancel := context .WithCancel (context .Background ())
782799 defer cancel ()
783800
784- // Make this short so test runs quickly
785801 const waitForBalanceTimeout = 100 * time .Millisecond
786802
787803 svc := & mockServiceability {
@@ -794,9 +810,10 @@ func TestTelemetry_Funder_Run(t *testing.T) {
794810 ProgramIDFunc : func () solana.PublicKey { return solana.PublicKey {} },
795811 }
796812
797- // Track calls to waitForBalance internally
798- var transferCalled atomic.Bool
799- var balanceCheckCount atomic.Int32
813+ var (
814+ transferCalled atomic.Bool
815+ balanceCheckCount atomic.Int32
816+ )
800817
801818 sol := & mockSolana {
802819 GetBalanceFunc : func (ctx context.Context , pubkey solana.PublicKey , _ solanarpc.CommitmentType ) (* solanarpc.GetBalanceResult , error ) {
@@ -806,7 +823,7 @@ func TestTelemetry_Funder_Run(t *testing.T) {
806823 case devicePK :
807824 if transferCalled .Load () {
808825 balanceCheckCount .Add (1 )
809- return & solanarpc.GetBalanceResult {Value : uint64 (0.01 * float64 (solana .LAMPORTS_PER_SOL ))}, nil // never enough
826+ return & solanarpc.GetBalanceResult {Value : uint64 (0.01 * float64 (solana .LAMPORTS_PER_SOL ))}, nil
810827 }
811828 return & solanarpc.GetBalanceResult {Value : uint64 (0.01 * float64 (solana .LAMPORTS_PER_SOL ))}, nil
812829 default :
@@ -844,16 +861,19 @@ func TestTelemetry_Funder_Run(t *testing.T) {
844861 require .NoError (t , err )
845862
846863 errCh := make (chan error , 1 )
847- go func () { errCh <- f .Run (ctx ) }()
864+ var once sync.Once
865+ go func () {
866+ err := f .Run (ctx )
867+ once .Do (func () { errCh <- err })
868+ }()
848869
849870 select {
850- case <- errCh :
851- t .Fatal ("funder unexpectedly exited early" )
871+ case err := <- errCh :
872+ t .Fatalf ("funder unexpectedly exited early: %v" , err )
852873 case <- time .After (waitForBalanceTimeout + 200 * time .Millisecond ):
853874 cancel ()
854875 }
855876
856- // Ensure it checked balance multiple times (wait loop kicked in)
857877 require .GreaterOrEqual (t , balanceCheckCount .Load (), int32 (2 ), "should retry balance during wait" )
858878 })
859879
0 commit comments