|
@@ -96,114 +96,118 @@ func TestParse(t *testing.T) {
|
96
|
96
|
baseVars := pprofVariables
|
97
|
97
|
defer func() { pprofVariables = baseVars }()
|
98
|
98
|
for _, tc := range testcase {
|
99
|
|
- // Reset the pprof variables before processing
|
100
|
|
- pprofVariables = baseVars.makeCopy()
|
|
99
|
+ t.Run(tc.flags+":"+tc.source, func(t *testing.T) {
|
|
100
|
+ // Reset the pprof variables before processing
|
|
101
|
+ pprofVariables = baseVars.makeCopy()
|
101
|
102
|
|
102
|
|
- f := baseFlags()
|
103
|
|
- f.args = []string{tc.source}
|
|
103
|
+ testUI := &proftest.TestUI{T: t, AllowRx: "Generating report in|Ignoring local file|expression matched no samples|Interpreted .* as range, not regexp"}
|
104
|
104
|
|
105
|
|
- flags := strings.Split(tc.flags, ",")
|
|
105
|
+ f := baseFlags()
|
|
106
|
+ f.args = []string{tc.source}
|
106
|
107
|
|
107
|
|
- // Skip the output format in the first flag, to output to a proto
|
108
|
|
- addFlags(&f, flags[1:])
|
|
108
|
+ flags := strings.Split(tc.flags, ",")
|
109
|
109
|
|
110
|
|
- // Encode profile into a protobuf and decode it again.
|
111
|
|
- protoTempFile, err := ioutil.TempFile("", "profile_proto")
|
112
|
|
- if err != nil {
|
113
|
|
- t.Errorf("cannot create tempfile: %v", err)
|
114
|
|
- }
|
115
|
|
- defer os.Remove(protoTempFile.Name())
|
116
|
|
- defer protoTempFile.Close()
|
117
|
|
- f.strings["output"] = protoTempFile.Name()
|
118
|
|
-
|
119
|
|
- if flags[0] == "topproto" {
|
120
|
|
- f.bools["proto"] = false
|
121
|
|
- f.bools["topproto"] = true
|
122
|
|
- }
|
|
110
|
+ // Skip the output format in the first flag, to output to a proto
|
|
111
|
+ addFlags(&f, flags[1:])
|
123
|
112
|
|
124
|
|
- // First pprof invocation to save the profile into a profile.proto.
|
125
|
|
- o1 := setDefaults(nil)
|
126
|
|
- o1.Flagset = f
|
127
|
|
- o1.Fetch = testFetcher{}
|
128
|
|
- o1.Sym = testSymbolizer{}
|
129
|
|
- if err := PProf(o1); err != nil {
|
130
|
|
- t.Errorf("%s %q: %v", tc.source, tc.flags, err)
|
131
|
|
- continue
|
132
|
|
- }
|
133
|
|
- // Reset the pprof variables after the proto invocation
|
134
|
|
- pprofVariables = baseVars.makeCopy()
|
|
113
|
+ // Encode profile into a protobuf and decode it again.
|
|
114
|
+ protoTempFile, err := ioutil.TempFile("", "profile_proto")
|
|
115
|
+ if err != nil {
|
|
116
|
+ t.Errorf("cannot create tempfile: %v", err)
|
|
117
|
+ }
|
|
118
|
+ defer os.Remove(protoTempFile.Name())
|
|
119
|
+ defer protoTempFile.Close()
|
|
120
|
+ f.strings["output"] = protoTempFile.Name()
|
135
|
121
|
|
136
|
|
- // Read the profile from the encoded protobuf
|
137
|
|
- outputTempFile, err := ioutil.TempFile("", "profile_output")
|
138
|
|
- if err != nil {
|
139
|
|
- t.Errorf("cannot create tempfile: %v", err)
|
140
|
|
- }
|
141
|
|
- defer os.Remove(outputTempFile.Name())
|
142
|
|
- defer outputTempFile.Close()
|
143
|
|
- f.strings["output"] = outputTempFile.Name()
|
144
|
|
- f.args = []string{protoTempFile.Name()}
|
145
|
|
-
|
146
|
|
- var solution string
|
147
|
|
- // Apply the flags for the second pprof run, and identify name of
|
148
|
|
- // the file containing expected results
|
149
|
|
- if flags[0] == "topproto" {
|
150
|
|
- solution = solutionFilename(tc.source, &f)
|
151
|
|
- delete(f.bools, "topproto")
|
152
|
|
- f.bools["text"] = true
|
153
|
|
- } else {
|
154
|
|
- delete(f.bools, "proto")
|
155
|
|
- addFlags(&f, flags[:1])
|
156
|
|
- solution = solutionFilename(tc.source, &f)
|
157
|
|
- }
|
158
|
|
- // The add_comment flag is not idempotent so only apply it on the first run.
|
159
|
|
- delete(f.strings, "add_comment")
|
160
|
|
-
|
161
|
|
- // Second pprof invocation to read the profile from profile.proto
|
162
|
|
- // and generate a report.
|
163
|
|
- o2 := setDefaults(nil)
|
164
|
|
- o2.Flagset = f
|
165
|
|
- o2.Sym = testSymbolizeDemangler{}
|
166
|
|
- o2.Obj = new(mockObjTool)
|
167
|
|
-
|
168
|
|
- if err := PProf(o2); err != nil {
|
169
|
|
- t.Errorf("%s: %v", tc.source, err)
|
170
|
|
- }
|
171
|
|
- b, err := ioutil.ReadFile(outputTempFile.Name())
|
172
|
|
- if err != nil {
|
173
|
|
- t.Errorf("Failed to read profile %s: %v", outputTempFile.Name(), err)
|
174
|
|
- }
|
|
122
|
+ if flags[0] == "topproto" {
|
|
123
|
+ f.bools["proto"] = false
|
|
124
|
+ f.bools["topproto"] = true
|
|
125
|
+ }
|
175
|
126
|
|
176
|
|
- // Read data file with expected solution
|
177
|
|
- solution = "testdata/" + solution
|
178
|
|
- sbuf, err := ioutil.ReadFile(solution)
|
179
|
|
- if err != nil {
|
180
|
|
- t.Errorf("reading solution file %s: %v", solution, err)
|
181
|
|
- continue
|
182
|
|
- }
|
183
|
|
- if runtime.GOOS == "windows" {
|
184
|
|
- sbuf = bytes.Replace(sbuf, []byte("testdata/"), []byte("testdata\\"), -1)
|
185
|
|
- sbuf = bytes.Replace(sbuf, []byte("/path/to/"), []byte("\\path\\to\\"), -1)
|
186
|
|
- }
|
|
127
|
+ // First pprof invocation to save the profile into a profile.proto.
|
|
128
|
+ o1 := setDefaults(nil)
|
|
129
|
+ o1.Flagset = f
|
|
130
|
+ o1.Fetch = testFetcher{}
|
|
131
|
+ o1.Sym = testSymbolizer{}
|
|
132
|
+ o1.UI = testUI
|
|
133
|
+ if err := PProf(o1); err != nil {
|
|
134
|
+ t.Fatalf("%s %q: %v", tc.source, tc.flags, err)
|
|
135
|
+ }
|
|
136
|
+ // Reset the pprof variables after the proto invocation
|
|
137
|
+ pprofVariables = baseVars.makeCopy()
|
187
|
138
|
|
188
|
|
- if flags[0] == "svg" {
|
189
|
|
- b = removeScripts(b)
|
190
|
|
- sbuf = removeScripts(sbuf)
|
191
|
|
- }
|
|
139
|
+ // Read the profile from the encoded protobuf
|
|
140
|
+ outputTempFile, err := ioutil.TempFile("", "profile_output")
|
|
141
|
+ if err != nil {
|
|
142
|
+ t.Errorf("cannot create tempfile: %v", err)
|
|
143
|
+ }
|
|
144
|
+ defer os.Remove(outputTempFile.Name())
|
|
145
|
+ defer outputTempFile.Close()
|
|
146
|
+ f.strings["output"] = outputTempFile.Name()
|
|
147
|
+ f.args = []string{protoTempFile.Name()}
|
|
148
|
+
|
|
149
|
+ var solution string
|
|
150
|
+ // Apply the flags for the second pprof run, and identify name of
|
|
151
|
+ // the file containing expected results
|
|
152
|
+ if flags[0] == "topproto" {
|
|
153
|
+ solution = solutionFilename(tc.source, &f)
|
|
154
|
+ delete(f.bools, "topproto")
|
|
155
|
+ f.bools["text"] = true
|
|
156
|
+ } else {
|
|
157
|
+ delete(f.bools, "proto")
|
|
158
|
+ addFlags(&f, flags[:1])
|
|
159
|
+ solution = solutionFilename(tc.source, &f)
|
|
160
|
+ }
|
|
161
|
+ // The add_comment flag is not idempotent so only apply it on the first run.
|
|
162
|
+ delete(f.strings, "add_comment")
|
|
163
|
+
|
|
164
|
+ // Second pprof invocation to read the profile from profile.proto
|
|
165
|
+ // and generate a report.
|
|
166
|
+ o2 := setDefaults(nil)
|
|
167
|
+ o2.Flagset = f
|
|
168
|
+ o2.Sym = testSymbolizeDemangler{}
|
|
169
|
+ o2.Obj = new(mockObjTool)
|
|
170
|
+ o2.UI = testUI
|
|
171
|
+
|
|
172
|
+ if err := PProf(o2); err != nil {
|
|
173
|
+ t.Errorf("%s: %v", tc.source, err)
|
|
174
|
+ }
|
|
175
|
+ b, err := ioutil.ReadFile(outputTempFile.Name())
|
|
176
|
+ if err != nil {
|
|
177
|
+ t.Errorf("Failed to read profile %s: %v", outputTempFile.Name(), err)
|
|
178
|
+ }
|
192
|
179
|
|
193
|
|
- if string(b) != string(sbuf) {
|
194
|
|
- t.Errorf("diff %s %s", solution, tc.source)
|
195
|
|
- d, err := proftest.Diff(sbuf, b)
|
|
180
|
+ // Read data file with expected solution
|
|
181
|
+ solution = "testdata/" + solution
|
|
182
|
+ sbuf, err := ioutil.ReadFile(solution)
|
196
|
183
|
if err != nil {
|
197
|
|
- t.Fatalf("diff %s %v", solution, err)
|
|
184
|
+ t.Fatalf("reading solution file %s: %v", solution, err)
|
198
|
185
|
}
|
199
|
|
- t.Errorf("%s\n%s\n", solution, d)
|
200
|
|
- if *updateFlag {
|
201
|
|
- err := ioutil.WriteFile(solution, b, 0644)
|
|
186
|
+ if runtime.GOOS == "windows" {
|
|
187
|
+ sbuf = bytes.Replace(sbuf, []byte("testdata/"), []byte("testdata\\"), -1)
|
|
188
|
+ sbuf = bytes.Replace(sbuf, []byte("/path/to/"), []byte("\\path\\to\\"), -1)
|
|
189
|
+ }
|
|
190
|
+
|
|
191
|
+ if flags[0] == "svg" {
|
|
192
|
+ b = removeScripts(b)
|
|
193
|
+ sbuf = removeScripts(sbuf)
|
|
194
|
+ }
|
|
195
|
+
|
|
196
|
+ if string(b) != string(sbuf) {
|
|
197
|
+ t.Errorf("diff %s %s", solution, tc.source)
|
|
198
|
+ d, err := proftest.Diff(sbuf, b)
|
202
|
199
|
if err != nil {
|
203
|
|
- t.Errorf("failed to update the solution file %q: %v", solution, err)
|
|
200
|
+ t.Fatalf("diff %s %v", solution, err)
|
|
201
|
+ }
|
|
202
|
+ t.Errorf("%s\n%s\n", solution, d)
|
|
203
|
+ if *updateFlag {
|
|
204
|
+ err := ioutil.WriteFile(solution, b, 0644)
|
|
205
|
+ if err != nil {
|
|
206
|
+ t.Errorf("failed to update the solution file %q: %v", solution, err)
|
|
207
|
+ }
|
204
|
208
|
}
|
205
|
209
|
}
|
206
|
|
- }
|
|
210
|
+ })
|
207
|
211
|
}
|
208
|
212
|
}
|
209
|
213
|
|