Path: blob/main/component/otelcol/exporter/otlphttp/otlphttp_test.go
4096 views
package otlphttp_test12import (3"fmt"4"io"5"net/http"6"net/http/httptest"7"testing"8"time"910"github.com/go-kit/log/level"11"github.com/grafana/agent/component/otelcol"12"github.com/grafana/agent/component/otelcol/exporter/otlphttp"13"github.com/grafana/agent/pkg/flow/componenttest"14"github.com/grafana/agent/pkg/river"15"github.com/grafana/agent/pkg/util"16"github.com/grafana/dskit/backoff"17"github.com/stretchr/testify/require"18"go.opentelemetry.io/collector/pdata/ptrace"19)2021// Test performs a basic integration test which runs the22// otelcol.exporter.otlphttp component and ensures that it can pass data to an23// OTLP HTTP server.24func Test(t *testing.T) {25ch := make(chan ptrace.Traces)26srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {27b, _ := io.ReadAll(r.Body)28decoder := &ptrace.ProtoUnmarshaler{}29trace, _ := decoder.UnmarshalTraces(b)30require.Equal(t, 1, trace.SpanCount())31name := trace.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Name()32require.Equal(t, "TestSpan", name)33ch <- trace34w.WriteHeader(http.StatusOK)35}))36defer srv.Close()3738ctx := componenttest.TestContext(t)39l := util.TestLogger(t)4041ctrl, err := componenttest.NewControllerFromID(l, "otelcol.exporter.otlphttp")42require.NoError(t, err)4344cfg := fmt.Sprintf(`45client {46endpoint = "%s"4748compression = "none"4950tls {51insecure = true52insecure_skip_verify = true53}54}55`, srv.URL)56var args otlphttp.Arguments57require.NoError(t, river.Unmarshal([]byte(cfg), &args))5859go func() {60err := ctrl.Run(ctx, args)61require.NoError(t, err)62}()6364require.NoError(t, ctrl.WaitRunning(time.Second), "component never started")65require.NoError(t, ctrl.WaitExports(time.Second), "component never exported anything")6667// Send traces in the background to our exporter.68go func() {69exports := ctrl.Exports().(otelcol.ConsumerExports)7071bo := backoff.New(ctx, backoff.Config{72MinBackoff: 10 * time.Millisecond,73MaxBackoff: 100 * time.Millisecond,74})75for bo.Ongoing() {76err := exports.Input.ConsumeTraces(ctx, createTestTraces())77if err != nil {78level.Error(l).Log("msg", "failed to send traces", "err", err)79bo.Wait()80continue81}8283return84}85}()8687// Wait for our exporter to finish and pass data to our HTTP server.88select {89case <-time.After(time.Second):90require.FailNow(t, "failed waiting for traces")91case tr := <-ch:92require.Equal(t, 1, tr.SpanCount())93}94}9596func createTestTraces() ptrace.Traces {97// Matches format from the protobuf definition:98// https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/trace/v1/trace.proto99var bb = `{100"resource_spans": [{101"scope_spans": [{102"spans": [{103"name": "TestSpan"104}]105}]106}]107}`108109decoder := &ptrace.JSONUnmarshaler{}110data, err := decoder.UnmarshalTraces([]byte(bb))111if err != nil {112panic(err)113}114return data115}116117118