// 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 []schema.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) return mapper }
func TestFilteredBy(t *testing.T) { all := discovery.ResourcePredicateFunc(func(gv string, r *metav1.APIResource) bool { return true }) none := discovery.ResourcePredicateFunc(func(gv string, r *metav1.APIResource) bool { return false }) onlyV2 := discovery.ResourcePredicateFunc(func(gv string, r *metav1.APIResource) bool { return strings.HasSuffix(gv, "/v2") || gv == "v2" }) onlyBar := discovery.ResourcePredicateFunc(func(gv string, r *metav1.APIResource) bool { return r.Kind == "Bar" }) foo := []*metav1.APIResourceList{ { GroupVersion: "foo/v1", APIResources: []metav1.APIResource{ {Name: "bar", Kind: "Bar"}, {Name: "test", Kind: "Test"}, }, }, { GroupVersion: "foo/v2", APIResources: []metav1.APIResource{ {Name: "bar", Kind: "Bar"}, {Name: "test", Kind: "Test"}, }, }, { GroupVersion: "foo/v3", APIResources: []metav1.APIResource{}, }, } tests := []struct { input []*metav1.APIResourceList pred discovery.ResourcePredicate expectedResources []string }{ {nil, all, []string{}}, {[]*metav1.APIResourceList{ {GroupVersion: "foo/v1"}, }, all, []string{}}, {foo, all, []string{"foo/v1.bar", "foo/v1.test", "foo/v2.bar", "foo/v2.test"}}, {foo, onlyV2, []string{"foo/v2.bar", "foo/v2.test"}}, {foo, onlyBar, []string{"foo/v1.bar", "foo/v2.bar"}}, {foo, none, []string{}}, } for i, test := range tests { filtered := discovery.FilteredBy(test.pred, test.input) if expected, got := sets.NewString(test.expectedResources...), sets.NewString(stringify(filtered)...); !expected.Equal(got) { t.Errorf("[%d] unexpected group versions: expected=%v, got=%v", i, test.expectedResources, stringify(filtered)) } } }
func newRESTMapper(externalVersions []schema.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( "Cluster", ) ignoredKinds := sets.NewString() return api.NewDefaultRESTMapper(externalVersions, 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 (m *APIRegistrationManager) RESTMapper(versionPatterns ...unversioned.GroupVersion) meta.RESTMapper { unionMapper := meta.MultiRESTMapper{} unionedGroups := sets.NewString() for enabledVersion := range m.enabledVersions { if !unionedGroups.Has(enabledVersion.Group) { unionedGroups.Insert(enabledVersion.Group) groupMeta := m.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(m.envRequestedVersions) != 0 { resourcePriority := []unversioned.GroupVersionResource{} kindPriority := []unversioned.GroupVersionKind{} for _, versionPriority := range m.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 := m.prioritiesForGroups(prioritizedGroups...) prioritizedGroupsSet := sets.NewString(prioritizedGroups...) remainingGroups := sets.String{} for enabledVersion := range m.enabledVersions { if !prioritizedGroupsSet.Has(enabledVersion.Group) { remainingGroups.Insert(enabledVersion.Group) } } remainingResourcePriority, remainingKindPriority := m.prioritiesForGroups(remainingGroups.List()...) resourcePriority = append(resourcePriority, remainingResourcePriority...) kindPriority = append(kindPriority, remainingKindPriority...) return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority} }
// 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) } } }
// 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 }
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) }
func TestGetServerResourcesWithV1Server(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { var obj interface{} switch req.URL.Path { case "/api": obj = &metav1.APIVersions{ Versions: []string{ "v1", }, } default: w.WriteHeader(http.StatusNotFound) return } output, err := json.Marshal(obj) if err != nil { t.Errorf("unexpected encoding error: %v", err) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(output) })) defer server.Close() client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL}) // ServerResources should not return an error even if server returns error at /api/v1. serverResources, err := client.ServerResources() if err != nil { t.Errorf("unexpected error: %v", err) } gvs := groupVersions(serverResources) if !sets.NewString(gvs...).Has("v1") { t.Errorf("missing v1 in resource list: %v", serverResources) } }
// 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 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 } } }
// 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 (gmf *GroupMetaFactory) newRESTMapper(scheme *runtime.Scheme, externalVersions []schema.GroupVersion, groupMeta *apimachinery.GroupMeta) 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() if gmf.GroupArgs.RootScopedKinds != nil { rootScoped = gmf.GroupArgs.RootScopedKinds } ignoredKinds := sets.NewString() if gmf.GroupArgs.IgnoredKinds != nil { ignoredKinds = gmf.GroupArgs.IgnoredKinds } return api.NewDefaultRESTMapperFromScheme( externalVersions, groupMeta.InterfacesFor, gmf.GroupArgs.ImportPrefix, ignoredKinds, rootScoped, scheme, ) }
// ToAggregate converts the ErrorList into an errors.Aggregate. func (list ErrorList) ToAggregate() utilerrors.Aggregate { errs := make([]error, 0, len(list)) errorMsgs := sets.NewString() for _, err := range list { msg := fmt.Sprintf("%v", err) if errorMsgs.Has(msg) { continue } errorMsgs.Insert(msg) errs = append(errs, err) } return utilerrors.NewAggregate(errs) }
// 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) }
func init() { if err := announced.NewGroupMetaFactory( &announced.GroupMetaFactoryArgs{ GroupName: rbac.GroupName, VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version}, ImportPrefix: "k8s.io/client-go/pkg/apis/rbac", RootScopedKinds: sets.NewString("ClusterRole", "ClusterRoleBinding"), AddInternalObjectsToScheme: rbac.AddToScheme, }, announced.VersionToSchemeFunc{ v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme, }, ).Announce().RegisterAndEnable(); err != nil { panic(err) } }
func init() { if err := announced.NewGroupMetaFactory( &announced.GroupMetaFactoryArgs{ GroupName: extensions.GroupName, VersionPreferenceOrder: []string{v1beta1.SchemeGroupVersion.Version}, ImportPrefix: "k8s.io/client-go/pkg/apis/extensions", RootScopedKinds: sets.NewString("PodSecurityPolicy", "ThirdPartyResource"), AddInternalObjectsToScheme: extensions.AddToScheme, }, announced.VersionToSchemeFunc{ v1beta1.SchemeGroupVersion.Version: v1beta1.AddToScheme, }, ).Announce().RegisterAndEnable(); err != nil { panic(err) } }
func init() { if err := announced.NewGroupMetaFactory( &announced.GroupMetaFactoryArgs{ GroupName: authorization.GroupName, VersionPreferenceOrder: []string{v1beta1.SchemeGroupVersion.Version}, ImportPrefix: "k8s.io/client-go/pkg/apis/authorization", RootScopedKinds: sets.NewString("SubjectAccessReview", "SelfSubjectAccessReview"), AddInternalObjectsToScheme: authorization.AddToScheme, }, announced.VersionToSchemeFunc{ v1beta1.SchemeGroupVersion.Version: v1beta1.AddToScheme, }, ).Announce().RegisterAndEnable(); err != nil { panic(err) } }
// 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, selection.Equals, 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) }
// Register constructs the finalized prioritized version list and sanity checks // the announced group & versions. Then it calls register. func (gmf *GroupMetaFactory) Register(m *registered.APIRegistrationManager) error { if gmf.GroupArgs == nil { return fmt.Errorf("partially announced groups are not allowed, only got versions: %#v", gmf.VersionArgs) } if len(gmf.VersionArgs) == 0 { return fmt.Errorf("group %v announced but no versions announced", gmf.GroupArgs.GroupName) } pvSet := sets.NewString(gmf.GroupArgs.VersionPreferenceOrder...) if pvSet.Len() != len(gmf.GroupArgs.VersionPreferenceOrder) { return fmt.Errorf("preference order for group %v has duplicates: %v", gmf.GroupArgs.GroupName, gmf.GroupArgs.VersionPreferenceOrder) } prioritizedVersions := []schema.GroupVersion{} for _, v := range gmf.GroupArgs.VersionPreferenceOrder { prioritizedVersions = append( prioritizedVersions, schema.GroupVersion{ Group: gmf.GroupArgs.GroupName, Version: v, }, ) } // Go through versions that weren't explicitly prioritized. unprioritizedVersions := []schema.GroupVersion{} for _, v := range gmf.VersionArgs { if v.GroupName != gmf.GroupArgs.GroupName { return fmt.Errorf("found %v/%v in group %v?", v.GroupName, v.VersionName, gmf.GroupArgs.GroupName) } if pvSet.Has(v.VersionName) { pvSet.Delete(v.VersionName) continue } unprioritizedVersions = append(unprioritizedVersions, schema.GroupVersion{Group: v.GroupName, Version: v.VersionName}) } if len(unprioritizedVersions) > 1 { glog.Warningf("group %v has multiple unprioritized versions: %#v. They will have an arbitrary preference order!", gmf.GroupArgs.GroupName, unprioritizedVersions) } if pvSet.Len() != 0 { return fmt.Errorf("group %v has versions in the priority list that were never announced: %s", gmf.GroupArgs.GroupName, pvSet) } prioritizedVersions = append(prioritizedVersions, unprioritizedVersions...) m.RegisterVersions(prioritizedVersions) gmf.prioritizedVersionList = prioritizedVersions return nil }
// 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(&v1.Node{ObjectMeta: v1.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) } }
"k8s.io/client-go/pkg/labels" "k8s.io/client-go/pkg/runtime" "k8s.io/client-go/pkg/runtime/schema" "k8s.io/client-go/pkg/runtime/serializer/streaming" "k8s.io/client-go/pkg/util/flowcontrol" "k8s.io/client-go/pkg/util/net" "k8s.io/client-go/pkg/util/sets" "k8s.io/client-go/pkg/watch" "k8s.io/client-go/pkg/watch/versioned" "k8s.io/client-go/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 ) // HTTPClient is an interface for testing a request object. type HTTPClient interface { Do(req *http.Request) (*http.Response, error) } // ResponseWrapper is an interface for getting a response. // The response may be either accessed as a raw data (the whole output is put into memory) or as a stream. type ResponseWrapper interface { DoRaw() ([]byte, error)
func TestStoreToNodeConditionLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) nodes := []*v1.Node{ { ObjectMeta: v1.ObjectMeta{Name: "foo"}, Status: v1.NodeStatus{ Conditions: []v1.NodeCondition{ { Type: v1.NodeReady, Status: v1.ConditionTrue, }, { Type: v1.NodeOutOfDisk, Status: v1.ConditionFalse, }, }, }, }, { ObjectMeta: v1.ObjectMeta{Name: "bar"}, Status: v1.NodeStatus{ Conditions: []v1.NodeCondition{ { Type: v1.NodeOutOfDisk, Status: v1.ConditionTrue, }, }, }, }, { ObjectMeta: v1.ObjectMeta{Name: "baz"}, Status: v1.NodeStatus{ Conditions: []v1.NodeCondition{ { Type: v1.NodeReady, Status: v1.ConditionFalse, }, { Type: v1.NodeOutOfDisk, Status: v1.ConditionUnknown, }, }, }, }, } for _, n := range nodes { store.Add(n) } predicate := func(node *v1.Node) bool { for _, cond := range node.Status.Conditions { if cond.Type == v1.NodeOutOfDisk && cond.Status == v1.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 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: v1.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: v1.ObjectMeta{Name: "basic"}}, {ObjectMeta: v1.ObjectMeta{Name: "complex"}}, {ObjectMeta: v1.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: v1.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: extensions.DaemonSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}}, }, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &v1.Pod{ ObjectMeta: v1.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodDaemonSets(pod) }, outDaemonSetNames: sets.NewString(), expectErr: true, }, // No DS selectors { inDSs: []*extensions.DaemonSet{ { ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &v1.Pod{ ObjectMeta: v1.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: v1.ObjectMeta{Name: "foo"}, Spec: extensions.DaemonSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, { ObjectMeta: v1.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.DaemonSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &v1.Pod{ ObjectMeta: v1.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 TestStoreToReplicaSetLister(t *testing.T) { store := NewIndexer(MetaNamespaceKeyFunc, Indexers{NamespaceIndex: MetaNamespaceIndexFunc}) 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: v1.ObjectMeta{Name: "basic"}}, }, list: func() ([]*extensions.ReplicaSet, error) { return lister.List(labels.Everything()) }, outRSNames: sets.NewString("basic"), }, // No pod labels { inRSs: []*extensions.ReplicaSet{ { ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: extensions.ReplicaSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}}, }, }, }, list: func() ([]*extensions.ReplicaSet, error) { pod := &v1.Pod{ ObjectMeta: v1.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodReplicaSets(pod) }, outRSNames: sets.NewString(), expectErr: true, }, // No ReplicaSet selectors { inRSs: []*extensions.ReplicaSet{ { ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]*extensions.ReplicaSet, error) { pod := &v1.Pod{ ObjectMeta: v1.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: v1.ObjectMeta{Name: "foo"}, Spec: extensions.ReplicaSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, { ObjectMeta: v1.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.ReplicaSetSpec{ Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, }, list: func() ([]*extensions.ReplicaSet, error) { pod := &v1.Pod{ ObjectMeta: v1.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 TestStoreToReplicationControllerLister(t *testing.T) { testCases := []struct { description string inRCs []*v1.ReplicationController list func(StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) outRCNames sets.String expectErr bool onlyIfIndexedByNamespace bool }{ { description: "Verify we can search all namespaces", inRCs: []*v1.ReplicationController{ { ObjectMeta: v1.ObjectMeta{Name: "foo", Namespace: "bar"}, }, { ObjectMeta: v1.ObjectMeta{Name: "hmm", Namespace: "hmm"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) { return lister.ReplicationControllers(v1.NamespaceAll).List(labels.Set{}.AsSelectorPreValidated()) }, outRCNames: sets.NewString("hmm", "foo"), }, { description: "Verify we can search a specific namespace", inRCs: []*v1.ReplicationController{ { ObjectMeta: v1.ObjectMeta{Name: "foo", Namespace: "bar"}, }, { ObjectMeta: v1.ObjectMeta{Name: "hmm", Namespace: "hmm"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) { return lister.ReplicationControllers("hmm").List(labels.Set{}.AsSelectorPreValidated()) }, outRCNames: sets.NewString("hmm"), }, { description: "Basic listing with all labels and no selectors", inRCs: []*v1.ReplicationController{ {ObjectMeta: v1.ObjectMeta{Name: "basic"}}, }, list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) { return lister.List(labels.Everything()) }, outRCNames: sets.NewString("basic"), }, { description: "No pod labels", inRCs: []*v1.ReplicationController{ { ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: v1.ReplicationControllerSpec{ Selector: map[string]string{"foo": "baz"}, }, }, }, list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) { pod := &v1.Pod{ ObjectMeta: v1.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodControllers(pod) }, outRCNames: sets.NewString(), expectErr: true, }, { description: "No RC selectors", inRCs: []*v1.ReplicationController{ { ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) { pod := &v1.Pod{ ObjectMeta: v1.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: []*v1.ReplicationController{ { ObjectMeta: v1.ObjectMeta{Name: "foo"}, Spec: v1.ReplicationControllerSpec{ Selector: map[string]string{"foo": "bar"}, }, }, { ObjectMeta: v1.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: v1.ReplicationControllerSpec{ Selector: map[string]string{"foo": "bar"}, }, }, }, list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) { pod := &v1.Pod{ ObjectMeta: v1.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) } } } }