From d153b985444842f6e09148b77006f53fa0341f61 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Thu, 13 Nov 2014 17:42:50 -0800 Subject: [PATCH 1/3] Simplify kubectl describe code --- pkg/kubectl/describe.go | 66 ++++++++---------------------------- pkg/kubectl/describe_test.go | 32 ++--------------- 2 files changed, 18 insertions(+), 80 deletions(-) diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index 4e79253fdf5..4ca06681fa7 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -38,29 +38,13 @@ type Describer interface { func DescriberFor(kind string, c *client.Client) (Describer, bool) { switch kind { case "Pod": - return &PodDescriber{ - PodClient: func(namespace string) (client.PodInterface, error) { - return c.Pods(namespace), nil - }, - ReplicationControllerClient: func(namespace string) (client.ReplicationControllerInterface, error) { - return c.ReplicationControllers(namespace), nil - }, - }, true + return &PodDescriber{c}, true case "ReplicationController": - return &ReplicationControllerDescriber{ - PodClient: func(namespace string) (client.PodInterface, error) { - return c.Pods(namespace), nil - }, - ReplicationControllerClient: func(namespace string) (client.ReplicationControllerInterface, error) { - return c.ReplicationControllers(namespace), nil - }, - }, true + return &ReplicationControllerDescriber{c}, true case "Service": - return &ServiceDescriber{ - ServiceClient: func(namespace string) (client.ServiceInterface, error) { - return c.Services(namespace), nil - }, - }, true + return &ServiceDescriber{c}, true + case "Minion", "Node": + return &MinionDescriber{c}, true } return nil, false } @@ -68,19 +52,12 @@ func DescriberFor(kind string, c *client.Client) (Describer, bool) { // PodDescriber generates information about a pod and the replication controllers that // create it. type PodDescriber struct { - PodClient func(namespace string) (client.PodInterface, error) - ReplicationControllerClient func(namespace string) (client.ReplicationControllerInterface, error) + client.Interface } func (d *PodDescriber) Describe(namespace, name string) (string, error) { - rc, err := d.ReplicationControllerClient(namespace) - if err != nil { - return "", err - } - pc, err := d.PodClient(namespace) - if err != nil { - return "", err - } + rc := d.ReplicationControllers(namespace) + pc := d.Pods(namespace) pod, err := pc.Get(name) if err != nil { @@ -107,19 +84,12 @@ func (d *PodDescriber) Describe(namespace, name string) (string, error) { // ReplicationControllerDescriber generates information about a replication controller // and the pods it has created. type ReplicationControllerDescriber struct { - ReplicationControllerClient func(namespace string) (client.ReplicationControllerInterface, error) - PodClient func(namespace string) (client.PodInterface, error) + client.Interface } func (d *ReplicationControllerDescriber) Describe(namespace, name string) (string, error) { - rc, err := d.ReplicationControllerClient(namespace) - if err != nil { - return "", err - } - pc, err := d.PodClient(namespace) - if err != nil { - return "", err - } + rc := d.ReplicationControllers(namespace) + pc := d.Pods(namespace) controller, err := rc.Get(name) if err != nil { @@ -144,14 +114,11 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string) (strin // ServiceDescriber generates information about a service. type ServiceDescriber struct { - ServiceClient func(namespace string) (client.ServiceInterface, error) + client.Interface } func (d *ServiceDescriber) Describe(namespace, name string) (string, error) { - c, err := d.ServiceClient(namespace) - if err != nil { - return "", err - } + c := d.Services(namespace) service, err := c.Get(name) if err != nil { @@ -169,14 +136,11 @@ func (d *ServiceDescriber) Describe(namespace, name string) (string, error) { // MinionDescriber generates information about a minion. type MinionDescriber struct { - MinionClient func() (client.MinionInterface, error) + client.Interface } func (d *MinionDescriber) Describe(namespace, name string) (string, error) { - mc, err := d.MinionClient() - if err != nil { - return "", err - } + mc := d.Minions() minion, err := mc.Get(name) if err != nil { return "", err diff --git a/pkg/kubectl/describe_test.go b/pkg/kubectl/describe_test.go index c0b2ac8d057..d1f54a67ccc 100644 --- a/pkg/kubectl/describe_test.go +++ b/pkg/kubectl/describe_test.go @@ -27,37 +27,13 @@ type describeClient struct { T *testing.T Namespace string Err error - Fake *client.Fake -} - -func (c *describeClient) Pod(namespace string) (client.PodInterface, error) { - if namespace != c.Namespace { - c.T.Errorf("unexpected namespace arg: %s", namespace) - } - return c.Fake.Pods(namespace), c.Err -} - -func (c *describeClient) ReplicationController(namespace string) (client.ReplicationControllerInterface, error) { - if namespace != c.Namespace { - c.T.Errorf("unexpected namespace arg: %s", namespace) - } - return c.Fake.ReplicationControllers(namespace), c.Err -} - -func (c *describeClient) Service(namespace string) (client.ServiceInterface, error) { - if namespace != c.Namespace { - c.T.Errorf("unexpected namespace arg: %s", namespace) - } - return c.Fake.Services(namespace), c.Err + *client.Fake } func TestDescribePod(t *testing.T) { fake := &client.Fake{} c := &describeClient{T: t, Namespace: "foo", Fake: fake} - d := PodDescriber{ - PodClient: c.Pod, - ReplicationControllerClient: c.ReplicationController, - } + d := PodDescriber{c} out, err := d.Describe("foo", "bar") if err != nil { t.Errorf("unexpected error: %v", err) @@ -70,9 +46,7 @@ func TestDescribePod(t *testing.T) { func TestDescribeService(t *testing.T) { fake := &client.Fake{} c := &describeClient{T: t, Namespace: "foo", Fake: fake} - d := ServiceDescriber{ - ServiceClient: c.Service, - } + d := ServiceDescriber{c} out, err := d.Describe("foo", "bar") if err != nil { t.Errorf("unexpected error: %v", err) From 3cf022786e7bcddb86b00e958566a6eba5f13de2 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Thu, 13 Nov 2014 19:09:03 -0800 Subject: [PATCH 2/3] fix up event client for namespaces --- pkg/client/client.go | 6 +-- pkg/client/client_test.go | 14 ++++-- pkg/client/events.go | 77 ++++++++++++++++++++++++------- pkg/client/events_test.go | 49 ++++++++++++++++++++ pkg/client/fake.go | 2 +- pkg/client/fake_events.go | 7 +++ plugin/cmd/scheduler/scheduler.go | 2 +- 7 files changed, 133 insertions(+), 24 deletions(-) create mode 100644 pkg/client/events_test.go diff --git a/pkg/client/client.go b/pkg/client/client.go index 7fd0772ec56..8af1d7e49d8 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -33,7 +33,7 @@ type Interface interface { EndpointsNamespacer VersionInterface MinionsInterface - EventsInterface + EventNamespacer } func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface { @@ -44,8 +44,8 @@ func (c *Client) Minions() MinionInterface { return newMinions(c) } -func (c *Client) Events() EventInterface { - return newEvents(c) +func (c *Client) Events(namespace string) EventInterface { + return newEvents(c, namespace) } func (c *Client) Endpoints(namespace string) EndpointsInterface { diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 46809e93c17..11d3b3a451e 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -23,6 +23,7 @@ import ( "net/url" "path" "reflect" + "strings" "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" @@ -121,6 +122,7 @@ func (c *testClient) ValidateCommon(t *testing.T, err error) { requestBody := body(c.Request.Body, c.Request.RawBody) actualQuery := c.handler.RequestReceived.URL.Query() + t.Logf("got query: %v", actualQuery) // We check the query manually, so blank it out so that FakeHandler.ValidateRequest // won't check it. c.handler.RequestReceived.URL.RawQuery = "" @@ -128,11 +130,17 @@ func (c *testClient) ValidateCommon(t *testing.T, err error) { for key, values := range c.Request.Query { validator, ok := c.QueryValidator[key] if !ok { - validator = func(a, b string) bool { return a == b } + switch key { + case "labels", "fields": + validator = validateLabels + default: + validator = func(a, b string) bool { return a == b } + } } observed := actualQuery.Get(key) - if !validator(values[0], observed) { - t.Errorf("Unexpected query arg for key: %s. Expected %s, Received %s", key, values[0], observed) + wanted := strings.Join(values, "") + if !validator(wanted, observed) { + t.Errorf("Unexpected query arg for key: %s. Expected %s, Received %s", key, wanted, observed) } } if c.Request.Header != "" { diff --git a/pkg/client/events.go b/pkg/client/events.go index a0123bdb168..a8cd6dc66d1 100644 --- a/pkg/client/events.go +++ b/pkg/client/events.go @@ -17,14 +17,17 @@ limitations under the License. package client import ( + "fmt" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" ) -// Events has methods to work with Event resources -type EventsInterface interface { - Events() EventInterface +// EventNamespacer can return an EventInterface for the given namespace. +type EventNamespacer interface { + Events(namespace string) EventInterface } // EventInterface has methods to work with Event resources @@ -33,32 +36,48 @@ type EventInterface interface { List(label, field labels.Selector) (*api.EventList, error) Get(id string) (*api.Event, error) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) + // Search finds events about the specified object + Search(objOrRef runtime.Object) (*api.EventList, error) } // events implements Events interface type events struct { - r *Client + client *Client + namespace string } -// newEvents returns a events -func newEvents(c *Client) *events { +// newEvents returns a new events object. +func newEvents(c *Client, ns string) *events { return &events{ - r: c, + client: c, + namespace: ns, } } -// Create makes a new event. Returns the copy of the event the server returns, or an error. -func (c *events) Create(event *api.Event) (*api.Event, error) { +// Create makes a new event. Returns the copy of the event the server returns, +// or an error. The namespace to create the event within is deduced from the +// event; it must either match this event client's namespace, or this event +// client must have been created with the "" namespace. +func (e *events) Create(event *api.Event) (*api.Event, error) { + if e.namespace != "" && event.Namespace != e.namespace { + return nil, fmt.Errorf("can't create an event with namespace '%v' in namespace '%v'", event.Namespace, e.namespace) + } result := &api.Event{} - err := c.r.Post().Path("events").Namespace(event.Namespace).Body(event).Do().Into(result) + err := e.client.Post(). + Path("events"). + Namespace(event.Namespace). + Body(event). + Do(). + Into(result) return result, err } // List returns a list of events matching the selectors. -func (c *events) List(label, field labels.Selector) (*api.EventList, error) { +func (e *events) List(label, field labels.Selector) (*api.EventList, error) { result := &api.EventList{} - err := c.r.Get(). + err := e.client.Get(). Path("events"). + Namespace(e.namespace). SelectorParam("labels", label). SelectorParam("fields", field). Do(). @@ -67,19 +86,45 @@ func (c *events) List(label, field labels.Selector) (*api.EventList, error) { } // Get returns the given event, or an error. -func (c *events) Get(id string) (*api.Event, error) { +func (e *events) Get(id string) (*api.Event, error) { result := &api.Event{} - err := c.r.Get().Path("events").Path(id).Do().Into(result) + err := e.client.Get(). + Path("events"). + Path(id). + Namespace(e.namespace). + Do(). + Into(result) return result, err } // Watch starts watching for events matching the given selectors. -func (c *events) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) { - return c.r.Get(). +func (e *events) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) { + return e.client.Get(). Path("watch"). Path("events"). Param("resourceVersion", resourceVersion). + Namespace(e.namespace). SelectorParam("labels", label). SelectorParam("fields", field). Watch() } + +// Search finds events about the specified object. The namespace of the +// object must match this event's client namespace unless the event client +// was made with the "" namespace. +func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) { + ref, err := api.GetReference(objOrRef) + if err != nil { + return nil, err + } + // TODO: search by UID if it's set + fields := labels.Set{ + "involvedObject.kind": ref.Kind, + "involvedObject.namespace": ref.Namespace, + "involvedObject.name": ref.Name, + }.AsSelector() + if e.namespace != "" && ref.Namespace != e.namespace { + return nil, fmt.Errorf("won't be able to find any events of namespace '%v' in namespace '%v'", ref.Namespace, e.namespace) + } + return e.List(labels.Everything(), fields) +} diff --git a/pkg/client/events_test.go b/pkg/client/events_test.go new file mode 100644 index 00000000000..3dd8cfc4381 --- /dev/null +++ b/pkg/client/events_test.go @@ -0,0 +1,49 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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 client + +import ( + "net/url" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" +) + +func TestEventSearch(t *testing.T) { + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: "/events", + Query: url.Values{ + "fields": []string{"involvedObject.kind=Pod,involvedObject.name=foo,involvedObject.namespace=baz"}, + "labels": []string{}, + }, + }, + Response: Response{StatusCode: 200, Body: &api.EventList{}}, + } + eventList, err := c.Setup().Events("").Search( + &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + SelfLink: testapi.SelfLink("pods", ""), + }, + }, + ) + c.Validate(t, eventList, err) +} diff --git a/pkg/client/fake.go b/pkg/client/fake.go index b7a508ad9ea..793c8d216fa 100644 --- a/pkg/client/fake.go +++ b/pkg/client/fake.go @@ -49,7 +49,7 @@ func (c *Fake) Minions() MinionInterface { return &FakeMinions{Fake: c} } -func (c *Fake) Events() EventInterface { +func (c *Fake) Events(namespace string) EventInterface { return &FakeEvents{Fake: c} } diff --git a/pkg/client/fake_events.go b/pkg/client/fake_events.go index 4dc3fca0d16..cdc5a61b356 100644 --- a/pkg/client/fake_events.go +++ b/pkg/client/fake_events.go @@ -19,6 +19,7 @@ package client import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" ) @@ -51,3 +52,9 @@ func (c *FakeEvents) Watch(label, field labels.Selector, resourceVersion string) c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-events", Value: resourceVersion}) return c.Fake.Watch, c.Fake.Err } + +// Search returns a list of events matching the specified object. +func (c *FakeEvents) Search(objOrRef runtime.Object) (*api.EventList, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "search-events"}) + return &c.Fake.EventsList, nil +} diff --git a/plugin/cmd/scheduler/scheduler.go b/plugin/cmd/scheduler/scheduler.go index 44c364fc4e8..3b5541af0be 100644 --- a/plugin/cmd/scheduler/scheduler.go +++ b/plugin/cmd/scheduler/scheduler.go @@ -56,7 +56,7 @@ func main() { glog.Fatalf("Invalid API configuration: %v", err) } - record.StartRecording(kubeClient.Events(), "scheduler") + record.StartRecording(kubeClient.Events(""), "scheduler") go http.ListenAndServe(net.JoinHostPort(address.String(), strconv.Itoa(*port)), nil) From de75e5a9bb939dcfeea443210917c90fa5117a2b Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Thu, 13 Nov 2014 20:20:42 -0800 Subject: [PATCH 3/3] Fix server-side namespace handling for events; add validation --- pkg/api/validation/events.go | 35 +++++++++++ pkg/api/validation/events_test.go | 60 +++++++++++++++++++ pkg/registry/event/rest.go | 11 +++- pkg/registry/event/rest_test.go | 96 ++++++++++++++++++++----------- test/integration/auth_test.go | 10 ++-- 5 files changed, 173 insertions(+), 39 deletions(-) create mode 100644 pkg/api/validation/events.go create mode 100644 pkg/api/validation/events_test.go diff --git a/pkg/api/validation/events.go b/pkg/api/validation/events.go new file mode 100644 index 00000000000..2ae27ea3575 --- /dev/null +++ b/pkg/api/validation/events.go @@ -0,0 +1,35 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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 validation + +import ( + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + errs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" +) + +// ValidateEvent makes sure that the event makes sense. +func ValidateEvent(event *api.Event) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if event.Namespace != event.InvolvedObject.Namespace { + allErrs = append(allErrs, errs.NewFieldInvalid("involvedObject.namespace", event.InvolvedObject.Namespace)) + } + if !util.IsDNSSubdomain(event.Namespace) { + allErrs = append(allErrs, errs.NewFieldInvalid("namespace", event.Namespace)) + } + return allErrs +} diff --git a/pkg/api/validation/events_test.go b/pkg/api/validation/events_test.go new file mode 100644 index 00000000000..393d3d300bd --- /dev/null +++ b/pkg/api/validation/events_test.go @@ -0,0 +1,60 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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 validation + +import ( + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" +) + +func TestValidateEvent(t *testing.T) { + table := []struct { + *api.Event + valid bool + }{ + { + &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "test1", + Namespace: "foo", + }, + InvolvedObject: api.ObjectReference{ + Namespace: "bar", + }, + }, + false, + }, { + &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "test1", + Namespace: "aoeu-_-aoeu", + }, + InvolvedObject: api.ObjectReference{ + Namespace: "aoeu-_-aoeu", + }, + }, + false, + }, + } + + for _, item := range table { + if e, a := item.valid, len(ValidateEvent(item.Event)) == 0; e != a { + t.Errorf("%v: expected %v, got %v", item.Event.Name, e, a) + } + } +} diff --git a/pkg/registry/event/rest.go b/pkg/registry/event/rest.go index a858a376ec0..1346691c96c 100644 --- a/pkg/registry/event/rest.go +++ b/pkg/registry/event/rest.go @@ -20,6 +20,8 @@ import ( "fmt" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" @@ -45,7 +47,14 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE if !ok { return nil, fmt.Errorf("invalid object type") } - + if api.Namespace(ctx) != "" { + if !api.ValidNamespace(ctx, &event.ObjectMeta) { + return nil, errors.NewConflict("event", event.Namespace, fmt.Errorf("event.namespace does not match the provided context")) + } + } + if errs := validation.ValidateEvent(event); len(errs) > 0 { + return nil, errors.NewInvalid("event", event.Name, errs) + } api.FillObjectMetaSystemFields(ctx, &event.ObjectMeta) return apiserver.MakeAsync(func() (runtime.Object, error) { diff --git a/pkg/registry/event/rest_test.go b/pkg/registry/event/rest_test.go index 40662e8f53c..0f62ad8e673 100644 --- a/pkg/registry/event/rest_test.go +++ b/pkg/registry/event/rest_test.go @@ -38,38 +38,74 @@ func NewTestREST() (testRegistry, *REST) { return reg, NewREST(reg) } +func testEvent(name string) *api.Event { + return &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: name, + Namespace: "default", + }, + InvolvedObject: api.ObjectReference{ + Namespace: "default", + }, + Reason: "forTesting", + } +} + func TestRESTCreate(t *testing.T) { - _, rest := NewTestREST() - eventA := &api.Event{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - Reason: "forTesting", + table := []struct { + ctx api.Context + event *api.Event + valid bool + }{ + { + ctx: api.NewDefaultContext(), + event: testEvent("foo"), + valid: true, + }, { + ctx: api.NewContext(), + event: testEvent("bar"), + valid: true, + }, { + ctx: api.WithNamespace(api.NewContext(), "nondefault"), + event: testEvent("bazzzz"), + valid: false, + }, } - c, err := rest.Create(api.NewContext(), eventA) - if err != nil { - t.Fatalf("Unexpected error %v", err) + + for _, item := range table { + _, rest := NewTestREST() + c, err := rest.Create(item.ctx, item.event) + if !item.valid { + if err == nil { + ctxNS := api.Namespace(item.ctx) + t.Errorf("unexpected non-error for %v (%v, %v)", item.event.Name, ctxNS, item.event.Namespace) + } + continue + } + if err != nil { + t.Errorf("%v: Unexpected error %v", item.event.Name, err) + continue + } + if !api.HasObjectMetaSystemFieldValues(&item.event.ObjectMeta) { + t.Errorf("storage did not populate object meta field values") + } + if e, a := item.event, (<-c).Object; !reflect.DeepEqual(e, a) { + t.Errorf("diff: %s", util.ObjectDiff(e, a)) + } + // Ensure we implement the interface + _ = apiserver.ResourceWatcher(rest) } - if !api.HasObjectMetaSystemFieldValues(&eventA.ObjectMeta) { - t.Errorf("storage did not populate object meta field values") - } - if e, a := eventA, (<-c).Object; !reflect.DeepEqual(e, a) { - t.Errorf("diff: %s", util.ObjectDiff(e, a)) - } - // Ensure we implement the interface - _ = apiserver.ResourceWatcher(rest) } func TestRESTDelete(t *testing.T) { _, rest := NewTestREST() - eventA := &api.Event{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - Reason: "forTesting", - } - c, err := rest.Create(api.NewContext(), eventA) + eventA := testEvent("foo") + c, err := rest.Create(api.NewDefaultContext(), eventA) if err != nil { t.Fatalf("Unexpected error %v", err) } <-c - c, err = rest.Delete(api.NewContext(), eventA.Name) + c, err = rest.Delete(api.NewDefaultContext(), eventA.Name) if err != nil { t.Fatalf("Unexpected error %v", err) } @@ -80,16 +116,13 @@ func TestRESTDelete(t *testing.T) { func TestRESTGet(t *testing.T) { _, rest := NewTestREST() - eventA := &api.Event{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - Reason: "forTesting", - } - c, err := rest.Create(api.NewContext(), eventA) + eventA := testEvent("foo") + c, err := rest.Create(api.NewDefaultContext(), eventA) if err != nil { t.Fatalf("Unexpected error %v", err) } <-c - got, err := rest.Get(api.NewContext(), eventA.Name) + got, err := rest.Get(api.NewDefaultContext(), eventA.Name) if err != nil { t.Fatalf("Unexpected error %v", err) } @@ -140,16 +173,13 @@ func TestRESTgetAttrs(t *testing.T) { func TestRESTUpdate(t *testing.T) { _, rest := NewTestREST() - eventA := &api.Event{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - Reason: "forTesting", - } - c, err := rest.Create(api.NewContext(), eventA) + eventA := testEvent("foo") + c, err := rest.Create(api.NewDefaultContext(), eventA) if err != nil { t.Fatalf("Unexpected error %v", err) } <-c - _, err = rest.Update(api.NewContext(), eventA) + _, err = rest.Update(api.NewDefaultContext(), eventA) if err == nil { t.Errorf("unexpected non-error") } diff --git a/test/integration/auth_test.go b/test/integration/auth_test.go index 6a3f9ca3056..0607b4d0ef7 100644 --- a/test/integration/auth_test.go +++ b/test/integration/auth_test.go @@ -202,13 +202,13 @@ var aEvent string = ` { "kind": "Event", "apiVersion": "v1beta1", + "namespace": "default", "id": "a", "involvedObject": { - { - "kind": "Minion", - "name": "a", - "apiVersion": "v1beta1", - } + "kind": "Minion", + "name": "a", + "namespace": "default", + "apiVersion": "v1beta1", } } `