From 575e9c60255f0df88dd2b864f191db395c02f8bf Mon Sep 17 00:00:00 2001 From: Adam Korczynski Date: Wed, 9 Oct 2024 11:39:07 +0000 Subject: [PATCH] add fuzz tests to multiple receivers and processors Signed-off-by: Adam Korczynski --- processor/groupbyattrsprocessor/fuzz_test.go | 59 +++++++++++++ processor/logdedupprocessor/fuzz_test.go | 30 +++++++ .../fuzz_test.go | 49 +++++++++++ processor/sumologicprocessor/fuzz_test.go | 84 +++++++++++++++++++ processor/tailsamplingprocessor/fuzz_test.go | 31 +++++++ receiver/cloudflarereceiver/fuzz_test.go | 47 +++++++++++ receiver/lokireceiver/internal/fuzz_test.go | 28 +++++++ receiver/mongodbatlasreceiver/fuzz_test.go | 37 ++++++++ receiver/sapmreceiver/fuzz_test.go | 31 +++++++ receiver/signalfxreceiver/fuzz_test.go | 31 +++++++ receiver/splunkhecreceiver/fuzz_test.go | 34 ++++++++ receiver/webhookeventreceiver/fuzz_test.go | 42 ++++++++++ 12 files changed, 503 insertions(+) create mode 100644 processor/groupbyattrsprocessor/fuzz_test.go create mode 100644 processor/logdedupprocessor/fuzz_test.go create mode 100644 processor/probabilisticsamplerprocessor/fuzz_test.go create mode 100644 processor/sumologicprocessor/fuzz_test.go create mode 100644 processor/tailsamplingprocessor/fuzz_test.go create mode 100644 receiver/cloudflarereceiver/fuzz_test.go create mode 100644 receiver/lokireceiver/internal/fuzz_test.go create mode 100644 receiver/mongodbatlasreceiver/fuzz_test.go create mode 100644 receiver/sapmreceiver/fuzz_test.go create mode 100644 receiver/signalfxreceiver/fuzz_test.go create mode 100644 receiver/splunkhecreceiver/fuzz_test.go create mode 100644 receiver/webhookeventreceiver/fuzz_test.go diff --git a/processor/groupbyattrsprocessor/fuzz_test.go b/processor/groupbyattrsprocessor/fuzz_test.go new file mode 100644 index 000000000000..f5bd91c018bc --- /dev/null +++ b/processor/groupbyattrsprocessor/fuzz_test.go @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package groupbyattrsprocessor + +import ( + "context" + "testing" + + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/collector/processor/processortest" +) + +func FuzzProcessTraces(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + ju := &ptrace.JSONUnmarshaler{} + traces, err := ju.UnmarshalTraces(data) + if err != nil { + return + } + gap, err := createGroupByAttrsProcessor(processortest.NewNopSettings(), []string{}) + if err != nil { + t.Fatal(err) + } + _, _ = gap.processTraces(context.Background(), traces) + }) +} + +func FuzzProcessLogs(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + ju := &plog.JSONUnmarshaler{} + logs, err := ju.UnmarshalLogs(data) + if err != nil { + return + } + gap, err := createGroupByAttrsProcessor(processortest.NewNopSettings(), []string{}) + if err != nil { + t.Fatal(err) + } + _, _ = gap.processLogs(context.Background(), logs) + }) +} + +func FuzzProcessMetrics(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + ju := &pmetric.JSONUnmarshaler{} + metrics, err := ju.UnmarshalMetrics(data) + if err != nil { + return + } + gap, err := createGroupByAttrsProcessor(processortest.NewNopSettings(), []string{}) + if err != nil { + t.Fatal(err) + } + _, _ = gap.processMetrics(context.Background(), metrics) + }) +} diff --git a/processor/logdedupprocessor/fuzz_test.go b/processor/logdedupprocessor/fuzz_test.go new file mode 100644 index 000000000000..e527eda81e5a --- /dev/null +++ b/processor/logdedupprocessor/fuzz_test.go @@ -0,0 +1,30 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package logdedupprocessor + +import ( + "context" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/processor/processortest" + "testing" +) + +func FuzzConsumeLogs(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + ju := &plog.JSONUnmarshaler{} + logs, err := ju.UnmarshalLogs(data) + if err != nil { + return + } + sink := new(consumertest.LogsSink) + set := processortest.NewNopSettings() + cfg := &Config{} + lp, err := newProcessor(cfg, sink, set) + if err != nil { + t.Fatal(err) + } + _ = lp.ConsumeLogs(context.Background(), logs) + }) +} diff --git a/processor/probabilisticsamplerprocessor/fuzz_test.go b/processor/probabilisticsamplerprocessor/fuzz_test.go new file mode 100644 index 000000000000..7880c518c2ef --- /dev/null +++ b/processor/probabilisticsamplerprocessor/fuzz_test.go @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package probabilisticsamplerprocessor + +import ( + "context" + "testing" + + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/collector/processor/processortest" +) + +func FuzzConsumeTraces(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + ju := &ptrace.JSONUnmarshaler{} + traces, err := ju.UnmarshalTraces(data) + if err != nil { + return + } + sink := new(consumertest.TracesSink) + set := processortest.NewNopSettings() + cfg := &Config{} + tsp, err := newTracesProcessor(context.Background(), set, cfg, sink) + if err != nil { + t.Fatal(err) + } + _ = tsp.ConsumeTraces(context.Background(), traces) + }) +} + +func FuzzConsumeLogs(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + ju := &plog.JSONUnmarshaler{} + logs, err := ju.UnmarshalLogs(data) + if err != nil { + return + } + nextConsumer := consumertest.NewNop() + cfg := &Config{} + lp, err := newLogsProcessor(context.Background(), processortest.NewNopSettings(), nextConsumer, cfg) + if err != nil { + t.Fatal(err) + } + _ = lp.ConsumeLogs(context.Background(), logs) + }) +} diff --git a/processor/sumologicprocessor/fuzz_test.go b/processor/sumologicprocessor/fuzz_test.go new file mode 100644 index 000000000000..eef555d6aeb0 --- /dev/null +++ b/processor/sumologicprocessor/fuzz_test.go @@ -0,0 +1,84 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sumologicprocessor + +import ( + "testing" + + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/ptrace" +) + +func FuzzProcessTraces(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte, processorType uint8) { + ju := &ptrace.JSONUnmarshaler{} + traces, err := ju.UnmarshalTraces(data) + if err != nil { + return + } + switch int(processorType) % 4 { + case 0: + proc := &aggregateAttributesProcessor{} + proc.processTraces(traces) + case 1: + proc := &cloudNamespaceProcessor{} + proc.processTraces(traces) + case 2: + proc := &NestingProcessor{} + proc.processTraces(traces) + case 3: + proc := &translateAttributesProcessor{} + proc.processTraces(traces) + } + }) +} + +func FuzzProcessLogs(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte, processorType uint8) { + ju := &plog.JSONUnmarshaler{} + logs, err := ju.UnmarshalLogs(data) + if err != nil { + return + } + switch int(processorType) % 4 { + case 0: + proc := &aggregateAttributesProcessor{} + proc.processLogs(logs) + case 1: + proc := &cloudNamespaceProcessor{} + proc.processLogs(logs) + case 2: + proc := &NestingProcessor{} + proc.processLogs(logs) + case 3: + proc := &translateAttributesProcessor{} + proc.processLogs(logs) + } + }) +} + +func FuzzProcessMetrics(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte, processorType uint8) { + ju := &pmetric.JSONUnmarshaler{} + metrics, err := ju.UnmarshalMetrics(data) + if err != nil { + return + } + switch int(processorType) % 4 { + case 0: + proc := &aggregateAttributesProcessor{} + proc.processMetrics(metrics) + case 1: + proc := &cloudNamespaceProcessor{} + proc.processMetrics(metrics) + case 2: + proc := &NestingProcessor{} + proc.processMetrics(metrics) + case 3: + proc := &translateAttributesProcessor{} + proc.processMetrics(metrics) + } + }) +} diff --git a/processor/tailsamplingprocessor/fuzz_test.go b/processor/tailsamplingprocessor/fuzz_test.go new file mode 100644 index 000000000000..ca6835c59a93 --- /dev/null +++ b/processor/tailsamplingprocessor/fuzz_test.go @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package tailsamplingprocessor + +import ( + "context" + "testing" + + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/collector/processor/processortest" +) + +func FuzzConsumeTraces(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + ju := &ptrace.JSONUnmarshaler{} + traces, err := ju.UnmarshalTraces(data) + if err != nil { + return + } + sink := new(consumertest.TracesSink) + set := processortest.NewNopSettings() + cfg := &Config{} + tsp, err := newTracesProcessor(context.Background(), set, sink, *cfg) + if err != nil { + t.Fatal(err) + } + _ = tsp.ConsumeTraces(context.Background(), traces) + }) +} diff --git a/receiver/cloudflarereceiver/fuzz_test.go b/receiver/cloudflarereceiver/fuzz_test.go new file mode 100644 index 000000000000..7c76768a58b1 --- /dev/null +++ b/receiver/cloudflarereceiver/fuzz_test.go @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cloudflarereceiver + +import ( + "bytes" + "net/http" + + "net/http/httptest" + "testing" + + "go.opentelemetry.io/collector/config/configtls" + "go.opentelemetry.io/collector/consumer/consumertest" +) + +func FuzzHandleReq(f *testing.F) { + f.Fuzz(func(t *testing.T, reqBody []byte, gZip bool) { + + req, err := http.NewRequest("POST", "http://example.com", bytes.NewReader(reqBody)) + if err != nil { + t.Skip() + } + req.Header.Add(secretHeaderName, "abc123") + req.Header.Add("Content-Type", "text/plain; charset=utf-8") + if gZip { + req.Header.Add("Content-Encoding", "gzip") + } + consumer := &consumertest.LogsSink{} + + r := newReceiver(t, &Config{ + Logs: LogsConfig{ + Endpoint: "localhost:0", + Secret: "abc123", + TimestampField: "MyTimestamp", + Attributes: map[string]string{ + "ClientIP": "http_request.client_ip", + }, + TLS: &configtls.ServerConfig{}, + }, + }, + consumer, + ) + rec := httptest.NewRecorder() + r.handleRequest(rec, req) + }) +} diff --git a/receiver/lokireceiver/internal/fuzz_test.go b/receiver/lokireceiver/internal/fuzz_test.go new file mode 100644 index 000000000000..abb82da39809 --- /dev/null +++ b/receiver/lokireceiver/internal/fuzz_test.go @@ -0,0 +1,28 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal + +import ( + "bytes" + "net/http" + "testing" +) + +func FuzzParseRequest(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte, headerType uint8) { + req, err := http.NewRequest("POST", "http://example.com", bytes.NewReader(data)) + if err != nil { + t.Skip() + } + switch int(headerType) % 3 { + case 0: + req.Header.Add("Content-Encoding", "snappy") + case 1: + req.Header.Add("Content-Encoding", "gzip") + case 2: + req.Header.Add("Content-Encoding", "deflat") + } + _, _ = ParseRequest(req) + }) +} diff --git a/receiver/mongodbatlasreceiver/fuzz_test.go b/receiver/mongodbatlasreceiver/fuzz_test.go new file mode 100644 index 000000000000..e79392d22f43 --- /dev/null +++ b/receiver/mongodbatlasreceiver/fuzz_test.go @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package mongodbatlasreceiver + +import ( + "bytes" + "net/http" + + "net/http/httptest" + "testing" + + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/receiver/receivertest" + "go.uber.org/zap/zaptest" +) + +func FuzzHandleReq(f *testing.F) { + f.Fuzz(func(t *testing.T, reqBody []byte, payloadSigHeader string) { + + req, err := http.NewRequest("POST", "http://example.com", bytes.NewReader(reqBody)) + if err != nil { + t.Skip() + } + req.Header.Add(signatureHeaderName, payloadSigHeader) + consumer := &consumertest.LogsSink{} + + set := receivertest.NewNopSettings() + set.Logger = zaptest.NewLogger(t) + ar, err := newAlertsReceiver(set, &Config{Alerts: AlertConfig{Secret: "some_secret"}}, consumer) + if err != nil { + t.Fatal(err) + } + rec := httptest.NewRecorder() + ar.handleRequest(rec, req) + }) +} diff --git a/receiver/sapmreceiver/fuzz_test.go b/receiver/sapmreceiver/fuzz_test.go new file mode 100644 index 000000000000..ce69af3f7ae3 --- /dev/null +++ b/receiver/sapmreceiver/fuzz_test.go @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sapmreceiver + +import ( + "bytes" + "net/http" + "testing" + + "github.com/signalfx/sapm-proto/sapmprotocol" +) + +func FuzzParseTraceV2Request(f *testing.F) { + f.Fuzz(func(t *testing.T, reqBody []byte, encoding uint8) { + req, err := http.NewRequest("POST", "http://example.com", bytes.NewReader(reqBody)) + if err != nil { + t.Skip() + } + req.Header.Add("Content-Type", "application/x-protobuf") + switch int(encoding) % 3 { + case 0: + req.Header.Add("Content-Encoding", "gzip") + case 1: + req.Header.Add("Content-Encoding", "zstd") + default: + } + + sapmprotocol.ParseTraceV2Request(req) + }) +} diff --git a/receiver/signalfxreceiver/fuzz_test.go b/receiver/signalfxreceiver/fuzz_test.go new file mode 100644 index 000000000000..b4296fb147d4 --- /dev/null +++ b/receiver/signalfxreceiver/fuzz_test.go @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package signalfxreceiver + +import ( + "bytes" + "net/http" + "net/http/httptest" + "testing" + + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +func FuzzHandleDatapointReq(f *testing.F) { + f.Fuzz(func(t *testing.T, reqBody []byte) { + req, err := http.NewRequest("POST", "http://example.com", bytes.NewReader(reqBody)) + if err != nil { + t.Skip() + } + req.Header.Add(httpContentTypeHeader, otlpProtobufContentType) + rec, err := newReceiver(receivertest.NewNopSettings(), Config{}) + if err != nil { + t.Fatal(err) + } + sink := new(consumertest.MetricsSink) + rec.RegisterMetricsConsumer(sink) + rec.handleDatapointReq(httptest.NewRecorder(), req) + }) +} diff --git a/receiver/splunkhecreceiver/fuzz_test.go b/receiver/splunkhecreceiver/fuzz_test.go new file mode 100644 index 000000000000..a1f1736c70c9 --- /dev/null +++ b/receiver/splunkhecreceiver/fuzz_test.go @@ -0,0 +1,34 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package splunkhecreceiver + +import ( + "bytes" + "net/http" + + "net/http/httptest" + "testing" + + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +func FuzzHandleRawReq(f *testing.F) { + f.Fuzz(func(t *testing.T, reqBody []byte) { + req, err := http.NewRequest("POST", "http://example.com", bytes.NewReader(reqBody)) + if err != nil { + t.Skip() + } + req.Header.Add("If-None-Match", `W/"wyzzy"`) + sink := new(consumertest.LogsSink) + defaultConfig := createDefaultConfig().(*Config) + rcv, err := newLogsReceiver(receivertest.NewNopSettings(), *defaultConfig, sink) + if err != nil { + t.Fatal(err) + } + r := rcv.(*splunkReceiver) + w := httptest.NewRecorder() + r.handleRawReq(w, req) + }) +} diff --git a/receiver/webhookeventreceiver/fuzz_test.go b/receiver/webhookeventreceiver/fuzz_test.go new file mode 100644 index 000000000000..4fbbe1244317 --- /dev/null +++ b/receiver/webhookeventreceiver/fuzz_test.go @@ -0,0 +1,42 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package webhookeventreceiver + +import ( + "bytes" + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/julienschmidt/httprouter" + "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +func FuzzHandleReq(f *testing.F) { + f.Fuzz(func(t *testing.T, reqBody []byte, useGzip bool) { + req, err := http.NewRequest("POST", "http://example.com", bytes.NewReader(reqBody)) + if err != nil { + t.Skip() + } + if useGzip { + req.Header.Add("Content-Encoding", "gzip") + } + + consumer := consumertest.NewNop() + receiver, err := newLogsReceiver(receivertest.NewNopSettings(), Config{ServerConfig: confighttp.ServerConfig{ + Endpoint: "localhost:8080", + }}, consumer) + if err != nil { + t.Fatal(err) + } + + r := receiver.(*eventReceiver) + + w := httptest.NewRecorder() + r.handleReq(w, req, httprouter.ParamsFromContext(context.Background())) + }) +}