...

Source file src/github.com/google/pprof/internal/driver/settings_test.go

Documentation: github.com/google/pprof/internal/driver

     1  package driver
     2  
     3  import (
     4  	"net/url"
     5  	"os"
     6  	"path/filepath"
     7  	"reflect"
     8  	"testing"
     9  )
    10  
    11  // settingsDirAndFile returns a directory in which settings should be stored
    12  // and the name of the settings file. The caller must delete the directory when
    13  // done.
    14  func settingsDirAndFile(t *testing.T) (string, string) {
    15  	tmpDir, err := os.MkdirTemp("", "pprof_settings_test")
    16  	if err != nil {
    17  		t.Fatalf("error creating temporary directory: %v", err)
    18  	}
    19  	return tmpDir, filepath.Join(tmpDir, "settings.json")
    20  }
    21  
    22  func TestSettings(t *testing.T) {
    23  	tmpDir, fname := settingsDirAndFile(t)
    24  	defer os.RemoveAll(tmpDir)
    25  	s, err := readSettings(fname)
    26  	if err != nil {
    27  		t.Fatalf("error reading empty settings: %v", err)
    28  	}
    29  	if len(s.Configs) != 0 {
    30  		t.Fatalf("expected empty settings; got %v", s)
    31  	}
    32  	s.Configs = append(s.Configs, namedConfig{
    33  		Name: "Foo",
    34  		config: config{
    35  			Focus: "focus",
    36  			// Ensure that transient fields are not saved/restored.
    37  			Output:     "output",
    38  			SourcePath: "source",
    39  			TrimPath:   "trim",
    40  			DivideBy:   -2,
    41  		},
    42  	})
    43  	if err := writeSettings(fname, s); err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	s2, err := readSettings(fname)
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	// Change the transient fields to their expected values.
    52  	s.Configs[0].resetTransient()
    53  	if !reflect.DeepEqual(s, s2) {
    54  		t.Fatalf("ReadSettings = %v; expected %v", s2, s)
    55  	}
    56  }
    57  
    58  func TestParseConfig(t *testing.T) {
    59  	// Use all the fields to check they are saved/restored from URL.
    60  	cfg := config{
    61  		Output:              "",
    62  		DropNegative:        true,
    63  		CallTree:            true,
    64  		RelativePercentages: true,
    65  		Unit:                "auto",
    66  		CompactLabels:       true,
    67  		SourcePath:          "",
    68  		TrimPath:            "",
    69  		NodeCount:           10,
    70  		NodeFraction:        0.1,
    71  		EdgeFraction:        0.2,
    72  		Trim:                true,
    73  		Focus:               "focus",
    74  		Ignore:              "ignore",
    75  		PruneFrom:           "prune_from",
    76  		Hide:                "hide",
    77  		Show:                "show",
    78  		ShowFrom:            "show_from",
    79  		TagFocus:            "tagfocus",
    80  		TagIgnore:           "tagignore",
    81  		TagShow:             "tagshow",
    82  		TagHide:             "taghide",
    83  		DivideBy:            1,
    84  		Mean:                true,
    85  		Normalize:           true,
    86  		Sort:                "cum",
    87  		Granularity:         "functions",
    88  		NoInlines:           true,
    89  		ShowColumns:         true,
    90  	}
    91  	url, changed := cfg.makeURL(url.URL{})
    92  	if !changed {
    93  		t.Error("applyConfig returned changed=false after applying non-empty config")
    94  	}
    95  	cfg2 := defaultConfig()
    96  	if err := cfg2.applyURL(url.Query()); err != nil {
    97  		t.Fatalf("fromURL failed: %v", err)
    98  	}
    99  	if !reflect.DeepEqual(cfg, cfg2) {
   100  		t.Fatalf("parsed config = %+v; expected match with %+v", cfg2, cfg)
   101  	}
   102  	if url2, changed := cfg.makeURL(url); changed {
   103  		t.Errorf("ApplyConfig returned changed=true after applying same config (%q instead of expected %q", url2.String(), url.String())
   104  	}
   105  }
   106  
   107  // TestDefaultConfig verifies that default config values are omitted from URL.
   108  func TestDefaultConfig(t *testing.T) {
   109  	cfg := defaultConfig()
   110  	url, changed := cfg.makeURL(url.URL{})
   111  	if changed {
   112  		t.Error("applyConfig returned changed=true after applying default config")
   113  	}
   114  	if url.String() != "" {
   115  		t.Errorf("applyConfig returned %q; expecting %q", url.String(), "")
   116  	}
   117  }
   118  
   119  func TestConfigMenu(t *testing.T) {
   120  	// Save some test settings.
   121  	tmpDir, fname := settingsDirAndFile(t)
   122  	defer os.RemoveAll(tmpDir)
   123  	a, b := defaultConfig(), defaultConfig()
   124  	a.Focus, b.Focus = "foo", "bar"
   125  	s := &settings{
   126  		Configs: []namedConfig{
   127  			{Name: "A", config: a},
   128  			{Name: "B", config: b},
   129  		},
   130  	}
   131  	if err := writeSettings(fname, s); err != nil {
   132  		t.Fatal("error writing settings", err)
   133  	}
   134  
   135  	pageURL, _ := url.Parse("/top?f=foo")
   136  	menu := configMenu(fname, *pageURL)
   137  	want := []configMenuEntry{
   138  		{Name: "Default", URL: "?", Current: false, UserConfig: false},
   139  		{Name: "A", URL: "?f=foo", Current: true, UserConfig: true},
   140  		{Name: "B", URL: "?f=bar", Current: false, UserConfig: true},
   141  	}
   142  	if !reflect.DeepEqual(menu, want) {
   143  		t.Errorf("ConfigMenu returned %v; want %v", menu, want)
   144  	}
   145  }
   146  
   147  func TestEditConfig(t *testing.T) {
   148  	tmpDir, fname := settingsDirAndFile(t)
   149  	defer os.RemoveAll(tmpDir)
   150  
   151  	type testConfig struct {
   152  		name  string
   153  		focus string
   154  		hide  string
   155  	}
   156  	type testCase struct {
   157  		remove  bool
   158  		request string
   159  		expect  []testConfig
   160  	}
   161  	for _, c := range []testCase{
   162  		// Create setting c1
   163  		{false, "/?config=c1&f=foo", []testConfig{
   164  			{"c1", "foo", ""},
   165  		}},
   166  		// Create setting c2
   167  		{false, "/?config=c2&h=bar", []testConfig{
   168  			{"c1", "foo", ""},
   169  			{"c2", "", "bar"},
   170  		}},
   171  		// Overwrite c1
   172  		{false, "/?config=c1&f=baz", []testConfig{
   173  			{"c1", "baz", ""},
   174  			{"c2", "", "bar"},
   175  		}},
   176  		// Delete c2
   177  		{true, "c2", []testConfig{
   178  			{"c1", "baz", ""},
   179  		}},
   180  	} {
   181  		if c.remove {
   182  			if err := removeConfig(fname, c.request); err != nil {
   183  				t.Errorf("error removing config %s: %v", c.request, err)
   184  				continue
   185  			}
   186  		} else {
   187  			req, err := url.Parse(c.request)
   188  			if err != nil {
   189  				t.Errorf("error parsing request %q: %v", c.request, err)
   190  				continue
   191  			}
   192  			if err := setConfig(fname, *req); err != nil {
   193  				t.Errorf("error saving request %q: %v", c.request, err)
   194  				continue
   195  			}
   196  		}
   197  
   198  		// Check resulting settings.
   199  		s, err := readSettings(fname)
   200  		if err != nil {
   201  			t.Errorf("error reading settings after applying %q: %v", c.request, err)
   202  			continue
   203  		}
   204  		// Convert to a list that can be compared to c.expect
   205  		got := make([]testConfig, len(s.Configs))
   206  		for i, c := range s.Configs {
   207  			got[i] = testConfig{c.Name, c.Focus, c.Hide}
   208  		}
   209  		if !reflect.DeepEqual(got, c.expect) {
   210  			t.Errorf("Settings after applying %q = %v; want %v", c.request, got, c.expect)
   211  		}
   212  	}
   213  }
   214  
   215  func TestAssign(t *testing.T) {
   216  	baseConfig := currentConfig()
   217  	defer setCurrentConfig(baseConfig)
   218  
   219  	// Test assigning to a simple field.
   220  	if err := configure("nodecount", "20"); err != nil {
   221  		t.Errorf("error setting nodecount: %v", err)
   222  	}
   223  	if n := currentConfig().NodeCount; n != 20 {
   224  		t.Errorf("incorrect nodecount; expecting 20, got %d", n)
   225  	}
   226  
   227  	// Test assignment to a group field.
   228  	if err := configure("granularity", "files"); err != nil {
   229  		t.Errorf("error setting granularity: %v", err)
   230  	}
   231  	if g := currentConfig().Granularity; g != "files" {
   232  		t.Errorf("incorrect granularity; expecting %v, got %v", "files", g)
   233  	}
   234  
   235  	// Test assignment to one choice of a group field.
   236  	if err := configure("lines", "t"); err != nil {
   237  		t.Errorf("error setting lines: %v", err)
   238  	}
   239  	if g := currentConfig().Granularity; g != "lines" {
   240  		t.Errorf("incorrect granularity; expecting %v, got %v", "lines", g)
   241  	}
   242  
   243  	// Test assignment to invalid choice,
   244  	if err := configure("granularity", "cheese"); err == nil {
   245  		t.Errorf("allowed assignment of invalid granularity")
   246  	}
   247  }
   248  

View as plain text