Add timestamp for events

Relates-To: #339
Change-Id: Iec939e167b6ae3c72aa31e102407d0fffc370766
This commit is contained in:
Vladislav Kuzmin 2020-10-15 16:49:01 +04:00
parent f681da04f2
commit f9f8c43e8a
5 changed files with 113 additions and 128 deletions

View File

@ -83,22 +83,16 @@ func (c *Executor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
return
}
evtCh <- events.Event{
Type: events.IsogenType,
IsogenEvent: events.IsogenEvent{
Operation: events.IsogenStart,
Message: "starting ISO generation",
},
}
evtCh <- events.NewEvent().WithIsogenEvent(events.IsogenEvent{
Operation: events.IsogenStart,
Message: "starting ISO generation",
})
if opts.DryRun {
log.Print("command isogen will be executed")
evtCh <- events.Event{
Type: events.IsogenType,
IsogenEvent: events.IsogenEvent{
Operation: events.IsogenEnd,
},
}
evtCh <- events.NewEvent().WithIsogenEvent(events.IsogenEvent{
Operation: events.IsogenEnd,
})
return
}
@ -131,26 +125,20 @@ func (c *Executor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
return
}
evtCh <- events.Event{
Type: events.IsogenType,
IsogenEvent: events.IsogenEvent{
Operation: events.IsogenValidation,
Message: "image is generated successfully, verifying artifacts",
},
}
evtCh <- events.NewEvent().WithIsogenEvent(events.IsogenEvent{
Operation: events.IsogenValidation,
Message: "image is generated successfully, verifying artifacts",
})
err = verifyArtifacts(c.imgConf)
if err != nil {
handleError(evtCh, err)
return
}
evtCh <- events.Event{
Type: events.IsogenType,
IsogenEvent: events.IsogenEvent{
Operation: events.IsogenEnd,
Message: "iso generation is complete and artifacts verified",
},
}
evtCh <- events.NewEvent().WithIsogenEvent(events.IsogenEvent{
Operation: events.IsogenEnd,
Message: "iso generation is complete and artifacts verified",
})
}
// Validate executor configuration and documents
@ -166,10 +154,7 @@ func (c *Executor) Render(w io.Writer, _ ifc.RenderOptions) error {
}
func handleError(ch chan<- events.Event, err error) {
ch <- events.Event{
Type: events.ErrorType,
ErrorEvent: events.ErrorEvent{
Error: err,
},
}
ch <- events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}

View File

@ -16,6 +16,7 @@ package isogen
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -109,24 +110,15 @@ func TestExecutorRun(t *testing.T) {
waitUntilFinished: func() error { return nil },
},
expectedEvt: []events.Event{
{
Type: events.IsogenType,
IsogenEvent: events.IsogenEvent{
Operation: events.IsogenStart,
},
},
{
Type: events.IsogenType,
IsogenEvent: events.IsogenEvent{
Operation: events.IsogenValidation,
},
},
{
Type: events.IsogenType,
IsogenEvent: events.IsogenEvent{
Operation: events.IsogenEnd,
},
},
events.NewEvent().WithIsogenEvent(events.IsogenEvent{
Operation: events.IsogenStart,
}),
events.NewEvent().WithIsogenEvent(events.IsogenEvent{
Operation: events.IsogenValidation,
}),
events.NewEvent().WithIsogenEvent(events.IsogenEvent{
Operation: events.IsogenEnd,
}),
},
},
{
@ -140,12 +132,9 @@ func TestExecutorRun(t *testing.T) {
},
expectedEvt: []events.Event{
{
Type: events.IsogenType,
IsogenEvent: events.IsogenEvent{
Operation: events.IsogenStart,
},
},
events.NewEvent().WithIsogenEvent(events.IsogenEvent{
Operation: events.IsogenStart,
}),
wrapError(container.ErrRunContainerCommand{Cmd: "super fail"}),
},
},
@ -163,24 +152,27 @@ func TestExecutorRun(t *testing.T) {
go executor.Run(ch, ifc.RunOptions{})
var actualEvt []events.Event
for evt := range ch {
// Skip timestamp for comparison
evt.Timestamp = time.Time{}
if evt.Type == events.IsogenType {
// Set message to empty string, so it's not compared
evt.IsogenEvent.Message = ""
}
actualEvt = append(actualEvt, evt)
}
for i := range tt.expectedEvt {
// Skip timestamp for comparison
tt.expectedEvt[i].Timestamp = time.Time{}
}
assert.Equal(t, tt.expectedEvt, actualEvt)
})
}
}
func wrapError(err error) events.Event {
return events.Event{
Type: events.ErrorType,
ErrorEvent: events.ErrorEvent{
Error: err,
},
}
return events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}
func testBundleFactory(path string) document.BundleFactoryFunc {

View File

@ -84,13 +84,10 @@ func (c *ClusterctlExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
}
func (c *ClusterctlExecutor) move(opts ifc.RunOptions, evtCh chan events.Event) {
evtCh <- events.Event{
Type: events.ClusterctlType,
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlMoveStart,
Message: "starting clusterctl move executor",
},
}
evtCh <- events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
Operation: events.ClusterctlMoveStart,
Message: "starting clusterctl move executor",
})
ns := c.options.MoveOptions.Namespace
kubeConfigFile, cleanup, err := c.kubecfg.GetFile()
if err != nil {
@ -113,23 +110,17 @@ func (c *ClusterctlExecutor) move(opts ifc.RunOptions, evtCh chan events.Event)
}
}
evtCh <- events.Event{
Type: events.ClusterctlType,
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlMoveEnd,
Message: "clusterctl move completed successfully",
},
}
evtCh <- events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
Operation: events.ClusterctlMoveEnd,
Message: "clusterctl move completed successfully",
})
}
func (c *ClusterctlExecutor) init(opts ifc.RunOptions, evtCh chan events.Event) {
evtCh <- events.Event{
Type: events.ClusterctlType,
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitStart,
Message: "starting clusterctl init executor",
},
}
evtCh <- events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
Operation: events.ClusterctlInitStart,
Message: "starting clusterctl init executor",
})
kubeConfigFile, cleanup, err := c.kubecfg.GetFile()
if err != nil {
c.handleErr(err, evtCh)
@ -141,13 +132,10 @@ func (c *ClusterctlExecutor) init(opts ifc.RunOptions, evtCh chan events.Event)
if opts.DryRun {
// TODO (dukov) add more details to dry-run
log.Print("command 'clusterctl init' is going to be executed")
evtCh <- events.Event{
Type: events.ClusterctlType,
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitEnd,
Message: "clusterctl init dry-run completed successfully",
},
}
evtCh <- events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
Operation: events.ClusterctlInitEnd,
Message: "clusterctl init dry-run completed successfully",
})
return
}
// Use cluster name as context in kubeconfig file
@ -155,22 +143,16 @@ func (c *ClusterctlExecutor) init(opts ifc.RunOptions, evtCh chan events.Event)
if err != nil {
c.handleErr(err, evtCh)
}
evtCh <- events.Event{
Type: events.ClusterctlType,
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitEnd,
Message: "clusterctl init completed successfully",
},
}
evtCh <- events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
Operation: events.ClusterctlInitEnd,
Message: "clusterctl init completed successfully",
})
}
func (c *ClusterctlExecutor) handleErr(err error, evtCh chan events.Event) {
evtCh <- events.Event{
Type: events.ErrorType,
ErrorEvent: events.ErrorEvent{
Error: err,
},
}
evtCh <- events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}
// Validate executor configuration and documents

View File

@ -19,6 +19,7 @@ import (
"errors"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -122,12 +123,9 @@ func TestExecutorRun(t *testing.T) {
},
bundlePath: "testdata/executor_init",
expectedEvt: []events.Event{
{
Type: events.ClusterctlType,
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitStart,
},
},
events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
Operation: events.ClusterctlInitStart,
}),
wrapError(errTmpFile),
},
},
@ -146,18 +144,12 @@ func TestExecutorRun(t *testing.T) {
},
bundlePath: "testdata/executor_init",
expectedEvt: []events.Event{
{
Type: events.ClusterctlType,
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitStart,
},
},
{
Type: events.ClusterctlType,
ClusterctlEvent: events.ClusterctlEvent{
Operation: events.ClusterctlInitEnd,
},
},
events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
Operation: events.ClusterctlInitStart,
}),
events.NewEvent().WithClusterctlEvent(events.ClusterctlEvent{
Operation: events.ClusterctlInitEnd,
}),
},
},
// TODO add move tests here
@ -180,12 +172,18 @@ func TestExecutorRun(t *testing.T) {
go executor.Run(ch, ifc.RunOptions{DryRun: true})
var actualEvt []events.Event
for evt := range ch {
// Skip timmestamp for comparison
evt.Timestamp = time.Time{}
if evt.Type == events.ClusterctlType {
// Set message to empty string, so it's not compared
evt.ClusterctlEvent.Message = ""
}
actualEvt = append(actualEvt, evt)
}
for i := range tt.expectedEvt {
// Skip timmestamp for comparison
tt.expectedEvt[i].Timestamp = time.Time{}
}
assert.Equal(t, tt.expectedEvt, actualEvt)
})
}
@ -237,10 +235,7 @@ func executorDoc(t *testing.T, action string) document.Document {
}
func wrapError(err error) events.Event {
return events.Event{
Type: events.ErrorType,
ErrorEvent: events.ErrorEvent{
Error: err,
},
}
return events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}

View File

@ -15,6 +15,8 @@
package events
import (
"time"
applyevent "sigs.k8s.io/cli-utils/pkg/apply/event"
statuspollerevent "sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
)
@ -40,6 +42,7 @@ const (
// Event holds all possible events that can be produced by airship
type Event struct {
Type Type
Timestamp time.Time
ApplierEvent applyevent.Event
ErrorEvent ErrorEvent
StatusPollerEvent statuspollerevent.Event
@ -47,11 +50,25 @@ type Event struct {
IsogenEvent IsogenEvent
}
// NewEvent create new event with timestamp
func NewEvent() Event {
return Event{
Timestamp: time.Now(),
}
}
// ErrorEvent is produced when error is encountered
type ErrorEvent struct {
Error error
}
// WithErrorEvent sets type and actual error event
func (e Event) WithErrorEvent(event ErrorEvent) Event {
e.Type = ErrorType
e.ErrorEvent = event
return e
}
// ClusterctlOperation type
type ClusterctlOperation int
@ -72,6 +89,13 @@ type ClusterctlEvent struct {
Message string
}
// WithClusterctlEvent sets type and actual clusterctl event
func (e Event) WithClusterctlEvent(concreteEvent ClusterctlEvent) Event {
e.Type = ClusterctlType
e.ClusterctlEvent = concreteEvent
return e
}
// IsogenOperation type
type IsogenOperation int
@ -89,3 +113,10 @@ type IsogenEvent struct {
Operation IsogenOperation
Message string
}
// WithIsogenEvent sets type and actual isogen event
func (e Event) WithIsogenEvent(concreteEvent IsogenEvent) Event {
e.Type = IsogenType
e.IsogenEvent = concreteEvent
return e
}