diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 16:12:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 16:12:43 +0000 |
commit | e28e21a9397e402a78499ceeef63dd19989be29e (patch) | |
tree | f4b7f6aaa6bb1563cac5f10b0bde8b6333ac4e37 /progress_test.go | |
parent | Initial commit. (diff) | |
download | golang-github-vbauerster-mpb-e28e21a9397e402a78499ceeef63dd19989be29e.tar.xz golang-github-vbauerster-mpb-e28e21a9397e402a78499ceeef63dd19989be29e.zip |
Adding upstream version 8.6.1.upstream/8.6.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'progress_test.go')
-rw-r--r-- | progress_test.go | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/progress_test.go b/progress_test.go new file mode 100644 index 0000000..7892062 --- /dev/null +++ b/progress_test.go @@ -0,0 +1,282 @@ +package mpb_test + +import ( + "bytes" + "container/heap" + "context" + "errors" + "io" + "strings" + "testing" + "time" + + "github.com/vbauerster/mpb/v8" + "github.com/vbauerster/mpb/v8/decor" +) + +const ( + timeout = 300 * time.Millisecond +) + +func TestWithContext(t *testing.T) { + shutdown := make(chan interface{}) + ctx, cancel := context.WithCancel(context.Background()) + p := mpb.NewWithContext(ctx, + mpb.WithOutput(io.Discard), + mpb.WithShutdownNotifier(shutdown), + ) + _ = p.AddBar(0) // never complete bar + _ = p.AddBar(0) // never complete bar + go func() { + time.Sleep(10 * time.Millisecond) + cancel() + }() + + p.Wait() + + select { + case v := <-shutdown: + if l := len(v.([]*mpb.Bar)); l != 2 { + t.Errorf("Expected len of bars: %d, got: %d", 2, l) + } + case <-time.After(timeout): + t.Errorf("Progress didn't shutdown after %v", timeout) + } +} + +func TestShutdownsWithErrFiller(t *testing.T) { + var debug bytes.Buffer + shutdown := make(chan interface{}) + p := mpb.New( + mpb.WithShutdownNotifier(shutdown), + mpb.WithOutput(io.Discard), + mpb.WithDebugOutput(&debug), + mpb.WithAutoRefresh(), + ) + + var errReturnCount int + testError := errors.New("test error") + bar := p.AddBar(100, + mpb.BarFillerMiddleware(func(base mpb.BarFiller) mpb.BarFiller { + return mpb.BarFillerFunc(func(w io.Writer, st decor.Statistics) error { + if st.Current >= 22 { + errReturnCount++ + return testError + } + return base.Fill(w, st) + }) + }), + ) + + go func() { + for bar.IsRunning() { + bar.Increment() + time.Sleep(10 * time.Millisecond) + } + }() + + p.Wait() + + if errReturnCount != 1 { + t.Errorf("Expected errReturnCount: %d, got: %d\n", 1, errReturnCount) + } + + select { + case v := <-shutdown: + if l := len(v.([]*mpb.Bar)); l != 0 { + t.Errorf("Expected len of bars: %d, got: %d\n", 0, l) + } + if err := strings.TrimSpace(debug.String()); err != testError.Error() { + t.Errorf("Expected err: %q, got %q\n", testError.Error(), err) + } + case <-time.After(timeout): + t.Errorf("Progress didn't shutdown after %v", timeout) + } +} + +func TestShutdownAfterBarAbortWithDrop(t *testing.T) { + shutdown := make(chan interface{}) + p := mpb.New( + mpb.WithShutdownNotifier(shutdown), + mpb.WithOutput(io.Discard), + mpb.WithAutoRefresh(), + ) + b := p.AddBar(100) + + var count int + for i := 0; !b.Aborted(); i++ { + if i >= 10 { + count++ + b.Abort(true) + } else { + b.Increment() + time.Sleep(10 * time.Millisecond) + } + } + + p.Wait() + + if count != 1 { + t.Errorf("Expected count: %d, got: %d", 1, count) + } + + select { + case v := <-shutdown: + if l := len(v.([]*mpb.Bar)); l != 0 { + t.Errorf("Expected len of bars: %d, got: %d", 0, l) + } + case <-time.After(timeout): + t.Errorf("Progress didn't shutdown after %v", timeout) + } +} + +func TestShutdownAfterBarAbortWithNoDrop(t *testing.T) { + shutdown := make(chan interface{}) + p := mpb.New( + mpb.WithShutdownNotifier(shutdown), + mpb.WithOutput(io.Discard), + mpb.WithAutoRefresh(), + ) + b := p.AddBar(100) + + var count int + for i := 0; !b.Aborted(); i++ { + if i >= 10 { + count++ + b.Abort(false) + } else { + b.Increment() + time.Sleep(10 * time.Millisecond) + } + } + + p.Wait() + + if count != 1 { + t.Errorf("Expected count: %d, got: %d", 1, count) + } + + select { + case v := <-shutdown: + if l := len(v.([]*mpb.Bar)); l != 1 { + t.Errorf("Expected len of bars: %d, got: %d", 1, l) + } + case <-time.After(timeout): + t.Errorf("Progress didn't shutdown after %v", timeout) + } +} + +func TestBarPristinePopOrder(t *testing.T) { + shutdown := make(chan interface{}) + ctx, cancel := context.WithCancel(context.Background()) + p := mpb.NewWithContext(ctx, + mpb.WithOutput(io.Discard), // auto refresh is disabled + mpb.WithShutdownNotifier(shutdown), + ) + a := p.AddBar(100, mpb.BarPriority(1), mpb.BarID(1)) + b := p.AddBar(100, mpb.BarPriority(2), mpb.BarID(2)) + c := p.AddBar(100, mpb.BarPriority(3), mpb.BarID(3)) + pristineOrder := []*mpb.Bar{c, b, a} + + go cancel() + + bars := (<-shutdown).([]*mpb.Bar) + if l := len(bars); l != 3 { + t.Fatalf("Expected len of bars: %d, got: %d", 3, l) + } + + p.Wait() + pq := mpb.PriorityQueue(bars) + + for _, b := range pristineOrder { + // higher priority pops first + if bar := heap.Pop(&pq).(*mpb.Bar); bar.ID() != b.ID() { + t.Errorf("Expected bar id: %d, got bar id: %d", b.ID(), bar.ID()) + } + } +} + +func makeUpdateBarPriorityTest(refresh, lazy bool) func(*testing.T) { + return func(t *testing.T) { + shutdown := make(chan interface{}) + refreshCh := make(chan interface{}) + ctx, cancel := context.WithCancel(context.Background()) + p := mpb.NewWithContext(ctx, + mpb.WithOutput(io.Discard), + mpb.WithManualRefresh(refreshCh), + mpb.WithShutdownNotifier(shutdown), + ) + a := p.AddBar(100, mpb.BarPriority(1), mpb.BarID(1)) + b := p.AddBar(100, mpb.BarPriority(2), mpb.BarID(2)) + c := p.AddBar(100, mpb.BarPriority(3), mpb.BarID(3)) + + p.UpdateBarPriority(c, 2, lazy) + p.UpdateBarPriority(b, 3, lazy) + checkOrder := []*mpb.Bar{b, c, a} // updated order + + if refresh { + refreshCh <- time.Now() + } else if lazy { + checkOrder = []*mpb.Bar{c, b, a} // pristine order + } + + go cancel() + + bars := (<-shutdown).([]*mpb.Bar) + if l := len(bars); l != 3 { + t.Fatalf("Expected len of bars: %d, got: %d", 3, l) + } + + p.Wait() + pq := mpb.PriorityQueue(bars) + + for _, b := range checkOrder { + // higher priority pops first + if bar := heap.Pop(&pq).(*mpb.Bar); bar.ID() != b.ID() { + t.Errorf("Expected bar id: %d, got bar id: %d", b.ID(), bar.ID()) + } + } + } +} + +func TestUpdateBarPriority(t *testing.T) { + makeUpdateBarPriorityTest(false, false)(t) + makeUpdateBarPriorityTest(true, false)(t) +} + +func TestUpdateBarPriorityLazy(t *testing.T) { + makeUpdateBarPriorityTest(false, true)(t) + makeUpdateBarPriorityTest(true, true)(t) +} + +func TestNoOutput(t *testing.T) { + var buf bytes.Buffer + p := mpb.New(mpb.WithOutput(&buf)) + bar := p.AddBar(100) + + go func() { + for !bar.Completed() { + bar.Increment() + } + }() + + p.Wait() + + if buf.Len() != 0 { + t.Errorf("Expected buf.Len == 0, got: %d\n", buf.Len()) + } +} + +func TestAddAfterDone(t *testing.T) { + p := mpb.New(mpb.WithOutput(io.Discard)) + bar := p.AddBar(100) + bar.IncrBy(100) + + p.Wait() + + _, err := p.Add(100, nil) + + if err != mpb.DoneError { + t.Errorf("Expected %q, got: %q\n", mpb.DoneError, err) + } +} |