github.com/argoproj/argo-cd/v3@v3.2.1/util/argo/audit_logger_test.go (about) 1 package argo 2 3 import ( 4 "bytes" 5 "sync" 6 "testing" 7 8 log "github.com/sirupsen/logrus" 9 "github.com/stretchr/testify/assert" 10 11 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 "k8s.io/client-go/kubernetes/fake" 13 14 argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" 15 ) 16 17 const ( 18 _somecomponent = "somecomponent" 19 _test = "test" 20 ) 21 22 var testEnableEventLog = []string{_somecomponent, _test} 23 24 // logCaptureMutex ensures that only one captureLogEntries call can run at a time 25 // to prevent log entries from parallel test runs from ending up in wrong buffers 26 var logCaptureMutex sync.Mutex 27 28 // ThreadSafeBuffer wraps bytes.Buffer with a mutex to make it thread-safe 29 type ThreadSafeBuffer struct { 30 buf bytes.Buffer 31 mu sync.RWMutex 32 } 33 34 func (tsb *ThreadSafeBuffer) Write(p []byte) (n int, err error) { 35 tsb.mu.Lock() 36 defer tsb.mu.Unlock() 37 return tsb.buf.Write(p) 38 } 39 40 func (tsb *ThreadSafeBuffer) String() string { 41 tsb.mu.RLock() 42 defer tsb.mu.RUnlock() 43 return tsb.buf.String() 44 } 45 46 // Helper to capture log entries generated by the logger and return it as string 47 func captureLogEntries(run func()) string { 48 logCaptureMutex.Lock() 49 defer logCaptureMutex.Unlock() 50 51 f := log.StandardLogger().Formatter 52 log.SetFormatter(&log.TextFormatter{DisableColors: true}) 53 defer log.SetFormatter(f) 54 55 output := &ThreadSafeBuffer{} 56 original := log.StandardLogger().Out 57 log.SetOutput(output) 58 defer log.SetOutput(original) 59 60 run() 61 62 return output.String() 63 } 64 65 func TestNewAuditLogger(t *testing.T) { 66 logger := NewAuditLogger(fake.NewClientset(), _somecomponent, testEnableEventLog) 67 assert.NotNil(t, logger) 68 } 69 70 func TestLogAppProjEvent(t *testing.T) { 71 logger := NewAuditLogger(fake.NewClientset(), _somecomponent, testEnableEventLog) 72 assert.NotNil(t, logger) 73 74 proj := argoappv1.AppProject{ 75 ObjectMeta: metav1.ObjectMeta{ 76 Name: "default", 77 Namespace: "argocd", 78 ResourceVersion: "1", 79 UID: "a-b-c-d-e", 80 }, 81 Spec: argoappv1.AppProjectSpec{ 82 Description: "Test project", 83 }, 84 } 85 86 ei := EventInfo{ 87 Reason: _test, 88 Type: "info", 89 } 90 91 output := captureLogEntries(func() { 92 logger.LogAppProjEvent(&proj, ei, "This is a test message", "") 93 }) 94 95 assert.Contains(t, output, "level=info") 96 assert.Contains(t, output, "project=default") 97 assert.Contains(t, output, "reason=test") 98 assert.Contains(t, output, "type=info") 99 assert.Contains(t, output, "msg=\"This is a test message\"") 100 101 ei.Reason = "Unknown" 102 103 // If K8s Event Disable Log 104 output = captureLogEntries(func() { 105 logger.LogAppProjEvent(&proj, ei, "This is a test message", "") 106 }) 107 108 assert.Empty(t, output) 109 } 110 111 func TestLogAppEvent(t *testing.T) { 112 logger := NewAuditLogger(fake.NewClientset(), _somecomponent, testEnableEventLog) 113 assert.NotNil(t, logger) 114 115 app := argoappv1.Application{ 116 ObjectMeta: metav1.ObjectMeta{ 117 Name: "testapp", 118 Namespace: "argocd", 119 ResourceVersion: "1", 120 UID: "a-b-c-d-e", 121 }, 122 Spec: argoappv1.ApplicationSpec{ 123 Destination: argoappv1.ApplicationDestination{ 124 Server: "https://127.0.0.1:6443", 125 Namespace: "testns", 126 }, 127 }, 128 } 129 130 ei := EventInfo{ 131 Reason: _test, 132 Type: "info", 133 } 134 135 output := captureLogEntries(func() { 136 logger.LogAppEvent(&app, ei, "This is a test message", "", nil) 137 }) 138 139 assert.Contains(t, output, "level=info") 140 assert.Contains(t, output, "application=testapp") 141 assert.Contains(t, output, "dest-namespace=testns") 142 assert.Contains(t, output, "dest-server=\"https://127.0.0.1:6443\"") 143 assert.Contains(t, output, "reason=test") 144 assert.Contains(t, output, "type=info") 145 assert.Contains(t, output, "msg=\"This is a test message\"") 146 147 ei.Reason = "Unknown" 148 149 // If K8s Event Disable Log 150 output = captureLogEntries(func() { 151 logger.LogAppEvent(&app, ei, "This is a test message", "", nil) 152 }) 153 154 assert.Empty(t, output) 155 } 156 157 func TestLogResourceEvent(t *testing.T) { 158 logger := NewAuditLogger(fake.NewClientset(), _somecomponent, testEnableEventLog) 159 assert.NotNil(t, logger) 160 161 res := argoappv1.ResourceNode{ 162 ResourceRef: argoappv1.ResourceRef{ 163 Group: "argocd.argoproj.io", 164 Version: "v1alpha1", 165 Kind: "SignatureKey", 166 Name: "testapp", 167 Namespace: "argocd", 168 UID: "a-b-c-d-e", 169 }, 170 } 171 172 ei := EventInfo{ 173 Reason: _test, 174 Type: "info", 175 } 176 177 output := captureLogEntries(func() { 178 logger.LogResourceEvent(&res, ei, "This is a test message", "") 179 }) 180 181 assert.Contains(t, output, "level=info") 182 assert.Contains(t, output, "name=testapp") 183 assert.Contains(t, output, "reason=test") 184 assert.Contains(t, output, "type=info") 185 assert.Contains(t, output, "msg=\"This is a test message\"") 186 187 ei.Reason = "Unknown" 188 189 // If K8s Event Disable Log 190 output = captureLogEntries(func() { 191 logger.LogResourceEvent(&res, ei, "This is a test message", "") 192 }) 193 194 assert.Empty(t, output) 195 }