GoPLS Viewer

Home|gopls/cover/profile_test.go
1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package cover
6
7import (
8    "fmt"
9    "io/ioutil"
10    "os"
11    "reflect"
12    "testing"
13)
14
15func TestParseProfiles(t *testing.T) {
16    tests := []struct {
17        name      string
18        input     string
19        output    []*Profile
20        expectErr bool
21    }{
22        {
23            name:   "parsing an empty file produces empty output",
24            input:  `mode: set`,
25            output: []*Profile{},
26        },
27        {
28            name"simple valid file produces expected output",
29            input`mode: set
30some/fancy/path:42.69,44.16 2 1`,
31            output: []*Profile{
32                {
33                    FileName"some/fancy/path",
34                    Mode:     "set",
35                    Blocks: []ProfileBlock{
36                        {
37                            StartLine42StartCol69,
38                            EndLine44EndCol16,
39                            NumStmt2Count1,
40                        },
41                    },
42                },
43            },
44        },
45        {
46            name"file with syntax characters in path produces expected output",
47            input`mode: set
48some fancy:path/some,file.go:42.69,44.16 2 1`,
49            output: []*Profile{
50                {
51                    FileName"some fancy:path/some,file.go",
52                    Mode:     "set",
53                    Blocks: []ProfileBlock{
54                        {
55                            StartLine42StartCol69,
56                            EndLine44EndCol16,
57                            NumStmt2Count1,
58                        },
59                    },
60                },
61            },
62        },
63        {
64            name"file with multiple blocks in one file produces expected output",
65            input`mode: set
66some/fancy/path:42.69,44.16 2 1
67some/fancy/path:44.16,46.3 1 0`,
68            output: []*Profile{
69                {
70                    FileName"some/fancy/path",
71                    Mode:     "set",
72                    Blocks: []ProfileBlock{
73                        {
74                            StartLine42StartCol69,
75                            EndLine44EndCol16,
76                            NumStmt2Count1,
77                        },
78                        {
79                            StartLine44StartCol16,
80                            EndLine46EndCol3,
81                            NumStmt1Count0,
82                        },
83                    },
84                },
85            },
86        },
87        {
88            name"file with multiple files produces expected output",
89            input`mode: set
90another/fancy/path:44.16,46.3 1 0
91some/fancy/path:42.69,44.16 2 1`,
92            output: []*Profile{
93                {
94                    FileName"another/fancy/path",
95                    Mode:     "set",
96                    Blocks: []ProfileBlock{
97                        {
98                            StartLine44StartCol16,
99                            EndLine46EndCol3,
100                            NumStmt1Count0,
101                        },
102                    },
103                },
104                {
105                    FileName"some/fancy/path",
106                    Mode:     "set",
107                    Blocks: []ProfileBlock{
108                        {
109                            StartLine42StartCol69,
110                            EndLine44EndCol16,
111                            NumStmt2Count1,
112                        },
113                    },
114                },
115            },
116        },
117        {
118            name"intertwined files are merged correctly",
119            input`mode: set
120some/fancy/path:42.69,44.16 2 1
121another/fancy/path:47.2,47.13 1 1
122some/fancy/path:44.16,46.3 1 0`,
123            output: []*Profile{
124                {
125                    FileName"another/fancy/path",
126                    Mode:     "set",
127                    Blocks: []ProfileBlock{
128                        {
129                            StartLine47StartCol2,
130                            EndLine47EndCol13,
131                            NumStmt1Count1,
132                        },
133                    },
134                },
135                {
136                    FileName"some/fancy/path",
137                    Mode:     "set",
138                    Blocks: []ProfileBlock{
139                        {
140                            StartLine42StartCol69,
141                            EndLine44EndCol16,
142                            NumStmt2Count1,
143                        },
144                        {
145                            StartLine44StartCol16,
146                            EndLine46EndCol3,
147                            NumStmt1Count0,
148                        },
149                    },
150                },
151            },
152        },
153        {
154            name"duplicate blocks are merged correctly",
155            input`mode: count
156some/fancy/path:42.69,44.16 2 4
157some/fancy/path:42.69,44.16 2 3`,
158            output: []*Profile{
159                {
160                    FileName"some/fancy/path",
161                    Mode:     "count",
162                    Blocks: []ProfileBlock{
163                        {
164                            StartLine42StartCol69,
165                            EndLine44EndCol16,
166                            NumStmt2Count7,
167                        },
168                    },
169                },
170            },
171        },
172        {
173            name:      "an invalid mode line is an error",
174            input:     `mode:count`,
175            expectErrtrue,
176        },
177        {
178            name"a missing field is an error",
179            input`mode: count
180some/fancy/path:42.69,44.16 2`,
181            expectErrtrue,
182        },
183        {
184            name"a missing path field is an error",
185            input`mode: count
18642.69,44.16 2 3`,
187            expectErrtrue,
188        },
189        {
190            name"a non-numeric count is an error",
191            input`mode: count
19242.69,44.16 2 nope`,
193            expectErrtrue,
194        },
195        {
196            name"an empty path is an error",
197            input`mode: count
198:42.69,44.16 2 3`,
199            expectErrtrue,
200        },
201        {
202            name"a negative count is an error",
203            input`mode: count
204some/fancy/path:42.69,44.16 2 -1`,
205            expectErrtrue,
206        },
207    }
208
209    for _tc := range tests {
210        t.Run(tc.name, func(t *testing.T) {
211            ferr := ioutil.TempFile("""")
212            if err != nil {
213                t.Fatalf("Failed to create a temp file: %v."err)
214            }
215            defer func() {
216                f.Close()
217                os.Remove(f.Name())
218            }()
219            nerr := f.WriteString(tc.input)
220            if err != nil {
221                t.Fatalf("Failed to write to temp file: %v"err)
222            }
223            if n < len(tc.input) {
224                t.Fatalf("Didn't write enough bytes to temp file (wrote %d, expected %d)."nlen(tc.input))
225            }
226            if err := f.Sync(); err != nil {
227                t.Fatalf("Failed to sync temp file: %v"err)
228            }
229
230            resulterr := ParseProfiles(f.Name())
231            if err != nil {
232                if !tc.expectErr {
233                    t.Errorf("Unexpected error: %v"err)
234                }
235                return
236            }
237            if tc.expectErr {
238                t.Errorf("Expected an error, but got value %q"stringifyProfileArray(result))
239            }
240            if !reflect.DeepEqual(resulttc.output) {
241                t.Errorf("Mismatched results.\nExpected: %s\nActual:   %s"stringifyProfileArray(tc.output), stringifyProfileArray(result))
242            }
243        })
244    }
245}
246
247func stringifyProfileArray(profiles []*Profilestring {
248    deref := make([]Profile0len(profiles))
249    for _p := range profiles {
250        deref = append(deref, *p)
251    }
252    return fmt.Sprintf("%#v"deref)
253}
254
255func BenchmarkParseLine(b *testing.B) {
256    const line = "k8s.io/kubernetes/cmd/kube-controller-manager/app/options/ttlafterfinishedcontroller.go:31.73,32.14 1 1"
257    b.SetBytes(int64(len(line)))
258    for n := 0n < b.Nn++ {
259        parseLine(line)
260    }
261}
262
MembersX
TestParseProfiles.RangeStmt_4305.BlockStmt.BlockStmt.f
BenchmarkParseLine.line
reflect
TestParseProfiles.t
TestParseProfiles.tests
TestParseProfiles.RangeStmt_4305.tc
stringifyProfileArray.deref
stringifyProfileArray.RangeStmt_5436.p
testing
BenchmarkParseLine.b
ioutil
TestParseProfiles
TestParseProfiles.RangeStmt_4305.BlockStmt.BlockStmt.err
TestParseProfiles.RangeStmt_4305.BlockStmt.BlockStmt.n
TestParseProfiles.RangeStmt_4305.BlockStmt.BlockStmt.result
stringifyProfileArray
stringifyProfileArray.profiles
BenchmarkParseLine
BenchmarkParseLine.n
Members
X