diff --git a/cmd/ssadump/main.go b/cmd/ssadump/main.go index 3d1dea14..8c4dbd12 100644 --- a/cmd/ssadump/main.go +++ b/cmd/ssadump/main.go @@ -49,14 +49,13 @@ Use -help flag to display options. Examples: % ssadump -build=F hello.go # dump SSA form of a single package +% ssadump -build=F -test fmt # dump SSA form of a package and its tests % ssadump -run -interp=T hello.go # interpret a program, with tracing -% ssadump -run -test unicode -- -test.v # interpret the unicode package's tests, verbosely ` + loader.FromArgsUsage + ` -When -run is specified, ssadump will run the program. -The entry point depends on the -test flag: -if clear, it runs the first package named main. -if set, it runs the tests of each package. +The -run flag causes ssadump to run the first package named main. + +Interpretation of the standard "testing" package is no longer supported. ` func main() { diff --git a/go/ssa/interp/external.go b/go/ssa/interp/external.go index f428e58d..66727d8e 100644 --- a/go/ssa/interp/external.go +++ b/go/ssa/interp/external.go @@ -138,9 +138,7 @@ func init() { "sync/atomic.LoadUint64": ext۰atomic۰LoadUint64, "sync/atomic.StoreInt64": ext۰atomic۰StoreInt64, "sync/atomic.StoreUint64": ext۰atomic۰StoreUint64, - "testing.callerEntry": ext۰testing۰callerEntry, - "testing.callerName": ext۰testing۰callerName, - "testing.runExample": ext۰testing۰runExample, + "testing.MainStart": ext۰testing۰MainStart, "time.Sleep": ext۰time۰Sleep, "time.now": ext۰time۰now, } { @@ -512,35 +510,6 @@ func ext۰runtime۰Func۰Entry(fr *frame, args []value) value { return uintptr(unsafe.Pointer(f)) } -// This is a workaround for a bug in go/ssa/testmain.go: it creates -// InternalExamples even for Example functions with no Output comment. -// TODO(adonovan): fix (and redesign) testmain.go.. -func ext۰testing۰runExample(fr *frame, args []value) value { - // This is a stripped down runExample that simply calls the function. - // It does not capture and compare output nor recover from panic. - // - // func runExample(eg testing.InternalExample) bool { - // eg.F() - // return true - // } - F := args[0].(structure)[1] - call(fr.i, fr, 0, F, nil) - return true -} - -// These two internal functions must be faked to avoid calls to -// runtime.CallersFrames, which is hard to emulate. We are inching -// towards the point at which I blow away this entire package, or at -// least all tests that interpret the standard "testing" package. - -func ext۰testing۰callerEntry(fr *frame, args []value) value { - return uintptr(0) // bogus implementation for now -} - -func ext۰testing۰callerName(fr *frame, args []value) value { - return "" // bogus implementation for now -} - func ext۰time۰now(fr *frame, args []value) value { nano := time.Now().UnixNano() return tuple{int64(nano / 1e9), int32(nano % 1e9), int64(0)} @@ -559,3 +528,10 @@ func valueToBytes(v value) []byte { } return b } + +func ext۰testing۰MainStart(fr *frame, args []value) value { + // We no longer support interpretation of the "testing" package + // because it changes too often and uses low-level features that + // are a pain to emulate. + panic(`interpretation of the "testing" package is no longer supported`) +} diff --git a/go/ssa/interp/interp.go b/go/ssa/interp/interp.go index 4c8602dc..c0929609 100644 --- a/go/ssa/interp/interp.go +++ b/go/ssa/interp/interp.go @@ -20,11 +20,13 @@ // // * The reflect package is only partially implemented. // -// * "sync/atomic" operations are not currently atomic due to the -// "boxed" value representation: it is not possible to read, modify -// and write an interface value atomically. As a consequence, Mutexes -// are currently broken. TODO(adonovan): provide a metacircular -// implementation of Mutex avoiding the broken atomic primitives. +// * The "testing" package is no longer supported because it +// depends on low-level details that change too often. +// +// * "sync/atomic" operations are not atomic due to the "boxed" value +// representation: it is not possible to read, modify and write an +// interface value atomically. As a consequence, Mutexes are currently +// broken. // // * recover is only partially implemented. Also, the interpreter // makes no attempt to distinguish target panics from interpreter diff --git a/go/ssa/interp/interp_test.go b/go/ssa/interp/interp_test.go index 6e9f7b2f..2683a28b 100644 --- a/go/ssa/interp/interp_test.go +++ b/go/ssa/interp/interp_test.go @@ -152,27 +152,6 @@ var testdataTests = []string{ "callstack.go", } -// These are files and packages in $GOROOT/src/. -var gorootSrcTests = []string{ - "encoding/ascii85", - "encoding/hex", - // "encoding/pem", // TODO(adonovan): implement (reflect.Value).SetString - // "testing", // TODO(adonovan): implement runtime.Goexit correctly - // "hash/crc32", // TODO(adonovan): implement hash/crc32.haveCLMUL - // "log", // TODO(adonovan): implement runtime.Callers correctly - - // Too slow: - // "container/ring", - // "hash/adler32", - - "unicode/utf8", - "path", - "flag", - "encoding/csv", - "text/scanner", - "unicode", -} - type successPredicate func(exitcode int, output string) error func run(t *testing.T, dir, input string, success successPredicate) bool { @@ -312,53 +291,9 @@ func TestGorootTest(t *testing.T) { failures = append(failures, input) } } - for _, input := range gorootSrcTests { - if !run(t, filepath.Join(build.Default.GOROOT, "src")+slash, input, success) { - failures = append(failures, input) - } - } printFailures(failures) } -// TestTestmainPackage runs the interpreter on a synthetic "testmain" package. -func TestTestmainPackage(t *testing.T) { - if testing.Short() { - t.Skip() // too slow on some platforms - } - - success := func(exitcode int, output string) error { - if exitcode == 0 { - return fmt.Errorf("unexpected success") - } - if !strings.Contains(output, "FAIL: TestFoo") { - return fmt.Errorf("missing failure log for TestFoo") - } - if !strings.Contains(output, "FAIL: TestBar") { - return fmt.Errorf("missing failure log for TestBar") - } - // TODO(adonovan): test benchmarks too - return nil - } - run(t, "testdata"+slash, "a_test.go", success) - - // Run a test with a custom TestMain function and ensure that it - // is executed, and that m.Run runs the tests. - success = func(exitcode int, output string) error { - if exitcode != 0 { - return fmt.Errorf("unexpected failure; output=%s", output) - } - if want := `TestMain start -TestC -PASS -TestMain end -`; output != want { - return fmt.Errorf("output was %q, want %q", output, want) - } - return nil - } - run(t, "testdata"+slash, "c_test.go", success) -} - // CreateTestMainPackage should return nil if there were no tests. func TestNullTestmainPackage(t *testing.T) { var conf loader.Config