github.com/rudderlabs/rudder-go-kit@v0.30.0/stats/testhelper/otel.go (about)

     1  package testhelper
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strconv"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/ory/dockertest/v3"
    11  	"github.com/ory/dockertest/v3/docker"
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/rudderlabs/rudder-go-kit/httputil"
    15  	"github.com/rudderlabs/rudder-go-kit/testhelper"
    16  	dt "github.com/rudderlabs/rudder-go-kit/testhelper/docker"
    17  )
    18  
    19  const healthPort = "13133"
    20  
    21  type StartOTelCollectorOpt func(*startOTelCollectorConf)
    22  
    23  // WithStartCollectorPort allows to specify the port on which the collector will be listening for gRPC requests.
    24  func WithStartCollectorPort(port int) StartOTelCollectorOpt {
    25  	return func(c *startOTelCollectorConf) {
    26  		c.port = port
    27  	}
    28  }
    29  
    30  func StartOTelCollector(t testing.TB, metricsPort, configPath string, opts ...StartOTelCollectorOpt) (
    31  	container *docker.Container,
    32  	grpcEndpoint string,
    33  ) {
    34  	t.Helper()
    35  
    36  	conf := &startOTelCollectorConf{}
    37  	for _, opt := range opts {
    38  		opt(conf)
    39  	}
    40  
    41  	if conf.port == 0 {
    42  		var err error
    43  		conf.port, err = testhelper.GetFreePort()
    44  		require.NoError(t, err)
    45  	}
    46  
    47  	pool, err := dockertest.NewPool("")
    48  	require.NoError(t, err)
    49  
    50  	collector, err := pool.RunWithOptions(&dockertest.RunOptions{
    51  		Repository:   "otel/opentelemetry-collector",
    52  		Tag:          "0.67.0",
    53  		ExposedPorts: []string{healthPort, metricsPort},
    54  		PortBindings: map[docker.Port][]docker.PortBinding{
    55  			"4317/tcp": {{HostPort: strconv.Itoa(conf.port)}},
    56  		},
    57  		Mounts: []string{configPath + ":/etc/otelcol/config.yaml"},
    58  	})
    59  	require.NoError(t, err)
    60  	t.Cleanup(func() {
    61  		if err := pool.Purge(collector); err != nil {
    62  			t.Logf("Could not purge resource: %v", err)
    63  		}
    64  	})
    65  
    66  	healthEndpoint := fmt.Sprintf("http://localhost:%d", dt.GetHostPort(t, healthPort, collector.Container))
    67  	require.Eventually(t, func() bool {
    68  		resp, err := http.Get(healthEndpoint)
    69  		if err != nil {
    70  			return false
    71  		}
    72  		defer func() { httputil.CloseResponse(resp) }()
    73  		return resp.StatusCode == http.StatusOK
    74  	}, 10*time.Second, 100*time.Millisecond, "Collector was not ready on health port")
    75  
    76  	t.Log("Container is healthy")
    77  
    78  	return collector.Container, "localhost:" + strconv.Itoa(conf.port)
    79  }
    80  
    81  type startOTelCollectorConf struct {
    82  	port int
    83  }