package utils import ( "errors" "fmt" "testing" ) func TestErrGroup(t *testing.T) { testCases := []struct { errs []error exp string }{ {nil, ""}, {[]error{errors.New("timeout")}, "errors(1): timeout"}, { []error{errors.New("timeout"), errors.New("deadline")}, "errors(2): timeout\ndeadline", }, } for _, tc := range testCases { eg := new(ErrGroup) for _, err := range tc.errs { eg.Add(err) } if len(tc.errs) == 0 { if eg.Err() != nil { t.Fatalf("expected to get nil error") } continue } if eg.Err() == nil { t.Fatalf("expected to get non-nil error") } if eg.Error() != tc.exp { t.Fatalf("expected to have: \n%q\ngot:\n%q", tc.exp, eg.Error()) } } } // TestErrGroupConcurrent supposed to test concurrent // use of error group. // Should be executed with -race flag func TestErrGroupConcurrent(_ *testing.T) { eg := new(ErrGroup) const writersN = 4 payload := make(chan error, writersN) for i := 0; i < writersN; i++ { go func() { for err := range payload { eg.Add(err) } }() } const iterations = 500 for i := 0; i < iterations; i++ { payload <- fmt.Errorf("error %d", i) if i%10 == 0 { _ = eg.Err() } } close(payload) }