@@ -36,7 +36,10 @@ var exeSuffix string
36
36
var GOOS , GOARCH , GOPATH string
37
37
var libgodir string
38
38
39
+ var testWork bool // If true, preserve temporary directories.
40
+
39
41
func TestMain (m * testing.M ) {
42
+ flag .BoolVar (& testWork , "testwork" , false , "if true, log and preserve the test's temporary working directory" )
40
43
flag .Parse ()
41
44
if testing .Short () && os .Getenv ("GO_BUILDER_NAME" ) == "" {
42
45
fmt .Printf ("SKIP - short mode and $GO_BUILDER_NAME not set\n " )
@@ -54,7 +57,11 @@ func testMain(m *testing.M) int {
54
57
if err != nil {
55
58
log .Panic (err )
56
59
}
57
- defer os .RemoveAll (GOPATH )
60
+ if testWork {
61
+ log .Println (GOPATH )
62
+ } else {
63
+ defer os .RemoveAll (GOPATH )
64
+ }
58
65
os .Setenv ("GOPATH" , GOPATH )
59
66
60
67
// Copy testdata into GOPATH/src/testarchive, along with a go.mod file
@@ -164,6 +171,38 @@ func cmdToRun(name string) []string {
164
171
return []string {executor , name }
165
172
}
166
173
174
+ // genHeader writes a C header file for the C-exported declarations found in .go
175
+ // source files in dir.
176
+ //
177
+ // TODO(golang.org/issue/35715): This should be simpler.
178
+ func genHeader (t * testing.T , header , dir string ) {
179
+ t .Helper ()
180
+
181
+ // The 'cgo' command generates a number of additional artifacts,
182
+ // but we're only interested in the header.
183
+ // Shunt the rest of the outputs to a temporary directory.
184
+ objDir , err := ioutil .TempDir (GOPATH , "_obj" )
185
+ if err != nil {
186
+ t .Fatal (err )
187
+ }
188
+ defer os .RemoveAll (objDir )
189
+
190
+ files , err := filepath .Glob (filepath .Join (dir , "*.go" ))
191
+ if err != nil {
192
+ t .Fatal (err )
193
+ }
194
+
195
+ cmd := exec .Command ("go" , "tool" , "cgo" ,
196
+ "-objdir" , objDir ,
197
+ "-exportheader" , header )
198
+ cmd .Args = append (cmd .Args , files ... )
199
+ t .Log (cmd .Args )
200
+ if out , err := cmd .CombinedOutput (); err != nil {
201
+ t .Logf ("%s" , out )
202
+ t .Fatal (err )
203
+ }
204
+ }
205
+
167
206
func testInstall (t * testing.T , exe , libgoa , libgoh string , buildcmd ... string ) {
168
207
t .Helper ()
169
208
cmd := exec .Command (buildcmd [0 ], buildcmd [1 :]... )
@@ -172,10 +211,12 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
172
211
t .Logf ("%s" , out )
173
212
t .Fatal (err )
174
213
}
175
- defer func () {
176
- os .Remove (libgoa )
177
- os .Remove (libgoh )
178
- }()
214
+ if ! testWork {
215
+ defer func () {
216
+ os .Remove (libgoa )
217
+ os .Remove (libgoh )
218
+ }()
219
+ }
179
220
180
221
ccArgs := append (cc , "-o" , exe , "main.c" )
181
222
if GOOS == "windows" {
@@ -191,7 +232,9 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
191
232
t .Logf ("%s" , out )
192
233
t .Fatal (err )
193
234
}
194
- defer os .Remove (exe )
235
+ if ! testWork {
236
+ defer os .Remove (exe )
237
+ }
195
238
196
239
binArgs := append (cmdToRun (exe ), "arg1" , "arg2" )
197
240
cmd = exec .Command (binArgs [0 ], binArgs [1 :]... )
@@ -227,17 +270,27 @@ func checkLineComments(t *testing.T, hdrname string) {
227
270
}
228
271
229
272
func TestInstall (t * testing.T ) {
230
- defer os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
273
+ if ! testWork {
274
+ defer os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
275
+ }
231
276
232
277
libgoa := "libgo.a"
233
278
if runtime .Compiler == "gccgo" {
234
279
libgoa = "liblibgo.a"
235
280
}
236
281
282
+ // Generate the p.h header file.
283
+ //
284
+ // 'go install -i -buildmode=c-archive ./libgo' would do that too, but that
285
+ // would also attempt to install transitive standard-library dependencies to
286
+ // GOROOT, and we cannot assume that GOROOT is writable. (A non-root user may
287
+ // be running this test in a GOROOT owned by root.)
288
+ genHeader (t , "p.h" , "./p" )
289
+
237
290
testInstall (t , "./testp1" + exeSuffix ,
238
291
filepath .Join (libgodir , libgoa ),
239
292
filepath .Join (libgodir , "libgo.h" ),
240
- "go" , "install" , "-i" , "- buildmode=c-archive" , "./libgo" )
293
+ "go" , "install" , "-buildmode=c-archive" , "./libgo" )
241
294
242
295
// Test building libgo other than installing it.
243
296
// Header files are now present.
@@ -259,12 +312,14 @@ func TestEarlySignalHandler(t *testing.T) {
259
312
t .Skip ("skipping signal test on Windows" )
260
313
}
261
314
262
- defer func () {
263
- os .Remove ("libgo2.a" )
264
- os .Remove ("libgo2.h" )
265
- os .Remove ("testp" )
266
- os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
267
- }()
315
+ if ! testWork {
316
+ defer func () {
317
+ os .Remove ("libgo2.a" )
318
+ os .Remove ("libgo2.h" )
319
+ os .Remove ("testp" )
320
+ os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
321
+ }()
322
+ }
268
323
269
324
cmd := exec .Command ("go" , "build" , "-buildmode=c-archive" , "-o" , "libgo2.a" , "./libgo2" )
270
325
if out , err := cmd .CombinedOutput (); err != nil {
@@ -297,12 +352,14 @@ func TestEarlySignalHandler(t *testing.T) {
297
352
func TestSignalForwarding (t * testing.T ) {
298
353
checkSignalForwardingTest (t )
299
354
300
- defer func () {
301
- os .Remove ("libgo2.a" )
302
- os .Remove ("libgo2.h" )
303
- os .Remove ("testp" )
304
- os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
305
- }()
355
+ if ! testWork {
356
+ defer func () {
357
+ os .Remove ("libgo2.a" )
358
+ os .Remove ("libgo2.h" )
359
+ os .Remove ("testp" )
360
+ os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
361
+ }()
362
+ }
306
363
307
364
cmd := exec .Command ("go" , "build" , "-buildmode=c-archive" , "-o" , "libgo2.a" , "./libgo2" )
308
365
if out , err := cmd .CombinedOutput (); err != nil {
@@ -345,12 +402,14 @@ func TestSignalForwardingExternal(t *testing.T) {
345
402
}
346
403
checkSignalForwardingTest (t )
347
404
348
- defer func () {
349
- os .Remove ("libgo2.a" )
350
- os .Remove ("libgo2.h" )
351
- os .Remove ("testp" )
352
- os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
353
- }()
405
+ if ! testWork {
406
+ defer func () {
407
+ os .Remove ("libgo2.a" )
408
+ os .Remove ("libgo2.h" )
409
+ os .Remove ("testp" )
410
+ os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
411
+ }()
412
+ }
354
413
355
414
cmd := exec .Command ("go" , "build" , "-buildmode=c-archive" , "-o" , "libgo2.a" , "./libgo2" )
356
415
if out , err := cmd .CombinedOutput (); err != nil {
@@ -460,12 +519,14 @@ func TestOsSignal(t *testing.T) {
460
519
t .Skip ("skipping signal test on Windows" )
461
520
}
462
521
463
- defer func () {
464
- os .Remove ("libgo3.a" )
465
- os .Remove ("libgo3.h" )
466
- os .Remove ("testp" )
467
- os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
468
- }()
522
+ if ! testWork {
523
+ defer func () {
524
+ os .Remove ("libgo3.a" )
525
+ os .Remove ("libgo3.h" )
526
+ os .Remove ("testp" )
527
+ os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
528
+ }()
529
+ }
469
530
470
531
cmd := exec .Command ("go" , "build" , "-buildmode=c-archive" , "-o" , "libgo3.a" , "./libgo3" )
471
532
if out , err := cmd .CombinedOutput (); err != nil {
@@ -495,12 +556,14 @@ func TestSigaltstack(t *testing.T) {
495
556
t .Skip ("skipping signal test on Windows" )
496
557
}
497
558
498
- defer func () {
499
- os .Remove ("libgo4.a" )
500
- os .Remove ("libgo4.h" )
501
- os .Remove ("testp" )
502
- os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
503
- }()
559
+ if ! testWork {
560
+ defer func () {
561
+ os .Remove ("libgo4.a" )
562
+ os .Remove ("libgo4.h" )
563
+ os .Remove ("testp" )
564
+ os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
565
+ }()
566
+ }
504
567
505
568
cmd := exec .Command ("go" , "build" , "-buildmode=c-archive" , "-o" , "libgo4.a" , "./libgo4" )
506
569
if out , err := cmd .CombinedOutput (); err != nil {
@@ -544,13 +607,15 @@ func TestExtar(t *testing.T) {
544
607
t .Skip ("shell scripts are not executable on iOS hosts" )
545
608
}
546
609
547
- defer func () {
548
- os .Remove ("libgo4.a" )
549
- os .Remove ("libgo4.h" )
550
- os .Remove ("testar" )
551
- os .Remove ("testar.ran" )
552
- os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
553
- }()
610
+ if ! testWork {
611
+ defer func () {
612
+ os .Remove ("libgo4.a" )
613
+ os .Remove ("libgo4.h" )
614
+ os .Remove ("testar" )
615
+ os .Remove ("testar.ran" )
616
+ os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
617
+ }()
618
+ }
554
619
555
620
os .Remove ("testar" )
556
621
dir , err := os .Getwd ()
@@ -584,12 +649,22 @@ func TestPIE(t *testing.T) {
584
649
t .Skipf ("skipping PIE test on %s" , GOOS )
585
650
}
586
651
587
- defer func () {
588
- os .Remove ("testp" + exeSuffix )
589
- os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
590
- }()
652
+ if ! testWork {
653
+ defer func () {
654
+ os .Remove ("testp" + exeSuffix )
655
+ os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
656
+ }()
657
+ }
658
+
659
+ // Generate the p.h header file.
660
+ //
661
+ // 'go install -i -buildmode=c-archive ./libgo' would do that too, but that
662
+ // would also attempt to install transitive standard-library dependencies to
663
+ // GOROOT, and we cannot assume that GOROOT is writable. (A non-root user may
664
+ // be running this test in a GOROOT owned by root.)
665
+ genHeader (t , "p.h" , "./p" )
591
666
592
- cmd := exec .Command ("go" , "install" , "-i" , "- buildmode=c-archive" , "./libgo" )
667
+ cmd := exec .Command ("go" , "install" , "-buildmode=c-archive" , "./libgo" )
593
668
if out , err := cmd .CombinedOutput (); err != nil {
594
669
t .Logf ("%s" , out )
595
670
t .Fatal (err )
@@ -669,11 +744,13 @@ func TestSIGPROF(t *testing.T) {
669
744
670
745
t .Parallel ()
671
746
672
- defer func () {
673
- os .Remove ("testp6" + exeSuffix )
674
- os .Remove ("libgo6.a" )
675
- os .Remove ("libgo6.h" )
676
- }()
747
+ if ! testWork {
748
+ defer func () {
749
+ os .Remove ("testp6" + exeSuffix )
750
+ os .Remove ("libgo6.a" )
751
+ os .Remove ("libgo6.h" )
752
+ }()
753
+ }
677
754
678
755
cmd := exec .Command ("go" , "build" , "-buildmode=c-archive" , "-o" , "libgo6.a" , "./libgo6" )
679
756
if out , err := cmd .CombinedOutput (); err != nil {
@@ -709,10 +786,12 @@ func TestCompileWithoutShared(t *testing.T) {
709
786
// For simplicity, reuse the signal forwarding test.
710
787
checkSignalForwardingTest (t )
711
788
712
- defer func () {
713
- os .Remove ("libgo2.a" )
714
- os .Remove ("libgo2.h" )
715
- }()
789
+ if ! testWork {
790
+ defer func () {
791
+ os .Remove ("libgo2.a" )
792
+ os .Remove ("libgo2.h" )
793
+ }()
794
+ }
716
795
717
796
cmd := exec .Command ("go" , "build" , "-buildmode=c-archive" , "-gcflags=-shared=false" , "-o" , "libgo2.a" , "./libgo2" )
718
797
t .Log (cmd .Args )
@@ -751,7 +830,9 @@ func TestCompileWithoutShared(t *testing.T) {
751
830
if err != nil {
752
831
t .Fatal (err )
753
832
}
754
- defer os .Remove (exe )
833
+ if ! testWork {
834
+ defer os .Remove (exe )
835
+ }
755
836
756
837
binArgs := append (cmdToRun (exe ), "1" )
757
838
t .Log (binArgs )
@@ -769,14 +850,15 @@ func TestCompileWithoutShared(t *testing.T) {
769
850
}
770
851
}
771
852
772
- // Test that installing a second time recreates the header files .
853
+ // Test that installing a second time recreates the header file .
773
854
func TestCachedInstall (t * testing.T ) {
774
- defer os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
855
+ if ! testWork {
856
+ defer os .RemoveAll (filepath .Join (GOPATH , "pkg" ))
857
+ }
775
858
776
- h1 := filepath .Join (libgodir , "libgo.h" )
777
- h2 := filepath .Join (libgodir , "p.h" )
859
+ h := filepath .Join (libgodir , "libgo.h" )
778
860
779
- buildcmd := []string {"go" , "install" , "-i" , "- buildmode=c-archive" , "./libgo" }
861
+ buildcmd := []string {"go" , "install" , "-buildmode=c-archive" , "./libgo" }
780
862
781
863
cmd := exec .Command (buildcmd [0 ], buildcmd [1 :]... )
782
864
t .Log (buildcmd )
@@ -785,17 +867,11 @@ func TestCachedInstall(t *testing.T) {
785
867
t .Fatal (err )
786
868
}
787
869
788
- if _ , err := os .Stat (h1 ); err != nil {
870
+ if _ , err := os .Stat (h ); err != nil {
789
871
t .Errorf ("libgo.h not installed: %v" , err )
790
872
}
791
- if _ , err := os .Stat (h2 ); err != nil {
792
- t .Errorf ("p.h not installed: %v" , err )
793
- }
794
873
795
- if err := os .Remove (h1 ); err != nil {
796
- t .Fatal (err )
797
- }
798
- if err := os .Remove (h2 ); err != nil {
874
+ if err := os .Remove (h ); err != nil {
799
875
t .Fatal (err )
800
876
}
801
877
@@ -806,23 +882,22 @@ func TestCachedInstall(t *testing.T) {
806
882
t .Fatal (err )
807
883
}
808
884
809
- if _ , err := os .Stat (h1 ); err != nil {
885
+ if _ , err := os .Stat (h ); err != nil {
810
886
t .Errorf ("libgo.h not installed in second run: %v" , err )
811
887
}
812
- if _ , err := os .Stat (h2 ); err != nil {
813
- t .Errorf ("p.h not installed in second run: %v" , err )
814
- }
815
888
}
816
889
817
890
// Issue 35294.
818
891
func TestManyCalls (t * testing.T ) {
819
892
t .Parallel ()
820
893
821
- defer func () {
822
- os .Remove ("testp7" + exeSuffix )
823
- os .Remove ("libgo7.a" )
824
- os .Remove ("libgo7.h" )
825
- }()
894
+ if ! testWork {
895
+ defer func () {
896
+ os .Remove ("testp7" + exeSuffix )
897
+ os .Remove ("libgo7.a" )
898
+ os .Remove ("libgo7.h" )
899
+ }()
900
+ }
826
901
827
902
cmd := exec .Command ("go" , "build" , "-buildmode=c-archive" , "-o" , "libgo7.a" , "./libgo7" )
828
903
if out , err := cmd .CombinedOutput (); err != nil {
0 commit comments