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  }