// 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 newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope rootScoped := sets.NewString( "Node", "Namespace", "PersistentVolume", "ComponentStatus", ) // these kinds should be excluded from the list of resources ignoredKinds := sets.NewString( "ListOptions", "DeleteOptions", "Status", "PodLogOptions", "PodExecOptions", "PodAttachOptions", "PodProxyOptions", "NodeProxyOptions", "ServiceProxyOptions", "ThirdPartyResource", "ThirdPartyResourceData", "ThirdPartyResourceList") mapper := api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) // setup aliases for groups of resources mapper.AddResourceAlias("all", userResources...) return mapper }
func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope rootScoped := sets.NewString() ignoredKinds := sets.NewString() return api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) }
func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { rootScoped := sets.NewString( "ClusterRole", "ClusterRoleBinding", ) ignoredKinds := sets.NewString() return api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) }
func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { worstToBestGroupVersions := []unversioned.GroupVersion{} for i := len(externalVersions) - 1; i >= 0; i-- { worstToBestGroupVersions = append(worstToBestGroupVersions, externalVersions[i]) } rootScoped := sets.NewString("SubjectAccessReview", "SelfSubjectAccessReview") ignoredKinds := sets.NewString() return api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) }
func TestReAddExpiredItem(t *testing.T) { deleteChan := make(chan string, 1) exp := &FakeExpirationPolicy{ NeverExpire: sets.NewString(), RetrieveKeyFunc: func(obj interface{}) (string, error) { return obj.(*timestampedEntry).obj.(testStoreObject).id, nil }, } ttlStore := NewFakeExpirationStore( testStoreKeyFunc, deleteChan, exp, clock.RealClock{}) testKey := "foo" testObj := testStoreObject{id: testKey, val: "bar"} err := ttlStore.Add(testObj) if err != nil { t.Errorf("Unable to add obj %#v", testObj) } // This get will expire the item. item, exists, err := ttlStore.Get(testObj) if err != nil { t.Errorf("Failed to get from store, %v", err) } if exists || item != nil { t.Errorf("Got unexpected item %#v", item) } key, _ := testStoreKeyFunc(testObj) differentValue := "different_bar" err = ttlStore.Add( testStoreObject{id: testKey, val: differentValue}) if err != nil { t.Errorf("Failed to add second value") } select { case delKey := <-deleteChan: if delKey != key { t.Errorf("Unexpected delete for key %s", key) } case <-time.After(wait.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") } exp.NeverExpire = sets.NewString(testKey) item, exists, err = ttlStore.GetByKey(testKey) if err != nil { t.Errorf("Failed to get from store, %v", err) } if !exists || item == nil || item.(testStoreObject).val != differentValue { t.Errorf("Got unexpected item %#v", item) } close(deleteChan) }
// RESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order: // 1. if KUBE_API_VERSIONS is specified, then KUBE_API_VERSIONS in order, OR // 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy // kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version, // all other groups alphabetical. func RESTMapper(versionPatterns ...unversioned.GroupVersion) meta.RESTMapper { unionMapper := meta.MultiRESTMapper{} unionedGroups := sets.NewString() for enabledVersion := range enabledVersions { if !unionedGroups.Has(enabledVersion.Group) { unionedGroups.Insert(enabledVersion.Group) groupMeta := groupMetaMap[enabledVersion.Group] unionMapper = append(unionMapper, groupMeta.RESTMapper) } } if len(versionPatterns) != 0 { resourcePriority := []unversioned.GroupVersionResource{} kindPriority := []unversioned.GroupVersionKind{} for _, versionPriority := range versionPatterns { resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource)) kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind)) } return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority} } if len(envRequestedVersions) != 0 { resourcePriority := []unversioned.GroupVersionResource{} kindPriority := []unversioned.GroupVersionKind{} for _, versionPriority := range envRequestedVersions { resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource)) kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind)) } return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority} } prioritizedGroups := []string{"", "extensions", "metrics"} resourcePriority, kindPriority := prioritiesForGroups(prioritizedGroups...) prioritizedGroupsSet := sets.NewString(prioritizedGroups...) remainingGroups := sets.String{} for enabledVersion := range enabledVersions { if !prioritizedGroupsSet.Has(enabledVersion.Group) { remainingGroups.Insert(enabledVersion.Group) } } remainingResourcePriority, remainingKindPriority := prioritiesForGroups(remainingGroups.List()...) resourcePriority = append(resourcePriority, remainingResourcePriority...) kindPriority = append(kindPriority, remainingKindPriority...) return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority} }
// getClientRepoConfig copies k8s.io/kubernetes/pkg/client/restclient.Config to // a k8s.io/client-go/pkg/client/restclient.Config. It's not a deep copy. Two // configs may share some common struct. func getClientRepoConfig(src *restclient.Config) (dst *clientreporestclient.Config) { skippedFields := sets.NewString("Transport", "WrapTransport", "RateLimiter", "AuthConfigPersister") dst = &clientreporestclient.Config{} dst.Transport = src.Transport dst.WrapTransport = src.WrapTransport dst.RateLimiter = src.RateLimiter dst.AuthConfigPersister = src.AuthConfigPersister sv := reflect.ValueOf(src).Elem() dv := reflect.ValueOf(dst).Elem() for i := 0; i < sv.NumField(); i++ { if skippedFields.Has(sv.Type().Field(i).Name) { continue } sf := sv.Field(i).Interface() data, err := json.Marshal(sf) if err != nil { Expect(err).NotTo(HaveOccurred()) } if !dv.Field(i).CanAddr() { Failf("unaddressable field: %v", dv.Type().Field(i).Name) } else { if err := json.Unmarshal(data, dv.Field(i).Addr().Interface()); err != nil { Expect(err).NotTo(HaveOccurred()) } } } return dst }
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements // labels.Selector. func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) { if len(nsm) == 0 { return labels.Nothing(), nil } selector := labels.NewSelector() for _, expr := range nsm { var op selection.Operator switch expr.Operator { case NodeSelectorOpIn: op = selection.In case NodeSelectorOpNotIn: op = selection.NotIn case NodeSelectorOpExists: op = selection.Exists case NodeSelectorOpDoesNotExist: op = selection.DoesNotExist case NodeSelectorOpGt: op = selection.GreaterThan case NodeSelectorOpLt: op = selection.LessThan default: return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator) } r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...)) if err != nil { return nil, err } selector = selector.Add(*r) } return selector, nil }
func TestTTLExpirationBasic(t *testing.T) { testObj := testStoreObject{id: "foo", val: "bar"} deleteChan := make(chan string, 1) ttlStore := NewFakeExpirationStore( testStoreKeyFunc, deleteChan, &FakeExpirationPolicy{ NeverExpire: sets.NewString(), RetrieveKeyFunc: func(obj interface{}) (string, error) { return obj.(*timestampedEntry).obj.(testStoreObject).id, nil }, }, clock.RealClock{}, ) err := ttlStore.Add(testObj) if err != nil { t.Errorf("Unable to add obj %#v", testObj) } item, exists, err := ttlStore.Get(testObj) if err != nil { t.Errorf("Failed to get from store, %v", err) } if exists || item != nil { t.Errorf("Got unexpected item %#v", item) } key, _ := testStoreKeyFunc(testObj) select { case delKey := <-deleteChan: if delKey != key { t.Errorf("Unexpected delete for key %s", key) } case <-time.After(wait.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") } close(deleteChan) }
// parseIdentifiersList parses a (possibly empty) list of // of comma separated (possibly empty) identifiers func (p *Parser) parseIdentifiersList() (sets.String, error) { s := sets.NewString() for { tok, lit := p.consume(Values) switch tok { case IdentifierToken: s.Insert(lit) tok2, lit2 := p.lookahead(Values) switch tok2 { case CommaToken: continue case ClosedParToken: return s, nil default: return nil, fmt.Errorf("found '%s', expected: ',' or ')'", lit2) } case CommaToken: // handled here since we can have "(," if s.Len() == 0 { s.Insert("") // to handle (, } tok2, _ := p.lookahead(Values) if tok2 == ClosedParToken { s.Insert("") // to handle ,) Double "" removed by StringSet return s, nil } if tok2 == CommaToken { p.consume(Values) s.Insert("") // to handle ,, Double "" removed by StringSet } default: // it can be operator return s, fmt.Errorf("found '%s', expected: ',', or identifier", lit) } } }
// EventAggregate identifies similar events and groups into a common event if required func (e *EventAggregator) EventAggregate(newEvent *v1.Event) (*v1.Event, error) { aggregateKey, localKey := e.keyFunc(newEvent) now := unversioned.NewTime(e.clock.Now()) record := aggregateRecord{localKeys: sets.NewString(), lastTimestamp: now} e.Lock() defer e.Unlock() value, found := e.cache.Get(aggregateKey) if found { record = value.(aggregateRecord) } // if the last event was far enough in the past, it is not aggregated, and we must reset state maxInterval := time.Duration(e.maxIntervalInSeconds) * time.Second interval := now.Time.Sub(record.lastTimestamp.Time) if interval > maxInterval { record = aggregateRecord{localKeys: sets.NewString()} } record.localKeys.Insert(localKey) record.lastTimestamp = now e.cache.Add(aggregateKey, record) if record.localKeys.Len() < e.maxEvents { return newEvent, nil } // do not grow our local key set any larger than max record.localKeys.PopAny() // create a new aggregate event eventCopy := &v1.Event{ ObjectMeta: v1.ObjectMeta{ Name: fmt.Sprintf("%v.%x", newEvent.InvolvedObject.Name, now.UnixNano()), Namespace: newEvent.Namespace, }, Count: 1, FirstTimestamp: now, InvolvedObject: newEvent.InvolvedObject, LastTimestamp: now, Message: e.messageFunc(newEvent), Type: newEvent.Type, Reason: newEvent.Reason, Source: newEvent.Source, } return eventCopy, nil }
func TestTTLList(t *testing.T) { testObjs := []testStoreObject{ {id: "foo", val: "bar"}, {id: "foo1", val: "bar1"}, {id: "foo2", val: "bar2"}, } expireKeys := sets.NewString(testObjs[0].id, testObjs[2].id) deleteChan := make(chan string, len(testObjs)) defer close(deleteChan) ttlStore := NewFakeExpirationStore( testStoreKeyFunc, deleteChan, &FakeExpirationPolicy{ NeverExpire: sets.NewString(testObjs[1].id), RetrieveKeyFunc: func(obj interface{}) (string, error) { return obj.(*timestampedEntry).obj.(testStoreObject).id, nil }, }, clock.RealClock{}, ) for _, obj := range testObjs { err := ttlStore.Add(obj) if err != nil { t.Errorf("Unable to add obj %#v", obj) } } listObjs := ttlStore.List() if len(listObjs) != 1 || !reflect.DeepEqual(listObjs[0], testObjs[1]) { t.Errorf("List returned unexpected results %#v", listObjs) } // Make sure all our deletes come through in an acceptable rate (1/100ms) for expireKeys.Len() != 0 { select { case delKey := <-deleteChan: if !expireKeys.Has(delKey) { t.Errorf("Unexpected delete for key %s", delKey) } expireKeys.Delete(delKey) case <-time.After(wait.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") return } } }
// parseExactValue parses the only value for exact match style func (p *Parser) parseExactValue() (sets.String, error) { s := sets.NewString() tok, lit := p.lookahead(Values) if tok == EndOfStringToken || tok == CommaToken { s.Insert("") return s, nil } tok, lit = p.consume(Values) if tok == IdentifierToken { s.Insert(lit) return s, nil } return nil, fmt.Errorf("found '%s', expected: identifier", lit) }
// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements // labels.Selector // Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) { if ps == nil { return labels.Nothing(), nil } if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 { return labels.Everything(), nil } selector := labels.NewSelector() for k, v := range ps.MatchLabels { r, err := labels.NewRequirement(k, labels.EqualsOperator, sets.NewString(v)) if err != nil { return nil, err } selector = selector.Add(*r) } for _, expr := range ps.MatchExpressions { var op labels.Operator switch expr.Operator { case LabelSelectorOpIn: op = labels.InOperator case LabelSelectorOpNotIn: op = labels.NotInOperator case LabelSelectorOpExists: op = labels.ExistsOperator case LabelSelectorOpDoesNotExist: op = labels.DoesNotExistOperator default: return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator) } r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...)) if err != nil { return nil, err } selector = selector.Add(*r) } return selector, nil }
// SelectorFromSet returns a Selector which will match exactly the given Set. A // nil and empty Sets are considered equivalent to Everything(). func SelectorFromSet(ls Set) Selector { if ls == nil { return internalSelector{} } var requirements internalSelector for label, value := range ls { if r, err := NewRequirement(label, EqualsOperator, sets.NewString(value)); err != nil { //TODO: double check errors when input comes from serialization? return internalSelector{} } else { requirements = append(requirements, *r) } } // sort to have deterministic string representation sort.Sort(ByKey(requirements)) return internalSelector(requirements) }
// Resync will touch all objects to put them into the processing queue func (f *FIFO) Resync() error { f.lock.Lock() defer f.lock.Unlock() inQueue := sets.NewString() for _, id := range f.queue { inQueue.Insert(id) } for id := range f.items { if !inQueue.Has(id) { f.queue = append(f.queue, id) } } if len(f.queue) > 0 { f.cond.Broadcast() } return nil }
// AliasesForResource finds the first alias response for the provided mappers. func (m MultiRESTMapper) AliasesForResource(alias string) ([]string, bool) { seenAliases := sets.NewString() allAliases := []string{} handled := false for _, t := range m { if currAliases, currOk := t.AliasesForResource(alias); currOk { for _, currAlias := range currAliases { if !seenAliases.Has(currAlias) { allAliases = append(allAliases, currAlias) seenAliases.Insert(currAlias) } } handled = true } } return allAliases, handled }
func TestStoreToNodeLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) ids := sets.NewString("foo", "bar", "baz") for id := range ids { store.Add(&api.Node{ObjectMeta: api.ObjectMeta{Name: id}}) } sml := StoreToNodeLister{store} gotNodes, err := sml.List() if err != nil { t.Fatalf("Unexpected error: %v", err) } got := make([]string, len(gotNodes.Items)) for ix := range gotNodes.Items { got[ix] = gotNodes.Items[ix].Name } if !ids.HasAll(got...) || len(got) != len(ids) { t.Errorf("Expected %v, got %v", ids, got) } }
// parseValues parses the values for set based matching (x,y,z) func (p *Parser) parseValues() (sets.String, error) { tok, lit := p.consume(Values) if tok != OpenParToken { return nil, fmt.Errorf("found '%s' expected: '('", lit) } tok, lit = p.lookahead(Values) switch tok { case IdentifierToken, CommaToken: s, err := p.parseIdentifiersList() // handles general cases if err != nil { return s, err } if tok, _ = p.consume(Values); tok != ClosedParToken { return nil, fmt.Errorf("found '%s', expected: ')'", lit) } return s, nil case ClosedParToken: // handles "()" p.consume(Values) return sets.NewString(""), nil default: return nil, fmt.Errorf("found '%s', expected: ',', ')' or identifier", lit) } }
// SelectorFromValidatedSet returns a Selector which will match exactly the given Set. // A nil and empty Sets are considered equivalent to Everything(). // It assumes that Set is already validated and doesn't do any validation. func SelectorFromValidatedSet(ls Set) Selector { if ls == nil { return internalSelector{} } var requirements internalSelector for label, value := range ls { requirements = append(requirements, Requirement{key: label, operator: selection.Equals, strValues: sets.NewString(value)}) } // sort to have deterministic string representation sort.Sort(ByKey(requirements)) return internalSelector(requirements) }
func TestStoreToNodeConditionLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) nodes := []*api.Node{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionTrue, }, { Type: api.NodeOutOfDisk, Status: api.ConditionFalse, }, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar"}, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeOutOfDisk, Status: api.ConditionTrue, }, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "baz"}, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionFalse, }, { Type: api.NodeOutOfDisk, Status: api.ConditionUnknown, }, }, }, }, } for _, n := range nodes { store.Add(n) } predicate := func(node *api.Node) bool { for _, cond := range node.Status.Conditions { if cond.Type == api.NodeOutOfDisk && cond.Status == api.ConditionTrue { return false } } return true } snl := StoreToNodeLister{store} sncl := snl.NodeCondition(predicate) want := sets.NewString("foo", "baz") gotNodes, err := sncl.List() if err != nil { t.Fatalf("Unexpected error: %v", err) } got := make([]string, len(gotNodes)) for ix := range gotNodes { got[ix] = gotNodes[ix].Name } if !want.HasAll(got...) || len(got) != len(want) { t.Errorf("Expected %v, got %v", want, got) } }
func TestStoreToReplicationControllerLister(t *testing.T) { testCases := []struct { description string inRCs []*api.ReplicationController list func(StoreToReplicationControllerLister) ([]api.ReplicationController, error) outRCNames sets.String expectErr bool onlyIfIndexedByNamespace bool }{ { description: "Verify we can search all namespaces", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"}, }, { ObjectMeta: api.ObjectMeta{Name: "hmm", Namespace: "hmm"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { return lister.ReplicationControllers(api.NamespaceAll).List(labels.Set{}.AsSelector()) }, outRCNames: sets.NewString("hmm", "foo"), }, { description: "Verify we can search a specific namespace", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"}, }, { ObjectMeta: api.ObjectMeta{Name: "hmm", Namespace: "hmm"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { return lister.ReplicationControllers("hmm").List(labels.Set{}.AsSelector()) }, outRCNames: sets.NewString("hmm"), }, { description: "Basic listing with all labels and no selectors", inRCs: []*api.ReplicationController{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { return lister.List() }, outRCNames: sets.NewString("basic"), }, { description: "No pod labels", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: api.ReplicationControllerSpec{ Selector: map[string]string{"foo": "baz"}, }, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodControllers(pod) }, outRCNames: sets.NewString(), expectErr: true, }, { description: "No RC selectors", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Namespace: "ns", Labels: map[string]string{"foo": "bar"}, }, } return lister.GetPodControllers(pod) }, outRCNames: sets.NewString(), expectErr: true, }, { description: "Matching labels to selectors and namespace", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ReplicationControllerSpec{ Selector: map[string]string{"foo": "bar"}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: api.ReplicationControllerSpec{ Selector: map[string]string{"foo": "bar"}, }, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Labels: map[string]string{"foo": "bar"}, Namespace: "ns", }, } return lister.GetPodControllers(pod) }, outRCNames: sets.NewString("bar"), onlyIfIndexedByNamespace: true, }, } for _, c := range testCases { for _, withIndex := range []bool{true, false} { if c.onlyIfIndexedByNamespace && !withIndex { continue } var store Indexer if withIndex { store = NewIndexer(MetaNamespaceKeyFunc, Indexers{NamespaceIndex: MetaNamespaceIndexFunc}) } else { store = NewIndexer(MetaNamespaceKeyFunc, Indexers{}) } for _, r := range c.inRCs { store.Add(r) } gotControllers, err := c.list(StoreToReplicationControllerLister{store}) if err != nil && c.expectErr { continue } else if c.expectErr { t.Errorf("(%q, withIndex=%v) Expected error, got none", c.description, withIndex) continue } else if err != nil { t.Errorf("(%q, withIndex=%v) Unexpected error %#v", c.description, withIndex, err) continue } gotNames := make([]string, len(gotControllers)) for ix := range gotControllers { gotNames[ix] = gotControllers[ix].Name } if !c.outRCNames.HasAll(gotNames...) || len(gotNames) != len(c.outRCNames) { t.Errorf("(%q, withIndex=%v) Unexpected got controllers %+v expected %+v", c.description, withIndex, gotNames, c.outRCNames) } } } }
"k8s.io/client-go/1.4/pkg/fields" "k8s.io/client-go/1.4/pkg/labels" "k8s.io/client-go/1.4/pkg/runtime" "k8s.io/client-go/1.4/pkg/runtime/serializer/streaming" "k8s.io/client-go/1.4/pkg/util/flowcontrol" "k8s.io/client-go/1.4/pkg/util/net" "k8s.io/client-go/1.4/pkg/util/sets" "k8s.io/client-go/1.4/pkg/watch" "k8s.io/client-go/1.4/pkg/watch/versioned" "k8s.io/client-go/1.4/tools/metrics" ) var ( // specialParams lists parameters that are handled specially and which users of Request // are therefore not allowed to set manually. specialParams = sets.NewString("timeout") // longThrottleLatency defines threshold for logging requests. All requests being // throttle for more than longThrottleLatency will be logged. longThrottleLatency = 50 * time.Millisecond ) func init() { metrics.Register() } // HTTPClient is an interface for testing a request object. type HTTPClient interface { Do(req *http.Request) (*http.Response, error) }
func TestStoreToReplicaSetLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) lister := StoreToReplicaSetLister{store} testCases := []struct { inRSs []*extensions.ReplicaSet list func() ([]extensions.ReplicaSet, error) outRSNames sets.String expectErr bool }{ // Basic listing with all labels and no selectors { inRSs: []*extensions.ReplicaSet{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func() ([]extensions.ReplicaSet, error) { return lister.List() }, outRSNames: sets.NewString("basic"), }, // No pod labels { inRSs: []*extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: extensions.ReplicaSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}}, }, }, }, list: func() ([]extensions.ReplicaSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodReplicaSets(pod) }, outRSNames: sets.NewString(), expectErr: true, }, // No ReplicaSet selectors { inRSs: []*extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]extensions.ReplicaSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Namespace: "ns", Labels: map[string]string{"foo": "bar"}, }, } return lister.GetPodReplicaSets(pod) }, outRSNames: sets.NewString(), expectErr: true, }, // Matching labels to selectors and namespace { inRSs: []*extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: extensions.ReplicaSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.ReplicaSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, }, list: func() ([]extensions.ReplicaSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Labels: map[string]string{"foo": "bar"}, Namespace: "ns", }, } return lister.GetPodReplicaSets(pod) }, outRSNames: sets.NewString("bar"), }, } for _, c := range testCases { for _, r := range c.inRSs { store.Add(r) } gotRSs, err := c.list() if err != nil && c.expectErr { continue } else if c.expectErr { t.Error("Expected error, got none") continue } else if err != nil { t.Errorf("Unexpected error %#v", err) continue } gotNames := make([]string, len(gotRSs)) for ix := range gotRSs { gotNames[ix] = gotRSs[ix].Name } if !c.outRSNames.HasAll(gotNames...) || len(gotNames) != len(c.outRSNames) { t.Errorf("Unexpected got ReplicaSets %+v expected %+v", gotNames, c.outRSNames) } } }
func TestStoreToDaemonSetLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) lister := StoreToDaemonSetLister{store} testCases := []struct { inDSs []*extensions.DaemonSet list func() ([]extensions.DaemonSet, error) outDaemonSetNames sets.String expectErr bool }{ // Basic listing { inDSs: []*extensions.DaemonSet{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func() ([]extensions.DaemonSet, error) { list, err := lister.List() return list.Items, err }, outDaemonSetNames: sets.NewString("basic"), }, // Listing multiple daemon sets { inDSs: []*extensions.DaemonSet{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, {ObjectMeta: api.ObjectMeta{Name: "complex"}}, {ObjectMeta: api.ObjectMeta{Name: "complex2"}}, }, list: func() ([]extensions.DaemonSet, error) { list, err := lister.List() return list.Items, err }, outDaemonSetNames: sets.NewString("basic", "complex", "complex2"), }, // No pod labels { inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: extensions.DaemonSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}}, }, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodDaemonSets(pod) }, outDaemonSetNames: sets.NewString(), expectErr: true, }, // No DS selectors { inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Namespace: "ns", Labels: map[string]string{"foo": "bar"}, }, } return lister.GetPodDaemonSets(pod) }, outDaemonSetNames: sets.NewString(), expectErr: true, }, // Matching labels to selectors and namespace { inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: extensions.DaemonSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.DaemonSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Labels: map[string]string{"foo": "bar"}, Namespace: "ns", }, } return lister.GetPodDaemonSets(pod) }, outDaemonSetNames: sets.NewString("bar"), }, } for _, c := range testCases { for _, r := range c.inDSs { store.Add(r) } daemonSets, err := c.list() if err != nil && c.expectErr { continue } else if c.expectErr { t.Error("Expected error, got none") continue } else if err != nil { t.Errorf("Unexpected error %#v", err) continue } daemonSetNames := make([]string, len(daemonSets)) for ix := range daemonSets { daemonSetNames[ix] = daemonSets[ix].Name } if !c.outDaemonSetNames.HasAll(daemonSetNames...) || len(daemonSetNames) != len(c.outDaemonSetNames) { t.Errorf("Unexpected got controllers %+v expected %+v", daemonSetNames, c.outDaemonSetNames) } } }
func TestStoreToJobLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) lister := StoreToJobLister{store} testCases := []struct { inJobs []*batch.Job list func() ([]batch.Job, error) outJobNames sets.String expectErr bool msg string }{ // Basic listing { inJobs: []*batch.Job{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func() ([]batch.Job, error) { list, err := lister.List() return list.Items, err }, outJobNames: sets.NewString("basic"), msg: "basic listing failed", }, // Listing multiple jobs { inJobs: []*batch.Job{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, {ObjectMeta: api.ObjectMeta{Name: "complex"}}, {ObjectMeta: api.ObjectMeta{Name: "complex2"}}, }, list: func() ([]batch.Job, error) { list, err := lister.List() return list.Items, err }, outJobNames: sets.NewString("basic", "complex", "complex2"), msg: "listing multiple jobs failed", }, // No pod labels { inJobs: []*batch.Job{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "baz"}, }, }, }, }, list: func() ([]batch.Job, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod", Namespace: "ns"}, } return lister.GetPodJobs(pod) }, outJobNames: sets.NewString(), expectErr: true, msg: "listing jobs failed when pod has no labels: expected error, got none", }, // No Job selectors { inJobs: []*batch.Job{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]batch.Job, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod", Namespace: "ns", Labels: map[string]string{"foo": "bar"}, }, } return lister.GetPodJobs(pod) }, outJobNames: sets.NewString(), expectErr: true, msg: "listing jobs failed when job has no selector: expected error, got none", }, // Matching labels to selectors and namespace { inJobs: []*batch.Job{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, }, list: func() ([]batch.Job, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod", Labels: map[string]string{"foo": "bar"}, Namespace: "ns", }, } return lister.GetPodJobs(pod) }, outJobNames: sets.NewString("bar"), msg: "listing jobs with namespace and selector failed", }, // Matching labels to selectors and namespace, error case { inJobs: []*batch.Job{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "foo"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "bar"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, }, list: func() ([]batch.Job, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod", Labels: map[string]string{"foo": "bar"}, Namespace: "baz", }, } return lister.GetPodJobs(pod) }, expectErr: true, msg: "listing jobs with namespace and selector failed: expected error, got none", }, } for _, c := range testCases { for _, r := range c.inJobs { store.Add(r) } Jobs, err := c.list() if err != nil && c.expectErr { continue } else if c.expectErr { t.Errorf("%v", c.msg) continue } else if err != nil { t.Errorf("Unexpected error %#v", err) continue } JobNames := make([]string, len(Jobs)) for ix := range Jobs { JobNames[ix] = Jobs[ix].Name } if !c.outJobNames.HasAll(JobNames...) || len(JobNames) != len(c.outJobNames) { t.Errorf("%v : expected %v, got %v", c.msg, JobNames, c.outJobNames) } } }
return a.Cmp(b) == 0 }, func(a, b unversioned.Time) bool { return a.UTC() == b.UTC() }, func(a, b labels.Selector) bool { return a.String() == b.String() }, func(a, b fields.Selector) bool { return a.String() == b.String() }, ) var standardResourceQuotaScopes = sets.NewString( string(ResourceQuotaScopeTerminating), string(ResourceQuotaScopeNotTerminating), string(ResourceQuotaScopeBestEffort), string(ResourceQuotaScopeNotBestEffort), ) // IsStandardResourceQuotaScope returns true if the scope is a standard value func IsStandardResourceQuotaScope(str string) bool { return standardResourceQuotaScopes.Has(str) } var podObjectCountQuotaResources = sets.NewString( string(ResourcePods), ) var podComputeQuotaResources = sets.NewString( string(ResourceCPU), string(ResourceMemory),
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package net import ( "strings" "k8s.io/client-go/1.4/pkg/util/sets" ) var validSchemes = sets.NewString("http", "https", "") // SplitSchemeNamePort takes a string of the following forms: // * "<name>", returns "", "<name>","", true // * "<name>:<port>", returns "", "<name>","<port>",true // * "<scheme>:<name>:<port>", returns "<scheme>","<name>","<port>",true // // Name must be non-empty or valid will be returned false. // Scheme must be "http" or "https" if specified // Port is returned as a string, and it is not required to be numeric (could be // used for a named port, for example). func SplitSchemeNamePort(id string) (scheme, name, port string, valid bool) { parts := strings.Split(id, ":") switch len(parts) { case 1: name = parts[0]