Skip to content

Commit 0a993a8

Browse files
author
Paulo Gomes
authored
Merge pull request #615 from fluxcd/go-test-race
build: enable `-race` for `go test`
2 parents 19292d4 + 230774c commit 0a993a8

File tree

5 files changed

+75
-42
lines changed

5 files changed

+75
-42
lines changed

.github/workflows/e2e.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ jobs:
7373
env:
7474
TEST_AZURE_ACCOUNT_NAME: ${{ secrets.TEST_AZURE_ACCOUNT_NAME }}
7575
TEST_AZURE_ACCOUNT_KEY: ${{ secrets.TEST_AZURE_ACCOUNT_KEY }}
76+
77+
# Temporarily disabling -race for arm64 as our GitHub action
78+
# runners don't seem to like it. The race detection was tested
79+
# on both Apple M1 and Linux arm64 with successful results.
80+
#
81+
# We should reenable go test -race for arm64 runners once the
82+
# current issue is resolved.
83+
GO_TEST_ARGS: ''
7684
run: make test
7785
- name: Prepare
7886
id: prep

Makefile

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ LIBGIT2_IMG ?= ghcr.io/fluxcd/golang-with-libgit2
77
LIBGIT2_TAG ?= libgit2-1.3.1
88

99
# Allows for defining additional Go test args, e.g. '-tags integration'.
10-
GO_TEST_ARGS ?=
10+
GO_TEST_ARGS ?= -race
1111

1212
# Allows for defining additional Docker buildx arguments,
1313
# e.g. '--push'.
1414
BUILD_ARGS ?=
1515
# Architectures to build images for
1616
BUILD_PLATFORMS ?= linux/amd64,linux/arm64,linux/arm/v7
1717

18-
# Go additional tag arguments, e.g. 'integration'
18+
# Go additional tag arguments, e.g. 'integration',
19+
# this is append to the tag arguments required for static builds
1920
GO_TAGS ?=
2021

2122
# Produce CRDs that work back to Kubernetes 1.16
@@ -112,7 +113,7 @@ ifeq ($(shell uname -s),Darwin)
112113
endif
113114

114115
test-api: ## Run api tests
115-
cd api; go test ./... -coverprofile cover.out
116+
cd api; go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
116117

117118
run: $(LIBGIT2) generate fmt vet manifests ## Run against the configured Kubernetes cluster in ~/.kube/config
118119
go run $(GO_STATIC_FLAGS) ./main.go

controllers/gitrepository_controller_test.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -431,19 +431,19 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
431431
}
432432

433433
for _, tt := range tests {
434-
obj := &sourcev1.GitRepository{
435-
ObjectMeta: metav1.ObjectMeta{
436-
GenerateName: "auth-strategy-",
437-
},
438-
Spec: sourcev1.GitRepositorySpec{
439-
Interval: metav1.Duration{Duration: interval},
440-
Timeout: &metav1.Duration{Duration: timeout},
441-
},
442-
}
443-
444434
t.Run(tt.name, func(t *testing.T) {
445435
g := NewWithT(t)
446436

437+
obj := &sourcev1.GitRepository{
438+
ObjectMeta: metav1.ObjectMeta{
439+
GenerateName: "auth-strategy-",
440+
},
441+
Spec: sourcev1.GitRepositorySpec{
442+
Interval: metav1.Duration{Duration: interval},
443+
Timeout: &metav1.Duration{Duration: timeout},
444+
},
445+
}
446+
447447
server, err := gittestserver.NewTempGitServer()
448448
g.Expect(err).NotTo(HaveOccurred())
449449
defer os.RemoveAll(server.Root())

internal/transport/transport_test.go

+5-10
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,18 @@ func Test_TransportReuse(t *testing.T) {
3434
t.Errorf("error releasing transport t2: %v", err)
3535
}
3636

37-
t3 := NewOrIdle(nil)
38-
if t2 != t3 {
39-
t.Errorf("transported not reused")
40-
}
41-
42-
t4 := NewOrIdle(&tls.Config{
37+
t3 := NewOrIdle(&tls.Config{
4338
ServerName: "testing",
4439
})
45-
if t4.TLSClientConfig == nil || t4.TLSClientConfig.ServerName != "testing" {
40+
if t3.TLSClientConfig == nil || t3.TLSClientConfig.ServerName != "testing" {
4641
t.Errorf("TLSClientConfig not properly configured")
4742
}
4843

49-
err = Release(t4)
44+
err = Release(t3)
5045
if err != nil {
51-
t.Errorf("error releasing transport t4: %v", err)
46+
t.Errorf("error releasing transport t3: %v", err)
5247
}
53-
if t4.TLSClientConfig != nil {
48+
if t3.TLSClientConfig != nil {
5449
t.Errorf("TLSClientConfig not cleared after release")
5550
}
5651

pkg/git/strategy/proxy/strategy_proxy_test.go

+48-19
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"net/url"
2525
"os"
2626
"strings"
27+
"sync/atomic"
2728
"testing"
2829
"time"
2930

@@ -58,7 +59,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
5859
gitImpl git.Implementation
5960
url string
6061
branch string
61-
setupGitProxy func(g *WithT, proxy *goproxy.ProxyHttpServer, proxyGotRequest *bool) (*git.AuthOptions, cleanupFunc)
62+
setupGitProxy func(g *WithT, proxy *goproxy.ProxyHttpServer, proxiedRequests *int32) (*git.AuthOptions, cleanupFunc)
6263
shortTimeout bool
6364
wantUsedProxy bool
6465
wantError bool
@@ -78,7 +79,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
7879
gitImpl: gogit.Implementation,
7980
url: "http://example.com/bar/test-reponame",
8081
branch: "main",
81-
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxyGotRequest *bool) (*git.AuthOptions, cleanupFunc) {
82+
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxiedRequests *int32) (*git.AuthOptions, cleanupFunc) {
8283
// Create the git server.
8384
gitServer, err := gittestserver.NewTempGitServer()
8485
g.Expect(err).ToNot(HaveOccurred())
@@ -101,7 +102,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
101102
var proxyHandler goproxy.FuncReqHandler = func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
102103
userAgent := req.Header.Get("User-Agent")
103104
if strings.Contains(req.Host, "example.com") && strings.Contains(userAgent, "git") {
104-
*proxyGotRequest = true
105+
atomic.AddInt32(proxiedRequests, 1)
105106
req.Host = u.Host
106107
req.URL.Host = req.Host
107108
return req, nil
@@ -129,13 +130,13 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
129130
gitImpl: gogit.Implementation,
130131
url: "https://github.com/git-fixtures/basic",
131132
branch: "master",
132-
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxyGotRequest *bool) (*git.AuthOptions, cleanupFunc) {
133+
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxiedRequests *int32) (*git.AuthOptions, cleanupFunc) {
133134
var proxyHandler goproxy.FuncHttpsHandler = func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
134135
// We don't check for user agent as this handler is only going to process CONNECT requests, and because Go's net/http
135136
// is the one making such a request on behalf of go-git, adding a check for the go net/http user agent (Go-http-client)
136137
// would only allow false positives from any request originating from Go's net/http.
137138
if strings.Contains(host, "github.com") {
138-
*proxyGotRequest = true
139+
atomic.AddInt32(proxiedRequests, 1)
139140
return goproxy.OkConnect, host
140141
}
141142
// Reject if it isnt our request.
@@ -156,10 +157,10 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
156157
gitImpl: gogit.Implementation,
157158
url: "https://192.0.2.1/bar/test-reponame",
158159
branch: "main",
159-
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxyGotRequest *bool) (*git.AuthOptions, cleanupFunc) {
160+
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxiedRequests *int32) (*git.AuthOptions, cleanupFunc) {
160161
var proxyHandler goproxy.FuncHttpsHandler = func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
161162
// We shouldn't hit the proxy so we just want to check for any interaction, then reject.
162-
*proxyGotRequest = true
163+
atomic.AddInt32(proxiedRequests, 1)
163164
return goproxy.RejectConnect, host
164165
}
165166
proxy.OnRequest().HandleConnect(proxyHandler)
@@ -175,7 +176,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
175176
gitImpl: libgit2.Implementation,
176177
url: "https://example.com/bar/test-reponame",
177178
branch: "main",
178-
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxyGotRequest *bool) (*git.AuthOptions, cleanupFunc) {
179+
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxiedRequests *int32) (*git.AuthOptions, cleanupFunc) {
179180
// Create the git server.
180181
gitServer, err := gittestserver.NewTempGitServer()
181182
g.Expect(err).ToNot(HaveOccurred())
@@ -210,7 +211,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
210211
// Check if the host matches with the git server address and the user-agent is the expected git client.
211212
userAgent := ctx.Req.Header.Get("User-Agent")
212213
if strings.Contains(host, "example.com") && strings.Contains(userAgent, "libgit2") {
213-
*proxyGotRequest = true
214+
atomic.AddInt32(proxiedRequests, 1)
214215
return goproxy.OkConnect, u.Host
215216
}
216217
// Reject if it isn't our request.
@@ -238,7 +239,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
238239
gitImpl: libgit2.Implementation,
239240
url: "http://example.com/bar/test-reponame",
240241
branch: "main",
241-
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxyGotRequest *bool) (*git.AuthOptions, cleanupFunc) {
242+
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxiedRequests *int32) (*git.AuthOptions, cleanupFunc) {
242243
// Create the git server.
243244
gitServer, err := gittestserver.NewTempGitServer()
244245
g.Expect(err).ToNot(HaveOccurred())
@@ -258,8 +259,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
258259
// The certificate used here is valid for both example.com and localhost.
259260
var proxyHandler goproxy.FuncReqHandler = func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
260261
userAgent := req.Header.Get("User-Agent")
261-
if strings.Contains(req.Host, "example.com") && strings.Contains(userAgent, "libgit2") {
262-
*proxyGotRequest = true
262+
if strings.Contains(req.Host, "example.com") && strings.Contains(userAgent, "git") {
263+
atomic.AddInt32(proxiedRequests, 1)
263264
req.Host = u.Host
264265
req.URL.Host = req.Host
265266
return req, nil
@@ -282,14 +283,41 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
282283
wantError: false,
283284
},
284285
{
285-
name: "libgit2_NO_PROXY",
286-
gitImpl: libgit2.Implementation,
286+
name: "gogit_HTTPS_PROXY",
287+
gitImpl: gogit.Implementation,
288+
url: "https://github.com/git-fixtures/basic",
289+
branch: "master",
290+
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxiedRequests *int32) (*git.AuthOptions, cleanupFunc) {
291+
var proxyHandler goproxy.FuncHttpsHandler = func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
292+
// We don't check for user agent as this handler is only going to process CONNECT requests, and because Go's net/http
293+
// is the one making such a request on behalf of go-git, adding a check for the go net/http user agent (Go-http-client)
294+
// would only allow false positives from any request originating from Go's net/http.
295+
if strings.Contains(host, "github.com") {
296+
atomic.AddInt32(proxiedRequests, 1)
297+
return goproxy.OkConnect, host
298+
}
299+
// Reject if it isnt our request.
300+
return goproxy.RejectConnect, host
301+
}
302+
proxy.OnRequest().HandleConnect(proxyHandler)
303+
304+
// go-git does not allow to use an HTTPS proxy and a custom root CA at the same time.
305+
// See https://github.com/fluxcd/source-controller/pull/524#issuecomment-1006673163.
306+
return nil, func() {}
307+
},
308+
shortTimeout: false,
309+
wantUsedProxy: true,
310+
wantError: false,
311+
},
312+
{
313+
name: "gogit_NO_PROXY",
314+
gitImpl: gogit.Implementation,
287315
url: "https://192.0.2.1/bar/test-reponame",
288316
branch: "main",
289-
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxyGotRequest *bool) (*git.AuthOptions, cleanupFunc) {
317+
setupGitProxy: func(g *WithT, proxy *goproxy.ProxyHttpServer, proxiedRequests *int32) (*git.AuthOptions, cleanupFunc) {
290318
var proxyHandler goproxy.FuncHttpsHandler = func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
291319
// We shouldn't hit the proxy so we just want to check for any interaction, then reject.
292-
*proxyGotRequest = true
320+
atomic.AddInt32(proxiedRequests, 1)
293321
return goproxy.RejectConnect, host
294322
}
295323
proxy.OnRequest().HandleConnect(proxyHandler)
@@ -310,8 +338,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
310338
proxy := goproxy.NewProxyHttpServer()
311339
proxy.Verbose = true
312340

313-
proxyGotRequest := false
314-
authOpts, cleanup := tt.setupGitProxy(g, proxy, &proxyGotRequest)
341+
proxiedRequests := int32(0)
342+
authOpts, cleanup := tt.setupGitProxy(g, proxy, &proxiedRequests)
315343
defer cleanup()
316344

317345
proxyServer := http.Server{
@@ -356,7 +384,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
356384
g.Expect(err).ToNot(HaveOccurred())
357385
}
358386

359-
g.Expect(proxyGotRequest).To(Equal(tt.wantUsedProxy))
387+
g.Expect(atomic.LoadInt32(&proxiedRequests) > 0).To(Equal(tt.wantUsedProxy))
388+
360389
})
361390
}
362391
}

0 commit comments

Comments
 (0)