// 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 TestRequirementConstructor(t *testing.T) { requirementConstructorTests := []struct { Key string Op Operator Vals sets.String Success bool }{ {"x", InOperator, nil, false}, {"x", NotInOperator, sets.NewString(), false}, {"x", InOperator, sets.NewString("foo"), true}, {"x", NotInOperator, sets.NewString("foo"), true}, {"x", ExistsOperator, nil, true}, {"x", DoesNotExistOperator, nil, true}, {"1foo", InOperator, sets.NewString("bar"), true}, {"1234", InOperator, sets.NewString("bar"), true}, {strings.Repeat("a", 254), ExistsOperator, nil, false}, //breaks DNS rule that len(key) <= 253 } for _, rc := range requirementConstructorTests { if _, err := NewRequirement(rc.Key, rc.Op, rc.Vals); err == nil && !rc.Success { t.Errorf("expected error with key:%#v op:%v vals:%v, got no error", rc.Key, rc.Op, rc.Vals) } else if err != nil && rc.Success { t.Errorf("expected no error with key:%#v op:%v vals:%v, got:%v", rc.Key, rc.Op, rc.Vals, err) } } }
func TestTTLExpirationBasic(t *testing.T) { testObj := testStoreObject{id: "foo", val: "bar"} deleteChan := make(chan string) ttlStore := NewFakeExpirationStore( testStoreKeyFunc, deleteChan, &FakeExpirationPolicy{ NeverExpire: sets.NewString(), RetrieveKeyFunc: func(obj interface{}) (string, error) { return obj.(*timestampedEntry).obj.(testStoreObject).id, nil }, }, util.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(util.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) } } }
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) 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 }, }, util.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(util.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") return } } }
func TestAdd(t *testing.T) { testCases := []struct { name string sel Selector key string operator Operator values []string refSelector Selector }{ { "keyInOperator", internalSelector{}, "key", InOperator, []string{"value"}, internalSelector{Requirement{"key", InOperator, sets.NewString("value")}}, }, { "keyEqualsOperator", internalSelector{Requirement{"key", InOperator, sets.NewString("value")}}, "key2", EqualsOperator, []string{"value2"}, internalSelector{ Requirement{"key", InOperator, sets.NewString("value")}, Requirement{"key2", EqualsOperator, sets.NewString("value2")}, }, }, } for _, ts := range testCases { req, err := NewRequirement(ts.key, ts.operator, sets.NewString(ts.values...)) if err != nil { t.Errorf("%s - Unable to create labels.Requirement", ts.name) } ts.sel = ts.sel.Add(*req) if !reflect.DeepEqual(ts.sel, ts.refSelector) { t.Errorf("%s - Expected %v found %v", ts.name, ts.refSelector, ts.sel) } } }
// 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 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.InOperator, 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) }
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) } }
func TestRequirementSelectorMatching(t *testing.T) { var req Requirement labelSelectorMatchingTests := []struct { Set Set Sel Selector Match bool }{ {Set{"x": "foo", "y": "baz"}, &internalSelector{ req, }, false}, {Set{"x": "foo", "y": "baz"}, &internalSelector{ getRequirement("x", InOperator, sets.NewString("foo"), t), getRequirement("y", NotInOperator, sets.NewString("alpha"), t), }, true}, {Set{"x": "foo", "y": "baz"}, &internalSelector{ getRequirement("x", InOperator, sets.NewString("foo"), t), getRequirement("y", InOperator, sets.NewString("alpha"), t), }, false}, {Set{"y": ""}, &internalSelector{ getRequirement("x", NotInOperator, sets.NewString(""), t), getRequirement("y", ExistsOperator, nil, t), }, true}, {Set{"y": ""}, &internalSelector{ getRequirement("x", DoesNotExistOperator, nil, t), getRequirement("y", ExistsOperator, nil, t), }, true}, {Set{"y": ""}, &internalSelector{ getRequirement("x", NotInOperator, sets.NewString(""), t), getRequirement("y", DoesNotExistOperator, nil, t), }, false}, {Set{"y": "baz"}, &internalSelector{ getRequirement("x", InOperator, sets.NewString(""), t), }, false}, } for _, lsm := range labelSelectorMatchingTests { if match := lsm.Sel.Matches(lsm.Set); match != lsm.Match { t.Errorf("%+v.Matches(%#v) => %v, want %v", lsm.Sel, lsm.Set, match, lsm.Match) } } }
// roundTripSame verifies the same source object is tested in all API versions. func roundTripSame(t *testing.T, item runtime.Object, except ...string) { set := sets.NewString(except...) seed := rand.Int63() fuzzInternalObject(t, testapi.Default.InternalGroupVersion(), item, seed) version := *testapi.Default.GroupVersion() codecs := []runtime.Codec{} for _, fn := range codecsToTest { codec, err := fn(version, item) if err != nil { t.Errorf("unable to get codec: %v", err) return } codecs = append(codecs, codec) } if !set.Has(version.String()) { fuzzInternalObject(t, version, item, seed) for _, codec := range codecs { roundTrip(t, codec, item) } } }
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" "github.com/jchauncey/kubeclient/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]
func TestStoreToJobLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) lister := StoreToJobLister{store} testCases := []struct { inJobs []*extensions.Job list func() ([]extensions.Job, error) outJobNames sets.String expectErr bool msg string }{ // Basic listing { inJobs: []*extensions.Job{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func() ([]extensions.Job, error) { list, err := lister.List() return list.Items, err }, outJobNames: sets.NewString("basic"), msg: "basic listing failed", }, // Listing multiple jobs { inJobs: []*extensions.Job{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, {ObjectMeta: api.ObjectMeta{Name: "complex"}}, {ObjectMeta: api.ObjectMeta{Name: "complex2"}}, }, list: func() ([]extensions.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: []*extensions.Job{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: extensions.JobSpec{ Selector: &extensions.LabelSelector{ MatchLabels: map[string]string{"foo": "baz"}, }, }, }, }, list: func() ([]extensions.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: []*extensions.Job{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]extensions.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: []*extensions.Job{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: extensions.JobSpec{ Selector: &extensions.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.JobSpec{ Selector: &extensions.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, }, list: func() ([]extensions.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: []*extensions.Job{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "foo"}, Spec: extensions.JobSpec{ Selector: &extensions.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "bar"}, Spec: extensions.JobSpec{ Selector: &extensions.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, }, list: func() ([]extensions.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) } } }
func TestToString(t *testing.T) { var req Requirement toStringTests := []struct { In *internalSelector Out string Valid bool }{ {&internalSelector{ getRequirement("x", InOperator, sets.NewString("abc", "def"), t), getRequirement("y", NotInOperator, sets.NewString("jkl"), t), getRequirement("z", ExistsOperator, nil, t)}, "x in (abc,def),y notin (jkl),z", true}, {&internalSelector{ getRequirement("x", NotInOperator, sets.NewString("abc", "def"), t), getRequirement("y", NotEqualsOperator, sets.NewString("jkl"), t), getRequirement("z", DoesNotExistOperator, nil, t)}, "x notin (abc,def),y!=jkl,!z", true}, {&internalSelector{ getRequirement("x", InOperator, sets.NewString("abc", "def"), t), req}, // adding empty req for the trailing ',' "x in (abc,def),", false}, {&internalSelector{ getRequirement("x", NotInOperator, sets.NewString("abc"), t), getRequirement("y", InOperator, sets.NewString("jkl", "mno"), t), getRequirement("z", NotInOperator, sets.NewString(""), t)}, "x notin (abc),y in (jkl,mno),z notin ()", true}, {&internalSelector{ getRequirement("x", EqualsOperator, sets.NewString("abc"), t), getRequirement("y", DoubleEqualsOperator, sets.NewString("jkl"), t), getRequirement("z", NotEqualsOperator, sets.NewString("a"), t), getRequirement("z", ExistsOperator, nil, t)}, "x=abc,y==jkl,z!=a,z", true}, } for _, ts := range toStringTests { if out := ts.In.String(); out == "" && ts.Valid { t.Errorf("%+v.String() => '%v' expected no error", ts.In, out) } else if out != ts.Out { t.Errorf("%+v.String() => '%v' want '%v'", ts.In, out, ts.Out) } } }
"github.com/jchauncey/kubeclient/api/errors" "github.com/jchauncey/kubeclient/api/unversioned" "github.com/jchauncey/kubeclient/api/v1" "github.com/jchauncey/kubeclient/api/validation" "github.com/jchauncey/kubeclient/fields" "github.com/jchauncey/kubeclient/labels" "github.com/jchauncey/kubeclient/runtime" "github.com/jchauncey/kubeclient/util/net" "github.com/jchauncey/kubeclient/util/sets" "github.com/jchauncey/kubeclient/watch" watchjson "github.com/jchauncey/kubeclient/watch/json" ) // specialParams lists parameters that are handled specially and which users of Request // are therefore not allowed to set manually. var specialParams = sets.NewString("timeout") func init() { } // 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) Stream() (io.ReadCloser, error) }
} func TestList(t *testing.T) { // api.Scheme.Log(t) // defer api.Scheme.Log(nil) kind := "List" item, err := api.Scheme.New(api.SchemeGroupVersion.WithKind(kind)) if err != nil { t.Errorf("Couldn't make a %v? %v", kind, err) return } roundTripSame(t, item) } var nonRoundTrippableTypes = sets.NewString("ExportOptions") var nonInternalRoundTrippableTypes = sets.NewString("List", "ListOptions", "ExportOptions") var nonRoundTrippableTypesByVersion = map[string][]string{} func TestRoundTripTypes(t *testing.T) { // api.Scheme.Log(t) // defer api.Scheme.Log(nil) for kind := range api.Scheme.KnownTypes(testapi.Default.InternalGroupVersion()) { t.Logf("working on %v in %v", kind, testapi.Default.InternalGroupVersion()) if nonRoundTrippableTypes.Has(kind) { continue } // Try a few times, since runTest uses random values. for i := 0; i < *fuzzIters; i++ {
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.Items)) for ix := range gotNodes.Items { got[ix] = gotNodes.Items[ix].Name } if !want.HasAll(got...) || len(got) != len(want) { t.Errorf("Expected %v, got %v", want, got) } }
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: &extensions.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: &extensions.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.ReplicaSetSpec{ Selector: &extensions.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 TestSetSelectorParser(t *testing.T) { setSelectorParserTests := []struct { In string Out Selector Match bool Valid bool }{ {"", NewSelector(), true, true}, {"\rx", internalSelector{ getRequirement("x", ExistsOperator, nil, t), }, true, true}, {"this-is-a-dns.domain.com/key-with-dash", internalSelector{ getRequirement("this-is-a-dns.domain.com/key-with-dash", ExistsOperator, nil, t), }, true, true}, {"this-is-another-dns.domain.com/key-with-dash in (so,what)", internalSelector{ getRequirement("this-is-another-dns.domain.com/key-with-dash", InOperator, sets.NewString("so", "what"), t), }, true, true}, {"0.1.2.domain/99 notin (10.10.100.1, tick.tack.clock)", internalSelector{ getRequirement("0.1.2.domain/99", NotInOperator, sets.NewString("10.10.100.1", "tick.tack.clock"), t), }, true, true}, {"foo in (abc)", internalSelector{ getRequirement("foo", InOperator, sets.NewString("abc"), t), }, true, true}, {"x notin\n (abc)", internalSelector{ getRequirement("x", NotInOperator, sets.NewString("abc"), t), }, true, true}, {"x notin \t (abc,def)", internalSelector{ getRequirement("x", NotInOperator, sets.NewString("abc", "def"), t), }, true, true}, {"x in (abc,def)", internalSelector{ getRequirement("x", InOperator, sets.NewString("abc", "def"), t), }, true, true}, {"x in (abc,)", internalSelector{ getRequirement("x", InOperator, sets.NewString("abc", ""), t), }, true, true}, {"x in ()", internalSelector{ getRequirement("x", InOperator, sets.NewString(""), t), }, true, true}, {"x notin (abc,,def),bar,z in (),w", internalSelector{ getRequirement("bar", ExistsOperator, nil, t), getRequirement("w", ExistsOperator, nil, t), getRequirement("x", NotInOperator, sets.NewString("abc", "", "def"), t), getRequirement("z", InOperator, sets.NewString(""), t), }, true, true}, {"x,y in (a)", internalSelector{ getRequirement("y", InOperator, sets.NewString("a"), t), getRequirement("x", ExistsOperator, nil, t), }, false, true}, {"x=a", internalSelector{ getRequirement("x", EqualsOperator, sets.NewString("a"), t), }, true, true}, {"x=a,y!=b", internalSelector{ getRequirement("x", EqualsOperator, sets.NewString("a"), t), getRequirement("y", NotEqualsOperator, sets.NewString("b"), t), }, true, true}, {"x=a,y!=b,z in (h,i,j)", internalSelector{ getRequirement("x", EqualsOperator, sets.NewString("a"), t), getRequirement("y", NotEqualsOperator, sets.NewString("b"), t), getRequirement("z", InOperator, sets.NewString("h", "i", "j"), t), }, true, true}, {"x=a||y=b", internalSelector{}, false, false}, {"x,,y", nil, true, false}, {",x,y", nil, true, false}, {"x nott in (y)", nil, true, false}, {"x notin ( )", internalSelector{ getRequirement("x", NotInOperator, sets.NewString(""), t), }, true, true}, {"x notin (, a)", internalSelector{ getRequirement("x", NotInOperator, sets.NewString("", "a"), t), }, true, true}, {"a in (xyz),", nil, true, false}, {"a in (xyz)b notin ()", nil, true, false}, {"a ", internalSelector{ getRequirement("a", ExistsOperator, nil, t), }, true, true}, {"a in (x,y,notin, z,in)", internalSelector{ getRequirement("a", InOperator, sets.NewString("in", "notin", "x", "y", "z"), t), }, true, true}, // operator 'in' inside list of identifiers {"a in (xyz abc)", nil, false, false}, // no comma {"a notin(", nil, true, false}, // bad formed {"a (", nil, false, false}, // cpar {"(", nil, false, false}, // opar } for _, ssp := range setSelectorParserTests { if sel, err := Parse(ssp.In); err != nil && ssp.Valid { t.Errorf("Parse(%s) => %v expected no error", ssp.In, err) } else if err == nil && !ssp.Valid { t.Errorf("Parse(%s) => %+v expected error", ssp.In, sel) } else if ssp.Match && !reflect.DeepEqual(sel, ssp.Out) { t.Errorf("Parse(%s) => parse output '%#v' doesn't match '%#v' expected match", ssp.In, sel, ssp.Out) } } }
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 standardResources = sets.NewString( string(ResourceCPU), string(ResourceMemory), string(ResourcePods), string(ResourceQuotas), string(ResourceServices), string(ResourceReplicationControllers), string(ResourceSecrets), string(ResourcePersistentVolumeClaims), string(ResourceStorage), ) // IsStandardResourceName returns true if the resource is known to the system func IsStandardResourceName(str string) bool { return standardResources.Has(str) } var integerResources = sets.NewString( string(ResourcePods), string(ResourceQuotas), string(ResourceServices),
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: &extensions.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: &extensions.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.DaemonSetSpec{ Selector: &extensions.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) } } }