bug: fix potential race condition in unit test

Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
This commit is contained in:
Bobby DeSimone 2019-09-29 14:15:13 -07:00
parent 1fa45c6ec2
commit 8bd79903db
No known key found for this signature in database
GPG key ID: AEE4CF12FE86D07E
2 changed files with 24 additions and 6 deletions

View file

@ -6,6 +6,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
"sync"
"time" "time"
"github.com/pomerium/pomerium/internal/cryptutil" "github.com/pomerium/pomerium/internal/cryptutil"
@ -65,18 +66,35 @@ func DeepCopy(u *url.URL) (*url.URL, error) {
return ParseAndValidateURL(u.String()) return ParseAndValidateURL(u.String())
} }
// testTimeNow can be used in tests to set a specific int64 time var mockNow testTime
var testTimeNow int64
// testTime is safe to use concurrently.
type testTime struct {
sync.Mutex
mockNow int64
}
func (tt *testTime) setNow(n int64) {
tt.Lock()
tt.mockNow = n
tt.Unlock()
}
func (tt *testTime) now() int64 {
tt.Lock()
defer tt.Unlock()
return tt.mockNow
}
// timestamp returns the current timestamp, in seconds. // timestamp returns the current timestamp, in seconds.
// //
// For testing purposes, the function that generates the timestamp can be // For testing purposes, the function that generates the timestamp can be
// overridden. If not set, it will return time.Now().UTC().Unix(). // overridden. If not set, it will return time.Now().UTC().Unix().
func timestamp() int64 { func timestamp() int64 {
if testTimeNow == 0 { if mockNow.now() == 0 {
return time.Now().UTC().Unix() return time.Now().UTC().Unix()
} }
return testTimeNow return mockNow.now()
} }
// SignedRedirectURL takes a destination URL and adds redirect_uri to it's // SignedRedirectURL takes a destination URL and adds redirect_uri to it's

View file

@ -122,7 +122,7 @@ func TestSignedRedirectURL(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
testTimeNow = tt.mockedTime mockNow.setNow(tt.mockedTime)
got := SignedRedirectURL(tt.key, tt.destination, tt.urlToSign) got := SignedRedirectURL(tt.key, tt.destination, tt.urlToSign)
if diff := cmp.Diff(got, tt.want); diff != "" { if diff := cmp.Diff(got, tt.want); diff != "" {
t.Errorf("SignedRedirectURL() = diff %v", diff) t.Errorf("SignedRedirectURL() = diff %v", diff)
@ -142,7 +142,7 @@ func Test_timestamp(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
testTimeNow = tt.dontWant mockNow.setNow(tt.dontWant)
if got := timestamp(); got == tt.dontWant { if got := timestamp(); got == tt.dontWant {
t.Errorf("timestamp() = %v, dontWant %v", got, tt.dontWant) t.Errorf("timestamp() = %v, dontWant %v", got, tt.dontWant)
} }