mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-06-02 23:40:50 +00:00
3c877c504b
This commit enables cpu, mem, block, and mutex profling of the FZF executable. To support flushing the profiles at program exit it adds util.AtExit to register "at exit" functions and mandates that util.Exit is used instead of os.Exit to stop the program. Co-authored-by: Junegunn Choi <junegunn.c@gmail.com>
90 lines
2.0 KiB
Go
90 lines
2.0 KiB
Go
//go:build pprof
|
|
// +build pprof
|
|
|
|
package fzf
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/junegunn/fzf/src/util"
|
|
)
|
|
|
|
// runInitProfileTests is an internal flag used TestInitProfiling
|
|
var runInitProfileTests = flag.Bool("test-init-profile", false, "run init profile tests")
|
|
|
|
func TestInitProfiling(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("short test")
|
|
}
|
|
|
|
// Run this test in a separate process since it interferes with
|
|
// profiling and modifies the global atexit state. Without this
|
|
// running `go test -bench . -cpuprofile cpu.out` will fail.
|
|
if !*runInitProfileTests {
|
|
t.Parallel()
|
|
|
|
// Make sure we are not the child process.
|
|
if os.Getenv("_FZF_CHILD_PROC") != "" {
|
|
t.Fatal("already running as child process!")
|
|
}
|
|
|
|
cmd := exec.Command(os.Args[0],
|
|
"-test.timeout", "30s",
|
|
"-test.run", "^"+t.Name()+"$",
|
|
"-test-init-profile",
|
|
)
|
|
cmd.Env = append(os.Environ(), "_FZF_CHILD_PROC=1")
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
out = bytes.TrimSpace(out)
|
|
if err != nil {
|
|
t.Fatalf("Child test process failed: %v:\n%s", err, out)
|
|
}
|
|
// Make sure the test actually ran
|
|
if bytes.Contains(out, []byte("no tests to run")) {
|
|
t.Fatalf("Failed to run test %q:\n%s", t.Name(), out)
|
|
}
|
|
return
|
|
}
|
|
|
|
// Child process
|
|
|
|
tempdir := t.TempDir()
|
|
t.Cleanup(util.RunAtExitFuncs)
|
|
|
|
o := Options{
|
|
CPUProfile: filepath.Join(tempdir, "cpu.prof"),
|
|
MEMProfile: filepath.Join(tempdir, "mem.prof"),
|
|
BlockProfile: filepath.Join(tempdir, "block.prof"),
|
|
MutexProfile: filepath.Join(tempdir, "mutex.prof"),
|
|
}
|
|
if err := o.initProfiling(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
profiles := []string{
|
|
o.CPUProfile,
|
|
o.MEMProfile,
|
|
o.BlockProfile,
|
|
o.MutexProfile,
|
|
}
|
|
for _, name := range profiles {
|
|
if _, err := os.Stat(name); err != nil {
|
|
t.Errorf("Failed to create profile %s: %v", filepath.Base(name), err)
|
|
}
|
|
}
|
|
|
|
util.RunAtExitFuncs()
|
|
|
|
for _, name := range profiles {
|
|
if _, err := os.Stat(name); err != nil {
|
|
t.Errorf("Failed to write profile %s: %v", filepath.Base(name), err)
|
|
}
|
|
}
|
|
}
|