Fix race in lifecycle admission test
.State.Phase is read and written by multiple goroutines as reported by `godep go test -race` on Go 1.5.1. Adding the mutex around the object fixes the issue.
This commit is contained in:
		@@ -18,6 +18,7 @@ package lifecycle
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/admission"
 | 
						"k8s.io/kubernetes/pkg/admission"
 | 
				
			||||||
@@ -39,6 +40,7 @@ func TestAdmission(t *testing.T) {
 | 
				
			|||||||
			Phase: api.NamespaceActive,
 | 
								Phase: api.NamespaceActive,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						var namespaceLock sync.RWMutex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	store := cache.NewStore(cache.MetaNamespaceKeyFunc)
 | 
						store := cache.NewStore(cache.MetaNamespaceKeyFunc)
 | 
				
			||||||
	store.Add(namespaceObj)
 | 
						store.Add(namespaceObj)
 | 
				
			||||||
@@ -46,12 +48,16 @@ func TestAdmission(t *testing.T) {
 | 
				
			|||||||
	mockClient := &testclient.Fake{}
 | 
						mockClient := &testclient.Fake{}
 | 
				
			||||||
	mockClient.AddWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil))
 | 
						mockClient.AddWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil))
 | 
				
			||||||
	mockClient.AddReactor("get", "namespaces", func(action testclient.Action) (bool, runtime.Object, error) {
 | 
						mockClient.AddReactor("get", "namespaces", func(action testclient.Action) (bool, runtime.Object, error) {
 | 
				
			||||||
 | 
							namespaceLock.RLock()
 | 
				
			||||||
 | 
							defer namespaceLock.RUnlock()
 | 
				
			||||||
		if getAction, ok := action.(testclient.GetAction); ok && getAction.GetName() == namespaceObj.Name {
 | 
							if getAction, ok := action.(testclient.GetAction); ok && getAction.GetName() == namespaceObj.Name {
 | 
				
			||||||
			return true, namespaceObj, nil
 | 
								return true, namespaceObj, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return true, nil, fmt.Errorf("No result for action %v", action)
 | 
							return true, nil, fmt.Errorf("No result for action %v", action)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	mockClient.AddReactor("list", "namespaces", func(action testclient.Action) (bool, runtime.Object, error) {
 | 
						mockClient.AddReactor("list", "namespaces", func(action testclient.Action) (bool, runtime.Object, error) {
 | 
				
			||||||
 | 
							namespaceLock.RLock()
 | 
				
			||||||
 | 
							defer namespaceLock.RUnlock()
 | 
				
			||||||
		return true, &api.NamespaceList{Items: []api.Namespace{*namespaceObj}}, nil
 | 
							return true, &api.NamespaceList{Items: []api.Namespace{*namespaceObj}}, nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -78,7 +84,9 @@ func TestAdmission(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// change namespace state to terminating
 | 
						// change namespace state to terminating
 | 
				
			||||||
 | 
						namespaceLock.Lock()
 | 
				
			||||||
	namespaceObj.Status.Phase = api.NamespaceTerminating
 | 
						namespaceObj.Status.Phase = api.NamespaceTerminating
 | 
				
			||||||
 | 
						namespaceLock.Unlock()
 | 
				
			||||||
	store.Add(namespaceObj)
 | 
						store.Add(namespaceObj)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// verify create operations in the namespace cause an error
 | 
						// verify create operations in the namespace cause an error
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user