Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions internal/pb/pb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2025 The CNAI Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package pb

import (
"io"
"sync"
"testing"
)

func TestSetDisableProgressIsRaceFree(t *testing.T) {
progress := NewProgressBar(io.Discard)
defer progress.Stop()
defer SetDisableProgress(false)

var wg sync.WaitGroup
wg.Add(2)

go func() {
defer wg.Done()
for i := 0; i < 1000; i++ {
SetDisableProgress(i%2 == 0)
}
}()

go func() {
defer wg.Done()
for i := 0; i < 1000; i++ {
progress.Add("copy", "blob", 1, nil)
}
}()
Comment on lines +33 to +45
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current test setup might not be as effective as intended for catching races. The goroutine performing SetDisableProgress will likely complete its 1000 iterations much faster than the goroutine calling progress.Add, as the latter involves significantly more work (locking, map operations, and bar creation). Consequently, for the majority of the Add calls, the disableProgress flag will remain static, reducing the window for detecting a race.

Consider synchronizing the toggling goroutine with the lifecycle of the worker goroutine to ensure the flag is being flipped throughout the entire duration of the test.

	done := make(chan struct{})
	go func() {
		defer wg.Done()
		for {
			select {
			case <-done:
				return
			default:
				SetDisableProgress(true)
				SetDisableProgress(false)
			}
		}
	}()

	go func() {
		defer wg.Done()
		defer close(done)
		for i := 0; i < 1000; i++ {
			progress.Add("copy", "blob", 1, nil)
		}
	}()


wg.Wait()
}
Loading