Remove usage of atomics

It turns out that running atomic.Read(...) in a tight loop breaks
Golang. The goroutine would never yield control over the scheduler,
so we ended up getting into a situation where the test would get
stuck forever. This moves to a different model, in which
there is a condition var, instead of atomics in loops.
This commit is contained in:
Sargun Dhillon
2019-08-13 08:43:20 -07:00
parent 75a399f6f4
commit fbed4ca702
3 changed files with 72 additions and 38 deletions

View File

@@ -16,7 +16,6 @@ package node
import (
"context"
"sync/atomic"
"testing"
pkgerrors "github.com/pkg/errors"
@@ -153,8 +152,8 @@ func TestPodCreateNewPod(t *testing.T) {
assert.Check(t, is.Nil(err))
// createOrUpdate called CreatePod but did not call UpdatePod because the pod did not exist
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.creates), uint64(1)))
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.updates), uint64(0)))
assert.Check(t, is.Equal(svr.mock.creates.read(), 1))
assert.Check(t, is.Equal(svr.mock.updates.read(), 0))
}
func TestPodUpdateExisting(t *testing.T) {
@@ -180,8 +179,8 @@ func TestPodUpdateExisting(t *testing.T) {
err := svr.provider.CreatePod(context.Background(), pod)
assert.Check(t, is.Nil(err))
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.creates), uint64(1)))
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.updates), uint64(0)))
assert.Check(t, is.Equal(svr.mock.creates.read(), 1))
assert.Check(t, is.Equal(svr.mock.updates.read(), 0))
pod2 := &corev1.Pod{}
pod2.ObjectMeta.Namespace = "default"
@@ -205,8 +204,8 @@ func TestPodUpdateExisting(t *testing.T) {
assert.Check(t, is.Nil(err))
// createOrUpdate didn't call CreatePod but did call UpdatePod because the spec changed
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.creates), uint64(1)))
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.updates), uint64(1)))
assert.Check(t, is.Equal(svr.mock.creates.read(), 1))
assert.Check(t, is.Equal(svr.mock.updates.read(), 1))
}
func TestPodNoSpecChange(t *testing.T) {
@@ -232,15 +231,15 @@ func TestPodNoSpecChange(t *testing.T) {
err := svr.mock.CreatePod(context.Background(), pod)
assert.Check(t, is.Nil(err))
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.creates), uint64(1)))
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.updates), uint64(0)))
assert.Check(t, is.Equal(svr.mock.creates.read(), 1))
assert.Check(t, is.Equal(svr.mock.updates.read(), 0))
err = svr.createOrUpdatePod(context.Background(), pod)
assert.Check(t, is.Nil(err))
// createOrUpdate didn't call CreatePod or UpdatePod, spec didn't change
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.creates), uint64(1)))
assert.Check(t, is.Equal(atomic.LoadUint64(&svr.mock.updates), uint64(0)))
assert.Check(t, is.Equal(svr.mock.creates.read(), 1))
assert.Check(t, is.Equal(svr.mock.updates.read(), 0))
}
func TestPodDelete(t *testing.T) {
@@ -280,7 +279,7 @@ func TestPodDelete(t *testing.T) {
ctx := context.Background()
err = c.createOrUpdatePod(ctx, p) // make sure it's actually created
assert.NilError(t, err)
assert.Check(t, is.Equal(atomic.LoadUint64(&c.mock.creates), uint64(1)))
assert.Check(t, is.Equal(c.mock.creates.read(), 1))
err = c.deletePod(ctx, pod.Namespace, pod.Name)
assert.Equal(t, pkgerrors.Cause(err), err)
@@ -289,7 +288,7 @@ func TestPodDelete(t *testing.T) {
if tc.delErr == nil {
expectDeletes = 1
}
assert.Check(t, is.Equal(atomic.LoadUint64(&c.mock.deletes), uint64(expectDeletes)))
assert.Check(t, is.Equal(c.mock.deletes.read(), expectDeletes))
expectDeleted := tc.delErr == nil || errdefs.IsNotFound(tc.delErr)