Skip to content

Commit fdcbe42

Browse files
committed
internal/worker: make tests hermetic
Refactor tests that contact proxy.golang.org to use a local HTTP server instead. Fixes failures on builders with no outbound network. For golang/go#51444. Change-Id: I7d4e5a0b2dc4b1c0cddd12435e3656307bed4c70 Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/419174 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Damien Neil <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]>
1 parent bb31b82 commit fdcbe42

File tree

4 files changed

+67
-18
lines changed

4 files changed

+67
-18
lines changed

internal/worker/module_proxy.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ const proxyURL = "https://proxy.golang.org"
2727

2828
// latestVersion returns the version of modulePath provided by the proxy's "@latest"
2929
// endpoint.
30-
func latestVersion(ctx context.Context, modulePath string) (string, error) {
31-
body, err := proxyRequest(ctx, modulePath, "/@latest")
30+
func latestVersion(ctx context.Context, proxyURL, modulePath string) (string, error) {
31+
body, err := proxyRequest(ctx, proxyURL, modulePath, "/@latest")
3232
if err != nil {
3333
return "", err
3434
}
@@ -46,8 +46,8 @@ func latestVersion(ctx context.Context, modulePath string) (string, error) {
4646
// latestTaggedVersion returns the latest (largest in the semver sense) tagged
4747
// version of modulePath, as determined by the module proxy's "list" endpoint.
4848
// It returns ("", nil) if there are no tagged versions.
49-
func latestTaggedVersion(ctx context.Context, modulePath string) (string, error) {
50-
body, err := proxyRequest(ctx, modulePath, "/@v/list")
49+
func latestTaggedVersion(ctx context.Context, proxyURL, modulePath string) (string, error) {
50+
body, err := proxyRequest(ctx, proxyURL, modulePath, "/@v/list")
5151
if err != nil {
5252
return "", err
5353
}
@@ -59,19 +59,19 @@ func latestTaggedVersion(ctx context.Context, modulePath string) (string, error)
5959
return vs[0], nil
6060
}
6161

62-
func moduleZip(ctx context.Context, modulePath, version string) (*zip.Reader, error) {
62+
func moduleZip(ctx context.Context, proxyURL, modulePath, version string) (*zip.Reader, error) {
6363
ev, err := module.EscapeVersion(version)
6464
if err != nil {
6565
return nil, err
6666
}
67-
body, err := proxyRequest(ctx, modulePath, fmt.Sprintf("/@v/%s.zip", ev))
67+
body, err := proxyRequest(ctx, proxyURL, modulePath, fmt.Sprintf("/@v/%s.zip", ev))
6868
if err != nil {
6969
return nil, err
7070
}
7171
return zip.NewReader(bytes.NewReader(body), int64(len(body)))
7272
}
7373

74-
func proxyRequest(ctx context.Context, modulePath, suffix string) ([]byte, error) {
74+
func proxyRequest(ctx context.Context, proxyURL, modulePath, suffix string) ([]byte, error) {
7575
ep, err := module.EscapePath(modulePath)
7676
if err != nil {
7777
return nil, fmt.Errorf("module path %v: %w", modulePath, err)

internal/worker/module_proxy_test.go

+51-5
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@
55
package worker
66

77
import (
8+
"archive/zip"
89
"context"
10+
"net/http"
11+
"net/http/httptest"
912
"testing"
1013

1114
"golang.org/x/mod/semver"
1215
)
1316

1417
func TestLatestVersion(t *testing.T) {
15-
got, err := latestVersion(context.Background(), "golang.org/x/build")
18+
pt := newProxyTest()
19+
defer pt.Close()
20+
21+
got, err := latestVersion(context.Background(), pt.URL, "golang.org/x/build")
1622
if err != nil {
1723
t.Fatal(err)
1824
}
@@ -22,15 +28,18 @@ func TestLatestVersion(t *testing.T) {
2228
}
2329

2430
func TestLatestTaggedVersion(t *testing.T) {
25-
got, err := latestTaggedVersion(context.Background(), "golang.org/x/build")
31+
pt := newProxyTest()
32+
defer pt.Close()
33+
34+
got, err := latestTaggedVersion(context.Background(), pt.URL, "golang.org/x/build")
2635
if err != nil {
2736
t.Fatal(err)
2837
}
2938
if got != "" {
3039
t.Errorf(`got %q, wanted ""`, got)
3140
}
3241

33-
got, err = latestTaggedVersion(context.Background(), "golang.org/x/tools")
42+
got, err = latestTaggedVersion(context.Background(), pt.URL, "golang.org/x/tools")
3443
if err != nil {
3544
t.Fatal(err)
3645
}
@@ -41,14 +50,51 @@ func TestLatestTaggedVersion(t *testing.T) {
4150
}
4251

4352
func TestModuleZip(t *testing.T) {
53+
pt := newProxyTest()
54+
defer pt.Close()
55+
4456
ctx := context.Background()
4557
const m = "golang.org/x/time"
46-
v, err := latestVersion(ctx, m)
58+
v, err := latestVersion(ctx, pt.URL, m)
4759
if err != nil {
4860
t.Fatal(err)
4961
}
50-
_, err = moduleZip(ctx, m, v)
62+
_, err = moduleZip(ctx, pt.URL, m, v)
5163
if err != nil {
5264
t.Fatal(err)
5365
}
5466
}
67+
68+
type proxyTest struct {
69+
*httptest.Server
70+
}
71+
72+
func (*proxyTest) ServeHTTP(w http.ResponseWriter, r *http.Request) {
73+
switch r.URL.Path {
74+
case "/golang.org/x/build/@latest":
75+
w.Write([]byte(`{"Version":"v0.0.0-20220722180300-9ed544e84dd1","Time":"2022-07-22T18:03:00Z"}`))
76+
case "/golang.org/x/build/@v/list":
77+
case "/golang.org/x/tools/@v/list":
78+
w.Write([]byte("v0.1.1\nv0.1.2\n"))
79+
case "/golang.org/x/time/@latest":
80+
w.Write([]byte(`{"Version":"v0.0.0-20220722155302-e5dcc9cfc0b9","Time":"2022-07-22T15:53:02Z"}`))
81+
case "/golang.org/x/time/@v/v0.0.0-20220722155302-e5dcc9cfc0b9.zip":
82+
zw := zip.NewWriter(w)
83+
fw, _ := zw.Create("golang.org/x/[email protected]/go.mod")
84+
fw.Write([]byte(`module golang.org/x/time`))
85+
zw.Close()
86+
case "/golang.org/x/mod/@v/v0.5.1.zip":
87+
zw := zip.NewWriter(w)
88+
fw, _ := zw.Create("golang.org/x/[email protected]/go.mod")
89+
fw.Write([]byte(`module golang.org/x/mod`))
90+
zw.Close()
91+
default:
92+
w.WriteHeader(404)
93+
}
94+
}
95+
96+
func newProxyTest() *proxyTest {
97+
pt := &proxyTest{}
98+
pt.Server = httptest.NewServer(pt)
99+
return pt
100+
}

internal/worker/scan_modules.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func ScanModules(ctx context.Context, st store.Store, force bool) error {
5858
}
5959
for _, modulePath := range modulesToScan {
6060
// Scan the latest version, and the latest tagged version (if they differ).
61-
latest, err := latestVersion(ctx, modulePath)
61+
latest, err := latestVersion(ctx, proxyURL, modulePath)
6262
if err != nil {
6363
return err
6464
}
@@ -68,7 +68,7 @@ func ScanModules(ctx context.Context, st store.Store, force bool) error {
6868
}
6969
// Otherwise, if the error was in the scanning itself, keep going.
7070
}
71-
latestTagged, err := latestTaggedVersion(ctx, modulePath)
71+
latestTagged, err := latestTaggedVersion(ctx, proxyURL, modulePath)
7272
if err != nil {
7373
return err
7474
}
@@ -99,7 +99,7 @@ func processModule(ctx context.Context, modulePath, version string, dbClient vul
9999
return nil
100100
}
101101
}
102-
res, err := scanModule(ctx, modulePath, version, dbClient)
102+
res, err := scanModule(ctx, proxyURL, modulePath, version, dbClient)
103103
if err2 := createModuleScanRecord(ctx, st, modulePath, version, dbTime, res, err); err2 != nil {
104104
return err2
105105
}
@@ -142,7 +142,7 @@ func createModuleScanRecord(ctx context.Context, st store.Store, path, version s
142142
// scanRepo clones the given repo and analyzes it for vulnerabilities. If commit
143143
// is "HEAD", the head commit is scanned. Otherwise, commit must be a hex string
144144
// corresponding to a commit, and that commit is checked out and scanned.
145-
func scanModule(ctx context.Context, modulePath, version string, dbClient vulnc.Client) (_ *vulncheck.Result, err error) {
145+
func scanModule(ctx context.Context, proxyURL, modulePath, version string, dbClient vulnc.Client) (_ *vulncheck.Result, err error) {
146146
defer derrors.Wrap(&err, "scanModule(%q, %q)", modulePath, version)
147147

148148
start := time.Now()
@@ -160,7 +160,7 @@ func scanModule(ctx context.Context, modulePath, version string, dbClient vulnc.
160160
}
161161
}()
162162

163-
zipr, err := moduleZip(ctx, modulePath, version)
163+
zipr, err := moduleZip(ctx, proxyURL, modulePath, version)
164164
if err != nil {
165165
return nil, err
166166
}

internal/worker/scan_modules_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,16 @@ func TestAsScanError(t *testing.T) {
4444
}
4545

4646
func TestScanModule(t *testing.T) {
47+
pt := newProxyTest()
48+
defer pt.Close()
49+
4750
ctx := event.WithExporter(context.Background(),
4851
event.NewExporter(log.NewLineHandler(os.Stderr), nil))
4952
dbClient, err := vulnc.NewClient([]string{vulnDBURL}, vulnc.Options{})
5053
if err != nil {
5154
t.Fatal(err)
5255
}
53-
got, err := scanModule(ctx, "golang.org/x/mod", "v0.5.1", dbClient)
56+
got, err := scanModule(ctx, pt.URL, "golang.org/x/mod", "v0.5.1", dbClient)
5457
if err != nil {
5558
t.Fatal(err)
5659
}

0 commit comments

Comments
 (0)