From a8f53c68dfe0fb22e15a2c37704b32a9fe45dcf5 Mon Sep 17 00:00:00 2001 From: Yonghwan SO Date: Fri, 29 Apr 2022 20:17:26 +0900 Subject: [PATCH] refactoring: context, tests for stackdriver --- cmd/bogo/main.go | 2 + exporters/stackdriver.go | 8 ++- exporters/stackdriver_dummy_test.go | 94 +++++++++++++++++++++++++++++ exporters/stackdriver_test.go | 47 +++++++++++++++ version.go | 2 +- 5 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 exporters/stackdriver_dummy_test.go diff --git a/cmd/bogo/main.go b/cmd/bogo/main.go index 414b37e..767621c 100644 --- a/cmd/bogo/main.go +++ b/cmd/bogo/main.go @@ -129,6 +129,8 @@ func startWebRoutine(c common.Context, opts *common.Options) (meari.Server, erro go func() { // nolint defer c.WG().Done() + logger.Info("starting webserver on %s...", server.Address()) + err := server.Serve() if errors.Is(err, http.ErrServerClosed) { logger.Info("webserver closed") diff --git a/exporters/stackdriver.go b/exporters/stackdriver.go index 5512c61..b14524d 100644 --- a/exporters/stackdriver.go +++ b/exporters/stackdriver.go @@ -18,6 +18,7 @@ const ( stackdriverMetricPrefix = "custom.googleapis.com/bogo" stackdriverExporter = "stackdriver" stackdriverExporterInterval = 1 * time.Minute + recordTimeout = 30 * time.Second ) // RegisterStackdriver returns a new Exporter and it is used by StartAll(). @@ -103,7 +104,7 @@ func stackdriverRunner(c common.Context, _ common.PluginOptions, in chan interfa func getReporter(c common.Context) (*reporter, error) { // currently, stackdriver exporter is only suppored on the GCE instance meta := c.Meta() - if meta == nil || meta.WhereAmI() != "Google" { + if meta == nil || meta.WhereAmI() != common.GOOGLE { return nil, common.ErrNotOnGCE } @@ -170,7 +171,10 @@ func createAndStartExporter() (*stackdriver.Exporter, error) { // recordPingMessage sends the given ping message to the Cloud Monitoring. func recordPingMessage(r *reporter, m *bogo.PingMessage) error { - if err := stats.RecordWithTags(context.Background(), + ctx, cancel := context.WithTimeout(context.Background(), recordTimeout) + defer cancel() + + if err := stats.RecordWithTags(ctx, []tag.Mutator{ tag.Upsert(tag.MustNewKey("node"), r.instanceName), tag.Upsert(tag.MustNewKey("addr"), r.externalIP), diff --git a/exporters/stackdriver_dummy_test.go b/exporters/stackdriver_dummy_test.go new file mode 100644 index 0000000..b177642 --- /dev/null +++ b/exporters/stackdriver_dummy_test.go @@ -0,0 +1,94 @@ +package exporters + +import ( + "context" + "sync" + + "github.com/hyeoncheon/bogo/internal/common" +) + +type DummyContext struct { + context.Context // nolint + common.Options + cancel context.CancelFunc + ch chan interface{} + wg *sync.WaitGroup + logger common.Logger + meta common.MetaClient +} + +var _ common.Context = &DummyContext{} + +// Cancel implements common.Context. +func (c *DummyContext) Cancel() { + c.cancel() + c.wg.Wait() + close(c.ch) +} + +// Logger implements common.Context. +func (c *DummyContext) Logger() common.Logger { + return c.logger +} + +// Meta implements common.Context. +func (c *DummyContext) Meta() common.MetaClient { + return c.meta +} + +// WG implements common.Context. +func (c *DummyContext) WG() *sync.WaitGroup { + return c.wg +} + +// Channel implements common.Context. +func (c *DummyContext) Channel() chan interface{} { + return c.ch +} + +type DummyMeta struct { + VarExternalIP string + VarInstanceName string + VarWhereAmI string + VarZone string +} + +// AttributeCSV implements common.MetaClient. +func (*DummyMeta) AttributeCSV(_ string) []string { + panic("unimplemented") +} + +// AttributeSSV implements common.MetaClient. +func (*DummyMeta) AttributeSSV(_ string) []string { + panic("unimplemented") +} + +// AttributeValue implements common.MetaClient. +func (*DummyMeta) AttributeValue(_ string) string { + panic("unimplemented") +} + +// AttributeValues implements common.MetaClient. +func (*DummyMeta) AttributeValues(_ string) []string { + panic("unimplemented") +} + +// ExternalIP implements common.MetaClient. +func (m *DummyMeta) ExternalIP() string { + return m.VarExternalIP +} + +// InstanceName implements common.MetaClient. +func (m *DummyMeta) InstanceName() string { + return m.VarInstanceName +} + +// WhereAmI implements common.MetaClient. +func (m *DummyMeta) WhereAmI() string { + return m.VarWhereAmI +} + +// Zone implements common.MetaClient. +func (m *DummyMeta) Zone() string { + return m.VarZone +} diff --git a/exporters/stackdriver_test.go b/exporters/stackdriver_test.go index 3ff92d1..01c925e 100644 --- a/exporters/stackdriver_test.go +++ b/exporters/stackdriver_test.go @@ -1,9 +1,12 @@ package exporters import ( + "context" + "sync" "testing" "github.com/hyeoncheon/bogo/internal/common" + "github.com/stretchr/testify/require" ) @@ -16,3 +19,47 @@ func TestRegisterStackdriver(t *testing.T) { r.Equal(stackdriverExporter, p.Name()) } + +func TestStackdriverRunner_NotOnGCE(t *testing.T) { + r := require.New(t) + + ctx, cancel := context.WithCancel(context.Background()) + opts := common.DefaultOptions() + c := &DummyContext{ + Context: ctx, + Options: opts, + cancel: cancel, + ch: make(chan interface{}), + wg: &sync.WaitGroup{}, + logger: common.NewDefaultLogger("info"), + meta: &DummyMeta{ + VarWhereAmI: common.UNKNOWN, + }, + } + o := common.PluginOptions{} + + r.ErrorIs(stackdriverRunner(c, o, c.Channel()), common.ErrNotOnGCE) + c.Cancel() +} + +func TestStackdriverRunner_OnGCE(t *testing.T) { + r := require.New(t) + + ctx, cancel := context.WithCancel(context.Background()) + opts := common.DefaultOptions() + c := &DummyContext{ + Context: ctx, + Options: opts, + cancel: cancel, + ch: make(chan interface{}), + wg: &sync.WaitGroup{}, + logger: common.NewDefaultLogger("info"), + meta: &DummyMeta{ + VarWhereAmI: common.GOOGLE, + }, + } + o := common.PluginOptions{} + + r.Error(stackdriverRunner(c, o, c.Channel())) + c.Cancel() +} diff --git a/version.go b/version.go index 3c2ebc9..f9ed2ee 100644 --- a/version.go +++ b/version.go @@ -4,5 +4,5 @@ package bogo // constants: name and version of the application. const ( Name = "bogo" - Version = "v0.3.1" + Version = "v0.4.0" )