Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / sync@v0.0.0-20200625203802-6e8e738ad208 / errgroup / errgroup_test.go
1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package errgroup_test
6
7 import (
8         "context"
9         "errors"
10         "fmt"
11         "net/http"
12         "os"
13         "testing"
14
15         "golang.org/x/sync/errgroup"
16 )
17
18 var (
19         Web   = fakeSearch("web")
20         Image = fakeSearch("image")
21         Video = fakeSearch("video")
22 )
23
24 type Result string
25 type Search func(ctx context.Context, query string) (Result, error)
26
27 func fakeSearch(kind string) Search {
28         return func(_ context.Context, query string) (Result, error) {
29                 return Result(fmt.Sprintf("%s result for %q", kind, query)), nil
30         }
31 }
32
33 // JustErrors illustrates the use of a Group in place of a sync.WaitGroup to
34 // simplify goroutine counting and error handling. This example is derived from
35 // the sync.WaitGroup example at https://golang.org/pkg/sync/#example_WaitGroup.
36 func ExampleGroup_justErrors() {
37         g := new(errgroup.Group)
38         var urls = []string{
39                 "http://www.golang.org/",
40                 "http://www.google.com/",
41                 "http://www.somestupidname.com/",
42         }
43         for _, url := range urls {
44                 // Launch a goroutine to fetch the URL.
45                 url := url // https://golang.org/doc/faq#closures_and_goroutines
46                 g.Go(func() error {
47                         // Fetch the URL.
48                         resp, err := http.Get(url)
49                         if err == nil {
50                                 resp.Body.Close()
51                         }
52                         return err
53                 })
54         }
55         // Wait for all HTTP fetches to complete.
56         if err := g.Wait(); err == nil {
57                 fmt.Println("Successfully fetched all URLs.")
58         }
59 }
60
61 // Parallel illustrates the use of a Group for synchronizing a simple parallel
62 // task: the "Google Search 2.0" function from
63 // https://talks.golang.org/2012/concurrency.slide#46, augmented with a Context
64 // and error-handling.
65 func ExampleGroup_parallel() {
66         Google := func(ctx context.Context, query string) ([]Result, error) {
67                 g, ctx := errgroup.WithContext(ctx)
68
69                 searches := []Search{Web, Image, Video}
70                 results := make([]Result, len(searches))
71                 for i, search := range searches {
72                         i, search := i, search // https://golang.org/doc/faq#closures_and_goroutines
73                         g.Go(func() error {
74                                 result, err := search(ctx, query)
75                                 if err == nil {
76                                         results[i] = result
77                                 }
78                                 return err
79                         })
80                 }
81                 if err := g.Wait(); err != nil {
82                         return nil, err
83                 }
84                 return results, nil
85         }
86
87         results, err := Google(context.Background(), "golang")
88         if err != nil {
89                 fmt.Fprintln(os.Stderr, err)
90                 return
91         }
92         for _, result := range results {
93                 fmt.Println(result)
94         }
95
96         // Output:
97         // web result for "golang"
98         // image result for "golang"
99         // video result for "golang"
100 }
101
102 func TestZeroGroup(t *testing.T) {
103         err1 := errors.New("errgroup_test: 1")
104         err2 := errors.New("errgroup_test: 2")
105
106         cases := []struct {
107                 errs []error
108         }{
109                 {errs: []error{}},
110                 {errs: []error{nil}},
111                 {errs: []error{err1}},
112                 {errs: []error{err1, nil}},
113                 {errs: []error{err1, nil, err2}},
114         }
115
116         for _, tc := range cases {
117                 g := new(errgroup.Group)
118
119                 var firstErr error
120                 for i, err := range tc.errs {
121                         err := err
122                         g.Go(func() error { return err })
123
124                         if firstErr == nil && err != nil {
125                                 firstErr = err
126                         }
127
128                         if gErr := g.Wait(); gErr != firstErr {
129                                 t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+
130                                         "g.Wait() = %v; want %v",
131                                         g, tc.errs[:i+1], err, firstErr)
132                         }
133                 }
134         }
135 }
136
137 func TestWithContext(t *testing.T) {
138         errDoom := errors.New("group_test: doomed")
139
140         cases := []struct {
141                 errs []error
142                 want error
143         }{
144                 {want: nil},
145                 {errs: []error{nil}, want: nil},
146                 {errs: []error{errDoom}, want: errDoom},
147                 {errs: []error{errDoom, nil}, want: errDoom},
148         }
149
150         for _, tc := range cases {
151                 g, ctx := errgroup.WithContext(context.Background())
152
153                 for _, err := range tc.errs {
154                         err := err
155                         g.Go(func() error { return err })
156                 }
157
158                 if err := g.Wait(); err != tc.want {
159                         t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+
160                                 "g.Wait() = %v; want %v",
161                                 g, tc.errs, err, tc.want)
162                 }
163
164                 canceled := false
165                 select {
166                 case <-ctx.Done():
167                         canceled = true
168                 default:
169                 }
170                 if !canceled {
171                         t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+
172                                 "ctx.Done() was not closed",
173                                 g, tc.errs)
174                 }
175         }
176 }