github.com/JBoudou/Itero@v0.1.7/pkg/events/mux_test.go (about) 1 // Itero - Online iterative vote application 2 // Copyright (C) 2020 Joseph Boudou 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as 6 // published by the Free Software Foundation, either version 3 of the 7 // License, or (at your option) any later version. 8 // 9 // This program 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 Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <https://www.gnu.org/licenses/>. 16 17 package events 18 19 import ( 20 "sync" 21 "testing" 22 ) 23 24 type muxTestReceiver struct { 25 id int 26 ch chan<- [2]int 27 t *testing.T 28 grp *sync.WaitGroup 29 } 30 31 func (self *muxTestReceiver) Receive(evt Event) { 32 i, ok := evt.(int) 33 if !ok { 34 self.t.Logf("Unknown event %v.", evt) 35 return 36 } 37 self.ch <- [2]int{self.id, i} 38 } 39 40 func (self *muxTestReceiver) Close() { 41 self.grp.Done() 42 } 43 44 type muxTestChecker struct { 45 missing map[[2]int]bool 46 unwanted [][2]int 47 grp *sync.WaitGroup 48 } 49 50 func (self *muxTestChecker) Listen(ch <-chan [2]int) { 51 for result := range ch { 52 if _, found := self.missing[result]; found { 53 delete(self.missing, result) 54 } else { 55 self.unwanted = append(self.unwanted, result) 56 } 57 } 58 self.grp.Done() 59 } 60 61 func TestMux(t *testing.T) { 62 const chanSize = 128 63 64 tests := []struct { 65 name string 66 receivers []int 67 events []int 68 expect [][2]int 69 }{ 70 { 71 name: "No receiver", 72 events: []int{27}, 73 }, 74 { 75 name: "One receiver", 76 receivers: []int{1}, 77 events: []int{2, 3}, 78 expect: [][2]int{{1, 2}, {1, 3}}, 79 }, 80 { 81 name: "Two receiver", 82 receivers: []int{1, 2}, 83 events: []int{2, 3}, 84 expect: [][2]int{{1, 2}, {1, 3}, {2, 2}, {2, 3}}, 85 }, 86 } 87 for _, tt := range tests { 88 t.Run(tt.name, func(t *testing.T) { 89 var grp sync.WaitGroup 90 grp.Add(len(tt.receivers)) 91 92 checker := &muxTestChecker{missing: make(map[[2]int]bool, len(tt.expect)), grp: &grp} 93 for _, result := range tt.expect { 94 checker.missing[result] = true 95 } 96 resultCh := make(chan [2]int, 0) 97 go checker.Listen(resultCh) 98 99 manager := NewAsyncManager(chanSize) 100 for _, id := range tt.receivers { 101 manager.AddReceiver(&muxTestReceiver{id: id, ch: resultCh, t: t, grp: &grp}) 102 } 103 104 for _, event := range tt.events { 105 manager.Send(event) 106 } 107 manager.Close() 108 grp.Wait() 109 grp.Add(1) 110 close(resultCh) 111 grp.Wait() 112 113 for result := range checker.missing { 114 t.Errorf("Missing %v.", result) 115 } 116 for result := range checker.unwanted { 117 t.Errorf("Unexpected %v.", result) 118 } 119 }) 120 } 121 }