Skip to content

Commit 4351562

Browse files
committed
add unit tests
1 parent 14351ed commit 4351562

File tree

5 files changed

+143
-6
lines changed

5 files changed

+143
-6
lines changed

instrumentation/github.com/aws/aws-lambda-go/otellambda/example/go.sum

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ3
6868
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
6969
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
7070
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
71+
go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
7172
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
7273
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
7374
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=

instrumentation/net/http/otelhttp/go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/stretchr/testify v1.8.4
88
go.opentelemetry.io/otel v1.21.0
99
go.opentelemetry.io/otel/metric v1.21.0
10+
go.opentelemetry.io/otel/sdk/metric v1.21.0
1011
go.opentelemetry.io/otel/trace v1.21.0
1112
)
1213

@@ -15,5 +16,7 @@ require (
1516
github.com/go-logr/logr v1.3.0 // indirect
1617
github.com/go-logr/stdr v1.2.2 // indirect
1718
github.com/pmezard/go-difflib v1.0.0 // indirect
19+
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
20+
golang.org/x/sys v0.14.0 // indirect
1821
gopkg.in/yaml.v3 v3.0.1 // indirect
1922
)

instrumentation/net/http/otelhttp/go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,14 @@ go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
1616
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
1717
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
1818
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
19+
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
20+
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
21+
go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
22+
go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
1923
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
2024
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
25+
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
26+
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
2127
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
2228
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
2329
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ func HTTPClientRequest(req *http.Request) []attribute.KeyValue {
5252
}
5353

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

298297
// ClientRequestMetrics returns metric attributes for an HTTP request made by a client. The
299-
// following attributes are always returned: "http.method",
300-
// "net.peer.name". The following attributes are returned if the related values
298+
// following attributes are always returned: "http.method", "net.peer.name".
299+
// The following attributes are returned if the related values
301300
// are defined in req: "net.peer.port".
302301
func (c *httpConv) ClientRequestMetrics(req *http.Request) []attribute.KeyValue {
303302
/* The following semantic conventions are returned if present:

instrumentation/net/http/otelhttp/transport_test.go

+128
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,16 @@ import (
1818
"bytes"
1919
"context"
2020
"errors"
21+
"fmt"
22+
"go.opentelemetry.io/otel/attribute"
23+
"go.opentelemetry.io/otel/sdk/instrumentation"
24+
"go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest"
25+
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
2126
"io"
27+
"net"
2228
"net/http"
2329
"net/http/httptest"
30+
"strconv"
2431
"strings"
2532
"testing"
2633

@@ -30,6 +37,9 @@ import (
3037
"go.opentelemetry.io/otel/codes"
3138
"go.opentelemetry.io/otel/propagation"
3239
"go.opentelemetry.io/otel/trace"
40+
41+
"go.opentelemetry.io/otel/sdk/metric"
42+
"go.opentelemetry.io/otel/sdk/metric/metricdata"
3343
)
3444

3545
func TestTransportFormatter(t *testing.T) {
@@ -432,3 +442,121 @@ func TestTransportOriginRequestNotModify(t *testing.T) {
432442

433443
assert.Equal(t, expectedRequest, r)
434444
}
445+
446+
func TestTransportMetrics(t *testing.T) {
447+
reader := metric.NewManualReader()
448+
meterProvider := metric.NewMeterProvider(metric.WithReader(reader))
449+
450+
responseBody := []byte("Hello, world!")
451+
452+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
453+
w.WriteHeader(http.StatusOK)
454+
if _, err := w.Write(responseBody); err != nil {
455+
t.Fatal(err)
456+
}
457+
}))
458+
defer ts.Close()
459+
460+
requestBody := []byte("john")
461+
r, err := http.NewRequest(http.MethodGet, ts.URL, bytes.NewReader(requestBody))
462+
if err != nil {
463+
t.Fatal(err)
464+
}
465+
466+
tr := NewTransport(
467+
http.DefaultTransport,
468+
WithMeterProvider(meterProvider),
469+
)
470+
471+
c := http.Client{Transport: tr}
472+
res, err := c.Do(r)
473+
if err != nil {
474+
t.Fatal(err)
475+
}
476+
477+
// Must read the body or else we won't get response metrics
478+
bodyBytes, err := io.ReadAll(res.Body)
479+
if err != nil {
480+
t.Fatal(err)
481+
}
482+
require.Len(t, bodyBytes, 13)
483+
require.NoError(t, res.Body.Close())
484+
485+
host, portStr, _ := net.SplitHostPort(r.Host)
486+
if host == "" {
487+
host = "127.0.0.1"
488+
}
489+
port, err := strconv.Atoi(portStr)
490+
if err != nil {
491+
port = 0
492+
}
493+
494+
rm := metricdata.ResourceMetrics{}
495+
err = reader.Collect(context.Background(), &rm)
496+
require.NoError(t, err)
497+
require.Len(t, rm.ScopeMetrics, 1)
498+
attrs := attribute.NewSet(
499+
semconv.NetPeerName(host),
500+
semconv.NetPeerPort(port),
501+
semconv.HTTPMethod("GET"),
502+
semconv.HTTPStatusCode(200),
503+
)
504+
assertClientScopeMetrics(t, rm.ScopeMetrics[0], attrs)
505+
}
506+
507+
func assertClientScopeMetrics(t *testing.T, sm metricdata.ScopeMetrics, attrs attribute.Set) {
508+
509+
assert.Equal(t, instrumentation.Scope{
510+
Name: "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",
511+
Version: Version(),
512+
}, sm.Scope)
513+
514+
require.Len(t, sm.Metrics, 3)
515+
516+
want := metricdata.Metrics{
517+
Name: "http.client.request_content_length",
518+
Data: metricdata.Sum[int64]{
519+
DataPoints: []metricdata.DataPoint[int64]{{Attributes: attrs, Value: 4}},
520+
Temporality: metricdata.CumulativeTemporality,
521+
IsMonotonic: true,
522+
},
523+
Description: "Measures the size of HTTP request content length (uncompressed)",
524+
Unit: "By",
525+
}
526+
metricdatatest.AssertEqual(t, want, sm.Metrics[0], metricdatatest.IgnoreTimestamp())
527+
528+
want = metricdata.Metrics{
529+
Name: "http.client.response_content_length",
530+
Data: metricdata.Sum[int64]{
531+
DataPoints: []metricdata.DataPoint[int64]{{Attributes: attrs, Value: 13}},
532+
Temporality: metricdata.CumulativeTemporality,
533+
IsMonotonic: true,
534+
},
535+
Description: "Measures the size of HTTP response content length (uncompressed)",
536+
Unit: "By",
537+
}
538+
metricdatatest.AssertEqual(t, want, sm.Metrics[1], metricdatatest.IgnoreTimestamp())
539+
540+
dur := sm.Metrics[2]
541+
assert.Equal(t, "http.client.duration", dur.Name)
542+
require.IsType(t, dur.Data, metricdata.Histogram[float64]{})
543+
hist := dur.Data.(metricdata.Histogram[float64])
544+
assert.Equal(t, metricdata.CumulativeTemporality, hist.Temporality)
545+
require.Len(t, hist.DataPoints, 1)
546+
dPt := hist.DataPoints[0]
547+
assert.Equal(t, attrs, dPt.Attributes, "attributes")
548+
assert.Equal(t, uint64(1), dPt.Count, "count")
549+
assert.Equal(t, []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, dPt.Bounds, "bounds")
550+
551+
t.Log(fmt.Sprintf("%+v", dPt.BucketCounts))
552+
553+
// Duration value is not deterministic because the code does not support a pluggable clock.
554+
// So just value that one of the buckets has been incremented.
555+
bucketSum := uint64(0)
556+
for _, bucketCount := range dPt.BucketCounts {
557+
bucketSum += bucketCount
558+
}
559+
560+
require.Equal(t, uint64(1), bucketSum)
561+
562+
}

0 commit comments

Comments
 (0)