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.
167 lines
3.7 KiB
Go
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())
|
|
})
|
|
}
|
|
}
|