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