github.com/prysmaticlabs/prysm@v1.4.4/shared/event/subscription_test.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package event 18 19 import ( 20 "context" 21 "errors" 22 "testing" 23 "time" 24 25 "github.com/prysmaticlabs/prysm/shared/testutil/require" 26 ) 27 28 var errInts = errors.New("error in subscribeInts") 29 30 func subscribeInts(max, fail int, c chan<- int) Subscription { 31 return NewSubscription(func(quit <-chan struct{}) error { 32 for i := 0; i < max; i++ { 33 if i >= fail { 34 return errInts 35 } 36 select { 37 case c <- i: 38 case <-quit: 39 return nil 40 } 41 } 42 return nil 43 }) 44 } 45 46 func TestNewSubscriptionError(t *testing.T) { 47 t.Parallel() 48 49 channel := make(chan int) 50 sub := subscribeInts(10, 2, channel) 51 loop: 52 for want := 0; want < 10; want++ { 53 select { 54 case got := <-channel: 55 require.Equal(t, want, got) 56 case err := <-sub.Err(): 57 require.Equal(t, errInts, err) 58 require.Equal(t, 2, want) 59 break loop 60 } 61 } 62 sub.Unsubscribe() 63 64 err, ok := <-sub.Err() 65 require.NoError(t, err) 66 if ok { 67 t.Fatal("channel still open after Unsubscribe") 68 } 69 } 70 71 func TestResubscribe(t *testing.T) { 72 t.Parallel() 73 74 var i int 75 nfails := 6 76 sub := Resubscribe(100*time.Millisecond, func(ctx context.Context) (Subscription, error) { 77 // fmt.Printf("call #%d @ %v\n", i, time.Now()) 78 i++ 79 if i == 2 { 80 // Delay the second failure a bit to reset the resubscribe interval. 81 time.Sleep(200 * time.Millisecond) 82 } 83 if i < nfails { 84 return nil, errors.New("oops") 85 } 86 sub := NewSubscription(func(unsubscribed <-chan struct{}) error { return nil }) 87 return sub, nil 88 }) 89 90 <-sub.Err() 91 require.Equal(t, nfails, i) 92 } 93 94 func TestResubscribeAbort(t *testing.T) { 95 t.Parallel() 96 97 done := make(chan error) 98 sub := Resubscribe(0, func(ctx context.Context) (Subscription, error) { 99 select { 100 case <-ctx.Done(): 101 done <- nil 102 case <-time.After(2 * time.Second): 103 done <- errors.New("context given to resubscribe function not canceled within 2s") 104 } 105 return nil, nil 106 }) 107 108 sub.Unsubscribe() 109 require.NoError(t, <-done) 110 }