refactor (events): QOL fix: turn off events for tests. (#3163)

pull/3164/head
Jim 3 years ago committed by GitHub
parent 8c265bf7c1
commit a4f54cb98f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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())
}
Loading…
Cancel
Save