github.com/avence12/go-ethereum@v1.5.10-0.20170320123548-1dfd65f6d047/event/subscription_test.go (about) 1 // Copyright 2017 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 "errors" 21 "testing" 22 "time" 23 24 "golang.org/x/net/context" 25 ) 26 27 var errInts = errors.New("error in subscribeInts") 28 29 func subscribeInts(max, fail int, c chan<- int) Subscription { 30 return NewSubscription(func(quit <-chan struct{}) error { 31 for i := 0; i < max; i++ { 32 if i >= fail { 33 return errInts 34 } 35 select { 36 case c <- i: 37 case <-quit: 38 return nil 39 } 40 } 41 return nil 42 }) 43 } 44 45 func TestNewSubscriptionError(t *testing.T) { 46 t.Parallel() 47 48 channel := make(chan int) 49 sub := subscribeInts(10, 2, channel) 50 loop: 51 for want := 0; want < 10; want++ { 52 select { 53 case got := <-channel: 54 if got != want { 55 t.Fatalf("wrong int %d, want %d", got, want) 56 } 57 case err := <-sub.Err(): 58 if err != errInts { 59 t.Fatalf("wrong error: got %q, want %q", err, errInts) 60 } 61 if want != 2 { 62 t.Fatalf("got errInts at int %d, should be received at 2", want) 63 } 64 break loop 65 } 66 } 67 sub.Unsubscribe() 68 69 err, ok := <-sub.Err() 70 if err != nil { 71 t.Fatal("got non-nil error after Unsubscribe") 72 } 73 if ok { 74 t.Fatal("channel still open after Unsubscribe") 75 } 76 } 77 78 func TestResubscribe(t *testing.T) { 79 t.Parallel() 80 81 var i int 82 nfails := 6 83 sub := Resubscribe(100*time.Millisecond, func(ctx context.Context) (Subscription, error) { 84 // fmt.Printf("call #%d @ %v\n", i, time.Now()) 85 i++ 86 if i == 2 { 87 // Delay the second failure a bit to reset the resubscribe interval. 88 time.Sleep(200 * time.Millisecond) 89 } 90 if i < nfails { 91 return nil, errors.New("oops") 92 } 93 sub := NewSubscription(func(unsubscribed <-chan struct{}) error { return nil }) 94 return sub, nil 95 }) 96 97 <-sub.Err() 98 if i != nfails { 99 t.Fatalf("resubscribe function called %d times, want %d times", i, nfails) 100 } 101 } 102 103 func TestResubscribeAbort(t *testing.T) { 104 t.Parallel() 105 106 done := make(chan error) 107 sub := Resubscribe(0, func(ctx context.Context) (Subscription, error) { 108 select { 109 case <-ctx.Done(): 110 done <- nil 111 case <-time.After(2 * time.Second): 112 done <- errors.New("context given to resubscribe function not canceled within 2s") 113 } 114 return nil, nil 115 }) 116 117 sub.Unsubscribe() 118 if err := <-done; err != nil { 119 t.Fatal(err) 120 } 121 }