Skip to content

Commit 0e5e2cc

Browse files
Rewrite the beats receiver log test using common tooling (#10507)
Co-authored-by: Mikołaj Świątek <[email protected]>
1 parent c4ca29e commit 0e5e2cc

File tree

1 file changed

+64
-45
lines changed

1 file changed

+64
-45
lines changed

testing/integration/ess/beat_receivers_test.go

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ func TestBeatsReceiverLogs(t *testing.T) {
706706
},
707707
Stack: nil,
708708
})
709+
709710
type configOptions struct {
710711
RuntimeExperimental string
711712
}
@@ -732,66 +733,85 @@ agent.monitoring.enabled: false
732733
require.NoError(t,
733734
template.Must(template.New("config").Parse(configTemplate)).Execute(&configBuffer,
734735
configOptions{
735-
RuntimeExperimental: "process",
736+
RuntimeExperimental: string(component.ProcessRuntimeManager),
736737
}))
737738
processConfig := configBuffer.Bytes()
738739
require.NoError(t,
739740
template.Must(template.New("config").Parse(configTemplate)).Execute(&configBuffer,
740741
configOptions{
741-
RuntimeExperimental: "otel",
742+
RuntimeExperimental: string(component.OtelRuntimeManager),
742743
}))
743744
receiverConfig := configBuffer.Bytes()
744745
// this is the context for the whole test, with a global timeout defined
745746
ctx, cancel := testcontext.WithDeadline(t, t.Context(), time.Now().Add(5*time.Minute))
746747
defer cancel()
747748

748-
// use a subcontext for the agent
749-
agentProcessCtx, agentProcessCancel := context.WithCancel(ctx)
750-
fixture, cmd, output := prepareAgentCmd(t, agentProcessCtx, processConfig)
749+
// since we set the output to a nonexistent ES endpoint, we expect it to be degraded, but the input to be healthy
750+
assertBeatsReady := func(t *assert.CollectT, status *atesting.AgentStatusOutput, runtime component.RuntimeManager) {
751+
var componentVersionInfoName string
752+
switch runtime {
753+
case component.OtelRuntimeManager:
754+
componentVersionInfoName = "beats-receiver"
755+
default:
756+
componentVersionInfoName = "beat-v2-client"
757+
}
751758

752-
require.NoError(t, cmd.Start())
759+
// we don't actually care about anything here other than the receiver itself
760+
assert.Equal(t, 1, len(status.Components))
761+
762+
// all the components should be degraded, their output units should be degraded, the input units should be healthy,
763+
// and should identify themselves appropriately via their version info
764+
for _, comp := range status.Components {
765+
assert.Equal(t, componentVersionInfoName, comp.VersionInfo.Name)
766+
for _, unit := range comp.Units {
767+
if unit.UnitType == int(cproto.UnitType_INPUT) {
768+
assert.Equal(t, int(cproto.State_HEALTHY), unit.State,
769+
"expected state of unit %s to be %s, got %s",
770+
unit.UnitID, cproto.State_HEALTHY.String(), cproto.State(unit.State).String())
771+
}
772+
}
773+
}
774+
}
753775

754-
require.EventuallyWithT(t, func(collect *assert.CollectT) {
755-
var statusErr error
756-
status, statusErr := fixture.ExecStatus(agentProcessCtx)
757-
assert.NoError(collect, statusErr)
758-
assertBeatsHealthy(collect, &status, component.ProcessRuntimeManager, 1)
759-
return
760-
}, 1*time.Minute, 1*time.Second)
776+
// set up a standalone agent
777+
fixture, err := define.NewFixtureFromLocalBuild(t, define.Version())
778+
require.NoError(t, err)
761779

762-
agentProcessCancel()
763-
require.Error(t, cmd.Wait())
764-
processLogsString := output.String()
765-
output.Reset()
780+
err = fixture.Prepare(ctx)
781+
require.NoError(t, err)
782+
err = fixture.Configure(ctx, processConfig)
783+
require.NoError(t, err)
766784

767-
// use a subcontext for the agent
768-
agentReceiverCtx, agentReceiverCancel := context.WithCancel(ctx)
769-
fixture, cmd, output = prepareAgentCmd(t, agentReceiverCtx, receiverConfig)
785+
output, err := fixture.Install(ctx, &atesting.InstallOpts{Privileged: true, Force: true})
786+
require.NoError(t, err, "failed to install agent: %s", output)
770787

771-
require.NoError(t, cmd.Start())
788+
require.EventuallyWithT(t, func(collect *assert.CollectT) {
789+
var statusErr error
790+
status, statusErr := fixture.ExecStatus(ctx)
791+
require.NoError(collect, statusErr)
792+
assertBeatsReady(collect, &status, component.ProcessRuntimeManager)
793+
return
794+
}, 2*time.Minute, 5*time.Second)
772795

773-
t.Cleanup(func() {
774-
if t.Failed() {
775-
t.Log("Elastic-Agent output:")
776-
t.Log(output.String())
777-
}
778-
})
796+
// change configuration and wait until the beats receiver is healthy
797+
err = fixture.Configure(ctx, receiverConfig)
798+
require.NoError(t, err)
779799

780800
require.EventuallyWithT(t, func(collect *assert.CollectT) {
781801
var statusErr error
782-
status, statusErr := fixture.ExecStatus(agentReceiverCtx)
783-
assert.NoError(collect, statusErr)
784-
assertBeatsHealthy(collect, &status, component.OtelRuntimeManager, 1)
802+
status, statusErr := fixture.ExecStatus(ctx)
803+
require.NoError(collect, statusErr)
804+
assertBeatsReady(collect, &status, component.OtelRuntimeManager)
785805
return
786-
}, 1*time.Minute, 1*time.Second)
787-
agentReceiverCancel()
788-
require.Error(t, cmd.Wait())
789-
receiverLogsString := output.String()
806+
}, 2*time.Minute, 5*time.Second)
807+
808+
logsBytes, err := fixture.Exec(ctx, []string{"logs", "-n", "1000", "--exclude-events"})
809+
require.NoError(t, err, "failed to read logs: %v", err)
790810

791-
processLog := getBeatStartLogRecord(processLogsString)
792-
assert.NotEmpty(t, processLog)
793-
receiverLog := getBeatStartLogRecord(receiverLogsString)
794-
assert.NotEmpty(t, receiverLog)
811+
beatStartLogs := getBeatStartLogRecords(string(logsBytes))
812+
813+
require.Len(t, beatStartLogs, 2, "expected to find one log line for each configuration")
814+
processLog, receiverLog := beatStartLogs[0], beatStartLogs[1]
795815

796816
// Check that the process log is a subset of the receiver log
797817
for key, value := range processLog {
@@ -835,9 +855,10 @@ func assertBeatsHealthy(t *assert.CollectT, status *atesting.AgentStatusOutput,
835855
}
836856
}
837857

838-
// getBeatStartLogRecord returns the log record for the a particular log line emitted when the beat starts
858+
// getBeatStartLogRecords returns the log records for a particular log line emitted when the beat starts
839859
// This log line is identical between beats processes and receivers, so it's a good point of comparison
840-
func getBeatStartLogRecord(logs string) map[string]any {
860+
func getBeatStartLogRecords(logs string) []map[string]any {
861+
var logRecords []map[string]any
841862
for _, line := range strings.Split(logs, "\n") {
842863
line = strings.TrimSpace(line)
843864
if line == "" {
@@ -848,13 +869,11 @@ func getBeatStartLogRecord(logs string) map[string]any {
848869
continue
849870
}
850871

851-
if message, ok := logRecord["message"].(string); !ok || !strings.HasPrefix(message, "Beat name:") {
852-
continue
872+
if message, ok := logRecord["message"].(string); ok && strings.HasPrefix(message, "Beat name:") {
873+
logRecords = append(logRecords, logRecord)
853874
}
854-
855-
return logRecord
856875
}
857-
return nil
876+
return logRecords
858877
}
859878

860879
func prepareAgentCmd(t *testing.T, ctx context.Context, config []byte) (*atesting.Fixture, *exec.Cmd, *strings.Builder) {

0 commit comments

Comments
 (0)