1 package driver
2
3 import (
4 "net/url"
5 "os"
6 "path/filepath"
7 "reflect"
8 "testing"
9 )
10
11
12
13
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
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
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
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
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
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
163 {false, "/?config=c1&f=foo", []testConfig{
164 {"c1", "foo", ""},
165 }},
166
167 {false, "/?config=c2&h=bar", []testConfig{
168 {"c1", "foo", ""},
169 {"c2", "", "bar"},
170 }},
171
172 {false, "/?config=c1&f=baz", []testConfig{
173 {"c1", "baz", ""},
174 {"c2", "", "bar"},
175 }},
176
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
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
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
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
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
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
244 if err := configure("granularity", "cheese"); err == nil {
245 t.Errorf("allowed assignment of invalid granularity")
246 }
247 }
248
View as plain text