lab.nexedi.com/kirr/go123@v0.0.0-20240207185015-8299741fa871/xsync/xsync_test.go (about) 1 // Copyright (C) 2019-2020 Nexedi SA and Contributors. 2 // Kirill Smelkov <kirr@nexedi.com> 3 // 4 // This program is free software: you can Use, Study, Modify and Redistribute 5 // it under the terms of the GNU General Public License version 3, or (at your 6 // option) any later version, as published by the Free Software Foundation. 7 // 8 // You can also Link and Combine this program with other software covered by 9 // the terms of any of the Free Software licenses or any of the Open Source 10 // Initiative approved licenses and Convey the resulting work. Corresponding 11 // source of such a combination shall include the source code for all other 12 // software used. 13 // 14 // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 // 17 // See COPYING file for full licensing terms. 18 // See https://www.nexedi.com/licensing for rationale and options. 19 20 package xsync 21 22 import ( 23 "context" 24 "fmt" 25 "reflect" 26 "testing" 27 ) 28 29 func TestWorkGroup(t *testing.T) { 30 ctx, cancel := context.WithCancel(context.Background()) 31 _ = cancel 32 33 var l []int // l[i] is data state for i'th worker 34 var wg *WorkGroup 35 // xwait waits for wg to complete, and asserts on returned error and state of l 36 xwait := func(eok string, lok ...int) { 37 t.Helper() 38 err := wg.Wait() 39 if eok == "" { 40 if err != nil { 41 t.Fatalf("xwait: failed: %q", err) 42 } 43 } else { 44 estr := "" 45 if err != nil { 46 estr = err.Error() 47 } 48 if estr != eok { 49 t.Fatalf("xwait: unexpected errror:\nhave: %q\nwant: %q", estr, eok) 50 } 51 } 52 if !reflect.DeepEqual(l, lok) { 53 t.Fatalf("xwait: unexpected l:\nhave: %v\nwant: %v", l, lok) 54 } 55 } 56 57 // t1=ok, t2=ok 58 wg = NewWorkGroup(ctx) 59 l = []int{0, 0} 60 for i := 0; i < 2; i++ { 61 i := i 62 wg.Go(func(ctx context.Context) error { 63 l[i] = i+1 64 return nil 65 }) 66 } 67 xwait("", 1, 2) 68 69 // t1=fail, t2=ok, does not look at ctx 70 wg = NewWorkGroup(ctx) 71 l = []int{0, 0} 72 for i := 0; i < 2; i++ { 73 i := i 74 wg.Go(func(ctx context.Context) error { 75 l[i] = i+1 76 if i == 0 { 77 return fmt.Errorf("aaa") 78 } 79 return nil 80 }) 81 } 82 xwait("aaa", 1, 2) 83 84 // t1=fail, t2=wait cancel, fail 85 wg = NewWorkGroup(ctx) 86 l = []int{0, 0} 87 for i := 0; i < 2; i++ { 88 i := i 89 wg.Go(func(ctx context.Context) error { 90 l[i] = i+1 91 if i == 0 { 92 return fmt.Errorf("bbb") 93 } 94 if i == 1 { 95 <-ctx.Done() 96 return fmt.Errorf("ccc") 97 } 98 panic("unreachable") 99 }) 100 } 101 xwait("bbb", 1, 2) 102 103 // t1=ok,wait cancel t2=ok,wait cancel 104 // cancel parent 105 wg = NewWorkGroup(ctx) 106 l = []int{0, 0} 107 for i := 0; i < 2; i++ { 108 i := i 109 wg.Go(func(ctx context.Context) error { 110 l[i] = i+1 111 <-ctx.Done() 112 return nil 113 }) 114 } 115 cancel() // parent cancel - must be propagated into workgroup 116 xwait("", 1, 2) 117 }