Skip to content

Commit

Permalink
Add another unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
Sovietaced committed Dec 29, 2023
1 parent 12db784 commit 2b2c02e
Showing 1 changed file with 123 additions and 52 deletions.
175 changes: 123 additions & 52 deletions instrumentation/net/http/otelhttp/test/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@ import (
"strings"
"testing"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
"go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest"
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
"go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest"

"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation"
Expand Down Expand Up @@ -250,64 +251,134 @@ func TestWithHTTPTrace(t *testing.T) {
}

func TestTransportMetrics(t *testing.T) {
reader := metric.NewManualReader()
meterProvider := metric.NewMeterProvider(metric.WithReader(reader))

requestBody := []byte("john")
responseBody := []byte("Hello, world!")

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
if _, err := w.Write(responseBody); err != nil {
t.Run("make http request and read entire response at once", func(t *testing.T) {
reader := metric.NewManualReader()
meterProvider := metric.NewMeterProvider(metric.WithReader(reader))

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
if _, err := w.Write(responseBody); err != nil {
t.Fatal(err)
}
}))
defer ts.Close()

r, err := http.NewRequest(http.MethodGet, ts.URL, bytes.NewReader(requestBody))
if err != nil {
t.Fatal(err)
}
}))
defer ts.Close()

requestBody := []byte("john")
r, err := http.NewRequest(http.MethodGet, ts.URL, bytes.NewReader(requestBody))
if err != nil {
t.Fatal(err)
}
tr := otelhttp.NewTransport(
http.DefaultTransport,
otelhttp.WithMeterProvider(meterProvider),
)

tr := otelhttp.NewTransport(
http.DefaultTransport,
otelhttp.WithMeterProvider(meterProvider),
)
c := http.Client{Transport: tr}
res, err := c.Do(r)
if err != nil {
t.Fatal(err)
}

c := http.Client{Transport: tr}
res, err := c.Do(r)
if err != nil {
t.Fatal(err)
}
// Must read the body or else we won't get response metrics
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
require.Len(t, bodyBytes, 13)
require.NoError(t, res.Body.Close())

// Must read the body or else we won't get response metrics
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
require.Len(t, bodyBytes, 13)
require.NoError(t, res.Body.Close())
host, portStr, _ := net.SplitHostPort(r.Host)
if host == "" {
host = "127.0.0.1"
}
port, err := strconv.Atoi(portStr)
if err != nil {
port = 0
}

host, portStr, _ := net.SplitHostPort(r.Host)
if host == "" {
host = "127.0.0.1"
}
port, err := strconv.Atoi(portStr)
if err != nil {
port = 0
}
rm := metricdata.ResourceMetrics{}
err = reader.Collect(context.Background(), &rm)
require.NoError(t, err)
require.Len(t, rm.ScopeMetrics, 1)
attrs := attribute.NewSet(
semconv.NetPeerName(host),
semconv.NetPeerPort(port),
semconv.HTTPMethod("GET"),
semconv.HTTPStatusCode(200),
)
assertClientScopeMetrics(t, rm.ScopeMetrics[0], attrs)
})

t.Run("make http request and buffer response", func(t *testing.T) {
reader := metric.NewManualReader()
meterProvider := metric.NewMeterProvider(metric.WithReader(reader))

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
if _, err := w.Write(responseBody); err != nil {
t.Fatal(err)
}
}))
defer ts.Close()

r, err := http.NewRequest(http.MethodGet, ts.URL, bytes.NewReader(requestBody))
if err != nil {
t.Fatal(err)
}

rm := metricdata.ResourceMetrics{}
err = reader.Collect(context.Background(), &rm)
require.NoError(t, err)
require.Len(t, rm.ScopeMetrics, 1)
attrs := attribute.NewSet(
semconv.NetPeerName(host),
semconv.NetPeerPort(port),
semconv.HTTPMethod("GET"),
semconv.HTTPStatusCode(200),
)
assertClientScopeMetrics(t, rm.ScopeMetrics[0], attrs)
tr := otelhttp.NewTransport(
http.DefaultTransport,
otelhttp.WithMeterProvider(meterProvider),
)

c := http.Client{Transport: tr}
res, err := c.Do(r)
if err != nil {
t.Fatal(err)
}

// Must read the body or else we won't get response metrics
smallBuf := make([]byte, 10)

// Read first 10 bytes
bc, err := res.Body.Read(smallBuf)
if err != nil {
t.Fatal(err)
}
require.Equal(t, 10, bc)

// reset byte array
// Read last 3 bytes
bc, err = res.Body.Read(smallBuf)
require.Equal(t, io.EOF, err)
require.Equal(t, 3, bc)

require.NoError(t, res.Body.Close())

host, portStr, _ := net.SplitHostPort(r.Host)
if host == "" {
host = "127.0.0.1"
}
port, err := strconv.Atoi(portStr)
if err != nil {
port = 0
}

rm := metricdata.ResourceMetrics{}
err = reader.Collect(context.Background(), &rm)
require.NoError(t, err)
require.Len(t, rm.ScopeMetrics, 1)
attrs := attribute.NewSet(
semconv.NetPeerName(host),
semconv.NetPeerPort(port),
semconv.HTTPMethod("GET"),
semconv.HTTPStatusCode(200),
)
assertClientScopeMetrics(t, rm.ScopeMetrics[0], attrs)
})
}

func assertClientScopeMetrics(t *testing.T, sm metricdata.ScopeMetrics, attrs attribute.Set) {
Expand Down

0 comments on commit 2b2c02e

Please sign in to comment.