blob: 2781833805ccec19657fa11dc33a9d6d2d1b56fd [file] [log] [blame]
alandonovan61fc5422019-04-05 16:12:13 -04001// Copyright 2019 The Bazel Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package starlark_test
6
7import (
8 "bytes"
9 "fmt"
10 "io/ioutil"
11 "os"
12 "os/exec"
13 "strings"
14 "testing"
15
16 "go.starlark.net/starlark"
17)
18
19// TestProfile is a simple integration test that the profiler
20// emits minimally plausible pprof-compatible output.
21func TestProfile(t *testing.T) {
22 prof, err := ioutil.TempFile("", "profile_test")
23 if err != nil {
24 t.Fatal(err)
25 }
26 defer prof.Close()
27 defer os.Remove(prof.Name())
28 if err := starlark.StartProfile(prof); err != nil {
29 t.Fatal(err)
30 }
31
32 const src = `
33def fibonacci(n):
34 res = list(range(n))
35 for i in res[2:]:
36 res[i] = res[i-2] + res[i-1]
37 return res
38
39fibonacci(100000)
40`
41
42 thread := new(starlark.Thread)
43 if _, err := starlark.ExecFile(thread, "foo.star", src, nil); err != nil {
44 _ = starlark.StopProfile()
45 t.Fatal(err)
46 }
47 if err := starlark.StopProfile(); err != nil {
48 t.Fatal(err)
49 }
50 prof.Sync()
51 cmd := exec.Command("go", "tool", "pprof", "-top", prof.Name())
52 cmd.Stderr = new(bytes.Buffer)
53 cmd.Stdout = new(bytes.Buffer)
54 if err := cmd.Run(); err != nil {
55 t.Fatalf("pprof failed: %v; output=<<%s>>", err, cmd.Stderr)
56 }
57
58 // Typical output (may vary by go release):
59 //
60 // Type: wall
61 // Time: Apr 4, 2019 at 11:10am (EDT)
62 // Duration: 251.62ms, Total samples = 250ms (99.36%)
63 // Showing nodes accounting for 250ms, 100% of 250ms total
64 // flat flat% sum% cum cum%
65 // 320ms 100% 100% 320ms 100% fibonacci
66 // 0 0% 100% 320ms 100% foo.star
67 //
68 // We'll assert a few key substrings are present.
69 got := fmt.Sprint(cmd.Stdout)
70 for _, want := range []string{
71 "flat%",
72 "fibonacci",
73 "foo.star",
74 } {
75 if !strings.Contains(got, want) {
76 t.Errorf("output did not contain %q", want)
77 }
78 }
79 if t.Failed() {
80 t.Logf("stderr=%v", cmd.Stderr)
81 t.Logf("stdout=%v", cmd.Stdout)
82 }
83}