123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- package driver
-
- import (
- "io/ioutil"
- "net/url"
- "os"
- "path/filepath"
- "reflect"
- "testing"
- )
-
- // settingsDirAndFile returns a directory in which settings should be stored
- // and the name of the settings file. The caller must delete the directory when
- // done.
- func settingsDirAndFile(t *testing.T) (string, string) {
- tmpDir, err := ioutil.TempDir("", "pprof_settings_test")
- if err != nil {
- t.Fatalf("error creating temporary directory: %v", err)
- }
- return tmpDir, filepath.Join(tmpDir, "settings.json")
- }
-
- func TestSettings(t *testing.T) {
- tmpDir, fname := settingsDirAndFile(t)
- defer os.RemoveAll(tmpDir)
- s, err := readSettings(fname)
- if err != nil {
- t.Fatalf("error reading empty settings: %v", err)
- }
- if len(s.Configs) != 0 {
- t.Fatalf("expected empty settings; got %v", s)
- }
- s.Configs = append(s.Configs, namedConfig{
- Name: "Foo",
- config: config{
- Focus: "focus",
- // Ensure that transient fields are not saved/restored.
- Output: "output",
- SourcePath: "source",
- TrimPath: "trim",
- DivideBy: -2,
- },
- })
- if err := writeSettings(fname, s); err != nil {
- t.Fatal(err)
- }
- s2, err := readSettings(fname)
- if err != nil {
- t.Fatal(err)
- }
-
- // Change the transient fields to their expected values.
- s.Configs[0].resetTransient()
- if !reflect.DeepEqual(s, s2) {
- t.Fatalf("ReadSettings = %v; expected %v", s2, s)
- }
- }
-
- func TestParseConfig(t *testing.T) {
- // Use all the fields to check they are saved/restored from URL.
- cfg := config{
- Output: "",
- DropNegative: true,
- CallTree: true,
- RelativePercentages: true,
- Unit: "auto",
- CompactLabels: true,
- SourcePath: "",
- TrimPath: "",
- NodeCount: 10,
- NodeFraction: 0.1,
- EdgeFraction: 0.2,
- Trim: true,
- Focus: "focus",
- Ignore: "ignore",
- PruneFrom: "prune_from",
- Hide: "hide",
- Show: "show",
- ShowFrom: "show_from",
- TagFocus: "tagfocus",
- TagIgnore: "tagignore",
- TagShow: "tagshow",
- TagHide: "taghide",
- DivideBy: 1,
- Mean: true,
- Normalize: true,
- Sort: "cum",
- Granularity: "functions",
- NoInlines: true,
- }
- url, changed := cfg.makeURL(url.URL{})
- if !changed {
- t.Error("applyConfig returned changed=false after applying non-empty config")
- }
- cfg2 := defaultConfig()
- if err := cfg2.applyURL(url.Query()); err != nil {
- t.Fatalf("fromURL failed: %v", err)
- }
- if !reflect.DeepEqual(cfg, cfg2) {
- t.Fatalf("parsed config = %+v; expected match with %+v", cfg2, cfg)
- }
- if url2, changed := cfg.makeURL(url); changed {
- t.Errorf("ApplyConfig returned changed=true after applying same config (%q instead of expected %q", url2.String(), url.String())
- }
- }
-
- // TestDefaultConfig verifies that default config values are omitted from URL.
- func TestDefaultConfig(t *testing.T) {
- cfg := defaultConfig()
- url, changed := cfg.makeURL(url.URL{})
- if changed {
- t.Error("applyConfig returned changed=true after applying default config")
- }
- if url.String() != "" {
- t.Errorf("applyConfig returned %q; expecting %q", url.String(), "")
- }
- }
-
- func TestConfigMenu(t *testing.T) {
- // Save some test settings.
- tmpDir, fname := settingsDirAndFile(t)
- defer os.RemoveAll(tmpDir)
- a, b := defaultConfig(), defaultConfig()
- a.Focus, b.Focus = "foo", "bar"
- s := &settings{
- Configs: []namedConfig{
- {Name: "A", config: a},
- {Name: "B", config: b},
- },
- }
- if err := writeSettings(fname, s); err != nil {
- t.Fatal("error writing settings", err)
- }
-
- pageURL, _ := url.Parse("/top?f=foo")
- menu := configMenu(fname, *pageURL)
- want := []configMenuEntry{
- {Name: "Default", URL: "/top", Current: false, UserConfig: false},
- {Name: "A", URL: "/top?f=foo", Current: true, UserConfig: true},
- {Name: "B", URL: "/top?f=bar", Current: false, UserConfig: true},
- }
- if !reflect.DeepEqual(menu, want) {
- t.Errorf("ConfigMenu returned %v; want %v", menu, want)
- }
- }
-
- func TestEditConfig(t *testing.T) {
- tmpDir, fname := settingsDirAndFile(t)
- defer os.RemoveAll(tmpDir)
-
- type testConfig struct {
- name string
- focus string
- hide string
- }
- type testCase struct {
- remove bool
- request string
- expect []testConfig
- }
- for _, c := range []testCase{
- // Create setting c1
- {false, "/?config=c1&f=foo", []testConfig{
- {"c1", "foo", ""},
- }},
- // Create setting c2
- {false, "/?config=c2&h=bar", []testConfig{
- {"c1", "foo", ""},
- {"c2", "", "bar"},
- }},
- // Overwrite c1
- {false, "/?config=c1&f=baz", []testConfig{
- {"c1", "baz", ""},
- {"c2", "", "bar"},
- }},
- // Delete c2
- {true, "c2", []testConfig{
- {"c1", "baz", ""},
- }},
- } {
- if c.remove {
- if err := removeConfig(fname, c.request); err != nil {
- t.Errorf("error removing config %s: %v", c.request, err)
- continue
- }
- } else {
- req, err := url.Parse(c.request)
- if err != nil {
- t.Errorf("error parsing request %q: %v", c.request, err)
- continue
- }
- if err := setConfig(fname, *req); err != nil {
- t.Errorf("error saving request %q: %v", c.request, err)
- continue
- }
- }
-
- // Check resulting settings.
- s, err := readSettings(fname)
- if err != nil {
- t.Errorf("error reading settings after applying %q: %v", c.request, err)
- continue
- }
- // Convert to a list that can be compared to c.expect
- got := make([]testConfig, len(s.Configs))
- for i, c := range s.Configs {
- got[i] = testConfig{c.Name, c.Focus, c.Hide}
- }
- if !reflect.DeepEqual(got, c.expect) {
- t.Errorf("Settings after applying %q = %v; want %v", c.request, got, c.expect)
- }
- }
- }
-
- func TestAssign(t *testing.T) {
- baseConfig := currentConfig()
- defer setCurrentConfig(baseConfig)
-
- // Test assigning to a simple field.
- if err := configure("nodecount", "20"); err != nil {
- t.Errorf("error setting nodecount: %v", err)
- }
- if n := currentConfig().NodeCount; n != 20 {
- t.Errorf("incorrect nodecount; expecting 20, got %d", n)
- }
-
- // Test assignment to a group field.
- if err := configure("granularity", "files"); err != nil {
- t.Errorf("error setting granularity: %v", err)
- }
- if g := currentConfig().Granularity; g != "files" {
- t.Errorf("incorrect granularity; expecting %v, got %v", "files", g)
- }
-
- // Test assignment to one choice of a group field.
- if err := configure("lines", "t"); err != nil {
- t.Errorf("error setting lines: %v", err)
- }
- if g := currentConfig().Granularity; g != "lines" {
- t.Errorf("incorrect granularity; expecting %v, got %v", "lines", g)
- }
-
- // Test assignment to invalid choice,
- if err := configure("granularity", "cheese"); err == nil {
- t.Errorf("allowed assignment of invalid granularity")
- }
- }
|