Files
threshold/internal/observability/event/eventer_gate_test.go
T
Jeff Mitchell e596daf34d Add hclog adapter and gating to eventer (#1915)
This contains to related things:

1. An adapter allowing an hclog interface to take in information and send them to the eventer
2. A gate on the eventer, which is the analogue to the behavior prior to eventing where we'd ensure logs were not printed prior to the startup information. Without this, plugin logs using the hclog adapter will start showing up too early.
2022-03-16 17:25:34 -04:00

167 lines
3.7 KiB
Go

package event
import (
"bytes"
"context"
"fmt"
"os"
"strings"
"sync"
"testing"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestEventer_Gating(t *testing.T) {
t.Parallel()
require := require.New(t)
// FIXME: Remove this when no longer needed:
os.Setenv(globals.BOUNDARY_DEVELOPER_ENABLE_EVENTS, "true")
buffer := new(bytes.Buffer)
eventerConfig := EventerConfig{
AuditEnabled: true,
ObservationsEnabled: true,
SysEventsEnabled: true,
Sinks: []*SinkConfig{
{
Name: "test-sink",
EventTypes: []Type{EveryType},
Format: TextHclogSinkFormat,
Type: WriterSink,
WriterConfig: &WriterSinkTypeConfig{
Writer: buffer,
},
},
},
}
testLock := &sync.Mutex{}
testLogger := hclog.New(&hclog.LoggerOptions{
Mutex: testLock,
Name: "test",
})
eventer, err := NewEventer(
testLogger,
testLock,
"TestEventer_Gating",
eventerConfig,
WithGating(true),
)
require.NoError(err)
ctx, err := NewEventerContext(context.Background(), eventer)
require.NoError(err)
// This test sends a series of events of different types. The tests are
// meant to be in order as we want to send some that should be gated and
// some that shouldn't and ensure correct behavior at each step.
var totalEvents int
tests := []struct {
name string
eventFn func()
expectedGatedEvents int
}{
{
name: "system-event-1",
eventFn: func() {
WriteSysEvent(ctx, "system-event-1", "system-event-1")
totalEvents++
},
expectedGatedEvents: 1,
},
{
name: "system-event-2",
eventFn: func() {
WriteSysEvent(ctx, "system-event-2", "system-event-2")
totalEvents++
},
expectedGatedEvents: 2,
},
{
name: "audit-1",
eventFn: func() {
require.NoError(WriteAudit(ctx, "audit-1"))
totalEvents++
},
expectedGatedEvents: 2,
},
{
name: "observation-1",
eventFn: func() {
require.NoError(WriteObservation(ctx, "observation-1", WithId("observation-1"), WithHeader("foo", "bar")))
totalEvents++
},
expectedGatedEvents: 2,
},
{
name: "error-1",
eventFn: func() {
WriteError(ctx, "error-1", fmt.Errorf("error-1"))
totalEvents++
},
expectedGatedEvents: 3,
},
{
name: "error-2",
eventFn: func() {
WriteError(ctx, "error-2", fmt.Errorf("error-2"))
totalEvents++
},
expectedGatedEvents: 4,
},
// This should result in all events being flushed so none gated
{
name: "release-gate",
eventFn: func() {
require.NoError(eventer.ReleaseGate())
},
expectedGatedEvents: 0,
},
// From here on out we're verifying that all events of all types go through
{
name: "system-event-3",
eventFn: func() {
WriteSysEvent(ctx, "system-event-3", "system-event-3")
totalEvents++
},
expectedGatedEvents: 0,
},
{
name: "audit-2",
eventFn: func() {
require.NoError(WriteAudit(ctx, "audit-2"))
totalEvents++
},
expectedGatedEvents: 0,
},
{
name: "observation-2",
eventFn: func() {
require.NoError(WriteObservation(ctx, "observation-2", WithId("observation-2"), WithHeader("foo", "bar")))
totalEvents++
},
expectedGatedEvents: 0,
},
{
name: "error-2",
eventFn: func() {
WriteError(ctx, "error-2", fmt.Errorf("error-2"))
totalEvents++
},
expectedGatedEvents: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert := assert.New(t)
tt.eventFn()
assert.Len(strutil.RemoveEmpty(strings.Split(buffer.String(), "\n")), totalEvents-tt.expectedGatedEvents, buffer.String())
})
}
}