8
8
"bytes"
9
9
"context"
10
10
"errors"
11
+ "flag"
11
12
"fmt"
12
13
"log"
13
14
"os"
@@ -30,6 +31,7 @@ var repos = map[string]*repo{
30
31
name : "istio" ,
31
32
url : "https://github.com/istio/istio" ,
32
33
commit : "1.17.0" ,
34
+ inDir :
flag .
String (
"istio_dir" ,
"" ,
"if set, reuse this directory as [email protected] " ),
33
35
},
34
36
35
37
// Kubernetes is a large repo with many dependencies, and in the past has
@@ -38,13 +40,15 @@ var repos = map[string]*repo{
38
40
name : "kubernetes" ,
39
41
url : "https://github.com/kubernetes/kubernetes" ,
40
42
commit : "v1.24.0" ,
43
+ inDir :
flag .
String (
"kubernetes_dir" ,
"" ,
"if set, reuse this directory as [email protected] " ),
41
44
},
42
45
43
46
// A large, industrial application.
44
47
"kuma" : {
45
48
name : "kuma" ,
46
49
url : "https://github.com/kumahq/kuma" ,
47
50
commit : "2.1.1" ,
51
+ inDir :
flag .
String (
"kuma_dir" ,
"" ,
"if set, reuse this directory as [email protected] " ),
48
52
},
49
53
50
54
// x/pkgsite is familiar and represents a common use case (a webserver). It
@@ -54,6 +58,7 @@ var repos = map[string]*repo{
54
58
url : "https://go.googlesource.com/pkgsite" ,
55
59
commit : "81f6f8d4175ad0bf6feaa03543cc433f8b04b19b" ,
56
60
short : true ,
61
+ inDir : flag .String ("pkgsite_dir" , "" , "if set, reuse this directory as pkgsite@81f6f8d4" ),
57
62
},
58
63
59
64
// A tiny self-contained project.
@@ -62,6 +67,7 @@ var repos = map[string]*repo{
62
67
url : "https://github.com/google/starlark-go" ,
63
68
commit : "3f75dec8e4039385901a30981e3703470d77e027" ,
64
69
short : true ,
70
+ inDir : flag .String ("starlark_dir" , "" , "if set, reuse this directory as starlark@3f75dec8" ),
65
71
},
66
72
67
73
// The current repository, which is medium-small and has very few dependencies.
@@ -70,6 +76,7 @@ var repos = map[string]*repo{
70
76
url : "https://go.googlesource.com/tools" ,
71
77
commit : "gopls/v0.9.0" ,
72
78
short : true ,
79
+ inDir :
flag .
String (
"tools_dir" ,
"" ,
"if set, reuse this directory as x/[email protected] " ),
73
80
},
74
81
}
75
82
@@ -94,10 +101,11 @@ func getRepo(tb testing.TB, name string) *repo {
94
101
// codebase.
95
102
type repo struct {
96
103
// static configuration
97
- name string // must be unique, used for subdirectory
98
- url string // repo url
99
- commit string // full commit hash or tag
100
- short bool // whether this repo runs with -short
104
+ name string // must be unique, used for subdirectory
105
+ url string // repo url
106
+ commit string // full commit hash or tag
107
+ short bool // whether this repo runs with -short
108
+ inDir * string // if set, use this dir as url@commit, and don't delete
101
109
102
110
dirOnce sync.Once
103
111
dir string // directory contaning source code checked out to url@commit
@@ -109,14 +117,37 @@ type repo struct {
109
117
awaiter * Awaiter
110
118
}
111
119
120
+ // reusableDir return a reusable directory for benchmarking, or "".
121
+ //
122
+ // If the user specifies a directory, the test will create and populate it
123
+ // on the first run an re-use it on subsequent runs. Otherwise it will
124
+ // create, populate, and delete a temporary directory.
125
+ func (r * repo ) reusableDir () string {
126
+ if r .inDir == nil {
127
+ return ""
128
+ }
129
+ return * r .inDir
130
+ }
131
+
112
132
// getDir returns directory containing repo source code, creating it if
113
133
// necessary. It is safe for concurrent use.
114
134
func (r * repo ) getDir () string {
115
135
r .dirOnce .Do (func () {
116
- r .dir = filepath .Join (getTempDir (), r .name )
117
- log .Printf ("cloning %s@%s into %s" , r .url , r .commit , r .dir )
118
- if err := shallowClone (r .dir , r .url , r .commit ); err != nil {
136
+ if r .dir = r .reusableDir (); r .dir == "" {
137
+ r .dir = filepath .Join (getTempDir (), r .name )
138
+ }
139
+
140
+ _ , err := os .Stat (r .dir )
141
+ switch {
142
+ case os .IsNotExist (err ):
143
+ log .Printf ("cloning %s@%s into %s" , r .url , r .commit , r .dir )
144
+ if err := shallowClone (r .dir , r .url , r .commit ); err != nil {
145
+ log .Fatal (err )
146
+ }
147
+ case err != nil :
119
148
log .Fatal (err )
149
+ default :
150
+ log .Printf ("reusing %s as %s@%s" , r .dir , r .url , r .commit )
120
151
}
121
152
})
122
153
return r .dir
@@ -200,7 +231,7 @@ func (r *repo) Close() error {
200
231
fmt .Fprintf (& errBuf , "closing sandbox: %v" , err )
201
232
}
202
233
}
203
- if r .dir != "" {
234
+ if r .dir != "" && r . reusableDir () == "" {
204
235
if err := os .RemoveAll (r .dir ); err != nil {
205
236
fmt .Fprintf (& errBuf , "cleaning dir: %v" , err )
206
237
}
0 commit comments