Skip to content

Commit f2aea09

Browse files
Merge branch 'main' into upgrade-kotlin-and-linter
2 parents 2489ce0 + 44974ec commit f2aea09

File tree

2 files changed

+167
-23
lines changed

2 files changed

+167
-23
lines changed

go/rtl/auth.go

+22-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"net/url"
1111
"os"
1212
"reflect"
13+
"time"
1314

1415
"golang.org/x/oauth2"
1516
"golang.org/x/oauth2/clientcredentials"
@@ -122,15 +123,34 @@ func (s *AuthSession) Do(result interface{}, method, ver, path string, reqPars m
122123
}
123124
}
124125

126+
// create request context with timeout
127+
var timeoutInSeconds int32 = 120 //seconds
128+
if s.Config.Timeout != 0 {
129+
timeoutInSeconds = s.Config.Timeout
130+
}
131+
if options != nil && options.Timeout != 0 {
132+
timeoutInSeconds = options.Timeout
133+
}
134+
135+
ctx, cncl := context.WithTimeout(context.Background(), time.Second * time.Duration(timeoutInSeconds))
136+
defer cncl()
137+
125138
// create new request
126-
req, err := http.NewRequest(method, u, bytes.NewBufferString(bodyString))
139+
req, err := http.NewRequestWithContext(ctx, method, u, bytes.NewBufferString(bodyString))
127140
if err != nil {
128141
return err
129142
}
130143

131-
// set content-type header
144+
// set headers
132145
req.Header.Add("Content-Type", contentTypeHeader)
133146

147+
if s.Config.AgentTag != "" {
148+
req.Header.Set("User-Agent", s.Config.AgentTag)
149+
}
150+
if options != nil && options.AgentTag != "" {
151+
req.Header.Set("User-Agent", options.AgentTag)
152+
}
153+
134154
// set query params
135155
setQuery(req.URL, reqPars)
136156

go/rtl/auth_test.go

+145-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package rtl
22

33
import (
4+
"context"
45
"encoding/json"
6+
"errors"
57
"fmt"
68
"net/http"
79
"net/http/httptest"
@@ -50,13 +52,13 @@ func TestAuthSession_Do_Authorization(t *testing.T) {
5052
}
5153
})
5254

53-
s := NewAuthSession(ApiSettings{
55+
session := NewAuthSession(ApiSettings{
5456
BaseUrl: server.URL,
5557
ApiVersion: apiVersion,
5658
})
5759

5860
var r string
59-
err := s.Do(&r, "GET", apiVersion, path, nil, nil, nil)
61+
err := session.Do(&r, "GET", apiVersion, path, nil, nil, nil)
6062

6163
if err != nil {
6264
t.Errorf("Do() call failed: %v", err)
@@ -91,13 +93,13 @@ func TestAuthSession_Do_Authorization(t *testing.T) {
9193
fmt.Fprint(w, string(s))
9294
})
9395

94-
s := NewAuthSession(ApiSettings{
96+
session := NewAuthSession(ApiSettings{
9597
BaseUrl: server.URL,
9698
ApiVersion: apiVersion,
9799
})
98100

99101
var r string
100-
err := s.Do(&r, "GET", apiVersion, path, nil, nil, nil)
102+
err := session.Do(&r, "GET", apiVersion, path, nil, nil, nil)
101103

102104
if err != nil {
103105
t.Errorf("First Do() call failed: %v", err)
@@ -106,7 +108,7 @@ func TestAuthSession_Do_Authorization(t *testing.T) {
106108
// wait till previous token is definitely expired
107109
time.Sleep(2 * time.Second)
108110

109-
err = s.Do(&r, "GET", apiVersion, path, nil, nil, nil)
111+
err = session.Do(&r, "GET", apiVersion, path, nil, nil, nil)
110112

111113
if err != nil {
112114
t.Errorf("Second Do() call failed: %v", err)
@@ -123,6 +125,70 @@ func TestAuthSession_Do_Authorization(t *testing.T) {
123125
})
124126
}
125127

128+
func TestAuthSession_Do_UserAgent(t *testing.T) {
129+
const path = "/someMethod"
130+
const apiVersion = "/4.0"
131+
132+
t.Run("Do() sets User-Agent header with AuthSession config's AgentTag", func(t *testing.T) {
133+
mux := http.NewServeMux()
134+
setupApi40Login(mux, foreverValidTestToken, http.StatusOK)
135+
server := httptest.NewServer(mux)
136+
defer server.Close()
137+
138+
mux.HandleFunc("/api"+apiVersion+path, func(w http.ResponseWriter, r *http.Request) {
139+
userAgentHeader := r.Header.Get("User-Agent")
140+
expectedHeader := "some-agent-tag"
141+
if userAgentHeader != expectedHeader {
142+
t.Errorf("User-Agent header not correct. got=%v want=%v", userAgentHeader, expectedHeader)
143+
}
144+
})
145+
146+
session := NewAuthSession(ApiSettings{
147+
BaseUrl: server.URL,
148+
ApiVersion: apiVersion,
149+
AgentTag: "some-agent-tag",
150+
})
151+
152+
var r string
153+
err := session.Do(&r, "GET", apiVersion, path, nil, nil, nil)
154+
155+
if err != nil {
156+
t.Errorf("Do() call failed: %v", err)
157+
}
158+
})
159+
160+
t.Run("Do() sets User-Agent header with Do's option's AgentTag, which will overwrite AuthSession config", func(t *testing.T) {
161+
mux := http.NewServeMux()
162+
setupApi40Login(mux, foreverValidTestToken, http.StatusOK)
163+
server := httptest.NewServer(mux)
164+
defer server.Close()
165+
166+
mux.HandleFunc("/api"+apiVersion+path, func(w http.ResponseWriter, r *http.Request) {
167+
userAgentHeader := r.Header.Get("User-Agent")
168+
expectedHeader := "new-agent-tag"
169+
if userAgentHeader != expectedHeader {
170+
t.Errorf("User-Agent header not correct. got=%v want=%v", userAgentHeader, expectedHeader)
171+
}
172+
})
173+
174+
session := NewAuthSession(ApiSettings{
175+
BaseUrl: server.URL,
176+
ApiVersion: apiVersion,
177+
AgentTag: "some-agent-tag",
178+
})
179+
180+
var r string
181+
options := ApiSettings{
182+
AgentTag: "new-agent-tag",
183+
}
184+
err := session.Do(&r, "GET", apiVersion, path, nil, nil, &options)
185+
186+
if err != nil {
187+
t.Errorf("Do() call failed: %v", err)
188+
}
189+
})
190+
}
191+
126192
func TestAuthSession_Do_Parse(t *testing.T) {
127193
type stringStruct struct {
128194
Field *string `json:"field"`
@@ -153,13 +219,13 @@ func TestAuthSession_Do_Parse(t *testing.T) {
153219
fmt.Fprint(w, string(s))
154220
})
155221

156-
s := NewAuthSession(ApiSettings{
222+
session := NewAuthSession(ApiSettings{
157223
BaseUrl: server.URL,
158224
ApiVersion: apiVersion,
159225
})
160226

161227
var result stringStruct
162-
s.Do(&result, "GET", apiVersion, path, nil, nil, nil)
228+
session.Do(&result, "GET", apiVersion, path, nil, nil, nil)
163229

164230
if *result.Field != stringField {
165231
t.Error("num type field was not unmarshaled correctly into string type field")
@@ -181,13 +247,13 @@ func TestAuthSession_Do_Parse(t *testing.T) {
181247
fmt.Fprint(w, string(s))
182248
})
183249

184-
s := NewAuthSession(ApiSettings{
250+
session := NewAuthSession(ApiSettings{
185251
BaseUrl: server.URL,
186252
ApiVersion: apiVersion,
187253
})
188254

189255
var result numStruct
190-
s.Do(&result, "GET", apiVersion, path, nil, nil, nil)
256+
session.Do(&result, "GET", apiVersion, path, nil, nil, nil)
191257

192258
if *result.Field != numField {
193259
t.Error("string type field was not unmarshaled correctly into num type field")
@@ -233,7 +299,7 @@ func TestAuthSession_Do_Parse(t *testing.T) {
233299
fmt.Fprint(w, string(s))
234300
})
235301

236-
s := NewAuthSession(ApiSettings{
302+
session := NewAuthSession(ApiSettings{
237303
BaseUrl: server.URL,
238304
ApiVersion: apiVersion,
239305
})
@@ -265,7 +331,7 @@ func TestAuthSession_Do_Parse(t *testing.T) {
265331

266332
var result expectedStructType
267333

268-
s.Do(&result, "GET", apiVersion, path, nil, nil, nil)
334+
session.Do(&result, "GET", apiVersion, path, nil, nil, nil)
269335

270336
if !reflect.DeepEqual(result, expectedStruct) {
271337
t.Error("fields of mixed types were not unmarshaled correctly into the right types")
@@ -283,14 +349,14 @@ func TestAuthSession_Do_Parse(t *testing.T) {
283349
fmt.Fprint(w, "a response")
284350
})
285351

286-
s := NewAuthSession(ApiSettings{
352+
session := NewAuthSession(ApiSettings{
287353
BaseUrl: server.URL,
288354
ApiVersion: apiVersion,
289355
})
290356

291357
var result string
292358

293-
err := s.Do(&result, "GET", apiVersion, path, nil, nil, nil)
359+
err := session.Do(&result, "GET", apiVersion, path, nil, nil, nil)
294360

295361
if err != nil {
296362
t.Errorf("Do() failed. error=%v", err)
@@ -318,15 +384,15 @@ func TestAuthSession_Do_Parse(t *testing.T) {
318384
fmt.Fprint(w, string(s))
319385
})
320386

321-
s := NewAuthSession(ApiSettings{
387+
session := NewAuthSession(ApiSettings{
322388
BaseUrl: server.URL,
323389
ApiVersion: apiVersion,
324390
})
325391

326392
var result interface{}
327393
var expectedField float64 = 10
328394

329-
err := s.Do(&result, "GET", apiVersion, path, nil, nil, nil)
395+
err := session.Do(&result, "GET", apiVersion, path, nil, nil, nil)
330396

331397
if err != nil {
332398
t.Errorf("Do() failed. error=%v", err)
@@ -356,7 +422,7 @@ func TestAuthSession_Do_Parse(t *testing.T) {
356422
fmt.Fprint(w, string(s))
357423
})
358424

359-
s := NewAuthSession(ApiSettings{
425+
session := NewAuthSession(ApiSettings{
360426
BaseUrl: server.URL,
361427
ApiVersion: apiVersion,
362428
})
@@ -376,7 +442,7 @@ func TestAuthSession_Do_Parse(t *testing.T) {
376442

377443
var result expectedStructType
378444

379-
err := s.Do(&result, "GET", apiVersion, path, nil, nil, nil)
445+
err := session.Do(&result, "GET", apiVersion, path, nil, nil, nil)
380446

381447
if err != nil {
382448
t.Errorf("Do() failed. error=%v", err)
@@ -406,7 +472,7 @@ func TestAuthSession_Do_Content_Type(t *testing.T) {
406472
}
407473
})
408474

409-
s := NewAuthSession(ApiSettings{
475+
session := NewAuthSession(ApiSettings{
410476
BaseUrl: server.URL,
411477
ApiVersion: apiVersion,
412478
})
@@ -418,7 +484,7 @@ func TestAuthSession_Do_Content_Type(t *testing.T) {
418484
key: "value",
419485
}
420486

421-
err := s.Do(&r, "GET", apiVersion, path, nil, body, nil)
487+
err := session.Do(&r, "GET", apiVersion, path, nil, body, nil)
422488

423489
if err != nil {
424490
t.Errorf("Do() call failed: %v", err)
@@ -439,20 +505,78 @@ func TestAuthSession_Do_Content_Type(t *testing.T) {
439505
}
440506
})
441507

442-
s := NewAuthSession(ApiSettings{
508+
session := NewAuthSession(ApiSettings{
443509
BaseUrl: server.URL,
444510
ApiVersion: apiVersion,
445511
})
446512

447513
var r string
448-
err := s.Do(&r, "GET", apiVersion, path, nil, "body", nil)
514+
err := session.Do(&r, "GET", apiVersion, path, nil, "body", nil)
449515

450516
if err != nil {
451517
t.Errorf("Do() call failed: %v", err)
452518
}
453519
})
454520
}
455521

522+
func TestAuthSession_Do_Timeout(t *testing.T) {
523+
const path = "/someMethod"
524+
const apiVersion = "/4.0"
525+
526+
t.Run("Do() follows Timeout set in AuthSession config", func(t *testing.T) {
527+
mux := http.NewServeMux()
528+
setupApi40Login(mux, foreverValidTestToken, http.StatusOK)
529+
server := httptest.NewServer(mux)
530+
defer server.Close()
531+
532+
mux.HandleFunc("/api"+apiVersion+path, func(w http.ResponseWriter, r *http.Request) {
533+
time.Sleep(4 * time.Second)
534+
})
535+
536+
session := NewAuthSession(ApiSettings{
537+
BaseUrl: server.URL,
538+
ApiVersion: apiVersion,
539+
Timeout: 1, // seconds
540+
})
541+
542+
err := session.Do(nil, "GET", apiVersion, path, nil, nil, nil)
543+
544+
if err == nil {
545+
t.Errorf("Do() call did not error/timeout")
546+
} else if !errors.Is(err, context.DeadlineExceeded) {
547+
t.Errorf("Do() call did not error with context.DeadlineExceeded, got=%v", err)
548+
}
549+
})
550+
551+
t.Run("Do() follows Timeout set in Do()'s options", func(t *testing.T) {
552+
mux := http.NewServeMux()
553+
setupApi40Login(mux, foreverValidTestToken, http.StatusOK)
554+
server := httptest.NewServer(mux)
555+
defer server.Close()
556+
557+
mux.HandleFunc("/api"+apiVersion+path, func(w http.ResponseWriter, r *http.Request) {
558+
time.Sleep(4 * time.Second)
559+
})
560+
561+
session := NewAuthSession(ApiSettings{
562+
BaseUrl: server.URL,
563+
ApiVersion: apiVersion,
564+
})
565+
566+
options := ApiSettings{
567+
Timeout: 1, //seconds
568+
}
569+
570+
err := session.Do(nil, "GET", apiVersion, path, nil, nil, &options)
571+
572+
if err == nil {
573+
t.Errorf("Do() call did not error/timeout")
574+
} else if !errors.Is(err, context.DeadlineExceeded) {
575+
t.Errorf("Do() call did not error with context.DeadlineExceeded, got=%v", err)
576+
}
577+
})
578+
}
579+
456580
func TestSetQuery(t *testing.T) {
457581
somestring := "somestring"
458582
testcases := []struct {

0 commit comments

Comments
 (0)