// TestDependentsRace relies on golang's data race detector to check if there is // data race among in the dependents field. func TestDependentsRace(t *testing.T) { clientPool := dynamic.NewClientPool(&restclient.Config{}, dynamic.LegacyAPIPathResolverFunc) podResource := []unversioned.GroupVersionResource{{Version: "v1", Resource: "pods"}} gc, err := NewGarbageCollector(clientPool, podResource) if err != nil { t.Fatal(err) } const updates = 100 owner := &node{dependentsLock: &sync.RWMutex{}, dependents: make(map[*node]struct{})} ownerUID := types.UID("owner") gc.propagator.uidToNode.Write(owner) go func() { for i := 0; i < updates; i++ { dependent := &node{} gc.propagator.addDependentToOwners(dependent, []metatypes.OwnerReference{{UID: ownerUID}}) gc.propagator.removeDependentFromOwners(dependent, []metatypes.OwnerReference{{UID: ownerUID}}) } }() go func() { gc.orphanQueue.Add(owner) for i := 0; i < updates; i++ { gc.orphanFinalizer() } }() }
func TestNewGarbageCollector(t *testing.T) { clientPool := dynamic.NewClientPool(&restclient.Config{}, dynamic.LegacyAPIPathResolverFunc) podResource := []unversioned.GroupVersionResource{{Version: "v1", Resource: "pods"}} gc, err := NewGarbageCollector(clientPool, podResource) if err != nil { t.Fatal(err) } assert.Equal(t, 1, len(gc.monitors)) }
// test the processItem function making the expected actions. func TestProcessItem(t *testing.T) { pod := newDanglingPod() podBytes, err := json.Marshal(pod) if err != nil { t.Fatal(err) } testHandler := &fakeActionHandler{ response: map[string]FakeResponse{ "GET" + "/api/v1/namespaces/ns1/replicationcontrollers/owner1": { 404, []byte{}, }, "GET" + "/api/v1/namespaces/ns1/pods/ToBeDeletedPod": { 200, podBytes, }, }, } podResource := []unversioned.GroupVersionResource{{Version: "v1", Resource: "pods"}} srv, clientConfig := testServerAndClientConfig(testHandler.ServeHTTP) defer srv.Close() clientPool := dynamic.NewClientPool(clientConfig, dynamic.LegacyAPIPathResolverFunc) gc, err := NewGarbageCollector(clientPool, podResource) if err != nil { t.Fatal(err) } item := &node{ identity: objectReference{ OwnerReference: metatypes.OwnerReference{ Kind: pod.Kind, APIVersion: pod.APIVersion, Name: pod.Name, UID: pod.UID, }, Namespace: pod.Namespace, }, // owners are intentionally left empty. The processItem routine should get the latest item from the server. owners: nil, } err = gc.processItem(item) if err != nil { t.Errorf("Unexpected Error: %v", err) } expectedActionSet := sets.NewString() expectedActionSet.Insert("GET=/api/v1/namespaces/ns1/replicationcontrollers/owner1") expectedActionSet.Insert("DELETE=/api/v1/namespaces/ns1/pods/ToBeDeletedPod") expectedActionSet.Insert("GET=/api/v1/namespaces/ns1/pods/ToBeDeletedPod") actualActionSet := sets.NewString() for _, action := range testHandler.actions { actualActionSet.Insert(action.String()) } if !expectedActionSet.Equal(actualActionSet) { t.Errorf("expected actions:\n%v\n but got:\n%v\nDifference:\n%v", expectedActionSet, actualActionSet, expectedActionSet.Difference(actualActionSet)) } }
// test the list and watch functions correctly converts the ListOptions func TestGCListWatcher(t *testing.T) { testHandler := &fakeActionHandler{} srv, clientConfig := testServerAndClientConfig(testHandler.ServeHTTP) defer srv.Close() clientPool := dynamic.NewClientPool(clientConfig, dynamic.LegacyAPIPathResolverFunc) podResource := unversioned.GroupVersionResource{Version: "v1", Resource: "pods"} client, err := clientPool.ClientForGroupVersion(podResource.GroupVersion()) if err != nil { t.Fatal(err) } lw := gcListWatcher(client, podResource) lw.Watch(api.ListOptions{ResourceVersion: "1"}) lw.List(api.ListOptions{ResourceVersion: "1"}) if e, a := 2, len(testHandler.actions); e != a { t.Errorf("expect %d requests, got %d", e, a) } if e, a := "resourceVersion=1", testHandler.actions[0].query; e != a { t.Errorf("expect %s, got %s", e, a) } if e, a := "resourceVersion=1", testHandler.actions[1].query; e != a { t.Errorf("expect %s, got %s", e, a) } }