open-match.dev/open-match@v1.8.1/examples/demo/bytesub/bytesub_test.go (about) 1 // Copyright 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package bytesub provides the ability for many clients to subscribe to the 16 // latest value of a byte array. 17 package bytesub 18 19 import ( 20 "context" 21 "errors" 22 "testing" 23 ) 24 25 // TestFastAndSlow ensures that if a slow subscriber is blocked, faster subscribers 26 // nor publishers aren't blocked. It also ensures that values published while slow 27 // wasn't listening are skipped. 28 func TestFastAndSlow(t *testing.T) { 29 ctx, cancel := context.WithCancel(context.Background()) 30 fast := make(chan string) 31 slow := make(chan string) 32 33 s := New() 34 35 go func() { 36 s.Subscribe(ctx, chanWriter{fast}) 37 close(fast) 38 }() 39 go func() { 40 s.Subscribe(ctx, chanWriter{slow}) 41 close(slow) 42 }() 43 44 for _, i := range []string{"0", "1", "2", "3"} { 45 s.AnnounceLatest([]byte(i)) 46 if v := <-fast; v != i { 47 t.Errorf("Expected \"%s\", got \"%s\"", i, v) 48 } 49 } 50 51 for count := 0; true; count++ { 52 if v := <-slow; v == "3" { 53 if count > 1 { 54 t.Error("Expected to receive at most 1 other value on slow before receiving the latest value.") 55 } 56 break 57 } 58 } 59 60 cancel() 61 _, ok := <-fast 62 if ok { 63 t.Error("Expected subscribe to return and fast to be closed") 64 } 65 _, ok = <-slow 66 if ok { 67 t.Error("Expected subscribe to return and slow to be closed") 68 } 69 } 70 71 func TestBadWriter(t *testing.T) { 72 ctx, cancel := context.WithCancel(context.Background()) 73 defer cancel() 74 75 s := New() 76 s.AnnounceLatest([]byte{0, 1, 2}) 77 err := s.Subscribe(ctx, writerFunc(func(b []byte) (int, error) { 78 return 1, nil 79 })) 80 81 if err != partialWriteError { 82 t.Errorf("Expected partialWriteError, got %s", err) 83 } 84 } 85 86 func TestErrorReturned(t *testing.T) { 87 ctx, cancel := context.WithCancel(context.Background()) 88 defer cancel() 89 90 expected := errors.New("Hello there.") 91 92 s := New() 93 s.AnnounceLatest([]byte{0, 1, 2}) 94 err := s.Subscribe(ctx, writerFunc(func(b []byte) (int, error) { 95 return 0, expected 96 })) 97 98 if err != expected { 99 t.Errorf("Expected returned error, got %s", err) 100 } 101 } 102 103 func TestContextError(t *testing.T) { 104 ctx, cancel := context.WithCancel(context.Background()) 105 cancel() 106 107 s := New() 108 s.AnnounceLatest([]byte{0, 1, 2}) 109 err := s.Subscribe(ctx, writerFunc(func(b []byte) (int, error) { 110 return len(b), nil 111 })) 112 113 if err != context.Canceled { 114 t.Errorf("Expected context canceled error, got %s", err) 115 } 116 } 117 118 type chanWriter struct { 119 c chan string 120 } 121 122 func (cw chanWriter) Write(b []byte) (int, error) { 123 cw.c <- string(b) 124 return len(b), nil 125 } 126 127 type writerFunc func(b []byte) (int, error) 128 129 func (w writerFunc) Write(b []byte) (int, error) { 130 return w(b) 131 }