From 9f789db548342896fb90af564c66c50d7ba3a9bf Mon Sep 17 00:00:00 2001 From: Maximilian Stefanac <137301184+corporatemax@users.noreply.github.com> Date: Wed, 27 Nov 2024 11:48:58 +0100 Subject: [PATCH] move spyLogClient to testhelper package --- src/internal/testhelper/spy_log_client.go | 82 +++++++++++++++++++ src/pkg/egress/syslog/app_log_emitter_test.go | 17 ++-- src/pkg/egress/syslog/retry_writer_test.go | 77 ----------------- .../egress/syslog/syslog_connector_test.go | 23 +++--- 4 files changed, 103 insertions(+), 96 deletions(-) create mode 100644 src/internal/testhelper/spy_log_client.go diff --git a/src/internal/testhelper/spy_log_client.go b/src/internal/testhelper/spy_log_client.go new file mode 100644 index 000000000..0faba6b91 --- /dev/null +++ b/src/internal/testhelper/spy_log_client.go @@ -0,0 +1,82 @@ +package testhelper + +import ( + "code.cloudfoundry.org/go-loggregator/v10" + v2 "code.cloudfoundry.org/go-loggregator/v10/rpc/loggregator_v2" + "sync" +) + +type spyLogClient struct { + mu sync.Mutex + _message []string + _appID []string + + // We use maps to ensure that we can query the keys + _sourceType map[string]struct{} + _sourceInstance map[string]struct{} +} + +func NewSpyLogClient() *spyLogClient { + return &spyLogClient{ + _sourceType: make(map[string]struct{}), + _sourceInstance: make(map[string]struct{}), + } +} + +func (s *spyLogClient) EmitLog(message string, opts ...loggregator.EmitLogOption) { + s.mu.Lock() + defer s.mu.Unlock() + + env := &v2.Envelope{ + Tags: make(map[string]string), + } + + for _, o := range opts { + o(env) + } + + s._message = append(s._message, message) + s._appID = append(s._appID, env.SourceId) + s._sourceType[env.GetTags()["source_type"]] = struct{}{} + s._sourceInstance[env.GetInstanceId()] = struct{}{} +} + +func (s *spyLogClient) Message() []string { + s.mu.Lock() + defer s.mu.Unlock() + + return s._message +} + +func (s *spyLogClient) AppID() []string { + s.mu.Lock() + defer s.mu.Unlock() + + return s._appID +} + +func (s *spyLogClient) SourceType() map[string]struct{} { + s.mu.Lock() + defer s.mu.Unlock() + + // Copy map so the orig does not escape the mutex and induce a race. + m := make(map[string]struct{}) + for k := range s._sourceType { + m[k] = struct{}{} + } + + return m +} + +func (s *spyLogClient) SourceInstance() map[string]struct{} { + s.mu.Lock() + defer s.mu.Unlock() + + // Copy map so the orig does not escape the mutex and induce a race. + m := make(map[string]struct{}) + for k := range s._sourceInstance { + m[k] = struct{}{} + } + + return m +} diff --git a/src/pkg/egress/syslog/app_log_emitter_test.go b/src/pkg/egress/syslog/app_log_emitter_test.go index 83904f80c..18873410d 100644 --- a/src/pkg/egress/syslog/app_log_emitter_test.go +++ b/src/pkg/egress/syslog/app_log_emitter_test.go @@ -1,6 +1,7 @@ package syslog_test import ( + "code.cloudfoundry.org/loggregator-agent-release/src/internal/testhelper" "code.cloudfoundry.org/loggregator-agent-release/src/pkg/egress/syslog" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -9,14 +10,14 @@ import ( var _ = Describe("Loggregator Emitter", func() { Describe("EmitLog()", func() { It("emits a log message", func() { - logClient := NewSpyLogClient() + logClient := testhelper.NewSpyLogClient() emitter := syslog.NewAppLogEmitter(logClient, "0") emitter.EmitLog("app-id", "some-message") - messages := logClient.message() - appIDs := logClient.appID() - sourceTypes := logClient.sourceType() + messages := logClient.Message() + appIDs := logClient.AppID() + sourceTypes := logClient.SourceType() Expect(messages).To(HaveLen(2)) Expect(messages[0]).To(Equal("some-message")) Expect(messages[1]).To(Equal("some-message")) @@ -27,14 +28,14 @@ var _ = Describe("Loggregator Emitter", func() { }) It("does not emit a log message if the appID is empty", func() { - logClient := NewSpyLogClient() + logClient := testhelper.NewSpyLogClient() emitter := syslog.NewAppLogEmitter(logClient, "0") emitter.EmitLog("", "some-message") - messages := logClient.message() - appIDs := logClient.appID() - sourceTypes := logClient.sourceType() + messages := logClient.Message() + appIDs := logClient.AppID() + sourceTypes := logClient.SourceType() Expect(messages).To(HaveLen(0)) Expect(appIDs).To(HaveLen(0)) Expect(sourceTypes).ToNot(HaveKey("LGR")) diff --git a/src/pkg/egress/syslog/retry_writer_test.go b/src/pkg/egress/syslog/retry_writer_test.go index 89a769c38..03063506f 100644 --- a/src/pkg/egress/syslog/retry_writer_test.go +++ b/src/pkg/egress/syslog/retry_writer_test.go @@ -3,11 +3,9 @@ package syslog_test import ( "errors" "net/url" - "sync" "sync/atomic" "time" - "code.cloudfoundry.org/go-loggregator/v10" v2 "code.cloudfoundry.org/go-loggregator/v10/rpc/loggregator_v2" "code.cloudfoundry.org/loggregator-agent-release/src/pkg/egress" "code.cloudfoundry.org/loggregator-agent-release/src/pkg/egress/syslog" @@ -165,81 +163,6 @@ func (s *spyWriteCloser) WriteAttempts() int { return int(atomic.LoadInt64(&s.writeAttempts)) } -type spyLogClient struct { - mu sync.Mutex - _message []string - _appID []string - - // We use maps to ensure that we can query the keys - _sourceType map[string]struct{} - _sourceInstance map[string]struct{} -} - -func NewSpyLogClient() *spyLogClient { - return &spyLogClient{ - _sourceType: make(map[string]struct{}), - _sourceInstance: make(map[string]struct{}), - } -} - -func (s *spyLogClient) EmitLog(message string, opts ...loggregator.EmitLogOption) { - s.mu.Lock() - defer s.mu.Unlock() - - env := &v2.Envelope{ - Tags: make(map[string]string), - } - - for _, o := range opts { - o(env) - } - - s._message = append(s._message, message) - s._appID = append(s._appID, env.SourceId) - s._sourceType[env.GetTags()["source_type"]] = struct{}{} - s._sourceInstance[env.GetInstanceId()] = struct{}{} -} - -func (s *spyLogClient) message() []string { - s.mu.Lock() - defer s.mu.Unlock() - - return s._message -} - -func (s *spyLogClient) appID() []string { - s.mu.Lock() - defer s.mu.Unlock() - - return s._appID -} - -func (s *spyLogClient) sourceType() map[string]struct{} { - s.mu.Lock() - defer s.mu.Unlock() - - // Copy map so the orig does not escape the mutex and induce a race. - m := make(map[string]struct{}) - for k := range s._sourceType { - m[k] = struct{}{} - } - - return m -} - -func (s *spyLogClient) sourceInstance() map[string]struct{} { - s.mu.Lock() - defer s.mu.Unlock() - - // Copy map so the orig does not escape the mutex and induce a race. - m := make(map[string]struct{}) - for k := range s._sourceInstance { - m[k] = struct{}{} - } - - return m -} - func buildDelay(multiplier time.Duration) func(int) time.Duration { return func(attempt int) time.Duration { return time.Duration(attempt) * multiplier diff --git a/src/pkg/egress/syslog/syslog_connector_test.go b/src/pkg/egress/syslog/syslog_connector_test.go index dbe6c7148..46f553f01 100644 --- a/src/pkg/egress/syslog/syslog_connector_test.go +++ b/src/pkg/egress/syslog/syslog_connector_test.go @@ -1,6 +1,7 @@ package syslog_test import ( + "code.cloudfoundry.org/loggregator-agent-release/src/internal/testhelper" "errors" "fmt" "io" @@ -172,7 +173,7 @@ var _ = Describe("SyslogConnector", func() { }) It("emits a LGR and SYS log to the log client about logs that have been dropped", func() { - logClient := NewSpyLogClient() + logClient := testhelper.NewSpyLogClient() connector := syslog.NewSyslogConnector( true, spyWaitGroup, @@ -201,20 +202,20 @@ var _ = Describe("SyslogConnector", func() { } }(writer) - Eventually(logClient.message).Should(ContainElement(MatchRegexp("\\d messages lost for application (.*) in user provided syslog drain with url"))) - Eventually(logClient.appID).Should(ContainElement("app-id")) + Eventually(logClient.Message).Should(ContainElement(MatchRegexp("\\d messages lost for application (.*) in user provided syslog drain with url"))) + Eventually(logClient.AppID).Should(ContainElement("app-id")) - Eventually(logClient.sourceType).Should(HaveLen(2)) - Eventually(logClient.sourceType).Should(HaveKey("LGR")) - Eventually(logClient.sourceType).Should(HaveKey("SYS")) + Eventually(logClient.SourceType).Should(HaveLen(2)) + Eventually(logClient.SourceType).Should(HaveKey("LGR")) + Eventually(logClient.SourceType).Should(HaveKey("SYS")) - Eventually(logClient.sourceInstance).Should(HaveLen(2)) - Eventually(logClient.sourceInstance).Should(HaveKey("")) - Eventually(logClient.sourceInstance).Should(HaveKey("3")) + Eventually(logClient.SourceInstance).Should(HaveLen(2)) + Eventually(logClient.SourceInstance).Should(HaveKey("")) + Eventually(logClient.SourceInstance).Should(HaveKey("3")) }) It("doesn't emit LGR and SYS log to the log client about aggregate drains drops", func() { - logClient := NewSpyLogClient() + logClient := testhelper.NewSpyLogClient() connector := syslog.NewSyslogConnector( true, spyWaitGroup, @@ -239,7 +240,7 @@ var _ = Describe("SyslogConnector", func() { } }(writer) - Consistently(logClient.message).ShouldNot(ContainElement(MatchRegexp("\\d messages lost for application (.*) in user provided syslog drain with url"))) + Consistently(logClient.Message()).ShouldNot(ContainElement(MatchRegexp("\\d messages lost for application (.*) in user provided syslog drain with url"))) }) It("does not panic on unknown dropped metrics", func() {