Source file src/pkg/cmd/go/internal/test/testflag.go
1
2
3
4
5 package test
6
7 import (
8 "flag"
9 "os"
10 "strings"
11
12 "cmd/go/internal/base"
13 "cmd/go/internal/cfg"
14 "cmd/go/internal/cmdflag"
15 "cmd/go/internal/str"
16 "cmd/go/internal/work"
17 )
18
19 const cmd = "test"
20
21
22
23
24
25
26
27 var testFlagDefn = []*cmdflag.Defn{
28
29 {Name: "c", BoolVar: &testC},
30 {Name: "i", BoolVar: &cfg.BuildI},
31 {Name: "o"},
32 {Name: "cover", BoolVar: &testCover},
33 {Name: "covermode"},
34 {Name: "coverpkg"},
35 {Name: "exec"},
36 {Name: "json", BoolVar: &testJSON},
37 {Name: "vet"},
38
39
40 {Name: "bench", PassToTest: true},
41 {Name: "benchmem", BoolVar: new(bool), PassToTest: true},
42 {Name: "benchtime", PassToTest: true},
43 {Name: "blockprofile", PassToTest: true},
44 {Name: "blockprofilerate", PassToTest: true},
45 {Name: "count", PassToTest: true},
46 {Name: "coverprofile", PassToTest: true},
47 {Name: "cpu", PassToTest: true},
48 {Name: "cpuprofile", PassToTest: true},
49 {Name: "failfast", BoolVar: new(bool), PassToTest: true},
50 {Name: "list", PassToTest: true},
51 {Name: "memprofile", PassToTest: true},
52 {Name: "memprofilerate", PassToTest: true},
53 {Name: "mutexprofile", PassToTest: true},
54 {Name: "mutexprofilefraction", PassToTest: true},
55 {Name: "outputdir", PassToTest: true},
56 {Name: "parallel", PassToTest: true},
57 {Name: "run", PassToTest: true},
58 {Name: "short", BoolVar: new(bool), PassToTest: true},
59 {Name: "timeout", PassToTest: true},
60 {Name: "trace", PassToTest: true},
61 {Name: "v", BoolVar: &testV, PassToTest: true},
62 }
63
64
65 func init() {
66 cmdflag.AddKnownFlags("test", testFlagDefn)
67 var cmd base.Command
68 work.AddBuildFlags(&cmd)
69 cmd.Flag.VisitAll(func(f *flag.Flag) {
70 if f.Name == "v" {
71
72 return
73 }
74 testFlagDefn = append(testFlagDefn, &cmdflag.Defn{
75 Name: f.Name,
76 Value: f.Value,
77 })
78 })
79 }
80
81
82
83
84
85
86
87
88
89
90 func testFlags(usage func(), args []string) (packageNames, passToTest []string) {
91 args = str.StringList(cmdflag.FindGOFLAGS(testFlagDefn), args)
92 inPkg := false
93 var explicitArgs []string
94 for i := 0; i < len(args); i++ {
95 if !strings.HasPrefix(args[i], "-") {
96 if !inPkg && packageNames == nil {
97
98 inPkg = true
99 }
100 if inPkg {
101 packageNames = append(packageNames, args[i])
102 continue
103 }
104 }
105
106 if inPkg {
107
108 inPkg = false
109 }
110
111 f, value, extraWord := cmdflag.Parse(cmd, usage, testFlagDefn, args, i)
112 if f == nil {
113
114
115
116 inPkg = false
117 if packageNames == nil {
118
119 packageNames = []string{}
120 }
121 if args[i] == "-args" || args[i] == "--args" {
122
123
124 explicitArgs = args[i+1:]
125 break
126 }
127 passToTest = append(passToTest, args[i])
128 continue
129 }
130 if f.Value != nil {
131 if err := f.Value.Set(value); err != nil {
132 base.Fatalf("invalid flag argument for -%s: %v", f.Name, err)
133 }
134 } else {
135
136
137 switch f.Name {
138
139 case "c", "i", "v", "cover", "json":
140 cmdflag.SetBool(cmd, f.BoolVar, value)
141 if f.Name == "json" && testJSON {
142 passToTest = append(passToTest, "-test.v=true")
143 }
144 case "o":
145 testO = value
146 testNeedBinary = true
147 case "exec":
148 xcmd, err := str.SplitQuotedFields(value)
149 if err != nil {
150 base.Fatalf("invalid flag argument for -%s: %v", f.Name, err)
151 }
152 work.ExecCmd = xcmd
153 case "bench":
154
155 testBench = true
156 case "list":
157 testList = true
158 case "timeout":
159 testTimeout = value
160 case "blockprofile", "cpuprofile", "memprofile", "mutexprofile":
161 testProfile = "-" + f.Name
162 testNeedBinary = true
163 case "trace":
164 testProfile = "-trace"
165 case "coverpkg":
166 testCover = true
167 if value == "" {
168 testCoverPaths = nil
169 } else {
170 testCoverPaths = strings.Split(value, ",")
171 }
172 case "coverprofile":
173 testCover = true
174 testCoverProfile = value
175 case "covermode":
176 switch value {
177 case "set", "count", "atomic":
178 testCoverMode = value
179 default:
180 base.Fatalf("invalid flag argument for -covermode: %q", value)
181 }
182 testCover = true
183 case "outputdir":
184 testOutputDir = value
185 case "vet":
186 testVetList = value
187 }
188 }
189 if extraWord {
190 i++
191 }
192 if f.PassToTest {
193 passToTest = append(passToTest, "-test."+f.Name+"="+value)
194 }
195 }
196
197 if testCoverMode == "" {
198 testCoverMode = "set"
199 if cfg.BuildRace {
200
201 testCoverMode = "atomic"
202 }
203 }
204
205 testVetExplicit = testVetList != ""
206 if testVetList != "" && testVetList != "off" {
207 if strings.Contains(testVetList, "=") {
208 base.Fatalf("-vet argument cannot contain equal signs")
209 }
210 if strings.Contains(testVetList, " ") {
211 base.Fatalf("-vet argument is comma-separated list, cannot contain spaces")
212 }
213 list := strings.Split(testVetList, ",")
214 for i, arg := range list {
215 list[i] = "-" + arg
216 }
217 testVetFlags = list
218 }
219
220 if cfg.BuildRace && testCoverMode != "atomic" {
221 base.Fatalf(`-covermode must be "atomic", not %q, when -race is enabled`, testCoverMode)
222 }
223
224
225 if testProfile != "" && testOutputDir == "" {
226 dir, err := os.Getwd()
227 if err != nil {
228 base.Fatalf("error from os.Getwd: %s", err)
229 }
230 passToTest = append(passToTest, "-test.outputdir", dir)
231 }
232
233 passToTest = append(passToTest, explicitArgs...)
234 return
235 }
236
View as plain text