Fix flaky tests for the parallel mutator (#1426)

## Changes
Around 0.5% to 1% of the time, the tests would fail due to concurrent
access to the underlying slice in the mutator. This PR makes the test
thread safe preventing race conditions.

Example of failed run:
https://github.com/databricks/cli/actions/runs/9004657555/job/24738145829
This commit is contained in:
shreyas-goenka 2024-05-13 17:46:43 +05:30 committed by GitHub
parent 649016d50d
commit 95bbe2ece1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 18 additions and 9 deletions

View File

@ -2,6 +2,7 @@ package bundle
import ( import (
"context" "context"
"sync"
"testing" "testing"
"github.com/databricks/cli/bundle/config" "github.com/databricks/cli/bundle/config"
@ -10,9 +11,14 @@ import (
) )
type addToContainer struct { type addToContainer struct {
t *testing.T
container *[]int container *[]int
value int value int
err bool err bool
// mu is a mutex that protects container. It is used to ensure that the
// container slice is only modified by one goroutine at a time.
mu *sync.Mutex
} }
func (m *addToContainer) Apply(ctx context.Context, b ReadOnlyBundle) diag.Diagnostics { func (m *addToContainer) Apply(ctx context.Context, b ReadOnlyBundle) diag.Diagnostics {
@ -20,9 +26,10 @@ func (m *addToContainer) Apply(ctx context.Context, b ReadOnlyBundle) diag.Diagn
return diag.Errorf("error") return diag.Errorf("error")
} }
c := *m.container m.mu.Lock()
c = append(c, m.value) *m.container = append(*m.container, m.value)
*m.container = c m.mu.Unlock()
return nil return nil
} }
@ -36,9 +43,10 @@ func TestParallelMutatorWork(t *testing.T) {
} }
container := []int{} container := []int{}
m1 := &addToContainer{container: &container, value: 1} var mu sync.Mutex
m2 := &addToContainer{container: &container, value: 2} m1 := &addToContainer{t: t, container: &container, value: 1, mu: &mu}
m3 := &addToContainer{container: &container, value: 3} m2 := &addToContainer{t: t, container: &container, value: 2, mu: &mu}
m3 := &addToContainer{t: t, container: &container, value: 3, mu: &mu}
m := Parallel(m1, m2, m3) m := Parallel(m1, m2, m3)
@ -57,9 +65,10 @@ func TestParallelMutatorWorkWithErrors(t *testing.T) {
} }
container := []int{} container := []int{}
m1 := &addToContainer{container: &container, value: 1} var mu sync.Mutex
m2 := &addToContainer{container: &container, err: true, value: 2} m1 := &addToContainer{container: &container, value: 1, mu: &mu}
m3 := &addToContainer{container: &container, value: 3} m2 := &addToContainer{container: &container, err: true, value: 2, mu: &mu}
m3 := &addToContainer{container: &container, value: 3, mu: &mu}
m := Parallel(m1, m2, m3) m := Parallel(m1, m2, m3)