// Test public interface func doTestIndex(t *testing.T, indexer Indexer) { mkObj := func(id string, val string) testStoreObject { return testStoreObject{id: id, val: val} } // Test Index expected := map[string]sets.String{} expected["b"] = sets.NewString("a", "c") expected["f"] = sets.NewString("e") expected["h"] = sets.NewString("g") indexer.Add(mkObj("a", "b")) indexer.Add(mkObj("c", "b")) indexer.Add(mkObj("e", "f")) indexer.Add(mkObj("g", "h")) { for k, v := range expected { found := sets.String{} indexResults, err := indexer.Index("by_val", mkObj("", k)) if err != nil { t.Errorf("Unexpected error %v", err) } for _, item := range indexResults { found.Insert(item.(testStoreObject).id) } items := v.List() if !found.HasAll(items...) { t.Errorf("missing items, index %s, expected %v but found %v", k, items, found.List()) } } } }
func filterInvalidPods(pods []*api.Pod, source string, recorder record.EventRecorder) (filtered []*api.Pod) { names := sets.String{} for i, pod := range pods { var errlist field.ErrorList if errs := validation.ValidatePod(pod); len(errs) != 0 { errlist = append(errlist, errs...) // If validation fails, don't trust it any further - // even Name could be bad. } else { name := kubecontainer.GetPodFullName(pod) if names.Has(name) { // TODO: when validation becomes versioned, this gets a bit // more complicated. errlist = append(errlist, field.Duplicate(field.NewPath("metadata", "name"), pod.Name)) } else { names.Insert(name) } } if len(errlist) > 0 { name := bestPodIdentString(pod) err := errlist.ToAggregate() glog.Warningf("Pod[%d] (%s) from %s failed validation, ignoring: %v", i+1, name, source, err) recorder.Eventf(pod, api.EventTypeWarning, kubecontainer.FailedValidation, "Error validating pod %s from %s, ignoring: %v", name, source, err) continue } filtered = append(filtered, pod) } return }
// Index returns a list of items that match on the index function // Index is thread-safe so long as you treat all items as immutable func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, error) { c.lock.RLock() defer c.lock.RUnlock() indexFunc := c.indexers[indexName] if indexFunc == nil { return nil, fmt.Errorf("Index with name %s does not exist", indexName) } indexKeys, err := indexFunc(obj) if err != nil { return nil, err } index := c.indices[indexName] // need to de-dupe the return list. Since multiple keys are allowed, this can happen. returnKeySet := sets.String{} for _, indexKey := range indexKeys { set := index[indexKey] for _, key := range set.List() { returnKeySet.Insert(key) } } list := make([]interface{}, 0, returnKeySet.Len()) for absoluteKey := range returnKeySet { list = append(list, c.items[absoluteKey]) } return list, nil }
func (e *EndpointController) getPodServiceMemberships(pod *api.Pod) (sets.String, error) { set := sets.String{} services, err := e.serviceStore.GetPodServices(pod) if err != nil { // don't log this error because this function makes pointless // errors when no services match. return set, nil } for i := range services { key, err := keyFunc(&services[i]) if err != nil { return nil, err } set.Insert(key) } return set, nil }
// Test public interface func doTestStore(t *testing.T, store Store) { mkObj := func(id string, val string) testStoreObject { return testStoreObject{id: id, val: val} } store.Add(mkObj("foo", "bar")) if item, ok, _ := store.Get(mkObj("foo", "")); !ok { t.Errorf("didn't find inserted item") } else { if e, a := "bar", item.(testStoreObject).val; e != a { t.Errorf("expected %v, got %v", e, a) } } store.Update(mkObj("foo", "baz")) if item, ok, _ := store.Get(mkObj("foo", "")); !ok { t.Errorf("didn't find inserted item") } else { if e, a := "baz", item.(testStoreObject).val; e != a { t.Errorf("expected %v, got %v", e, a) } } store.Delete(mkObj("foo", "")) if _, ok, _ := store.Get(mkObj("foo", "")); ok { t.Errorf("found deleted item??") } // Test List. store.Add(mkObj("a", "b")) store.Add(mkObj("c", "d")) store.Add(mkObj("e", "e")) { found := sets.String{} for _, item := range store.List() { found.Insert(item.(testStoreObject).val) } if !found.HasAll("b", "d", "e") { t.Errorf("missing items, found: %v", found) } if len(found) != 3 { t.Errorf("extra items") } } // Test Replace. store.Replace([]interface{}{ mkObj("foo", "foo"), mkObj("bar", "bar"), }, "0") { found := sets.String{} for _, item := range store.List() { found.Insert(item.(testStoreObject).val) } if !found.HasAll("foo", "bar") { t.Errorf("missing items") } if len(found) != 2 { t.Errorf("extra items") } } }
func TestWatchCacheBasic(t *testing.T) { store := newTestWatchCache(2) // Test Add/Update/Delete. pod1 := makeTestPod("pod", 1) if err := store.Add(pod1); err != nil { t.Errorf("unexpected error: %v", err) } if item, ok, _ := store.Get(pod1); !ok { t.Errorf("didn't find pod") } else { if !api.Semantic.DeepEqual(pod1, item) { t.Errorf("expected %v, got %v", pod1, item) } } pod2 := makeTestPod("pod", 2) if err := store.Update(pod2); err != nil { t.Errorf("unexpected error: %v", err) } if item, ok, _ := store.Get(pod2); !ok { t.Errorf("didn't find pod") } else { if !api.Semantic.DeepEqual(pod2, item) { t.Errorf("expected %v, got %v", pod1, item) } } pod3 := makeTestPod("pod", 3) if err := store.Delete(pod3); err != nil { t.Errorf("unexpected error: %v", err) } if _, ok, _ := store.Get(pod3); ok { t.Errorf("found pod") } // Test List. store.Add(makeTestPod("pod1", 4)) store.Add(makeTestPod("pod2", 5)) store.Add(makeTestPod("pod3", 6)) { podNames := sets.String{} for _, item := range store.List() { podNames.Insert(item.(*api.Pod).ObjectMeta.Name) } if !podNames.HasAll("pod1", "pod2", "pod3") { t.Errorf("missing pods, found %v", podNames) } if len(podNames) != 3 { t.Errorf("found missing/extra items") } } // Test Replace. store.Replace([]interface{}{ makeTestPod("pod4", 7), makeTestPod("pod5", 8), }, "8") { podNames := sets.String{} for _, item := range store.List() { podNames.Insert(item.(*api.Pod).ObjectMeta.Name) } if !podNames.HasAll("pod4", "pod5") { t.Errorf("missing pods, found %v", podNames) } if len(podNames) != 2 { t.Errorf("found missing/extra items") } } }
func TestList(t *testing.T) { server, etcdStorage := newEtcdTestStorage(t, testapi.Default.Codec(), etcdtest.PathPrefix()) defer server.Terminate(t) cacher := newTestCacher(etcdStorage) defer cacher.Stop() podFoo := makeTestPod("foo") podBar := makeTestPod("bar") podBaz := makeTestPod("baz") podFooPrime := makeTestPod("foo") podFooPrime.Spec.NodeName = "fakeNode" fooCreated := updatePod(t, etcdStorage, podFoo, nil) _ = updatePod(t, etcdStorage, podBar, nil) _ = updatePod(t, etcdStorage, podBaz, nil) _ = updatePod(t, etcdStorage, podFooPrime, fooCreated) deleted := api.Pod{} if err := etcdStorage.Delete(context.TODO(), etcdtest.AddPrefix("pods/ns/bar"), &deleted, nil); err != nil { t.Errorf("Unexpected error: %v", err) } // We first List directly from etcd by passing empty resourceVersion, // to get the current etcd resourceVersion. rvResult := &api.PodList{} if err := cacher.List(context.TODO(), "pods/ns", "", storage.Everything, rvResult); err != nil { t.Errorf("Unexpected error: %v", err) } deletedPodRV := rvResult.ListMeta.ResourceVersion result := &api.PodList{} // We pass the current etcd ResourceVersion received from the above List() operation, // since there is not easy way to get ResourceVersion of barPod deletion operation. if err := cacher.List(context.TODO(), "pods/ns", deletedPodRV, storage.Everything, result); err != nil { t.Errorf("Unexpected error: %v", err) } if result.ListMeta.ResourceVersion != deletedPodRV { t.Errorf("Incorrect resource version: %v", result.ListMeta.ResourceVersion) } if len(result.Items) != 2 { t.Errorf("Unexpected list result: %d", len(result.Items)) } keys := sets.String{} for _, item := range result.Items { keys.Insert(item.Name) } if !keys.HasAll("foo", "baz") { t.Errorf("Unexpected list result: %#v", result) } for _, item := range result.Items { // unset fields that are set by the infrastructure item.ResourceVersion = "" item.CreationTimestamp = unversioned.Time{} var expected *api.Pod switch item.Name { case "foo": expected = podFooPrime case "baz": expected = podBaz default: t.Errorf("Unexpected item: %v", item) } if e, a := *expected, item; !reflect.DeepEqual(e, a) { t.Errorf("Expected: %#v, got: %#v", e, a) } } }