@@ -200,8 +200,26 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
200
200
return false , err
201
201
}
202
202
203
+ // Pass test flags to the test binary.
204
+ var flags []string
205
+ if testVerbose {
206
+ flags = append (flags , "-test.v" )
207
+ }
208
+ if testShort {
209
+ flags = append (flags , "-test.short" )
210
+ }
211
+ if testRunRegexp != "" {
212
+ flags = append (flags , "-test.run=" + testRunRegexp )
213
+ }
214
+ if testBenchRegexp != "" {
215
+ flags = append (flags , "-test.bench=" + testBenchRegexp )
216
+ }
217
+ if testBenchTime != "" {
218
+ flags = append (flags , "-test.benchtime=" + testBenchTime )
219
+ }
220
+
203
221
passed := false
204
- err = builder . Build (pkgName , outpath , config , func (result builder.BuildResult ) error {
222
+ err = buildAndRun (pkgName , config , os . Stdout , flags , nil , 0 , func (cmd * exec. Cmd , result builder.BuildResult ) error {
205
223
if testCompileOnly || outpath != "" {
206
224
// Write test binary to the specified file name.
207
225
if outpath == "" {
@@ -217,27 +235,53 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
217
235
return nil
218
236
}
219
237
238
+ // Tests are always run in the package directory.
239
+ cmd .Dir = result .MainDir
240
+
241
+ // Wasmtime needs a few extra flags to work.
242
+ emulator := config .Emulator ()
243
+ if len (emulator ) != 0 && emulator [0 ] == "wasmtime" {
244
+ // Add directories to the module root, but skip the current working
245
+ // directory which is already added by buildAndRun.
246
+ dirs := dirsToModuleRoot (result .MainDir , result .ModuleRoot )
247
+ var args []string
248
+ for _ , d := range dirs [1 :] {
249
+ args = append (args , "--dir=" + d )
250
+ }
251
+
252
+ // create a new temp directory just for this run, announce it to os.TempDir() via TMPDIR
253
+ tmpdir , err := ioutil .TempDir ("" , "tinygotmp" )
254
+ if err != nil {
255
+ return fmt .Errorf ("failed to create temporary directory: %w" , err )
256
+ }
257
+ args = append (args , "--dir=" + tmpdir , "--env=TMPDIR=" + tmpdir )
258
+ // TODO: add option to not delete temp dir for debugging?
259
+ defer os .RemoveAll (tmpdir )
260
+
261
+ // Insert new argments at the front of the command line argments.
262
+ args = append (args , cmd .Args [1 :]... )
263
+ cmd .Args = append (cmd .Args [:1 :1 ], args ... )
264
+ }
265
+
220
266
// Run the test.
221
- config .Options .Semaphore <- struct {}{}
222
- defer func () {
223
- <- config .Options .Semaphore
224
- }()
225
267
start := time .Now ()
226
- var err error
227
- passed , err = runPackageTest (config , stdout , stderr , result , testVerbose , testShort , testRunRegexp , testBenchRegexp , testBenchTime )
228
- if err != nil {
229
- return err
230
- }
268
+ err = cmd .Run ()
231
269
duration := time .Since (start )
232
270
233
271
// Print the result.
234
272
importPath := strings .TrimSuffix (result .ImportPath , ".test" )
273
+ passed = err == nil
235
274
if passed {
236
275
fmt .Fprintf (stdout , "ok \t %s\t %.3fs\n " , importPath , duration .Seconds ())
237
276
} else {
238
277
fmt .Fprintf (stdout , "FAIL\t %s\t %.3fs\n " , importPath , duration .Seconds ())
239
278
}
240
- return nil
279
+ if _ , ok := err .(* exec.ExitError ); ok {
280
+ // Binary exited with a non-zero exit code, which means the test
281
+ // failed.
282
+ return nil
283
+ }
284
+ return err
241
285
})
242
286
if err , ok := err .(loader.NoTestFilesError ); ok {
243
287
fmt .Fprintf (stdout , "? \t %s\t [no test files]\n " , err .ImportPath )
@@ -260,81 +304,6 @@ func dirsToModuleRoot(maindir, modroot string) []string {
260
304
return dirs
261
305
}
262
306
263
- // runPackageTest runs a test binary that was previously built. The return
264
- // values are whether the test passed and any errors encountered while trying to
265
- // run the binary.
266
- func runPackageTest (config * compileopts.Config , stdout , stderr io.Writer , result builder.BuildResult , testVerbose , testShort bool , testRunRegexp string , testBenchRegexp string , testBenchTime string ) (bool , error ) {
267
- var cmd * exec.Cmd
268
- emulator := config .Emulator ()
269
- if len (emulator ) == 0 {
270
- // Run directly.
271
- var flags []string
272
- if testVerbose {
273
- flags = append (flags , "-test.v" )
274
- }
275
- if testShort {
276
- flags = append (flags , "-test.short" )
277
- }
278
- if testRunRegexp != "" {
279
- flags = append (flags , "-test.run=" + testRunRegexp )
280
- }
281
- if testBenchRegexp != "" {
282
- flags = append (flags , "-test.bench=" + testBenchRegexp )
283
- }
284
- if testBenchTime != "" {
285
- flags = append (flags , "-test.benchtime=" + testBenchTime )
286
- }
287
- cmd = executeCommand (config .Options , result .Binary , flags ... )
288
- } else {
289
- // Run in an emulator.
290
- args := append (emulator [1 :], result .Binary )
291
- if emulator [0 ] == "wasmtime" {
292
- // create a new temp directory just for this run, announce it to os.TempDir() via TMPDIR
293
- tmpdir , err := ioutil .TempDir ("" , "tinygotmp" )
294
- if err != nil {
295
- return false , & commandError {"failed to create temporary directory" , "tinygotmp" , err }
296
- }
297
- args = append (args , "--dir=" + tmpdir , "--env=TMPDIR=" + tmpdir )
298
- // TODO: add option to not delete temp dir for debugging?
299
- defer os .RemoveAll (tmpdir )
300
-
301
- // allow reading from directories up to module root
302
- for _ , d := range dirsToModuleRoot (result .MainDir , result .ModuleRoot ) {
303
- args = append (args , "--dir=" + d )
304
- }
305
-
306
- // mark end of wasmtime arguments and start of program ones: --
307
- args = append (args , "--" )
308
- if testVerbose {
309
- args = append (args , "-test.v" )
310
- }
311
- if testShort {
312
- args = append (args , "-test.short" )
313
- }
314
- if testRunRegexp != "" {
315
- args = append (args , "-test.run=" + testRunRegexp )
316
- }
317
- if testBenchRegexp != "" {
318
- args = append (args , "-test.bench=" + testBenchRegexp )
319
- }
320
- }
321
- cmd = executeCommand (config .Options , emulator [0 ], args ... )
322
- }
323
- cmd .Dir = result .MainDir
324
- cmd .Stdout = stdout
325
- cmd .Stderr = stderr
326
- err := cmd .Run ()
327
- if err != nil {
328
- if _ , ok := err .(* exec.ExitError ); ok {
329
- // Binary exited with a non-zero exit code, which means the test
330
- // failed.
331
- return false , nil
332
- }
333
- return false , & commandError {"failed to run compiled binary" , result .Binary , err }
334
- }
335
- return true , nil
336
- }
337
-
338
307
// Flash builds and flashes the built binary to the given serial port.
339
308
func Flash (pkgName , port string , options * compileopts.Options ) error {
340
309
config , err := builder .NewConfig (options )
@@ -715,14 +684,16 @@ func Run(pkgName string, options *compileopts.Options, cmdArgs []string) error {
715
684
return err
716
685
}
717
686
718
- return buildAndRun (pkgName , config , os .Stdout , cmdArgs , nil , 0 )
687
+ return buildAndRun (pkgName , config , os .Stdout , cmdArgs , nil , 0 , func (cmd * exec.Cmd , result builder.BuildResult ) error {
688
+ return cmd .Run ()
689
+ })
719
690
}
720
691
721
692
// buildAndRun builds and runs the given program, writing output to stdout and
722
693
// errors to os.Stderr. It takes care of emulators (qemu, wasmtime, etc) and
723
694
// passes command line arguments and evironment variables in a way appropriate
724
695
// for the given emulator.
725
- func buildAndRun (pkgName string , config * compileopts.Config , stdout io.Writer , cmdArgs , environmentVars []string , timeout time.Duration ) error {
696
+ func buildAndRun (pkgName string , config * compileopts.Config , stdout io.Writer , cmdArgs , environmentVars []string , timeout time.Duration , run func ( cmd * exec. Cmd , result builder. BuildResult ) error ) error {
726
697
// make sure any special vars in the emulator definition are rewritten
727
698
emulator := config .Emulator ()
728
699
@@ -764,7 +735,11 @@ func buildAndRun(pkgName string, config *compileopts.Config, stdout io.Writer, c
764
735
for _ , v := range environmentVars {
765
736
args = append (args , "--env" , v )
766
737
}
767
- args = append (args , cmdArgs ... )
738
+ if len (cmdArgs ) != 0 {
739
+ // mark end of wasmtime arguments and start of program ones: --
740
+ args = append (args , "--" )
741
+ args = append (args , cmdArgs ... )
742
+ }
768
743
} else {
769
744
// Pass environment variables and command line parameters as usual.
770
745
// This also works on qemu-aarch64 etc.
@@ -821,11 +796,11 @@ func buildAndRun(pkgName string, config *compileopts.Config, stdout io.Writer, c
821
796
if config .Options .PrintCommands != nil {
822
797
config .Options .PrintCommands (cmd .Path , cmd .Args ... )
823
798
}
824
- err := cmd . Run ( )
799
+ err := run ( cmd , result )
825
800
if err != nil {
826
- if cerr := ctx .Err (); cerr == context .DeadlineExceeded {
801
+ if ctx != nil && ctx .Err () == context .DeadlineExceeded {
827
802
stdout .Write ([]byte (fmt .Sprintf ("--- timeout of %s exceeded, terminating...\n " , timeout )))
828
- err = cerr
803
+ err = ctx . Err ()
829
804
}
830
805
return & commandError {"failed to run compiled binary" , result .Binary , err }
831
806
}
0 commit comments