Bladeren bron

Add tests for CheckValid, fix a couple crashers. (#248)

Add tests for CheckValid, fix a couple crashers.
Alexey Alexandrov 7 jaren geleden
bovenliggende
commit
4f5906cc8a
No account linked to committer's email address
2 gewijzigde bestanden met toevoegingen van 70 en 2 verwijderingen
  1. 13
    1
      profile/profile.go
  2. 57
    1
      profile/profile_test.go

+ 13
- 1
profile/profile.go Bestand weergeven

337
 		return fmt.Errorf("missing sample type information")
337
 		return fmt.Errorf("missing sample type information")
338
 	}
338
 	}
339
 	for _, s := range p.Sample {
339
 	for _, s := range p.Sample {
340
+		if s == nil {
341
+			return fmt.Errorf("profile has nil sample")
342
+		}
340
 		if len(s.Value) != sampleLen {
343
 		if len(s.Value) != sampleLen {
341
-			return fmt.Errorf("mismatch: sample has: %d values vs. %d types", len(s.Value), len(p.SampleType))
344
+			return fmt.Errorf("mismatch: sample has %d values vs. %d types", len(s.Value), len(p.SampleType))
342
 		}
345
 		}
343
 		for _, l := range s.Location {
346
 		for _, l := range s.Location {
344
 			if l == nil {
347
 			if l == nil {
351
 	// Check that there are no duplicate ids
354
 	// Check that there are no duplicate ids
352
 	mappings := make(map[uint64]*Mapping, len(p.Mapping))
355
 	mappings := make(map[uint64]*Mapping, len(p.Mapping))
353
 	for _, m := range p.Mapping {
356
 	for _, m := range p.Mapping {
357
+		if m == nil {
358
+			return fmt.Errorf("profile has nil mapping")
359
+		}
354
 		if m.ID == 0 {
360
 		if m.ID == 0 {
355
 			return fmt.Errorf("found mapping with reserved ID=0")
361
 			return fmt.Errorf("found mapping with reserved ID=0")
356
 		}
362
 		}
361
 	}
367
 	}
362
 	functions := make(map[uint64]*Function, len(p.Function))
368
 	functions := make(map[uint64]*Function, len(p.Function))
363
 	for _, f := range p.Function {
369
 	for _, f := range p.Function {
370
+		if f == nil {
371
+			return fmt.Errorf("profile has nil function")
372
+		}
364
 		if f.ID == 0 {
373
 		if f.ID == 0 {
365
 			return fmt.Errorf("found function with reserved ID=0")
374
 			return fmt.Errorf("found function with reserved ID=0")
366
 		}
375
 		}
371
 	}
380
 	}
372
 	locations := make(map[uint64]*Location, len(p.Location))
381
 	locations := make(map[uint64]*Location, len(p.Location))
373
 	for _, l := range p.Location {
382
 	for _, l := range p.Location {
383
+		if l == nil {
384
+			return fmt.Errorf("profile has nil location")
385
+		}
374
 		if l.ID == 0 {
386
 		if l.ID == 0 {
375
 			return fmt.Errorf("found location with reserved id=0")
387
 			return fmt.Errorf("found location with reserved id=0")
376
 		}
388
 		}

+ 57
- 1
profile/profile_test.go Bestand weergeven

93
 }
93
 }
94
 
94
 
95
 func TestParseError(t *testing.T) {
95
 func TestParseError(t *testing.T) {
96
-
97
 	testcases := []string{
96
 	testcases := []string{
98
 		"",
97
 		"",
99
 		"garbage text",
98
 		"garbage text",
109
 	}
108
 	}
110
 }
109
 }
111
 
110
 
111
+func TestCheckValid(t *testing.T) {
112
+	const path = "testdata/java.cpu"
113
+
114
+	inbytes, err := ioutil.ReadFile(path)
115
+	if err != nil {
116
+		t.Fatalf("failed to read profile file %q: %v", path, err)
117
+	}
118
+	p, err := Parse(bytes.NewBuffer(inbytes))
119
+	if err != nil {
120
+		t.Fatalf("failed to parse profile %q: %s", path, err)
121
+	}
122
+
123
+	for _, tc := range []struct {
124
+		mutateFn func(*Profile)
125
+		wantErr  string
126
+	}{
127
+		{
128
+			mutateFn: func(p *Profile) { p.SampleType = nil },
129
+			wantErr:  "missing sample type information",
130
+		},
131
+		{
132
+			mutateFn: func(p *Profile) { p.Sample[0] = nil },
133
+			wantErr:  "profile has nil sample",
134
+		},
135
+		{
136
+			mutateFn: func(p *Profile) { p.Sample[0].Value = append(p.Sample[0].Value, 0) },
137
+			wantErr:  "sample has 3 values vs. 2 types",
138
+		},
139
+		{
140
+			mutateFn: func(p *Profile) { p.Sample[0].Location[0] = nil },
141
+			wantErr:  "sample has nil location",
142
+		},
143
+		{
144
+			mutateFn: func(p *Profile) { p.Location[0] = nil },
145
+			wantErr:  "profile has nil location",
146
+		},
147
+		{
148
+			mutateFn: func(p *Profile) { p.Mapping = append(p.Mapping, nil) },
149
+			wantErr:  "profile has nil mapping",
150
+		},
151
+		{
152
+			mutateFn: func(p *Profile) { p.Function[0] = nil },
153
+			wantErr:  "profile has nil function",
154
+		},
155
+	} {
156
+		t.Run(tc.wantErr, func(t *testing.T) {
157
+			p := p.Copy()
158
+			tc.mutateFn(p)
159
+			if err := p.CheckValid(); err == nil {
160
+				t.Errorf("CheckValid(): got no error, want error %q", tc.wantErr)
161
+			} else if !strings.Contains(err.Error(), tc.wantErr) {
162
+				t.Errorf("CheckValid(): got error %v, want error %q", err, tc.wantErr)
163
+			}
164
+		})
165
+	}
166
+}
167
+
112
 // leaveTempfile leaves |b| in a temporary file on disk and returns the
168
 // leaveTempfile leaves |b| in a temporary file on disk and returns the
113
 // temp filename. This is useful to recover a profile when the test
169
 // temp filename. This is useful to recover a profile when the test
114
 // fails.
170
 // fails.