Merge pull request #2911 from smarterclayton/event_field_should_be_condition

Rename Event.Status to Event.Condition to match v1beta3 agreement
This commit is contained in:
Clayton Coleman 2014-12-16 14:28:18 -05:00
commit eb0f32bf0f
14 changed files with 133 additions and 60 deletions

View File

@ -953,18 +953,18 @@ type Event struct {
// Required. The object that this event is about. // Required. The object that this event is about.
InvolvedObject ObjectReference `json:"involvedObject,omitempty"` InvolvedObject ObjectReference `json:"involvedObject,omitempty"`
// Should be a short, machine understandable string that describes the current status // Should be a short, machine understandable string that describes the current condition
// of the referred object. This should not give the reason for being in this state. // of the referred object. This should not give the reason for being in this state.
// Examples: "running", "cantStart", "cantSchedule", "deleted". // Examples: "Running", "CantStart", "CantSchedule", "Deleted".
// It's OK for components to make up statuses to report here, but the same string should // It's OK for components to make up conditions to report here, but the same string should
// always be used for the same status. // always be used for the same conditions.
// TODO: define a way of making sure these are consistent and don't collide. // TODO: define a way of making sure these are consistent and don't collide.
// TODO: provide exact specification for format. // TODO: provide exact specification for format.
Status string `json:"status,omitempty"` Condition string `json:"condition,omitempty"`
// Optional; this should be a short, machine understandable string that gives the reason // Optional; this should be a short, machine understandable string that gives the reason
// for the transition into the object's current status. For example, if ObjectStatus is // for the transition into the object's current condition. For example, if ObjectCondition is
// "cantStart", StatusReason might be "imageNotFound". // "CantStart", StatusReason might be "ImageNotFound".
// TODO: provide exact specification for format. // TODO: provide exact specification for format.
Reason string `json:"reason,omitempty"` Reason string `json:"reason,omitempty"`

View File

@ -34,6 +34,10 @@ func init() {
newer.Scheme.AddStructFieldConversion(newer.ObjectMeta{}, "ObjectMeta", TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(newer.ObjectMeta{}, "ObjectMeta", TypeMeta{}, "TypeMeta")
newer.Scheme.AddStructFieldConversion(newer.ListMeta{}, "ListMeta", TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(newer.ListMeta{}, "ListMeta", TypeMeta{}, "TypeMeta")
// TODO: scope this to a specific type once that becomes available and remove the Event conversion functions below
// newer.Scheme.AddStructFieldConversion(string(""), "Status", string(""), "Condition")
// newer.Scheme.AddStructFieldConversion(string(""), "Condition", string(""), "Status")
newer.Scheme.AddConversionFuncs( newer.Scheme.AddConversionFuncs(
// TypeMeta must be split into two objects // TypeMeta must be split into two objects
func(in *newer.TypeMeta, out *TypeMeta, s conversion.Scope) error { func(in *newer.TypeMeta, out *TypeMeta, s conversion.Scope) error {
@ -521,5 +525,36 @@ func init() {
out.FieldPath = in.FieldPath out.FieldPath = in.FieldPath
return nil return nil
}, },
// Event Status -> Condition
// TODO: remove this when it becomes possible to specify a field name conversion on a specific type
func(in *newer.Event, out *Event, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil {
return err
}
out.Status = in.Condition
out.Reason = in.Reason
out.Message = in.Message
out.Source = in.Source
out.Timestamp = in.Timestamp
return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0)
},
func(in *Event, out *newer.Event, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Condition = in.Status
out.Reason = in.Reason
out.Message = in.Message
out.Source = in.Source
out.Timestamp = in.Timestamp
return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0)
},
) )
} }

View File

@ -776,7 +776,7 @@ type Event struct {
// Should be a short, machine understandable string that describes the current status // Should be a short, machine understandable string that describes the current status
// of the referred object. This should not give the reason for being in this state. // of the referred object. This should not give the reason for being in this state.
// Examples: "running", "cantStart", "cantSchedule", "deleted". // Examples: "Running", "CantStart", "CantSchedule", "Deleted".
// It's OK for components to make up statuses to report here, but the same string should // It's OK for components to make up statuses to report here, but the same string should
// always be used for the same status. // always be used for the same status.
// TODO: define a way of making sure these are consistent and don't collide. // TODO: define a way of making sure these are consistent and don't collide.
@ -785,7 +785,7 @@ type Event struct {
// Optional; this should be a short, machine understandable string that gives the reason // Optional; this should be a short, machine understandable string that gives the reason
// for the transition into the object's current status. For example, if ObjectStatus is // for the transition into the object's current status. For example, if ObjectStatus is
// "cantStart", StatusReason might be "imageNotFound". // "CantStart", Reason might be "ImageNotFound".
// TODO: provide exact specification for format. // TODO: provide exact specification for format.
Reason string `json:"reason,omitempty" description:"short, machine understandable string that gives the reason for the transition into the object's current status"` Reason string `json:"reason,omitempty" description:"short, machine understandable string that gives the reason for the transition into the object's current status"`

View File

@ -34,6 +34,10 @@ func init() {
newer.Scheme.AddStructFieldConversion(newer.ObjectMeta{}, "ObjectMeta", TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(newer.ObjectMeta{}, "ObjectMeta", TypeMeta{}, "TypeMeta")
newer.Scheme.AddStructFieldConversion(newer.ListMeta{}, "ListMeta", TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(newer.ListMeta{}, "ListMeta", TypeMeta{}, "TypeMeta")
// TODO: scope this to a specific type once that becomes available and remove the Event conversion functions below
// newer.Scheme.AddStructFieldConversion(string(""), "Status", string(""), "Condition")
// newer.Scheme.AddStructFieldConversion(string(""), "Condition", string(""), "Status")
newer.Scheme.AddConversionFuncs( newer.Scheme.AddConversionFuncs(
// TypeMeta must be split into two objects // TypeMeta must be split into two objects
func(in *newer.TypeMeta, out *TypeMeta, s conversion.Scope) error { func(in *newer.TypeMeta, out *TypeMeta, s conversion.Scope) error {
@ -439,5 +443,36 @@ func init() {
out.FieldPath = in.FieldPath out.FieldPath = in.FieldPath
return nil return nil
}, },
// Event Status -> Condition
// TODO: remove this when it becomes possible to specify a field name conversion on a specific type
func(in *newer.Event, out *Event, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil {
return err
}
out.Status = in.Condition
out.Reason = in.Reason
out.Message = in.Message
out.Source = in.Source
out.Timestamp = in.Timestamp
return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0)
},
func(in *Event, out *newer.Event, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Condition = in.Status
out.Reason = in.Reason
out.Message = in.Message
out.Source = in.Source
out.Timestamp = in.Timestamp
return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0)
},
) )
} }

View File

@ -751,7 +751,7 @@ type Event struct {
// Should be a short, machine understandable string that describes the current status // Should be a short, machine understandable string that describes the current status
// of the referred object. This should not give the reason for being in this state. // of the referred object. This should not give the reason for being in this state.
// Examples: "running", "cantStart", "cantSchedule", "deleted". // Examples: "Running", "CantStart", "CantSchedule", "Deleted".
// It's OK for components to make up statuses to report here, but the same string should // It's OK for components to make up statuses to report here, but the same string should
// always be used for the same status. // always be used for the same status.
// TODO: define a way of making sure these are consistent and don't collide. // TODO: define a way of making sure these are consistent and don't collide.
@ -760,7 +760,7 @@ type Event struct {
// Optional; this should be a short, machine understandable string that gives the reason // Optional; this should be a short, machine understandable string that gives the reason
// for the transition into the object's current status. For example, if ObjectStatus is // for the transition into the object's current status. For example, if ObjectStatus is
// "cantStart", StatusReason might be "imageNotFound". // "CantStart", Reason might be "ImageNotFound".
// TODO: provide exact specification for format. // TODO: provide exact specification for format.
Reason string `json:"reason,omitempty" description:"short, machine understandable string that gives the reason for the transition into the object's current status"` Reason string `json:"reason,omitempty" description:"short, machine understandable string that gives the reason for the transition into the object's current status"`

View File

@ -973,18 +973,18 @@ type Event struct {
// Required. The object that this event is about. // Required. The object that this event is about.
InvolvedObject ObjectReference `json:"involvedObject,omitempty"` InvolvedObject ObjectReference `json:"involvedObject,omitempty"`
// Should be a short, machine understandable string that describes the current status // Should be a short, machine understandable string that describes the current condition
// of the referred object. This should not give the reason for being in this state. // of the referred object. This should not give the reason for being in this state.
// Examples: "Running", "CantStart", "CantSchedule", "Deleted". // Examples: "Running", "CantStart", "CantSchedule", "Deleted".
// It's OK for components to make up statuses to report here, but the same string should // It's OK for components to make up conditions to report here, but the same string should
// always be used for the same status. // always be used for the same conditions.
// TODO: define a way of making sure these are consistent and don't collide. // TODO: define a way of making sure these are consistent and don't collide.
// TODO: provide exact specification for format. // TODO: provide exact specification for format.
Condition string `json:"condition,omitempty"` Condition string `json:"condition,omitempty"`
// Optional; this should be a short, machine understandable string that gives the reason // Optional; this should be a short, machine understandable string that gives the reason
// for the transition into the object's current status. For example, if ObjectStatus is // for the transition into the object's current condition. For example, if ObjectCondition is
// "cantStart", StatusReason might be "imageNotFound". // "CantStart", StatusReason might be "ImageNotFound".
// TODO: provide exact specification for format. // TODO: provide exact specification for format.
Reason string `json:"reason,omitempty"` Reason string `json:"reason,omitempty"`

View File

@ -62,7 +62,8 @@ func TestEventCreate(t *testing.T) {
} }
timeStamp := util.Now() timeStamp := util.Now()
event := &api.Event{ event := &api.Event{
Status: "running", //namespace: namespace{"default"},
Condition: "Running",
InvolvedObject: *objReference, InvolvedObject: *objReference,
Timestamp: timeStamp, Timestamp: timeStamp,
} }
@ -97,7 +98,7 @@ func TestEventGet(t *testing.T) {
} }
timeStamp := util.Now() timeStamp := util.Now()
event := &api.Event{ event := &api.Event{
Status: "running", Condition: "Running",
InvolvedObject: *objReference, InvolvedObject: *objReference,
Timestamp: timeStamp, Timestamp: timeStamp,
} }
@ -135,7 +136,7 @@ func TestEventList(t *testing.T) {
eventList := &api.EventList{ eventList := &api.EventList{
Items: []api.Event{ Items: []api.Event{
{ {
Status: "running", Condition: "Running",
InvolvedObject: *objReference, InvolvedObject: *objReference,
Timestamp: timeStamp, Timestamp: timeStamp,
}, },

View File

@ -89,7 +89,7 @@ func StartRecording(recorder EventRecorder, sourceName string) watch.Interface {
// return value can be ignored or used to stop logging, if desired. // return value can be ignored or used to stop logging, if desired.
func StartLogging(logf func(format string, args ...interface{})) watch.Interface { func StartLogging(logf func(format string, args ...interface{})) watch.Interface {
return GetEvents(func(e *api.Event) { return GetEvents(func(e *api.Event) {
logf("Event(%#v): status: '%v', reason: '%v' %v", e.InvolvedObject, e.Status, e.Reason, e.Message) logf("Event(%#v): status: '%v', reason: '%v' %v", e.InvolvedObject, e.Condition, e.Reason, e.Message)
}) })
} }
@ -123,17 +123,17 @@ var events = watch.NewBroadcaster(queueLen)
// Event constructs an event from the given information and puts it in the queue for sending. // Event constructs an event from the given information and puts it in the queue for sending.
// 'object' is the object this event is about. Event will make a reference-- or you may also // 'object' is the object this event is about. Event will make a reference-- or you may also
// pass a reference to the object directly. // pass a reference to the object directly.
// 'status' is the new status of the object. 'reason' is the reason it now has this status. // 'condition' is the new condition of the object. 'reason' is the reason it now has this status.
// Both 'status' and 'reason' should be short and unique; they will be used to automate // Both 'condition' and 'reason' should be short and unique; they will be used to automate
// handling of events, so imagine people writing switch statements to handle them. You want to // handling of events, so imagine people writing switch statements to handle them. You want to
// make that easy. // make that easy.
// 'message' is intended to be human readable. // 'message' is intended to be human readable.
// //
// The resulting event will be created in the same namespace as the reference object. // The resulting event will be created in the same namespace as the reference object.
func Event(object runtime.Object, status, reason, message string) { func Event(object runtime.Object, condition, reason, message string) {
ref, err := api.GetReference(object) ref, err := api.GetReference(object)
if err != nil { if err != nil {
glog.Errorf("Could not construct reference to: '%#v' due to: '%v'. Will not report event: '%v' '%v' '%v'", object, err, status, reason, message) glog.Errorf("Could not construct reference to: '%#v' due to: '%v'. Will not report event: '%v' '%v' '%v'", object, err, condition, reason, message)
return return
} }
t := util.Now() t := util.Now()
@ -144,7 +144,7 @@ func Event(object runtime.Object, status, reason, message string) {
Namespace: ref.Namespace, Namespace: ref.Namespace,
}, },
InvolvedObject: *ref, InvolvedObject: *ref,
Status: status, Condition: condition,
Reason: reason, Reason: reason,
Message: message, Message: message,
Timestamp: t, Timestamp: t,

View File

@ -69,8 +69,8 @@ func TestEventf(t *testing.T) {
}{ }{
{ {
obj: testRef, obj: testRef,
status: "running", status: "Running",
reason: "started", reason: "Started",
messageFmt: "some verbose message: %v", messageFmt: "some verbose message: %v",
elements: []interface{}{1}, elements: []interface{}{1},
expect: &api.Event{ expect: &api.Event{
@ -86,17 +86,17 @@ func TestEventf(t *testing.T) {
APIVersion: "v1beta1", APIVersion: "v1beta1",
FieldPath: "desiredState.manifest.containers[2]", FieldPath: "desiredState.manifest.containers[2]",
}, },
Status: "running", Condition: "Running",
Reason: "started", Reason: "Started",
Message: "some verbose message: 1", Message: "some verbose message: 1",
Source: "eventTest", Source: "eventTest",
}, },
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:"desiredState.manifest.containers[2]"}): status: 'running', reason: 'started' some verbose message: 1`, expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:"desiredState.manifest.containers[2]"}): status: 'Running', reason: 'Started' some verbose message: 1`,
}, },
{ {
obj: testPod, obj: testPod,
status: "running", status: "Running",
reason: "started", reason: "Started",
messageFmt: "some verbose message: %v", messageFmt: "some verbose message: %v",
elements: []interface{}{1}, elements: []interface{}{1},
expect: &api.Event{ expect: &api.Event{
@ -111,12 +111,12 @@ func TestEventf(t *testing.T) {
UID: "bar", UID: "bar",
APIVersion: "v1beta1", APIVersion: "v1beta1",
}, },
Status: "running", Condition: "Running",
Reason: "started", Reason: "Started",
Message: "some verbose message: 1", Message: "some verbose message: 1",
Source: "eventTest", Source: "eventTest",
}, },
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:""}): status: 'running', reason: 'started' some verbose message: 1`, expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:""}): status: 'Running', reason: 'Started' some verbose message: 1`,
}, },
} }

View File

@ -143,7 +143,7 @@ var replicationControllerColumns = []string{"Name", "Image(s)", "Selector", "Rep
var serviceColumns = []string{"Name", "Labels", "Selector", "IP", "Port"} var serviceColumns = []string{"Name", "Labels", "Selector", "IP", "Port"}
var minionColumns = []string{"Minion identifier", "Labels"} var minionColumns = []string{"Minion identifier", "Labels"}
var statusColumns = []string{"Status"} var statusColumns = []string{"Status"}
var eventColumns = []string{"Name", "Kind", "Status", "Reason", "Message"} var eventColumns = []string{"Name", "Kind", "Condition", "Reason", "Message"}
// addDefaultHandlers adds print handlers for default Kubernetes types. // addDefaultHandlers adds print handlers for default Kubernetes types.
func (h *HumanReadablePrinter) addDefaultHandlers() { func (h *HumanReadablePrinter) addDefaultHandlers() {
@ -272,7 +272,7 @@ func printEvent(event *api.Event, w io.Writer) error {
w, "%s\t%s\t%s\t%s\t%s\n", w, "%s\t%s\t%s\t%s\t%s\n",
event.InvolvedObject.Name, event.InvolvedObject.Name,
event.InvolvedObject.Kind, event.InvolvedObject.Kind,
event.Status, event.Condition,
event.Reason, event.Reason,
event.Message, event.Message,
) )

View File

@ -205,10 +205,10 @@ func describeEvents(el *api.EventList, w io.Writer) {
return return
} }
sort.Sort(sortableEvents(el.Items)) sort.Sort(sortableEvents(el.Items))
fmt.Fprint(w, "Events:\nFrom\tSubobjectPath\tStatus\tReason\tMessage\n") fmt.Fprint(w, "Events:\nFrom\tSubobjectPath\tCondition\tReason\tMessage\n")
for _, e := range el.Items { for _, e := range el.Items {
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n",
e.Source, e.InvolvedObject.FieldPath, e.Status, e.Reason, e.Message) e.Source, e.InvolvedObject.FieldPath, e.Condition, e.Reason, e.Message)
} }
} }

View File

@ -191,7 +191,7 @@ var replicationControllerColumns = []string{"NAME", "IMAGE(S)", "SELECTOR", "REP
var serviceColumns = []string{"NAME", "LABELS", "SELECTOR", "IP", "PORT"} var serviceColumns = []string{"NAME", "LABELS", "SELECTOR", "IP", "PORT"}
var minionColumns = []string{"NAME", "LABELS"} var minionColumns = []string{"NAME", "LABELS"}
var statusColumns = []string{"STATUS"} var statusColumns = []string{"STATUS"}
var eventColumns = []string{"NAME", "KIND", "STATUS", "REASON", "MESSAGE"} var eventColumns = []string{"NAME", "KIND", "CONDITION", "REASON", "MESSAGE"}
// addDefaultHandlers adds print handlers for default Kubernetes types. // addDefaultHandlers adds print handlers for default Kubernetes types.
func (h *HumanReadablePrinter) addDefaultHandlers() { func (h *HumanReadablePrinter) addDefaultHandlers() {
@ -320,7 +320,7 @@ func printEvent(event *api.Event, w io.Writer) error {
w, "%s\t%s\t%s\t%s\t%s\n", w, "%s\t%s\t%s\t%s\t%s\n",
event.InvolvedObject.Name, event.InvolvedObject.Name,
event.InvolvedObject.Kind, event.InvolvedObject.Kind,
event.Status, event.Condition,
event.Reason, event.Reason,
event.Message, event.Message,
) )

View File

@ -106,7 +106,8 @@ func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, e
"involvedObject.apiVersion": event.InvolvedObject.APIVersion, "involvedObject.apiVersion": event.InvolvedObject.APIVersion,
"involvedObject.resourceVersion": fmt.Sprintf("%s", event.InvolvedObject.ResourceVersion), "involvedObject.resourceVersion": fmt.Sprintf("%s", event.InvolvedObject.ResourceVersion),
"involvedObject.fieldPath": event.InvolvedObject.FieldPath, "involvedObject.fieldPath": event.InvolvedObject.FieldPath,
"status": event.Status, "condition": event.Condition,
"status": event.Condition, // TODO: remove me when we version fields
"reason": event.Reason, "reason": event.Reason,
"source": event.Source, "source": event.Source,
}, nil }, nil

View File

@ -143,8 +143,8 @@ func TestRESTgetAttrs(t *testing.T) {
ResourceVersion: "0", ResourceVersion: "0",
FieldPath: "", FieldPath: "",
}, },
Status: "tested", Condition: "Tested",
Reason: "forTesting", Reason: "ForTesting",
Source: "test", Source: "test",
} }
label, field, err := rest.getAttrs(eventA) label, field, err := rest.getAttrs(eventA)
@ -162,8 +162,9 @@ func TestRESTgetAttrs(t *testing.T) {
"involvedObject.apiVersion": testapi.Version(), "involvedObject.apiVersion": testapi.Version(),
"involvedObject.resourceVersion": "0", "involvedObject.resourceVersion": "0",
"involvedObject.fieldPath": "", "involvedObject.fieldPath": "",
"status": "tested", "condition": "Tested",
"reason": "forTesting", "status": "Tested",
"reason": "ForTesting",
"source": "test", "source": "test",
} }
if e, a := expect, field; !reflect.DeepEqual(e, a) { if e, a := expect, field; !reflect.DeepEqual(e, a) {
@ -196,8 +197,8 @@ func TestRESTList(t *testing.T) {
ResourceVersion: "0", ResourceVersion: "0",
FieldPath: "", FieldPath: "",
}, },
Status: "tested", Condition: "Tested",
Reason: "forTesting", Reason: "ForTesting",
} }
eventB := &api.Event{ eventB := &api.Event{
InvolvedObject: api.ObjectReference{ InvolvedObject: api.ObjectReference{
@ -208,8 +209,8 @@ func TestRESTList(t *testing.T) {
ResourceVersion: "0", ResourceVersion: "0",
FieldPath: "", FieldPath: "",
}, },
Status: "tested", Condition: "Tested",
Reason: "forTesting", Reason: "ForTesting",
} }
eventC := &api.Event{ eventC := &api.Event{
InvolvedObject: api.ObjectReference{ InvolvedObject: api.ObjectReference{
@ -220,13 +221,13 @@ func TestRESTList(t *testing.T) {
ResourceVersion: "0", ResourceVersion: "0",
FieldPath: "", FieldPath: "",
}, },
Status: "untested", Condition: "Untested",
Reason: "forTesting", Reason: "ForTesting",
} }
reg.ObjectList = &api.EventList{ reg.ObjectList = &api.EventList{
Items: []api.Event{*eventA, *eventB, *eventC}, Items: []api.Event{*eventA, *eventB, *eventC},
} }
got, err := rest.List(api.NewContext(), labels.Everything(), labels.Set{"status": "tested"}.AsSelector()) got, err := rest.List(api.NewContext(), labels.Everything(), labels.Set{"status": "Tested"}.AsSelector())
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
@ -248,8 +249,8 @@ func TestRESTWatch(t *testing.T) {
ResourceVersion: "0", ResourceVersion: "0",
FieldPath: "", FieldPath: "",
}, },
Status: "tested", Condition: "Tested",
Reason: "forTesting", Reason: "ForTesting",
} }
reg, rest := NewTestREST() reg, rest := NewTestREST()
wi, err := rest.Watch(api.NewContext(), labels.Everything(), labels.Everything(), "0") wi, err := rest.Watch(api.NewContext(), labels.Everything(), labels.Everything(), "0")