refactor (events): QOL fix: turn off events for tests. (#3163)
This commit is contained in:
15 files changed
+196
-55
No files matched your search
@@ -309,14 +309,20 @@ type Plugins struct {
|
||||
}
|
||||
|
||||
// DevWorker is a Config that is used for dev mode of Boundary
|
||||
// workers
|
||||
func DevWorker() (*Config, error) {
|
||||
// workers. Supported options: WithObservationsEnabled, WithSysEventsEnabled,
|
||||
// WithAuditEventsEnabled, TestWithErrorEventsEnabled
|
||||
func DevWorker(opt ...Option) (*Config, error) {
|
||||
workerAuthStorageKey := DevKeyGeneration()
|
||||
hclStr := fmt.Sprintf(devConfig+devWorkerExtraConfig, workerAuthStorageKey)
|
||||
parsed, err := Parse(hclStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing dev config: %w", err)
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
parsed.Eventing.AuditEnabled = opts.withAuditEventsEnabled
|
||||
parsed.Eventing.ObservationsEnabled = opts.withObservationsEnabled
|
||||
parsed.Eventing.SysEventsEnabled = opts.withSysEventsEnabled
|
||||
parsed.Eventing.ErrorEventsDisabled = !opts.testWithErrorEventsEnabled
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
@@ -339,7 +345,7 @@ func DevKeyGeneration() string {
|
||||
|
||||
// DevController is a Config that is used for dev mode of Boundary
|
||||
// controllers
|
||||
func DevController() (*Config, error) {
|
||||
func DevController(opt ...Option) (*Config, error) {
|
||||
controllerKey := DevKeyGeneration()
|
||||
workerAuthKey := DevKeyGeneration()
|
||||
recoveryKey := DevKeyGeneration()
|
||||
@@ -353,6 +359,11 @@ func DevController() (*Config, error) {
|
||||
parsed.DevControllerKey = controllerKey
|
||||
parsed.DevWorkerAuthKey = workerAuthKey
|
||||
parsed.DevRecoveryKey = recoveryKey
|
||||
opts := getOpts(opt...)
|
||||
parsed.Eventing.AuditEnabled = opts.withAuditEventsEnabled
|
||||
parsed.Eventing.ObservationsEnabled = opts.withObservationsEnabled
|
||||
parsed.Eventing.SysEventsEnabled = opts.withSysEventsEnabled
|
||||
parsed.Eventing.ErrorEventsDisabled = !opts.testWithErrorEventsEnabled
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,9 @@ func TestDevController(t *testing.T) {
|
||||
},
|
||||
DevController: true,
|
||||
}
|
||||
exp.Eventing.ErrorEventsDisabled = true
|
||||
exp.Eventing.SysEventsEnabled = false
|
||||
exp.Eventing.ObservationsEnabled = false
|
||||
|
||||
exp.Listeners[0].RawConfig = actual.Listeners[0].RawConfig
|
||||
exp.Listeners[1].RawConfig = actual.Listeners[1].RawConfig
|
||||
@@ -191,11 +194,10 @@ func TestDevController(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDevWorker(t *testing.T) {
|
||||
actual, err := DevWorker()
|
||||
actual, err := DevWorker(WithSysEventsEnabled(true), WithObservationsEnabled(true), TestWithErrorEventsEnabled(t, true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
exp := &Config{
|
||||
Eventing: event.DefaultEventerConfig(),
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
|
||||
package config
|
||||
|
||||
import "testing"
|
||||
|
||||
// getOpts - iterate the inbound Options and return a struct
|
||||
func getOpts(opt ...Option) options {
|
||||
opts := getDefaultOptions()
|
||||
for _, o := range opt {
|
||||
o(&opts)
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
// Option - how Options are passed as arguments
|
||||
type Option func(*options)
|
||||
|
||||
// options = how options are represented
|
||||
type options struct {
|
||||
withSysEventsEnabled bool
|
||||
withAuditEventsEnabled bool
|
||||
withObservationsEnabled bool
|
||||
testWithErrorEventsEnabled bool
|
||||
}
|
||||
|
||||
func getDefaultOptions() options {
|
||||
return options{}
|
||||
}
|
||||
|
||||
// WithSysEventsEnabled provides an option for enabling system events
|
||||
func WithSysEventsEnabled(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withSysEventsEnabled = enable
|
||||
}
|
||||
}
|
||||
|
||||
// WithAuditEventsEnabled provides an option for enabling audit events
|
||||
func WithAuditEventsEnabled(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAuditEventsEnabled = enable
|
||||
}
|
||||
}
|
||||
|
||||
// WithObservationsEnabled provides an option for enabling observation events
|
||||
func WithObservationsEnabled(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withObservationsEnabled = enable
|
||||
}
|
||||
}
|
||||
|
||||
// TestWithErrorEventsEnabled provides an option for enabling error events
|
||||
// during tests.
|
||||
func TestWithErrorEventsEnabled(_ testing.TB, enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.testWithErrorEventsEnabled = enable
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,8 @@ func TestHandler_CORS(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg.Eventing.ErrorEventsDisabled = true
|
||||
cfg.Eventing.SysEventsEnabled = false
|
||||
|
||||
var wildcardListenerNum int
|
||||
for listenerNum, listener := range cfg.Listeners {
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -409,10 +408,11 @@ type TestControllerOpts struct {
|
||||
// If true, the controller will not be started
|
||||
DisableAutoStart bool
|
||||
|
||||
// DisableEventing, if true the test controller will not create events
|
||||
// You must not run the test in parallel (no calls to t.Parallel) since the
|
||||
// this option relies on modifying the system wide default eventer.
|
||||
DisableEventing bool
|
||||
// EnableEventing, if true the test controller will create sys and error
|
||||
// events. You must not run the test in parallel (no calls to t.Parallel)
|
||||
// since the this option relies on modifying the system wide default
|
||||
// eventer.
|
||||
EnableEventing bool
|
||||
|
||||
// DisableAuthorizationFailures will still cause authz checks to be
|
||||
// performed but they won't cause 403 Forbidden. Useful for API-level
|
||||
@@ -613,39 +613,22 @@ func TestControllerConfig(t testing.TB, ctx context.Context, tc *TestController,
|
||||
}
|
||||
opts.Config.Controller.Scheduler.JobRunIntervalDuration = opts.SchedulerRunJobInterval
|
||||
|
||||
switch {
|
||||
case opts.DisableEventing:
|
||||
if opts.EnableEventing {
|
||||
opts.Config.Eventing = &event.EventerConfig{
|
||||
AuditEnabled: false,
|
||||
ObservationsEnabled: false,
|
||||
SysEventsEnabled: false,
|
||||
}
|
||||
testLogger := hclog.New(&hclog.LoggerOptions{
|
||||
Mutex: tc.b.StderrLock,
|
||||
Output: io.Discard,
|
||||
})
|
||||
e, err := event.NewEventer(
|
||||
testLogger,
|
||||
tc.b.StderrLock,
|
||||
opts.Config.Controller.Name,
|
||||
*opts.Config.Eventing,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tc.b.Eventer = e
|
||||
event.TestWithoutEventing(t) // this ensures the sys eventer will also stop eventing
|
||||
default:
|
||||
|
||||
serverName, err := os.Hostname()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
serverName = fmt.Sprintf("%s/controller", serverName)
|
||||
if err := tc.b.SetupEventing(tc.b.Logger, tc.b.StderrLock, serverName, base.WithEventerConfig(opts.Config.Eventing)); err != nil {
|
||||
t.Fatal(err)
|
||||
AuditEnabled: true,
|
||||
ObservationsEnabled: true,
|
||||
SysEventsEnabled: true,
|
||||
ErrorEventsDisabled: true,
|
||||
}
|
||||
}
|
||||
serverName, err := os.Hostname()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
serverName = fmt.Sprintf("%s/controller", serverName)
|
||||
if err := tc.b.SetupEventing(tc.b.Logger, tc.b.StderrLock, serverName, base.WithEventerConfig(opts.Config.Eventing)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if opts.WorkerStatusGracePeriodDuration != 0 {
|
||||
opts.Config.Controller.WorkerStatusGracePeriodDuration = opts.WorkerStatusGracePeriodDuration
|
||||
|
||||
@@ -57,11 +57,11 @@ func Test_TestController(t *testing.T) {
|
||||
}
|
||||
|
||||
assert.Empty(captureFn(func() {
|
||||
tc := NewTestController(t, &TestControllerOpts{DisableEventing: true})
|
||||
tc := NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
}))
|
||||
assert.NotEmpty(captureFn(func() {
|
||||
tc := NewTestController(t, nil)
|
||||
tc := NewTestController(t, &TestControllerOpts{EnableEventing: true})
|
||||
defer tc.Shutdown()
|
||||
}))
|
||||
})
|
||||
|
||||
@@ -226,6 +226,18 @@ type TestWorkerOpts struct {
|
||||
|
||||
// Toggle worker auth debugging
|
||||
WorkerAuthDebuggingEnabled *atomic.Bool
|
||||
|
||||
// Enable audit events
|
||||
EnableAuditEvents bool
|
||||
|
||||
// Enable system events
|
||||
EnableSysEvents bool
|
||||
|
||||
// Enable observation events
|
||||
EnableObservationEvents bool
|
||||
|
||||
// Enable error events
|
||||
EnableErrorEvents bool
|
||||
}
|
||||
|
||||
func NewTestWorker(t testing.TB, opts *TestWorkerOpts) *TestWorker {
|
||||
@@ -255,7 +267,12 @@ func NewTestWorker(t testing.TB, opts *TestWorkerOpts) *TestWorker {
|
||||
// Get dev config, or use a provided one
|
||||
var err error
|
||||
if opts.Config == nil {
|
||||
opts.Config, err = config.DevWorker()
|
||||
var configOpts []config.Option
|
||||
configOpts = append(configOpts, config.WithAuditEventsEnabled(opts.EnableAuditEvents))
|
||||
configOpts = append(configOpts, config.WithSysEventsEnabled(opts.EnableSysEvents))
|
||||
configOpts = append(configOpts, config.WithObservationsEnabled(opts.EnableObservationEvents))
|
||||
configOpts = append(configOpts, config.TestWithErrorEventsEnabled(t, opts.EnableErrorEvents))
|
||||
opts.Config, err = config.DevWorker(configOpts...)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -9,9 +9,14 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/test"
|
||||
)
|
||||
|
||||
var ci bool
|
||||
var (
|
||||
ci bool
|
||||
isTest bool
|
||||
)
|
||||
|
||||
type key int
|
||||
|
||||
@@ -24,6 +29,7 @@ const (
|
||||
|
||||
func init() {
|
||||
ci = os.Getenv("CI") != ""
|
||||
isTest = test.IsTestRun()
|
||||
}
|
||||
|
||||
// NewEventerContext will return a context containing a value of the provided Eventer
|
||||
@@ -136,7 +142,10 @@ func WriteError(ctx context.Context, caller Op, e error, opt ...Option) {
|
||||
if !ok {
|
||||
eventer = SysEventer()
|
||||
if eventer == nil {
|
||||
if !ci {
|
||||
switch {
|
||||
case !ci:
|
||||
case !isTest:
|
||||
default:
|
||||
fallbackLogger().Error(fmt.Sprintf("%s: no eventer available to write error: %v", op, e))
|
||||
}
|
||||
return
|
||||
|
||||
@@ -661,6 +661,9 @@ func (e *Eventer) writeError(ctx context.Context, event *err, opt ...Option) err
|
||||
if event == nil {
|
||||
return fmt.Errorf("%s: missing event: %w", op, ErrInvalidParameter)
|
||||
}
|
||||
if e.conf.ErrorEventsDisabled {
|
||||
return nil
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
if e.gated.Load() && !opts.withNoGateLocking {
|
||||
e.gatedQueueLock.Lock()
|
||||
@@ -689,6 +692,9 @@ func (e *Eventer) writeSysEvent(ctx context.Context, event *sysEvent, opt ...Opt
|
||||
if event == nil {
|
||||
return fmt.Errorf("%s: missing event: %w", op, ErrInvalidParameter)
|
||||
}
|
||||
if !e.conf.SysEventsEnabled {
|
||||
return nil
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
if e.gated.Load() && !opts.withNoGateLocking {
|
||||
e.gatedQueueLock.Lock()
|
||||
|
||||
@@ -13,6 +13,7 @@ type EventerConfig struct {
|
||||
ObservationsEnabled bool `hcl:"observations_enabled"` // ObservationsEnabled specifies if observation events should be emitted.
|
||||
SysEventsEnabled bool `hcl:"sysevents_enabled"` // SysEventsEnabled specifies if sysevents should be emitted.
|
||||
Sinks []*SinkConfig `hcl:"-"` // Sinks are all the configured sinks
|
||||
ErrorEventsDisabled bool `hcl:"-"` // ErrorEventsDisabled will disable error events from being emitted. This should only be used to turn off error events in tests.
|
||||
}
|
||||
|
||||
// Validate will Validate the config. A config isn't required to have any
|
||||
|
||||
@@ -350,11 +350,11 @@ func TestEventer_writeError(t *testing.T) {
|
||||
|
||||
func Test_NewEventer(t *testing.T) {
|
||||
t.Parallel()
|
||||
testSetup := TestEventerConfig(t, "Test_NewEventer")
|
||||
testSetup := TestEventerConfig(t, "Test_NewEventer", TestWithStderrSink(t))
|
||||
|
||||
testSetupWithOpts := TestEventerConfig(t, "Test_NewEventer", TestWithAuditSink(t), TestWithObservationSink(t), TestWithSysSink(t))
|
||||
testSetupWithOpts := TestEventerConfig(t, "Test_NewEventer", TestWithStderrSink(t), TestWithAuditSink(t), TestWithObservationSink(t), TestWithSysSink(t))
|
||||
|
||||
testHclogSetup := TestEventerConfig(t, "Test_NewEventer", testWithSinkFormat(t, TextHclogSinkFormat))
|
||||
testHclogSetup := TestEventerConfig(t, "Test_NewEventer", TestWithStderrSink(t), testWithSinkFormat(t, TextHclogSinkFormat))
|
||||
|
||||
testLock := &sync.Mutex{}
|
||||
testLogger := testLogger(t, testLock)
|
||||
|
||||
@@ -53,6 +53,7 @@ type options struct {
|
||||
withHclogLevel hclog.Level
|
||||
|
||||
withBroker broker // test only option
|
||||
withStderrSink bool // test only option
|
||||
withAuditSink bool // test only option
|
||||
withObservationSink bool // test only option
|
||||
withSysSink bool // test only option
|
||||
|
||||
@@ -89,6 +89,7 @@ func TestEventerConfig(t testing.TB, testName string, opt ...Option) TestConfig
|
||||
EventerConfig: EventerConfig{
|
||||
ObservationsEnabled: true,
|
||||
AuditEnabled: true,
|
||||
SysEventsEnabled: true,
|
||||
Sinks: []*SinkConfig{
|
||||
{
|
||||
Name: "every-type-file-sink",
|
||||
@@ -101,13 +102,6 @@ func TestEventerConfig(t testing.TB, testName string, opt ...Option) TestConfig
|
||||
},
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
},
|
||||
{
|
||||
Name: "stderr",
|
||||
Type: StderrSink,
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: opts.withSinkFormat,
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
},
|
||||
{
|
||||
Name: "err-file-sink",
|
||||
Type: FileSink,
|
||||
@@ -123,6 +117,15 @@ func TestEventerConfig(t testing.TB, testName string, opt ...Option) TestConfig
|
||||
AllEvents: tmpAllFile,
|
||||
ErrorEvents: tmpErrFile,
|
||||
}
|
||||
if opts.withStderrSink {
|
||||
c.EventerConfig.Sinks = append(c.EventerConfig.Sinks, &SinkConfig{
|
||||
Name: "stderr",
|
||||
Type: StderrSink,
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: opts.withSinkFormat,
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
})
|
||||
}
|
||||
if opts.withAuditSink {
|
||||
tmpFile, err := ioutil.TempFile("./", "tmp-audit-"+testName)
|
||||
require.NoError(err)
|
||||
@@ -259,6 +262,14 @@ func TestWithSysSink(t testing.TB) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// TestWithStderrSink is a test option
|
||||
func TestWithStderrSink(t testing.TB) Option {
|
||||
t.Helper()
|
||||
return func(o *options) {
|
||||
o.withStderrSink = true
|
||||
}
|
||||
}
|
||||
|
||||
// withNoDefaultSink is an unexported test option
|
||||
func withNoDefaultSink(t testing.TB) Option {
|
||||
t.Helper()
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
testing.Init()
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
// IsTestRun will return whether or not we're operating within the context of a
|
||||
// test.
|
||||
func IsTestRun() bool {
|
||||
// TODO jimlambrt 4/23 -> convert to go 1.21 built-in func when it's
|
||||
// available in boundary:
|
||||
// https://github.com/golang/go/commit/7f38067acb738c43d870400dd648662d31456f5f#diff-b3e6126779b5ec9d3d6cea7cc54054ba78f4d7a0a6248d9e458bbd9b3d72fce3
|
||||
|
||||
// just check if the test verbose (test.v) has been initialized... we don't
|
||||
// care about it's value.
|
||||
return flag.Lookup("test.v") != nil
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_IsTestRun(t *testing.T) {
|
||||
require.True(t, IsTestRun())
|
||||
}
|
||||
Reference in new issue
Block a user