@@ -3,6 +3,7 @@ package com
33import (
44 "context"
55 "github.com/stretchr/testify/require"
6+ "golang.org/x/sync/errgroup"
67 "io"
78 "testing"
89 "time"
@@ -50,6 +51,71 @@ func TestWaitAsync(t *testing.T) {
5051 }
5152}
5253
54+ func TestErrgroupReceive (t * testing.T ) {
55+ subtests := []struct {
56+ name string
57+ input []error
58+ error bool
59+ }{
60+ {"nothing" , nil , false },
61+ {"nil" , []error {nil }, false },
62+ {"non-nil" , []error {io .EOF }, true },
63+ }
64+
65+ latencies := []struct {
66+ name string
67+ latency time.Duration
68+ }{
69+ {"instantly" , 0 },
70+ {"1us" , time .Microsecond },
71+ {"20ms" , 20 * time .Millisecond },
72+ }
73+
74+ for _ , st := range subtests {
75+ t .Run (st .name , func (t * testing.T ) {
76+ for _ , l := range latencies {
77+ t .Run (l .name , func (t * testing.T ) {
78+ ctx , cancel := context .WithCancel (context .Background ())
79+ defer cancel ()
80+
81+ gCtx , gCancel := context .WithCancel (context .Background ())
82+ gCancel ()
83+
84+ g , _ := errgroup .WithContext (gCtx )
85+
86+ errs := make (chan error )
87+ go func () {
88+ defer close (errs )
89+
90+ for _ , e := range st .input {
91+ if l .latency > 0 {
92+ select {
93+ case <- time .After (l .latency ):
94+ case <- ctx .Done ():
95+ return
96+ }
97+ }
98+
99+ select {
100+ case errs <- e :
101+ case <- ctx .Done ():
102+ return
103+ }
104+ }
105+ }()
106+
107+ ErrgroupReceive (g , errs )
108+ if err := g .Wait (); st .error {
109+ require .Error (t , err )
110+ } else {
111+ require .NoError (t , err )
112+ }
113+ })
114+ }
115+ })
116+ }
117+ }
118+
53119func TestCopyFirst (t * testing.T ) {
54120 subtests := []struct {
55121 name string
0 commit comments