From 4cb69036f8df809a80331fc312faad1d15b6efea Mon Sep 17 00:00:00 2001 From: Victor Marmol Date: Wed, 1 Apr 2015 09:17:43 -0700 Subject: [PATCH] Move Event to info since it is a public API object. --- api/handler.go | 6 ++--- api/versions_test.go | 9 ++++--- events/handler.go | 55 ++++++++++------------------------------- events/handler_test.go | 23 ++++++++--------- info/v1/container.go | 30 ++++++++++++++++++++++ manager/manager.go | 16 ++++++------ manager/manager_mock.go | 6 ++--- 7 files changed, 74 insertions(+), 71 deletions(-) diff --git a/api/handler.go b/api/handler.go index f255130d..4caa247e 100644 --- a/api/handler.go +++ b/api/handler.go @@ -204,19 +204,19 @@ func getEventRequest(r *http.Request) (*events.Request, bool, error) { if val, ok := urlMap["oom_events"]; ok { newBool, err := strconv.ParseBool(val[0]) if err == nil { - query.EventType[events.TypeOom] = newBool + query.EventType[info.EventOom] = newBool } } if val, ok := urlMap["creation_events"]; ok { newBool, err := strconv.ParseBool(val[0]) if err == nil { - query.EventType[events.TypeContainerCreation] = newBool + query.EventType[info.EventContainerCreation] = newBool } } if val, ok := urlMap["deletion_events"]; ok { newBool, err := strconv.ParseBool(val[0]) if err == nil { - query.EventType[events.TypeContainerDeletion] = newBool + query.EventType[info.EventContainerDeletion] = newBool } } if val, ok := urlMap["max_events"]; ok { diff --git a/api/versions_test.go b/api/versions_test.go index 26709827..e655eeb0 100644 --- a/api/versions_test.go +++ b/api/versions_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/google/cadvisor/events" + info "github.com/google/cadvisor/info/v1" "github.com/stretchr/testify/assert" ) @@ -35,8 +36,8 @@ func makeHTTPRequest(requestURL string, t *testing.T) *http.Request { func TestGetEventRequestBasicRequest(t *testing.T) { r := makeHTTPRequest("http://localhost:8080/api/v1.3/events?oom_events=true&historical=true&max_events=10", t) expectedQuery := &events.Request{ - EventType: map[events.EventType]bool{ - events.TypeOom: true, + EventType: map[info.EventType]bool{ + info.EventOom: true, }, MaxEventsReturned: 10, } @@ -66,8 +67,8 @@ func TestGetEventEmptyRequest(t *testing.T) { func TestGetEventRequestDoubleArgument(t *testing.T) { r := makeHTTPRequest("http://localhost:8080/api/v1.3/events?historical=true&oom_events=true&oom_events=false", t) expectedQuery := &events.Request{ - EventType: map[events.EventType]bool{ - events.TypeOom: true, + EventType: map[info.EventType]bool{ + info.EventOom: true, }, } diff --git a/events/handler.go b/events/handler.go index cb6a56c5..92089b4a 100644 --- a/events/handler.go +++ b/events/handler.go @@ -22,6 +22,7 @@ import ( "time" "github.com/golang/glog" + info "github.com/google/cadvisor/info/v1" ) // EventManager is implemented by Events. It provides two ways to monitor @@ -35,7 +36,7 @@ type EventManager interface { GetEvents(request *Request) (EventSlice, error) // AddEvent allows the caller to add an event to an EventManager // object - AddEvent(e *Event) error + AddEvent(e *info.Event) error // Removes a watch instance from the EventManager's watchers map StopWatch(watch_id int) } @@ -80,22 +81,7 @@ type watch struct { } // typedef of a slice of Event pointers -type EventSlice []*Event - -// Event contains information general to events such as the time at which they -// occurred, their specific type, and the actual event. Event types are -// differentiated by the EventType field of Event. -type Event struct { - // the absolute container name for which the event occurred - ContainerName string - // the time at which the event occurred - Timestamp time.Time - // the type of event. EventType is an enumerated type - EventType EventType - // the original event object and all of its extraneous data, ex. an - // OomInstance - EventData EventDataInterface -} +type EventSlice []*info.Event // Request holds a set of parameters by which Event objects may be screened. // The caller may want events that occurred within a specific timeframe @@ -109,7 +95,7 @@ type Request struct { // must be left blank in calls to WatchEvents EndTime time.Time // EventType is a map that specifies the type(s) of events wanted - EventType map[EventType]bool + EventType map[info.EventType]bool // allows the caller to put a limit on how many // events they receive. If there are more events than MaxEventsReturned // then the most chronologically recent events in the time period @@ -122,30 +108,15 @@ type Request struct { IncludeSubcontainers bool } -// EventType is an enumerated type which lists the categories under which -// events may fall. The Event field EventType is populated by this enum. -type EventType int - -const ( - TypeOom EventType = iota - TypeContainerCreation - TypeContainerDeletion -) - -// a general interface which populates the Event field EventData. The actual -// object, such as an OomInstance, is set as an Event's EventData -type EventDataInterface interface { -} - type EventChannel struct { watchId int - channel chan *Event + channel chan *info.Event } func NewEventChannel(watchId int) *EventChannel { return &EventChannel{ watchId: watchId, - channel: make(chan *Event, 10), + channel: make(chan *info.Event, 10), } } @@ -160,7 +131,7 @@ func NewEventManager() *events { // returns a pointer to an initialized Request object func NewRequest() *Request { return &Request{ - EventType: map[EventType]bool{}, + EventType: map[info.EventType]bool{}, IncludeSubcontainers: false, } } @@ -173,7 +144,7 @@ func newWatch(request *Request, eventChannel *EventChannel) *watch { } } -func (self *EventChannel) GetChannel() chan *Event { +func (self *EventChannel) GetChannel() chan *info.Event { return self.channel } @@ -210,7 +181,7 @@ func getMaxEventsReturned(request *Request, eSlice EventSlice) EventSlice { // container path is a prefix of the event container path. Otherwise, // it checks that the container paths of the event and request are // equivalent -func checkIfIsSubcontainer(request *Request, event *Event) bool { +func checkIfIsSubcontainer(request *Request, event *info.Event) bool { if request.IncludeSubcontainers == true { return strings.HasPrefix(event.ContainerName+"/", request.ContainerName+"/") } @@ -218,7 +189,7 @@ func checkIfIsSubcontainer(request *Request, event *Event) bool { } // determines if an event occurs within the time set in the request object and is the right type -func checkIfEventSatisfiesRequest(request *Request, event *Event) bool { +func checkIfEventSatisfiesRequest(request *Request, event *info.Event) bool { startTime := request.StartTime endTime := request.EndTime eventTime := event.Timestamp @@ -280,13 +251,13 @@ func (self *events) WatchEvents(request *Request) (*EventChannel, error) { } // helper function to update the event manager's eventlist -func (self *events) updateEventList(e *Event) { +func (self *events) updateEventList(e *info.Event) { self.eventsLock.Lock() defer self.eventsLock.Unlock() self.eventlist = append(self.eventlist, e) } -func (self *events) findValidWatchers(e *Event) []*watch { +func (self *events) findValidWatchers(e *info.Event) []*watch { watchesToSend := make([]*watch, 0) for _, watcher := range self.watchers { watchRequest := watcher.request @@ -300,7 +271,7 @@ func (self *events) findValidWatchers(e *Event) []*watch { // method of Events object that adds the argument Event object to the // eventlist. It also feeds the event to a set of watch channels // held by the manager if it satisfies the request keys of the channels -func (self *events) AddEvent(e *Event) error { +func (self *events) AddEvent(e *info.Event) error { self.updateEventList(e) self.watcherLock.RLock() defer self.watcherLock.RUnlock() diff --git a/events/handler_test.go b/events/handler_test.go index 7ff9fbef..d11b4b9b 100644 --- a/events/handler_test.go +++ b/events/handler_test.go @@ -18,6 +18,7 @@ import ( "testing" "time" + info "github.com/google/cadvisor/info/v1" "github.com/stretchr/testify/assert" ) @@ -33,16 +34,16 @@ func createOldTime(t *testing.T) time.Time { } // used to convert an OomInstance to an Event object -func makeEvent(inTime time.Time, containerName string) *Event { - return &Event{ +func makeEvent(inTime time.Time, containerName string) *info.Event { + return &info.Event{ ContainerName: containerName, Timestamp: inTime, - EventType: TypeOom, + EventType: info.EventOom, } } // returns EventManager and Request to use in tests -func initializeScenario(t *testing.T) (*events, *Request, *Event, *Event) { +func initializeScenario(t *testing.T) (*events, *Request, *info.Event, *info.Event) { fakeEvent := makeEvent(createOldTime(t), "/") fakeEvent2 := makeEvent(time.Now(), "/") @@ -56,7 +57,7 @@ func checkNumberOfEvents(t *testing.T, numEventsExpected int, numEventsReceived } } -func ensureProperEventReturned(t *testing.T, expectedEvent *Event, eventObjectFound *Event) { +func ensureProperEventReturned(t *testing.T, expectedEvent *info.Event, eventObjectFound *info.Event) { if eventObjectFound != expectedEvent { t.Errorf("Expected to find test object %v but found a different object: %v", expectedEvent, eventObjectFound) @@ -67,13 +68,13 @@ func TestCheckIfIsSubcontainer(t *testing.T) { myRequest := NewRequest() myRequest.ContainerName = "/root" - sameContainerEvent := &Event{ + sameContainerEvent := &info.Event{ ContainerName: "/root", } - subContainerEvent := &Event{ + subContainerEvent := &info.Event{ ContainerName: "/root/subdir", } - differentContainerEvent := &Event{ + differentContainerEvent := &info.Event{ ContainerName: "/root-completely-different-container", } @@ -104,7 +105,7 @@ func TestCheckIfIsSubcontainer(t *testing.T) { func TestWatchEventsDetectsNewEvents(t *testing.T) { myEventHolder, myRequest, fakeEvent, fakeEvent2 := initializeScenario(t) - myRequest.EventType[TypeOom] = true + myRequest.EventType[info.EventOom] = true returnEventChannel, err := myEventHolder.WatchEvents(myRequest) assert.Nil(t, err) @@ -145,7 +146,7 @@ func TestAddEventAddsEventsToEventManager(t *testing.T) { func TestGetEventsForOneEvent(t *testing.T) { myEventHolder, myRequest, fakeEvent, fakeEvent2 := initializeScenario(t) myRequest.MaxEventsReturned = 1 - myRequest.EventType[TypeOom] = true + myRequest.EventType[info.EventOom] = true myEventHolder.AddEvent(fakeEvent) myEventHolder.AddEvent(fakeEvent2) @@ -160,7 +161,7 @@ func TestGetEventsForTimePeriod(t *testing.T) { myEventHolder, myRequest, fakeEvent, fakeEvent2 := initializeScenario(t) myRequest.StartTime = createOldTime(t).Add(-1 * time.Second * 10) myRequest.EndTime = createOldTime(t).Add(time.Second * 10) - myRequest.EventType[TypeOom] = true + myRequest.EventType[info.EventOom] = true myEventHolder.AddEvent(fakeEvent) myEventHolder.AddEvent(fakeEvent2) diff --git a/info/v1/container.go b/info/v1/container.go index a6e70fb1..a06d388d 100644 --- a/info/v1/container.go +++ b/info/v1/container.go @@ -473,3 +473,33 @@ func calculateCpuUsage(prev, cur uint64) uint64 { } return cur - prev } + +// Event contains information general to events such as the time at which they +// occurred, their specific type, and the actual event. Event types are +// differentiated by the EventType field of Event. +type Event struct { + // the absolute container name for which the event occurred + ContainerName string + // the time at which the event occurred + Timestamp time.Time + // the type of event. EventType is an enumerated type + EventType EventType + // the original event object and all of its extraneous data, ex. an + // OomInstance + EventData EventDataInterface +} + +// EventType is an enumerated type which lists the categories under which +// events may fall. The Event field EventType is populated by this enum. +type EventType int + +const ( + EventOom EventType = iota + EventContainerCreation + EventContainerDeletion +) + +// a general interface which populates the Event field EventData. The actual +// object, such as an OomInstance, is set as an Event's EventData +type EventDataInterface interface { +} diff --git a/manager/manager.go b/manager/manager.go index 8beace84..30cd9ff4 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -86,7 +86,7 @@ type Manager interface { WatchForEvents(request *events.Request) (*events.EventChannel, error) // Get past events that have been detected and that fit the request. - GetPastEvents(request *events.Request) (events.EventSlice, error) + GetPastEvents(request *events.Request) ([]*info.Event, error) CloseEventChannel(watch_id int) } @@ -671,11 +671,11 @@ func (m *manager) createContainer(containerName string) error { return err } - newEvent := &events.Event{ + newEvent := &info.Event{ ContainerName: contRef.Name, EventData: contSpecs, Timestamp: contSpecs.CreationTime, - EventType: events.TypeContainerCreation, + EventType: info.EventContainerCreation, } err = m.eventHandler.AddEvent(newEvent) if err != nil { @@ -723,10 +723,10 @@ func (m *manager) destroyContainer(containerName string) error { return err } - newEvent := &events.Event{ + newEvent := &info.Event{ ContainerName: contRef.Name, Timestamp: time.Now(), - EventType: events.TypeContainerDeletion, + EventType: info.EventContainerDeletion, } err = m.eventHandler.AddEvent(newEvent) if err != nil { @@ -874,10 +874,10 @@ func (self *manager) watchForNewOoms() error { go func() { for oomInstance := range outStream { - newEvent := &events.Event{ + newEvent := &info.Event{ ContainerName: oomInstance.ContainerName, Timestamp: oomInstance.TimeOfDeath, - EventType: events.TypeOom, + EventType: info.EventOom, EventData: oomInstance, } glog.V(1).Infof("Created an oom event: %v", newEvent) @@ -896,7 +896,7 @@ func (self *manager) WatchForEvents(request *events.Request) (*events.EventChann } // can be called by the api which will return all events satisfying the request -func (self *manager) GetPastEvents(request *events.Request) (events.EventSlice, error) { +func (self *manager) GetPastEvents(request *events.Request) ([]*info.Event, error) { return self.eventHandler.GetEvents(request) } diff --git a/manager/manager_mock.go b/manager/manager_mock.go index d732da09..a74fda5f 100644 --- a/manager/manager_mock.go +++ b/manager/manager_mock.go @@ -70,14 +70,14 @@ func (c *ManagerMock) GetRequestedContainersInfo(containerName string, options v return args.Get(0).(map[string]*info.ContainerInfo), args.Error(1) } -func (c *ManagerMock) WatchForEvents(queryuest *events.Request, passedChannel chan *events.Event) error { +func (c *ManagerMock) WatchForEvents(queryuest *events.Request, passedChannel chan *info.Event) error { args := c.Called(queryuest, passedChannel) return args.Error(0) } -func (c *ManagerMock) GetPastEvents(queryuest *events.Request) (events.EventSlice, error) { +func (c *ManagerMock) GetPastEvents(queryuest *events.Request) ([]*info.Event, error) { args := c.Called(queryuest) - return args.Get(0).(events.EventSlice), args.Error(1) + return args.Get(0).([]*info.Event), args.Error(1) } func (c *ManagerMock) GetMachineInfo() (*info.MachineInfo, error) {