mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-29 17:52:32 +00:00 
			
		
		
		
	 69c0433f9f
			
		
	
	69c0433f9f
	
	
	
		
			
			* Added optional logger for sink nodes (supplied by backends) will log on errors when context is also done * changelog
		
			
				
	
	
		
			461 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			461 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) HashiCorp, Inc.
 | |
| // SPDX-License-Identifier: BUSL-1.1
 | |
| 
 | |
| package event
 | |
| 
 | |
| import (
 | |
| 	"os"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/hashicorp/go-hclog"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| // TestOptions_WithNow exercises WithNow option to ensure it performs as expected.
 | |
| func TestOptions_WithNow(t *testing.T) {
 | |
| 	tests := map[string]struct {
 | |
| 		Value                time.Time
 | |
| 		IsErrorExpected      bool
 | |
| 		ExpectedErrorMessage string
 | |
| 		ExpectedValue        time.Time
 | |
| 	}{
 | |
| 		"default-time": {
 | |
| 			Value:                time.Time{},
 | |
| 			IsErrorExpected:      true,
 | |
| 			ExpectedErrorMessage: "cannot specify 'now' to be the zero time instant: invalid parameter",
 | |
| 		},
 | |
| 		"valid-time": {
 | |
| 			Value:           time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local),
 | |
| 			IsErrorExpected: false,
 | |
| 			ExpectedValue:   time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local),
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		name := name
 | |
| 		tc := tc
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 
 | |
| 			opts := &options{}
 | |
| 			applyOption := WithNow(tc.Value)
 | |
| 			err := applyOption(opts)
 | |
| 			switch {
 | |
| 			case tc.IsErrorExpected:
 | |
| 				require.Error(t, err)
 | |
| 				require.EqualError(t, err, tc.ExpectedErrorMessage)
 | |
| 			default:
 | |
| 				require.NoError(t, err)
 | |
| 				require.Equal(t, tc.ExpectedValue, opts.withNow)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestOptions_WithID exercises WithID option to ensure it performs as expected.
 | |
| func TestOptions_WithID(t *testing.T) {
 | |
| 	tests := map[string]struct {
 | |
| 		Value                string
 | |
| 		IsErrorExpected      bool
 | |
| 		ExpectedErrorMessage string
 | |
| 		ExpectedValue        string
 | |
| 	}{
 | |
| 		"empty": {
 | |
| 			Value:                "",
 | |
| 			IsErrorExpected:      true,
 | |
| 			ExpectedErrorMessage: "id cannot be empty: invalid parameter",
 | |
| 		},
 | |
| 		"whitespace": {
 | |
| 			Value:                "     ",
 | |
| 			IsErrorExpected:      true,
 | |
| 			ExpectedErrorMessage: "id cannot be empty: invalid parameter",
 | |
| 		},
 | |
| 		"valid": {
 | |
| 			Value:           "test",
 | |
| 			IsErrorExpected: false,
 | |
| 			ExpectedValue:   "test",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		name := name
 | |
| 		tc := tc
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			opts := &options{}
 | |
| 			applyOption := WithID(tc.Value)
 | |
| 			err := applyOption(opts)
 | |
| 			switch {
 | |
| 			case tc.IsErrorExpected:
 | |
| 				require.Error(t, err)
 | |
| 				require.EqualError(t, err, tc.ExpectedErrorMessage)
 | |
| 			default:
 | |
| 				require.NoError(t, err)
 | |
| 				require.Equal(t, tc.ExpectedValue, opts.withID)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestOptions_Default exercises getDefaultOptions to assert the default values.
 | |
| func TestOptions_Default(t *testing.T) {
 | |
| 	opts := getDefaultOptions()
 | |
| 	require.NotNil(t, opts)
 | |
| 	require.True(t, time.Now().After(opts.withNow))
 | |
| 	require.False(t, opts.withNow.IsZero())
 | |
| 	require.Equal(t, "AUTH", opts.withFacility)
 | |
| 	require.Equal(t, "vault", opts.withTag)
 | |
| 	require.Equal(t, 2*time.Second, opts.withMaxDuration)
 | |
| }
 | |
| 
 | |
| // TestOptions_Opts exercises getOpts with various Option values.
 | |
| func TestOptions_Opts(t *testing.T) {
 | |
| 	tests := map[string]struct {
 | |
| 		opts                 []Option
 | |
| 		IsErrorExpected      bool
 | |
| 		ExpectedErrorMessage string
 | |
| 		ExpectedID           string
 | |
| 		IsNowExpected        bool
 | |
| 		ExpectedNow          time.Time
 | |
| 	}{
 | |
| 		"nil-options": {
 | |
| 			opts:            nil,
 | |
| 			IsErrorExpected: false,
 | |
| 			IsNowExpected:   true,
 | |
| 		},
 | |
| 		"empty-options": {
 | |
| 			opts:            []Option{},
 | |
| 			IsErrorExpected: false,
 | |
| 			IsNowExpected:   true,
 | |
| 		},
 | |
| 		"with-multiple-valid-id": {
 | |
| 			opts: []Option{
 | |
| 				WithID("qwerty"),
 | |
| 				WithID("juan"),
 | |
| 			},
 | |
| 			IsErrorExpected: false,
 | |
| 			ExpectedID:      "juan",
 | |
| 			IsNowExpected:   true,
 | |
| 		},
 | |
| 		"with-multiple-valid-now": {
 | |
| 			opts: []Option{
 | |
| 				WithNow(time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local)),
 | |
| 				WithNow(time.Date(2023, time.July, 4, 13, 3, 0, 0, time.Local)),
 | |
| 			},
 | |
| 			IsErrorExpected: false,
 | |
| 			ExpectedNow:     time.Date(2023, time.July, 4, 13, 3, 0, 0, time.Local),
 | |
| 			IsNowExpected:   false,
 | |
| 		},
 | |
| 		"with-multiple-valid-then-invalid-now": {
 | |
| 			opts: []Option{
 | |
| 				WithNow(time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local)),
 | |
| 				WithNow(time.Time{}),
 | |
| 			},
 | |
| 			IsErrorExpected:      true,
 | |
| 			ExpectedErrorMessage: "cannot specify 'now' to be the zero time instant: invalid parameter",
 | |
| 		},
 | |
| 		"with-multiple-valid-options": {
 | |
| 			opts: []Option{
 | |
| 				WithID("qwerty"),
 | |
| 				WithNow(time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local)),
 | |
| 			},
 | |
| 			IsErrorExpected: false,
 | |
| 			ExpectedID:      "qwerty",
 | |
| 			ExpectedNow:     time.Date(2023, time.July, 4, 12, 3, 0, 0, time.Local),
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		name := name
 | |
| 		tc := tc
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			opts, err := getOpts(tc.opts...)
 | |
| 
 | |
| 			switch {
 | |
| 			case tc.IsErrorExpected:
 | |
| 				require.Error(t, err)
 | |
| 				require.EqualError(t, err, tc.ExpectedErrorMessage)
 | |
| 			default:
 | |
| 				require.NotNil(t, opts)
 | |
| 				require.NoError(t, err)
 | |
| 				require.Equal(t, tc.ExpectedID, opts.withID)
 | |
| 				switch {
 | |
| 				case tc.IsNowExpected:
 | |
| 					require.True(t, time.Now().After(opts.withNow))
 | |
| 					require.False(t, opts.withNow.IsZero())
 | |
| 				default:
 | |
| 					require.Equal(t, tc.ExpectedNow, opts.withNow)
 | |
| 				}
 | |
| 
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestOptions_WithFacility exercises WithFacility Option to ensure it performs as expected.
 | |
| func TestOptions_WithFacility(t *testing.T) {
 | |
| 	tests := map[string]struct {
 | |
| 		Value         string
 | |
| 		ExpectedValue string
 | |
| 	}{
 | |
| 		"empty": {
 | |
| 			Value:         "",
 | |
| 			ExpectedValue: "",
 | |
| 		},
 | |
| 		"whitespace": {
 | |
| 			Value:         "    ",
 | |
| 			ExpectedValue: "",
 | |
| 		},
 | |
| 		"value": {
 | |
| 			Value:         "juan",
 | |
| 			ExpectedValue: "juan",
 | |
| 		},
 | |
| 		"spacey-value": {
 | |
| 			Value:         "   juan   ",
 | |
| 			ExpectedValue: "juan",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		name := name
 | |
| 		tc := tc
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			opts := &options{}
 | |
| 			applyOption := WithFacility(tc.Value)
 | |
| 			err := applyOption(opts)
 | |
| 			require.NoError(t, err)
 | |
| 			require.Equal(t, tc.ExpectedValue, opts.withFacility)
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestOptions_WithTag exercises WithTag Option to ensure it performs as expected.
 | |
| func TestOptions_WithTag(t *testing.T) {
 | |
| 	tests := map[string]struct {
 | |
| 		Value         string
 | |
| 		ExpectedValue string
 | |
| 	}{
 | |
| 		"empty": {
 | |
| 			Value:         "",
 | |
| 			ExpectedValue: "",
 | |
| 		},
 | |
| 		"whitespace": {
 | |
| 			Value:         "    ",
 | |
| 			ExpectedValue: "",
 | |
| 		},
 | |
| 		"value": {
 | |
| 			Value:         "juan",
 | |
| 			ExpectedValue: "juan",
 | |
| 		},
 | |
| 		"spacey-value": {
 | |
| 			Value:         "   juan   ",
 | |
| 			ExpectedValue: "juan",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		name := name
 | |
| 		tc := tc
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			opts := &options{}
 | |
| 			applyOption := WithTag(tc.Value)
 | |
| 			err := applyOption(opts)
 | |
| 			require.NoError(t, err)
 | |
| 			require.Equal(t, tc.ExpectedValue, opts.withTag)
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestOptions_WithSocketType exercises WithSocketType Option to ensure it performs as expected.
 | |
| func TestOptions_WithSocketType(t *testing.T) {
 | |
| 	tests := map[string]struct {
 | |
| 		Value         string
 | |
| 		ExpectedValue string
 | |
| 	}{
 | |
| 		"empty": {
 | |
| 			Value:         "",
 | |
| 			ExpectedValue: "",
 | |
| 		},
 | |
| 		"whitespace": {
 | |
| 			Value:         "    ",
 | |
| 			ExpectedValue: "",
 | |
| 		},
 | |
| 		"value": {
 | |
| 			Value:         "juan",
 | |
| 			ExpectedValue: "juan",
 | |
| 		},
 | |
| 		"spacey-value": {
 | |
| 			Value:         "   juan   ",
 | |
| 			ExpectedValue: "juan",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		name := name
 | |
| 		tc := tc
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			opts := &options{}
 | |
| 			applyOption := WithSocketType(tc.Value)
 | |
| 			err := applyOption(opts)
 | |
| 			require.NoError(t, err)
 | |
| 			require.Equal(t, tc.ExpectedValue, opts.withSocketType)
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestOptions_WithMaxDuration exercises WithMaxDuration Option to ensure it performs as expected.
 | |
| func TestOptions_WithMaxDuration(t *testing.T) {
 | |
| 	tests := map[string]struct {
 | |
| 		Value                string
 | |
| 		ExpectedValue        time.Duration
 | |
| 		IsErrorExpected      bool
 | |
| 		ExpectedErrorMessage string
 | |
| 	}{
 | |
| 		"empty-gives-default": {
 | |
| 			Value: "",
 | |
| 		},
 | |
| 		"whitespace-give-default": {
 | |
| 			Value: "    ",
 | |
| 		},
 | |
| 		"bad-value": {
 | |
| 			Value:                "juan",
 | |
| 			IsErrorExpected:      true,
 | |
| 			ExpectedErrorMessage: "unable to parse max duration: invalid parameter: time: invalid duration \"juan\"",
 | |
| 		},
 | |
| 		"bad-spacey-value": {
 | |
| 			Value:                "   juan   ",
 | |
| 			IsErrorExpected:      true,
 | |
| 			ExpectedErrorMessage: "unable to parse max duration: invalid parameter: time: invalid duration \"juan\"",
 | |
| 		},
 | |
| 		"duration-2s": {
 | |
| 			Value:         "2s",
 | |
| 			ExpectedValue: 2 * time.Second,
 | |
| 		},
 | |
| 		"duration-2m": {
 | |
| 			Value:         "2m",
 | |
| 			ExpectedValue: 2 * time.Minute,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		name := name
 | |
| 		tc := tc
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			opts := &options{}
 | |
| 			applyOption := WithMaxDuration(tc.Value)
 | |
| 			err := applyOption(opts)
 | |
| 			switch {
 | |
| 			case tc.IsErrorExpected:
 | |
| 				require.Error(t, err)
 | |
| 				require.EqualError(t, err, tc.ExpectedErrorMessage)
 | |
| 			default:
 | |
| 				require.NoError(t, err)
 | |
| 				require.Equal(t, tc.ExpectedValue, opts.withMaxDuration)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestOptions_WithFileMode exercises WithFileMode Option to ensure it performs as expected.
 | |
| func TestOptions_WithFileMode(t *testing.T) {
 | |
| 	tests := map[string]struct {
 | |
| 		Value                string
 | |
| 		IsErrorExpected      bool
 | |
| 		ExpectedErrorMessage string
 | |
| 		IsNilExpected        bool
 | |
| 		ExpectedValue        os.FileMode
 | |
| 	}{
 | |
| 		"empty": {
 | |
| 			Value:           "",
 | |
| 			IsErrorExpected: false,
 | |
| 			IsNilExpected:   true,
 | |
| 		},
 | |
| 		"whitespace": {
 | |
| 			Value:           "     ",
 | |
| 			IsErrorExpected: false,
 | |
| 			IsNilExpected:   true,
 | |
| 		},
 | |
| 		"nonsense": {
 | |
| 			Value:                "juan",
 | |
| 			IsErrorExpected:      true,
 | |
| 			ExpectedErrorMessage: "unable to parse file mode: invalid parameter: strconv.ParseUint: parsing \"juan\": invalid syntax",
 | |
| 		},
 | |
| 		"zero": {
 | |
| 			Value:           "0000",
 | |
| 			IsErrorExpected: false,
 | |
| 			ExpectedValue:   os.FileMode(0o000),
 | |
| 		},
 | |
| 		"valid": {
 | |
| 			Value:           "0007",
 | |
| 			IsErrorExpected: false,
 | |
| 			ExpectedValue:   os.FileMode(0o007),
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		name := name
 | |
| 		tc := tc
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			opts := &options{}
 | |
| 			applyOption := WithFileMode(tc.Value)
 | |
| 			err := applyOption(opts)
 | |
| 			switch {
 | |
| 			case tc.IsErrorExpected:
 | |
| 				require.Error(t, err)
 | |
| 				require.EqualError(t, err, tc.ExpectedErrorMessage)
 | |
| 			default:
 | |
| 				require.NoError(t, err)
 | |
| 				switch {
 | |
| 				case tc.IsNilExpected:
 | |
| 					// Optional Option 'not supplied' (i.e. was whitespace/empty string)
 | |
| 					require.Nil(t, opts.withFileMode)
 | |
| 				default:
 | |
| 					// Dereference the pointer, so we can examine the file mode.
 | |
| 					require.Equal(t, tc.ExpectedValue, *opts.withFileMode)
 | |
| 				}
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TestOptions_WithLogger exercises WithLogger Option to ensure it performs as expected.
 | |
| func TestOptions_WithLogger(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	tests := map[string]struct {
 | |
| 		value         hclog.Logger
 | |
| 		isNilExpected bool
 | |
| 	}{
 | |
| 		"nil-pointer": {
 | |
| 			value:         nil,
 | |
| 			isNilExpected: true,
 | |
| 		},
 | |
| 		"logger": {
 | |
| 			value: hclog.NewNullLogger(),
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range tests {
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 
 | |
| 			opts := &options{}
 | |
| 			applyOption := WithLogger(tc.value)
 | |
| 			err := applyOption(opts)
 | |
| 			require.NoError(t, err)
 | |
| 			if tc.isNilExpected {
 | |
| 				require.Nil(t, opts.withLogger)
 | |
| 			} else {
 | |
| 				require.NotNil(t, opts.withLogger)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 |