diff --git a/pytest/pytest.go b/pytest/pytest.go index 54d4b980..7dbd6f3d 100644 --- a/pytest/pytest.go +++ b/pytest/pytest.go @@ -18,8 +18,8 @@ import ( "github.com/go-python/gpython/vm" ) -// Run the code in str -func Run(t *testing.T, prog string) { +// Compile the program in the file prog to code in the module that is returned +func compileProgram(t testing.TB, prog string) (*py.Module, *py.Code) { f, err := os.Open(prog) if err != nil { t.Fatalf("%s: Open failed: %v", prog, err) @@ -43,26 +43,30 @@ func Run(t *testing.T, prog string) { code := obj.(*py.Code) module := py.NewModule("__main__", "", nil, nil) module.Globals["__file__"] = py.String(prog) + return module, code +} - _, err = vm.Run(module.Globals, module.Globals, code, nil) +// Run the code in the module +func run(t testing.TB, module *py.Module, code *py.Code) { + _, err := vm.Run(module.Globals, module.Globals, code, nil) if err != nil { if wantErr, ok := module.Globals["err"]; ok { wantErrObj, ok := wantErr.(py.Object) if !ok { - t.Fatalf("%s: want err is not py.Object: %#v", prog, wantErr) + t.Fatalf("want err is not py.Object: %#v", wantErr) } gotExc, ok := err.(py.ExceptionInfo) if !ok { - t.Fatalf("%s: got err is not ExceptionInfo: %#v", prog, err) + t.Fatalf("got err is not ExceptionInfo: %#v", err) } if gotExc.Value.Type() != wantErrObj.Type() { - t.Fatalf("%s: Want exception %v got %v", prog, wantErrObj, gotExc.Value) + t.Fatalf("Want exception %v got %v", wantErrObj, gotExc.Value) } - t.Logf("%s: matched exception", prog) + // t.Logf("matched exception") return } else { py.TracebackDump(err) - t.Fatalf("%s: Run failed: %v at %q", prog, err, module.Globals["doc"]) + t.Fatalf("Run failed: %v at %q", err, module.Globals["doc"]) } } @@ -70,18 +74,18 @@ func Run(t *testing.T, prog string) { if doc, ok := module.Globals["doc"]; ok { if docStr, ok := doc.(py.String); ok { if string(docStr) != "finished" { - t.Fatalf("%s: Didn't finish at %q", prog, docStr) + t.Fatalf("Didn't finish at %q", docStr) } } else { - t.Fatalf("%s: Set doc variable to non string: %#v", prog, doc) + t.Fatalf("Set doc variable to non string: %#v", doc) } } else { - t.Fatalf("%s: Didn't set doc variable at all", prog) + t.Fatalf("Didn't set doc variable at all") } } -// Runs the tests in the directory passed in -func RunTests(t *testing.T, testDir string) { +// find the python files in the directory passed in +func findFiles(t testing.TB, testDir string) (names []string) { files, err := ioutil.ReadDir(testDir) if err != nil { t.Fatalf("ReadDir failed: %v", err) @@ -89,9 +93,30 @@ func RunTests(t *testing.T, testDir string) { for _, f := range files { name := f.Name() if !strings.HasPrefix(name, "lib") && strings.HasSuffix(name, ".py") { - name := path.Join(testDir, name) - t.Logf("%s: Running", name) - Run(t, name) + names = append(names, name) } } + return names +} + +// RunTests runs the tests in the directory passed in +func RunTests(t *testing.T, testDir string) { + for _, name := range findFiles(t, testDir) { + t.Run(name, func(t *testing.T) { + module, code := compileProgram(t, path.Join(testDir, name)) + run(t, module, code) + }) + } +} + +// RunBenchmarks runs the benchmarks in the directory passed in +func RunBenchmarks(b *testing.B, testDir string) { + for _, name := range findFiles(b, testDir) { + module, code := compileProgram(b, path.Join(testDir, name)) + b.Run(name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + run(b, module, code) + } + }) + } } diff --git a/vm/benchmarks/fib.py b/vm/benchmarks/fib.py new file mode 100644 index 00000000..18c69a5a --- /dev/null +++ b/vm/benchmarks/fib.py @@ -0,0 +1,15 @@ +# Copyright 2019 The go-python Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# Benchmark adapted from https://github.com/d5/tengobench/ +doc="fib recursion test" +def fib(n): + if n == 0: + return 0 + elif n == 1: + return 1 + return fib(n - 2) + fib(n - 1) + +fib(25) +doc="finished" diff --git a/vm/benchmarks/fibtc.py b/vm/benchmarks/fibtc.py new file mode 100644 index 00000000..1b8b5f73 --- /dev/null +++ b/vm/benchmarks/fibtc.py @@ -0,0 +1,15 @@ +# Copyright 2019 The go-python Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# Benchmark adapted from https://github.com/d5/tengobench/ +doc="fib tail call recursion test" +def fib(n, a, b): + if n == 0: + return a + elif n == 1: + return b + return fib(n-1, b, a+b) + +fib(35, 0, 1) +doc="finished" diff --git a/vm/vm_test.go b/vm/vm_test.go index 51aa30e3..f1686207 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -13,3 +13,7 @@ import ( func TestVm(t *testing.T) { pytest.RunTests(t, "tests") } + +func BenchmarkVM(b *testing.B) { + pytest.RunBenchmarks(b, "benchmarks") +}
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: