otelroundtripper.TestNew   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
nop 1
dl 0
loc 16
rs 9.75
c 0
b 0
f 0
1
package otelroundtripper
2
3
import (
4
	"context"
5
	"errors"
6
	"go.opentelemetry.io/otel/metric/noop"
7
	"io"
8
	"net"
9
	"net/http"
10
	"net/http/httptest"
11
	"strings"
12
	"testing"
13
	"time"
14
15
	semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
16
17
	"github.com/stretchr/testify/assert"
18
	"go.opentelemetry.io/otel/attribute"
19
)
20
21
func TestNew(t *testing.T) {
22
	t.Run("with no options", func(t *testing.T) {
23
		t.Parallel()
24
		roundTripper := New()
25
		assert.NotNil(t, roundTripper)
26
	})
27
28
	t.Run("with options", func(t *testing.T) {
29
		t.Parallel()
30
		roundTripper := New(
31
			WithName("name"),
32
			WithParent(http.DefaultTransport),
33
			WithMeter(noop.NewMeterProvider().Meter("http.client")),
34
			WithAttributes([]attribute.KeyValue{semconv.ServiceNameKey.String("service")}...),
35
		)
36
		assert.NotNil(t, roundTripper)
37
	})
38
}
39
40
func TestOtelRoundTripper_RoundTrip(t *testing.T) {
41
	// Setup
42
	t.Parallel()
43
	server := makeTestServer(http.StatusOK, http.StatusText(http.StatusOK), 0)
44
45
	// Arrange
46
	client := &http.Client{
47
		Transport: New(),
48
	}
49
50
	// Act
51
	response, err := client.Get(server.URL)
52
53
	// Assert
54
	assert.Nil(t, err)
55
56
	defer func() { _ = response.Body.Close() }()
57
58
	body, err := io.ReadAll(response.Body)
59
	assert.Nil(t, err)
60
61
	assert.Equal(t, http.StatusText(http.StatusOK), string(body))
62
63
	// Teardown
64
	server.Close()
65
}
66
67
func TestOtelRoundTripper_RoundTripWithTimeout(t *testing.T) {
68
	// Setup
69
	t.Parallel()
70
	server := makeTestServer(http.StatusOK, http.StatusText(http.StatusOK), 100)
71
72
	// Arrange
73
	client := &http.Client{
74
		Transport: New(),
75
		Timeout:   10,
76
	}
77
78
	// Act
79
	_, err := client.Get(server.URL) //nolint:bodyclose
80
81
	// Assert
82
	assert.NotNil(t, err)
83
84
	var timeoutError net.Error
85
	assert.True(t, errors.As(err, &timeoutError) && timeoutError.Timeout())
86
87
	// Teardown
88
	server.Close()
89
}
90
91
func TestOtelRoundTripper_RoundTripWithCancelledContext(t *testing.T) {
92
	// Setup
93
	t.Parallel()
94
	server := makeTestServer(http.StatusOK, http.StatusText(http.StatusOK), 0)
95
96
	// Arrange
97
	client := &http.Client{
98
		Transport: New(),
99
	}
100
101
	ctx, cancelFunc := context.WithCancel(context.Background())
102
	cancelFunc()
103
104
	// Act
105
	request, err := http.NewRequestWithContext(ctx, http.MethodGet, server.URL, nil)
106
	assert.Nil(t, err)
107
108
	_, err = client.Do(request) //nolint:bodyclose
109
110
	// Assert
111
	assert.NotNil(t, err)
112
	assert.True(t, strings.HasSuffix(err.Error(), context.Canceled.Error()))
113
114
	// Teardown
115
	server.Close()
116
}
117
118
// makeTestServer creates an api server for testing
119
func makeTestServer(responseCode int, body string, delay int) *httptest.Server {
120
	return httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
121
		res.WriteHeader(responseCode)
122
123
		if delay > 0 {
124
			time.Sleep(time.Duration(delay) * time.Millisecond)
125
		}
126
127
		_, err := res.Write([]byte(body))
128
		if err != nil {
129
			panic(err)
130
		}
131
	}))
132
}
133