diff --git a/pkg/proxy/ipvs/graceful_termination.go b/pkg/proxy/ipvs/graceful_termination.go index 26e3c0f02a8..5cc92db57c0 100644 --- a/pkg/proxy/ipvs/graceful_termination.go +++ b/pkg/proxy/ipvs/graceful_termination.go @@ -80,6 +80,14 @@ func (q *graceTerminateRSList) remove(rs *listItem) bool { return false } +// return the size of the list +func (q *graceTerminateRSList) len() int { + q.lock.Lock() + defer q.lock.Unlock() + + return len(q.list) +} + func (q *graceTerminateRSList) flushList(handler func(rsToDelete *listItem) (bool, error)) bool { q.lock.Lock() defer q.lock.Unlock() diff --git a/pkg/proxy/ipvs/graceful_termination_test.go b/pkg/proxy/ipvs/graceful_termination_test.go index 4a3431e22fb..c41e1ad1f07 100644 --- a/pkg/proxy/ipvs/graceful_termination_test.go +++ b/pkg/proxy/ipvs/graceful_termination_test.go @@ -18,10 +18,11 @@ package ipvs import ( "fmt" - netutils "k8s.io/utils/net" "reflect" "testing" + netutils "k8s.io/utils/net" + utilipvs "k8s.io/kubernetes/pkg/util/ipvs" utilipvstest "k8s.io/kubernetes/pkg/util/ipvs/testing" ) @@ -403,18 +404,28 @@ func Test_GracefulDeleteRS(t *testing.T) { } func Test_RaceTerminateRSList(t *testing.T) { - ipvs := &utilipvstest.FakeIPVS{} + ipvs := utilipvstest.NewFake() gracefulTerminationManager := NewGracefulTerminationManager(ipvs) + // run in parallel to cause the race go func() { for i := 1; i <= 10; i++ { - for j := 1; i <= 100; j++ { - gracefulTerminationManager.rsList.add(makeListItem(i, j)) + for j := 1; j <= 100; j++ { + item := makeListItem(i, j) + gracefulTerminationManager.rsList.add(item) } } }() - if !gracefulTerminationManager.rsList.flushList(gracefulTerminationManager.deleteRsFunc) { + // wait until the list has some elements + for gracefulTerminationManager.rsList.len() < 20 { + } + + // fake the handler to avoid the check against the IPVS virtual servers + fakeHandler := func(rsToDelete *listItem) (bool, error) { + return true, nil + } + if !gracefulTerminationManager.rsList.flushList(fakeHandler) { t.Error("failed to flush entries") } }