refactoring progress_test
Vladimir Bauer
3 years ago
| 4 | 4 | "context" |
| 5 | 5 | "errors" |
| 6 | 6 | "io" |
| 7 | "math/rand" | |
| 8 | 7 | "strings" |
| 9 | 8 | "testing" |
| 10 | 9 | "time" |
| 17 | 16 | timeout = 300 * time.Millisecond |
| 18 | 17 | ) |
| 19 | 18 | |
| 20 | func init() { | |
| 21 | rand.Seed(time.Now().UnixNano()) | |
| 22 | } | |
| 23 | ||
| 24 | func TestBarCount(t *testing.T) { | |
| 25 | p := mpb.New(mpb.WithOutput(io.Discard)) | |
| 26 | ||
| 27 | b := p.AddBar(0, mpb.BarRemoveOnComplete()) | |
| 28 | ||
| 29 | if count := p.BarCount(); count != 1 { | |
| 30 | t.Errorf("BarCount want: %d, got: %d\n", 1, count) | |
| 31 | } | |
| 32 | ||
| 33 | b.SetTotal(100, true) | |
| 34 | ||
| 35 | b.Wait() | |
| 36 | ||
| 37 | if count := p.BarCount(); count != 0 { | |
| 38 | t.Errorf("BarCount want: %d, got: %d\n", 0, count) | |
| 39 | } | |
| 19 | func TestWithContext(t *testing.T) { | |
| 20 | shutdown := make(chan interface{}) | |
| 21 | ctx, cancel := context.WithCancel(context.Background()) | |
| 22 | p := mpb.NewWithContext(ctx, | |
| 23 | mpb.WithShutdownNotifier(shutdown), | |
| 24 | ) | |
| 25 | _ = p.AddBar(0) // never complete bar | |
| 26 | _ = p.AddBar(0) // never complete bar | |
| 27 | go func() { | |
| 28 | time.Sleep(10 * time.Millisecond) | |
| 29 | cancel() | |
| 30 | }() | |
| 40 | 31 | |
| 41 | 32 | p.Wait() |
| 42 | } | |
| 43 | ||
| 44 | func TestBarAbort(t *testing.T) { | |
| 45 | shutdown := make(chan struct{}) | |
| 46 | p := mpb.New(mpb.WithShutdownNotifier(shutdown), mpb.WithOutput(io.Discard)) | |
| 47 | n := 2 | |
| 48 | bars := make([]*mpb.Bar, n) | |
| 49 | for i := 0; i < n; i++ { | |
| 50 | b := p.AddBar(100) | |
| 51 | switch i { | |
| 52 | case n - 1: | |
| 53 | var abortCalledTimes int | |
| 54 | for j := 0; !b.Aborted(); j++ { | |
| 55 | if j >= 10 { | |
| 56 | b.Abort(true) | |
| 57 | abortCalledTimes++ | |
| 58 | } else { | |
| 59 | b.Increment() | |
| 60 | } | |
| 61 | } | |
| 62 | if abortCalledTimes != 1 { | |
| 63 | t.Errorf("Expected abortCalledTimes: %d, got: %d\n", 1, abortCalledTimes) | |
| 64 | } | |
| 65 | b.Wait() | |
| 66 | count := p.BarCount() | |
| 67 | if count != 1 { | |
| 68 | t.Errorf("BarCount want: %d, got: %d\n", 1, count) | |
| 69 | } | |
| 70 | default: | |
| 71 | go func() { | |
| 72 | for !b.Completed() { | |
| 73 | b.Increment() | |
| 74 | time.Sleep(randomDuration(100 * time.Millisecond)) | |
| 75 | } | |
| 76 | }() | |
| 77 | } | |
| 78 | bars[i] = b | |
| 79 | } | |
| 80 | ||
| 81 | go p.Wait() | |
| 82 | ||
| 83 | bars[0].Abort(false) | |
| 84 | 33 | |
| 85 | 34 | select { |
| 86 | case <-shutdown: | |
| 35 | case v := <-shutdown: | |
| 36 | if l := len(v.([]*mpb.Bar)); l != 2 { | |
| 37 | t.Errorf("Expected len of bars: %d, got: %d", 2, l) | |
| 38 | } | |
| 87 | 39 | case <-time.After(timeout): |
| 88 | 40 | t.Errorf("Progress didn't shutdown after %v", timeout) |
| 89 | 41 | } |
| 90 | 42 | } |
| 91 | 43 | |
| 92 | func TestWithContext(t *testing.T) { | |
| 93 | shutdown := make(chan struct{}) | |
| 94 | ctx, cancel := context.WithCancel(context.Background()) | |
| 95 | p := mpb.NewWithContext(ctx, | |
| 96 | mpb.WithShutdownNotifier(shutdown), | |
| 97 | mpb.WithOutput(io.Discard), | |
| 98 | ) | |
| 99 | _ = p.AddBar(0) // never complete bar | |
| 100 | _ = p.AddBar(0) // never complete bar | |
| 101 | go func() { | |
| 102 | time.Sleep(randomDuration(100 * time.Millisecond)) | |
| 103 | cancel() | |
| 104 | p.Wait() | |
| 105 | }() | |
| 106 | ||
| 107 | select { | |
| 108 | case <-shutdown: | |
| 109 | case <-time.After(timeout): | |
| 110 | t.Errorf("Progress didn't shutdown after %v", timeout) | |
| 111 | } | |
| 112 | } | |
| 113 | ||
| 114 | func TestProgressShutdownsWithErrFiller(t *testing.T) { | |
| 44 | func TestShutdownsWithErrFiller(t *testing.T) { | |
| 115 | 45 | var debug bytes.Buffer |
| 116 | shutdown := make(chan struct{}) | |
| 46 | shutdown := make(chan interface{}) | |
| 117 | 47 | p := mpb.New( |
| 118 | 48 | mpb.WithShutdownNotifier(shutdown), |
| 119 | 49 | mpb.WithOutput(io.Discard), |
| 120 | 50 | mpb.WithDebugOutput(&debug), |
| 51 | mpb.ForceAutoRefresh(), | |
| 121 | 52 | ) |
| 122 | 53 | |
| 54 | var errReturnCount int | |
| 123 | 55 | testError := errors.New("test error") |
| 124 | 56 | bar := p.AddBar(100, |
| 125 | 57 | mpb.BarFillerMiddleware(func(base mpb.BarFiller) mpb.BarFiller { |
| 126 | 58 | return mpb.BarFillerFunc(func(w io.Writer, st decor.Statistics) error { |
| 127 | if st.Current >= 42 { | |
| 59 | if st.Current >= 22 { | |
| 60 | errReturnCount++ | |
| 128 | 61 | return testError |
| 129 | 62 | } |
| 130 | 63 | return base.Fill(w, st) |
| 135 | 68 | go func() { |
| 136 | 69 | for bar.IsRunning() { |
| 137 | 70 | bar.Increment() |
| 71 | time.Sleep(10 * time.Millisecond) | |
| 138 | 72 | } |
| 139 | 73 | }() |
| 140 | 74 | |
| 75 | p.Wait() | |
| 76 | ||
| 77 | if errReturnCount != 1 { | |
| 78 | t.Errorf("Expected errReturnCount: %d, got: %d\n", 1, errReturnCount) | |
| 79 | } | |
| 80 | ||
| 141 | 81 | select { |
| 142 | case <-shutdown: | |
| 82 | case v := <-shutdown: | |
| 83 | if l := len(v.([]*mpb.Bar)); l != 0 { | |
| 84 | t.Errorf("Expected len of bars: %d, got: %d\n", 0, l) | |
| 85 | } | |
| 143 | 86 | if err := strings.TrimSpace(debug.String()); err != testError.Error() { |
| 144 | 87 | t.Errorf("Expected err: %q, got %q\n", testError.Error(), err) |
| 145 | 88 | } |
| 146 | 89 | case <-time.After(timeout): |
| 147 | 90 | t.Errorf("Progress didn't shutdown after %v", timeout) |
| 148 | 91 | } |
| 149 | p.Wait() | |
| 150 | 92 | } |
| 151 | 93 | |
| 152 | func randomDuration(max time.Duration) time.Duration { | |
| 153 | return time.Duration(rand.Intn(10)+1) * max / 10 | |
| 94 | func TestShutdownAfterBarAbortWithDrop(t *testing.T) { | |
| 95 | shutdown := make(chan interface{}) | |
| 96 | p := mpb.New( | |
| 97 | mpb.WithShutdownNotifier(shutdown), | |
| 98 | mpb.WithOutput(io.Discard), | |
| 99 | mpb.ForceAutoRefresh(), | |
| 100 | ) | |
| 101 | b := p.AddBar(100) | |
| 102 | ||
| 103 | var count int | |
| 104 | for i := 0; !b.Aborted(); i++ { | |
| 105 | if i >= 10 { | |
| 106 | count++ | |
| 107 | b.Abort(true) | |
| 108 | } else { | |
| 109 | b.Increment() | |
| 110 | time.Sleep(10 * time.Millisecond) | |
| 111 | } | |
| 112 | } | |
| 113 | ||
| 114 | p.Wait() | |
| 115 | ||
| 116 | if count != 1 { | |
| 117 | t.Errorf("Expected count: %d, got: %d", 1, count) | |
| 118 | } | |
| 119 | ||
| 120 | select { | |
| 121 | case v := <-shutdown: | |
| 122 | if l := len(v.([]*mpb.Bar)); l != 0 { | |
| 123 | t.Errorf("Expected len of bars: %d, got: %d", 0, l) | |
| 124 | } | |
| 125 | case <-time.After(timeout): | |
| 126 | t.Errorf("Progress didn't shutdown after %v", timeout) | |
| 127 | } | |
| 154 | 128 | } |
| 129 | ||
| 130 | func TestShutdownAfterBarAbortWithNoDrop(t *testing.T) { | |
| 131 | shutdown := make(chan interface{}) | |
| 132 | p := mpb.New( | |
| 133 | mpb.WithShutdownNotifier(shutdown), | |
| 134 | mpb.WithOutput(io.Discard), | |
| 135 | mpb.ForceAutoRefresh(), | |
| 136 | ) | |
| 137 | b := p.AddBar(100) | |
| 138 | ||
| 139 | var count int | |
| 140 | for i := 0; !b.Aborted(); i++ { | |
| 141 | if i >= 10 { | |
| 142 | count++ | |
| 143 | b.Abort(false) | |
| 144 | } else { | |
| 145 | b.Increment() | |
| 146 | time.Sleep(10 * time.Millisecond) | |
| 147 | } | |
| 148 | } | |
| 149 | ||
| 150 | p.Wait() | |
| 151 | ||
| 152 | if count != 1 { | |
| 153 | t.Errorf("Expected count: %d, got: %d", 1, count) | |
| 154 | } | |
| 155 | ||
| 156 | select { | |
| 157 | case v := <-shutdown: | |
| 158 | if l := len(v.([]*mpb.Bar)); l != 1 { | |
| 159 | t.Errorf("Expected len of bars: %d, got: %d", 1, l) | |
| 160 | } | |
| 161 | case <-time.After(timeout): | |
| 162 | t.Errorf("Progress didn't shutdown after %v", timeout) | |
| 163 | } | |
| 164 | } | |