Skip to content

Commit

Permalink
add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Sovietaced committed Dec 17, 2023
1 parent 14351ed commit 4351562
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ3
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
Expand Down
3 changes: 3 additions & 0 deletions instrumentation/net/http/otelhttp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/stretchr/testify v1.8.4
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/metric v1.21.0
go.opentelemetry.io/otel/sdk/metric v1.21.0
go.opentelemetry.io/otel/trace v1.21.0
)

Expand All @@ -15,5 +16,7 @@ require (
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
golang.org/x/sys v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
6 changes: 6 additions & 0 deletions instrumentation/net/http/otelhttp/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ func HTTPClientRequest(req *http.Request) []attribute.KeyValue {
}

// HTTPClientRequestMetrics returns metric attributes for an HTTP request made by a client.
// The following attributes are always returned: "http.flavor",
// "http.method", "net.peer.name". The following attributes are returned if the
// related values are defined in req: "http.url", "net.peer.port", "http.user_agent",
// "enduser.id".
// The following attributes are always returned: "http.method", "net.peer.name".
// The following attributes are returned if the
// related values are defined in req: "net.peer.port".
func HTTPClientRequestMetrics(req *http.Request) []attribute.KeyValue {
return hc.ClientRequestMetrics(req)
}
Expand Down Expand Up @@ -296,8 +295,8 @@ func (c *httpConv) ClientRequest(req *http.Request) []attribute.KeyValue {
}

// ClientRequestMetrics returns metric attributes for an HTTP request made by a client. The
// following attributes are always returned: "http.method",
// "net.peer.name". The following attributes are returned if the related values
// following attributes are always returned: "http.method", "net.peer.name".
// The following attributes are returned if the related values
// are defined in req: "net.peer.port".
func (c *httpConv) ClientRequestMetrics(req *http.Request) []attribute.KeyValue {
/* The following semantic conventions are returned if present:
Expand Down
128 changes: 128 additions & 0 deletions instrumentation/net/http/otelhttp/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@ import (
"bytes"
"context"
"errors"
"fmt"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest"
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
"io"
"net"
"net/http"
"net/http/httptest"
"strconv"
"strings"
"testing"

Expand All @@ -30,6 +37,9 @@ import (
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"

"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
)

func TestTransportFormatter(t *testing.T) {
Expand Down Expand Up @@ -432,3 +442,121 @@ func TestTransportOriginRequestNotModify(t *testing.T) {

assert.Equal(t, expectedRequest, r)
}

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

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.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 := NewTransport(
http.DefaultTransport,
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
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
}

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) {

assert.Equal(t, instrumentation.Scope{
Name: "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",
Version: Version(),
}, sm.Scope)

require.Len(t, sm.Metrics, 3)

want := metricdata.Metrics{
Name: "http.client.request_content_length",
Data: metricdata.Sum[int64]{
DataPoints: []metricdata.DataPoint[int64]{{Attributes: attrs, Value: 4}},
Temporality: metricdata.CumulativeTemporality,
IsMonotonic: true,
},
Description: "Measures the size of HTTP request content length (uncompressed)",
Unit: "By",
}
metricdatatest.AssertEqual(t, want, sm.Metrics[0], metricdatatest.IgnoreTimestamp())

want = metricdata.Metrics{
Name: "http.client.response_content_length",
Data: metricdata.Sum[int64]{
DataPoints: []metricdata.DataPoint[int64]{{Attributes: attrs, Value: 13}},
Temporality: metricdata.CumulativeTemporality,
IsMonotonic: true,
},
Description: "Measures the size of HTTP response content length (uncompressed)",
Unit: "By",
}
metricdatatest.AssertEqual(t, want, sm.Metrics[1], metricdatatest.IgnoreTimestamp())

dur := sm.Metrics[2]
assert.Equal(t, "http.client.duration", dur.Name)
require.IsType(t, dur.Data, metricdata.Histogram[float64]{})
hist := dur.Data.(metricdata.Histogram[float64])
assert.Equal(t, metricdata.CumulativeTemporality, hist.Temporality)
require.Len(t, hist.DataPoints, 1)
dPt := hist.DataPoints[0]
assert.Equal(t, attrs, dPt.Attributes, "attributes")
assert.Equal(t, uint64(1), dPt.Count, "count")
assert.Equal(t, []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, dPt.Bounds, "bounds")

t.Log(fmt.Sprintf("%+v", dPt.BucketCounts))

// Duration value is not deterministic because the code does not support a pluggable clock.
// So just value that one of the buckets has been incremented.
bucketSum := uint64(0)
for _, bucketCount := range dPt.BucketCounts {
bucketSum += bucketCount
}

require.Equal(t, uint64(1), bucketSum)

}

0 comments on commit 4351562

Please sign in to comment.