github.com/codysnider/go-ethereum@v1.10.18-0.20220420071915-14f4ae99222a/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 "fmt" 23 "reflect" 24 "testing" 25 "time" 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 if got != want { 56 t.Fatalf("wrong int %d, want %d", got, want) 57 } 58 case err := <-sub.Err(): 59 if err != errInts { 60 t.Fatalf("wrong error: got %q, want %q", err, errInts) 61 } 62 if want != 2 { 63 t.Fatalf("got errInts at int %d, should be received at 2", want) 64 } 65 break loop 66 } 67 } 68 sub.Unsubscribe() 69 70 err, ok := <-sub.Err() 71 if err != nil { 72 t.Fatal("got non-nil error after Unsubscribe") 73 } 74 if ok { 75 t.Fatal("channel still open after Unsubscribe") 76 } 77 } 78 79 func TestResubscribe(t *testing.T) { 80 t.Parallel() 81 82 var i int 83 nfails := 6 84 sub := Resubscribe(100*time.Millisecond, func(ctx context.Context) (Subscription, error) { 85 // fmt.Printf("call #%d @ %v\n", i, time.Now()) 86 i++ 87 if i == 2 { 88 // Delay the second failure a bit to reset the resubscribe interval. 89 time.Sleep(200 * time.Millisecond) 90 } 91 if i < nfails { 92 return nil, errors.New("oops") 93 } 94 sub := NewSubscription(func(unsubscribed <-chan struct{}) error { return nil }) 95 return sub, nil 96 }) 97 98 <-sub.Err() 99 if i != nfails { 100 t.Fatalf("resubscribe function called %d times, want %d times", i, nfails) 101 } 102 } 103 104 func TestResubscribeAbort(t *testing.T) { 105 t.Parallel() 106 107 done := make(chan error, 1) 108 sub := Resubscribe(0, func(ctx context.Context) (Subscription, error) { 109 select { 110 case <-ctx.Done(): 111 done <- nil 112 case <-time.After(2 * time.Second): 113 done <- errors.New("context given to resubscribe function not canceled within 2s") 114 } 115 return nil, nil 116 }) 117 118 sub.Unsubscribe() 119 if err := <-done; err != nil { 120 t.Fatal(err) 121 } 122 } 123 124 func TestResubscribeWithErrorHandler(t *testing.T) { 125 t.Parallel() 126 127 var i int 128 nfails := 6 129 subErrs := make([]string, 0) 130 sub := ResubscribeErr(100*time.Millisecond, func(ctx context.Context, lastErr error) (Subscription, error) { 131 i++ 132 var lastErrVal string 133 if lastErr != nil { 134 lastErrVal = lastErr.Error() 135 } 136 subErrs = append(subErrs, lastErrVal) 137 sub := NewSubscription(func(unsubscribed <-chan struct{}) error { 138 if i < nfails { 139 return fmt.Errorf("err-%v", i) 140 } else { 141 return nil 142 } 143 }) 144 return sub, nil 145 }) 146 147 <-sub.Err() 148 if i != nfails { 149 t.Fatalf("resubscribe function called %d times, want %d times", i, nfails) 150 } 151 152 expectedSubErrs := []string{"", "err-1", "err-2", "err-3", "err-4", "err-5"} 153 if !reflect.DeepEqual(subErrs, expectedSubErrs) { 154 t.Fatalf("unexpected subscription errors %v, want %v", subErrs, expectedSubErrs) 155 } 156 }