summaryrefslogtreecommitdiffstats
path: root/progress_test.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 16:12:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 16:12:43 +0000
commite28e21a9397e402a78499ceeef63dd19989be29e (patch)
treef4b7f6aaa6bb1563cac5f10b0bde8b6333ac4e37 /progress_test.go
parentInitial commit. (diff)
downloadgolang-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.go282
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)
+ }
+}