2014-10-11 00:46:38 +00:00
/ *
2015-05-01 16:19:44 +00:00
Copyright 2014 The Kubernetes Authors All rights reserved .
2014-10-11 00:46:38 +00:00
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 .
* /
2015-01-09 18:02:48 +00:00
package record
2014-10-11 00:46:38 +00:00
import (
"fmt"
"reflect"
2015-01-10 00:58:07 +00:00
"strconv"
2014-10-30 00:27:11 +00:00
"strings"
2014-10-11 00:46:38 +00:00
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
2014-11-21 00:01:42 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
2014-10-11 00:46:38 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
2015-01-09 18:02:48 +00:00
func init ( ) {
2015-01-10 00:58:07 +00:00
// Don't bother sleeping between retries.
2015-01-13 19:13:24 +00:00
sleepDuration = 0
2015-01-09 18:02:48 +00:00
}
2015-03-03 06:06:20 +00:00
type testEventSink struct {
2015-02-11 00:49:32 +00:00
OnCreate func ( e * api . Event ) ( * api . Event , error )
OnUpdate func ( e * api . Event ) ( * api . Event , error )
2014-10-11 00:46:38 +00:00
}
// CreateEvent records the event for testing.
2015-03-03 06:06:20 +00:00
func ( t * testEventSink ) Create ( e * api . Event ) ( * api . Event , error ) {
2015-02-11 00:49:32 +00:00
if t . OnCreate != nil {
return t . OnCreate ( e )
2014-10-11 00:46:38 +00:00
}
return e , nil
}
2015-02-11 00:49:32 +00:00
// UpdateEvent records the event for testing.
2015-03-03 06:06:20 +00:00
func ( t * testEventSink ) Update ( e * api . Event ) ( * api . Event , error ) {
2015-02-11 00:49:32 +00:00
if t . OnUpdate != nil {
return t . OnUpdate ( e )
}
return e , nil
2014-10-11 00:46:38 +00:00
}
func TestEventf ( t * testing . T ) {
2014-11-04 00:06:36 +00:00
testPod := & api . Pod {
ObjectMeta : api . ObjectMeta {
2015-04-08 23:28:28 +00:00
SelfLink : "/api/version/pods/foo" ,
2014-11-04 00:06:36 +00:00
Name : "foo" ,
Namespace : "baz" ,
UID : "bar" ,
} ,
}
2015-02-11 00:49:32 +00:00
testPod2 := & api . Pod {
ObjectMeta : api . ObjectMeta {
2015-04-08 23:28:28 +00:00
SelfLink : "/api/version/pods/foo" ,
2015-02-11 00:49:32 +00:00
Name : "foo" ,
Namespace : "baz" ,
UID : "differentUid" ,
} ,
}
2015-06-09 17:45:46 +00:00
testRef , err := api . GetPartialReference ( testPod , "spec.containers[2]" )
testRef2 , err := api . GetPartialReference ( testPod2 , "spec.containers[3]" )
2014-11-04 00:06:36 +00:00
if err != nil {
t . Fatal ( err )
}
2014-10-11 00:46:38 +00:00
table := [ ] struct {
2015-02-11 00:49:32 +00:00
obj runtime . Object
reason string
messageFmt string
elements [ ] interface { }
expect * api . Event
expectLog string
expectUpdate bool
2014-10-11 00:46:38 +00:00
} {
{
2014-11-04 00:06:36 +00:00
obj : testRef ,
2014-12-12 21:27:25 +00:00
reason : "Started" ,
2014-11-04 00:06:36 +00:00
messageFmt : "some verbose message: %v" ,
elements : [ ] interface { } { 1 } ,
expect : & api . Event {
2014-10-23 20:51:34 +00:00
ObjectMeta : api . ObjectMeta {
2014-10-30 00:27:11 +00:00
Name : "foo" ,
Namespace : "baz" ,
2014-10-11 00:46:38 +00:00
} ,
2014-11-04 00:06:36 +00:00
InvolvedObject : api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "baz" ,
UID : "bar" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2015-06-09 17:45:46 +00:00
FieldPath : "spec.containers[2]" ,
2014-11-04 00:06:36 +00:00
} ,
2015-01-14 01:10:57 +00:00
Reason : "Started" ,
Message : "some verbose message: 1" ,
Source : api . EventSource { Component : "eventTest" } ,
2015-02-06 02:21:01 +00:00
Count : 1 ,
2014-10-11 00:46:38 +00:00
} ,
2015-06-09 17:45:46 +00:00
expectLog : ` Event(api.ObjectReference { Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): reason: 'Started' some verbose message: 1 ` ,
2015-02-11 00:49:32 +00:00
expectUpdate : false ,
2014-11-04 00:06:36 +00:00
} ,
{
obj : testPod ,
2015-02-11 00:49:32 +00:00
reason : "Killed" ,
messageFmt : "some other verbose message: %v" ,
elements : [ ] interface { } { 1 } ,
expect : & api . Event {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "baz" ,
} ,
InvolvedObject : api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "baz" ,
UID : "bar" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2015-02-11 00:49:32 +00:00
} ,
Reason : "Killed" ,
Message : "some other verbose message: 1" ,
Source : api . EventSource { Component : "eventTest" } ,
Count : 1 ,
} ,
2015-04-08 23:28:28 +00:00
expectLog : ` Event(api.ObjectReference { Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:""}): reason: 'Killed' some other verbose message: 1 ` ,
2015-02-11 00:49:32 +00:00
expectUpdate : false ,
} ,
{
obj : testRef ,
2014-12-12 21:27:25 +00:00
reason : "Started" ,
2014-10-11 00:46:38 +00:00
messageFmt : "some verbose message: %v" ,
elements : [ ] interface { } { 1 } ,
expect : & api . Event {
2014-10-30 00:27:11 +00:00
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "baz" ,
} ,
2014-10-11 00:46:38 +00:00
InvolvedObject : api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
2014-10-30 00:27:11 +00:00
Namespace : "baz" ,
2014-10-23 02:59:15 +00:00
UID : "bar" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2015-06-09 17:45:46 +00:00
FieldPath : "spec.containers[2]" ,
2015-02-11 00:49:32 +00:00
} ,
Reason : "Started" ,
Message : "some verbose message: 1" ,
Source : api . EventSource { Component : "eventTest" } ,
Count : 2 ,
} ,
2015-06-09 17:45:46 +00:00
expectLog : ` Event(api.ObjectReference { Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): reason: 'Started' some verbose message: 1 ` ,
2015-02-11 00:49:32 +00:00
expectUpdate : true ,
} ,
{
obj : testRef2 ,
reason : "Started" ,
messageFmt : "some verbose message: %v" ,
elements : [ ] interface { } { 1 } ,
expect : & api . Event {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "baz" ,
} ,
InvolvedObject : api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "baz" ,
UID : "differentUid" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2015-06-09 17:45:46 +00:00
FieldPath : "spec.containers[3]" ,
2014-10-11 00:46:38 +00:00
} ,
2015-01-14 01:10:57 +00:00
Reason : "Started" ,
Message : "some verbose message: 1" ,
Source : api . EventSource { Component : "eventTest" } ,
2015-02-06 02:21:01 +00:00
Count : 1 ,
2014-10-11 00:46:38 +00:00
} ,
2015-06-09 17:45:46 +00:00
expectLog : ` Event(api.ObjectReference { Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): reason: 'Started' some verbose message: 1 ` ,
2015-02-11 00:49:32 +00:00
expectUpdate : false ,
} ,
{
obj : testRef ,
reason : "Started" ,
messageFmt : "some verbose message: %v" ,
elements : [ ] interface { } { 1 } ,
expect : & api . Event {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "baz" ,
} ,
InvolvedObject : api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "baz" ,
UID : "bar" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2015-06-09 17:45:46 +00:00
FieldPath : "spec.containers[2]" ,
2015-02-11 00:49:32 +00:00
} ,
Reason : "Started" ,
Message : "some verbose message: 1" ,
Source : api . EventSource { Component : "eventTest" } ,
Count : 3 ,
} ,
2015-06-09 17:45:46 +00:00
expectLog : ` Event(api.ObjectReference { Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): reason: 'Started' some verbose message: 1 ` ,
2015-02-11 00:49:32 +00:00
expectUpdate : true ,
} ,
{
obj : testRef2 ,
reason : "Stopped" ,
messageFmt : "some verbose message: %v" ,
elements : [ ] interface { } { 1 } ,
expect : & api . Event {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "baz" ,
} ,
InvolvedObject : api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "baz" ,
UID : "differentUid" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2015-06-09 17:45:46 +00:00
FieldPath : "spec.containers[3]" ,
2015-02-11 00:49:32 +00:00
} ,
Reason : "Stopped" ,
Message : "some verbose message: 1" ,
Source : api . EventSource { Component : "eventTest" } ,
Count : 1 ,
} ,
2015-06-09 17:45:46 +00:00
expectLog : ` Event(api.ObjectReference { Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): reason: 'Stopped' some verbose message: 1 ` ,
2015-02-11 00:49:32 +00:00
expectUpdate : false ,
} ,
{
obj : testRef2 ,
reason : "Stopped" ,
messageFmt : "some verbose message: %v" ,
elements : [ ] interface { } { 1 } ,
expect : & api . Event {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "baz" ,
} ,
InvolvedObject : api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "baz" ,
UID : "differentUid" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2015-06-09 17:45:46 +00:00
FieldPath : "spec.containers[3]" ,
2015-02-11 00:49:32 +00:00
} ,
Reason : "Stopped" ,
Message : "some verbose message: 1" ,
Source : api . EventSource { Component : "eventTest" } ,
Count : 2 ,
} ,
2015-06-09 17:45:46 +00:00
expectLog : ` Event(api.ObjectReference { Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): reason: 'Stopped' some verbose message: 1 ` ,
2015-02-11 00:49:32 +00:00
expectUpdate : true ,
2014-10-11 00:46:38 +00:00
} ,
}
for _ , item := range table {
called := make ( chan struct { } )
2015-03-03 06:06:20 +00:00
testEvents := testEventSink {
2015-02-11 00:49:32 +00:00
OnCreate : func ( event * api . Event ) ( * api . Event , error ) {
returnEvent , _ := validateEvent ( event , item . expect , t )
if item . expectUpdate {
t . Errorf ( "Expected event update(), got event create()" )
2014-10-30 00:27:11 +00:00
}
2015-02-11 00:49:32 +00:00
called <- struct { } { }
return returnEvent , nil
} ,
OnUpdate : func ( event * api . Event ) ( * api . Event , error ) {
returnEvent , _ := validateEvent ( event , item . expect , t )
if ! item . expectUpdate {
t . Errorf ( "Expected event create(), got event update()" )
2014-10-11 00:46:38 +00:00
}
called <- struct { } { }
2015-02-11 00:49:32 +00:00
return returnEvent , nil
2014-10-11 00:46:38 +00:00
} ,
}
2015-03-17 04:03:07 +00:00
eventBroadcaster := NewBroadcaster ( )
sinkWatcher := eventBroadcaster . StartRecordingToSink ( & testEvents )
logWatcher1 := eventBroadcaster . StartLogging ( t . Logf ) // Prove that it is useful
logWatcher2 := eventBroadcaster . StartLogging ( func ( formatter string , args ... interface { } ) {
2014-10-11 00:46:38 +00:00
if e , a := item . expectLog , fmt . Sprintf ( formatter , args ... ) ; e != a {
t . Errorf ( "Expected '%v', got '%v'" , e , a )
}
called <- struct { } { }
} )
2015-03-17 04:03:07 +00:00
recorder := eventBroadcaster . NewRecorder ( api . EventSource { Component : "eventTest" } )
recorder . Eventf ( item . obj , item . reason , item . messageFmt , item . elements ... )
2014-10-11 00:46:38 +00:00
<- called
<- called
2015-03-17 04:03:07 +00:00
sinkWatcher . Stop ( )
logWatcher1 . Stop ( )
logWatcher2 . Stop ( )
2014-10-11 00:46:38 +00:00
}
}
2014-11-21 00:01:42 +00:00
2015-02-11 00:49:32 +00:00
func validateEvent ( actualEvent * api . Event , expectedEvent * api . Event , t * testing . T ) ( * api . Event , error ) {
expectCompression := expectedEvent . Count > 1
// Just check that the timestamp was set.
if actualEvent . FirstTimestamp . IsZero ( ) || actualEvent . LastTimestamp . IsZero ( ) {
t . Errorf ( "timestamp wasn't set: %#v" , * actualEvent )
}
if actualEvent . FirstTimestamp . Equal ( actualEvent . LastTimestamp . Time ) {
if expectCompression {
t . Errorf ( "FirstTimestamp (%q) and LastTimestamp (%q) must be equal to indicate only one occurance of the event, but were different. Actual Event: %#v" , actualEvent . FirstTimestamp , actualEvent . LastTimestamp , * actualEvent )
}
} else {
if ! expectCompression {
t . Errorf ( "FirstTimestamp (%q) and LastTimestamp (%q) must be different to indicate event compression happened, but were the same. Actual Event: %#v" , actualEvent . FirstTimestamp , actualEvent . LastTimestamp , * actualEvent )
}
}
actualFirstTimestamp := actualEvent . FirstTimestamp
actualLastTimestamp := actualEvent . LastTimestamp
// Temp clear time stamps for comparison because actual values don't matter for comparison
actualEvent . FirstTimestamp = expectedEvent . FirstTimestamp
actualEvent . LastTimestamp = expectedEvent . LastTimestamp
// Check that name has the right prefix.
if n , en := actualEvent . Name , expectedEvent . Name ; ! strings . HasPrefix ( n , en ) {
t . Errorf ( "Name '%v' does not contain prefix '%v'" , n , en )
}
actualEvent . Name = expectedEvent . Name
if e , a := expectedEvent , actualEvent ; ! reflect . DeepEqual ( e , a ) {
t . Errorf ( "diff: %s" , util . ObjectGoPrintDiff ( e , a ) )
}
actualEvent . FirstTimestamp = actualFirstTimestamp
actualEvent . LastTimestamp = actualLastTimestamp
return actualEvent , nil
}
2014-11-21 00:01:42 +00:00
func TestWriteEventError ( t * testing . T ) {
ref := & api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "baz" ,
UID : "bar" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2014-11-21 00:01:42 +00:00
}
type entry struct {
timesToSendError int
attemptsMade int
attemptsWanted int
err error
}
table := map [ string ] * entry {
"giveUp1" : {
timesToSendError : 1000 ,
attemptsWanted : 1 ,
err : & client . RequestConstructionError { } ,
} ,
"giveUp2" : {
timesToSendError : 1000 ,
attemptsWanted : 1 ,
err : & errors . StatusError { } ,
} ,
"retry1" : {
timesToSendError : 1000 ,
2015-01-13 19:13:24 +00:00
attemptsWanted : 12 ,
2014-11-21 00:01:42 +00:00
err : & errors . UnexpectedObjectError { } ,
} ,
"retry2" : {
timesToSendError : 1000 ,
2015-01-13 19:13:24 +00:00
attemptsWanted : 12 ,
2014-11-21 00:01:42 +00:00
err : fmt . Errorf ( "A weird error" ) ,
} ,
"succeedEventually" : {
timesToSendError : 2 ,
attemptsWanted : 2 ,
err : fmt . Errorf ( "A weird error" ) ,
} ,
}
done := make ( chan struct { } )
2015-03-17 04:03:07 +00:00
eventBroadcaster := NewBroadcaster ( )
defer eventBroadcaster . StartRecordingToSink (
2015-03-03 06:06:20 +00:00
& testEventSink {
2015-02-11 00:49:32 +00:00
OnCreate : func ( event * api . Event ) ( * api . Event , error ) {
2014-11-21 00:01:42 +00:00
if event . Message == "finished" {
close ( done )
return event , nil
}
item , ok := table [ event . Message ]
if ! ok {
t . Errorf ( "Unexpected event: %#v" , event )
return event , nil
}
item . attemptsMade ++
if item . attemptsMade < item . timesToSendError {
return nil , item . err
}
return event , nil
} ,
} ,
) . Stop ( )
2015-03-17 04:03:07 +00:00
recorder := eventBroadcaster . NewRecorder ( api . EventSource { Component : "eventTest" } )
2014-11-21 00:01:42 +00:00
for caseName := range table {
2015-03-17 04:03:07 +00:00
recorder . Event ( ref , "Reason" , caseName )
2014-11-21 00:01:42 +00:00
}
2015-03-17 04:03:07 +00:00
recorder . Event ( ref , "Reason" , "finished" )
2014-11-21 00:01:42 +00:00
<- done
for caseName , item := range table {
if e , a := item . attemptsWanted , item . attemptsMade ; e != a {
t . Errorf ( "case %v: wanted %v, got %v attempts" , caseName , e , a )
}
}
}
2015-01-10 00:58:07 +00:00
func TestLotsOfEvents ( t * testing . T ) {
recorderCalled := make ( chan struct { } )
loggerCalled := make ( chan struct { } )
// Fail each event a few times to ensure there's some load on the tested code.
var counts [ 1000 ] int
2015-03-03 06:06:20 +00:00
testEvents := testEventSink {
2015-02-11 00:49:32 +00:00
OnCreate : func ( event * api . Event ) ( * api . Event , error ) {
2015-01-10 00:58:07 +00:00
num , err := strconv . Atoi ( event . Message )
if err != nil {
t . Error ( err )
return event , nil
}
counts [ num ] ++
if counts [ num ] < 5 {
return nil , fmt . Errorf ( "fake error" )
}
recorderCalled <- struct { } { }
return event , nil
} ,
}
2015-03-17 04:03:07 +00:00
eventBroadcaster := NewBroadcaster ( )
sinkWatcher := eventBroadcaster . StartRecordingToSink ( & testEvents )
logWatcher := eventBroadcaster . StartLogging ( func ( formatter string , args ... interface { } ) {
2015-01-10 00:58:07 +00:00
loggerCalled <- struct { } { }
} )
2015-03-17 04:03:07 +00:00
recorder := eventBroadcaster . NewRecorder ( api . EventSource { Component : "eventTest" } )
2015-01-10 00:58:07 +00:00
ref := & api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "baz" ,
UID : "bar" ,
2015-04-08 23:28:28 +00:00
APIVersion : "version" ,
2015-01-10 00:58:07 +00:00
}
for i := 0 ; i < maxQueuedEvents ; i ++ {
2015-03-17 04:03:07 +00:00
go recorder . Eventf ( ref , "Reason" , strconv . Itoa ( i ) )
2015-01-10 00:58:07 +00:00
}
// Make sure no events were dropped by either of the listeners.
for i := 0 ; i < maxQueuedEvents ; i ++ {
<- recorderCalled
<- loggerCalled
}
// Make sure that every event was attempted 5 times
for i := 0 ; i < maxQueuedEvents ; i ++ {
if counts [ i ] < 5 {
t . Errorf ( "Only attempted to record event '%d' %d times." , i , counts [ i ] )
}
}
2015-03-17 04:03:07 +00:00
sinkWatcher . Stop ( )
logWatcher . Stop ( )
2015-01-10 00:58:07 +00:00
}
2015-04-28 23:08:16 +00:00
func TestEventfNoNamespace ( t * testing . T ) {
testPod := & api . Pod {
ObjectMeta : api . ObjectMeta {
SelfLink : "/api/version/pods/foo" ,
Name : "foo" ,
UID : "bar" ,
} ,
}
2015-06-09 17:45:46 +00:00
testRef , err := api . GetPartialReference ( testPod , "spec.containers[2]" )
2015-04-28 23:08:16 +00:00
if err != nil {
t . Fatal ( err )
}
table := [ ] struct {
obj runtime . Object
reason string
messageFmt string
elements [ ] interface { }
expect * api . Event
expectLog string
expectUpdate bool
} {
{
obj : testRef ,
reason : "Started" ,
messageFmt : "some verbose message: %v" ,
elements : [ ] interface { } { 1 } ,
expect : & api . Event {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "default" ,
} ,
InvolvedObject : api . ObjectReference {
Kind : "Pod" ,
Name : "foo" ,
Namespace : "" ,
UID : "bar" ,
APIVersion : "version" ,
2015-06-09 17:45:46 +00:00
FieldPath : "spec.containers[2]" ,
2015-04-28 23:08:16 +00:00
} ,
Reason : "Started" ,
Message : "some verbose message: 1" ,
Source : api . EventSource { Component : "eventTest" } ,
Count : 1 ,
} ,
2015-06-09 17:45:46 +00:00
expectLog : ` Event(api.ObjectReference { Kind:"Pod", Namespace:"", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): reason: 'Started' some verbose message: 1 ` ,
2015-04-28 23:08:16 +00:00
expectUpdate : false ,
} ,
}
for _ , item := range table {
called := make ( chan struct { } )
testEvents := testEventSink {
OnCreate : func ( event * api . Event ) ( * api . Event , error ) {
returnEvent , _ := validateEvent ( event , item . expect , t )
if item . expectUpdate {
t . Errorf ( "Expected event update(), got event create()" )
}
called <- struct { } { }
return returnEvent , nil
} ,
OnUpdate : func ( event * api . Event ) ( * api . Event , error ) {
returnEvent , _ := validateEvent ( event , item . expect , t )
if ! item . expectUpdate {
t . Errorf ( "Expected event create(), got event update()" )
}
called <- struct { } { }
return returnEvent , nil
} ,
}
eventBroadcaster := NewBroadcaster ( )
sinkWatcher := eventBroadcaster . StartRecordingToSink ( & testEvents )
logWatcher1 := eventBroadcaster . StartLogging ( t . Logf ) // Prove that it is useful
logWatcher2 := eventBroadcaster . StartLogging ( func ( formatter string , args ... interface { } ) {
if e , a := item . expectLog , fmt . Sprintf ( formatter , args ... ) ; e != a {
t . Errorf ( "Expected '%v', got '%v'" , e , a )
}
called <- struct { } { }
} )
recorder := eventBroadcaster . NewRecorder ( api . EventSource { Component : "eventTest" } )
recorder . Eventf ( item . obj , item . reason , item . messageFmt , item . elements ... )
<- called
<- called
sinkWatcher . Stop ( )
logWatcher1 . Stop ( )
logWatcher2 . Stop ( )
}
}