소스 검색

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

Add tests for CheckValid, fix a couple crashers.
Alexey Alexandrov 7 년 전
부모
커밋
4f5906cc8a
No account linked to committer's email address
2개의 변경된 파일70개의 추가작업 그리고 2개의 파일을 삭제
  1. 13
    1
      profile/profile.go
  2. 57
    1
      profile/profile_test.go

+ 13
- 1
profile/profile.go 파일 보기

@@ -337,8 +337,11 @@ func (p *Profile) CheckValid() error {
337 337
 		return fmt.Errorf("missing sample type information")
338 338
 	}
339 339
 	for _, s := range p.Sample {
340
+		if s == nil {
341
+			return fmt.Errorf("profile has nil sample")
342
+		}
340 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 346
 		for _, l := range s.Location {
344 347
 			if l == nil {
@@ -351,6 +354,9 @@ func (p *Profile) CheckValid() error {
351 354
 	// Check that there are no duplicate ids
352 355
 	mappings := make(map[uint64]*Mapping, len(p.Mapping))
353 356
 	for _, m := range p.Mapping {
357
+		if m == nil {
358
+			return fmt.Errorf("profile has nil mapping")
359
+		}
354 360
 		if m.ID == 0 {
355 361
 			return fmt.Errorf("found mapping with reserved ID=0")
356 362
 		}
@@ -361,6 +367,9 @@ func (p *Profile) CheckValid() error {
361 367
 	}
362 368
 	functions := make(map[uint64]*Function, len(p.Function))
363 369
 	for _, f := range p.Function {
370
+		if f == nil {
371
+			return fmt.Errorf("profile has nil function")
372
+		}
364 373
 		if f.ID == 0 {
365 374
 			return fmt.Errorf("found function with reserved ID=0")
366 375
 		}
@@ -371,6 +380,9 @@ func (p *Profile) CheckValid() error {
371 380
 	}
372 381
 	locations := make(map[uint64]*Location, len(p.Location))
373 382
 	for _, l := range p.Location {
383
+		if l == nil {
384
+			return fmt.Errorf("profile has nil location")
385
+		}
374 386
 		if l.ID == 0 {
375 387
 			return fmt.Errorf("found location with reserved id=0")
376 388
 		}

+ 57
- 1
profile/profile_test.go 파일 보기

@@ -93,7 +93,6 @@ func TestParse(t *testing.T) {
93 93
 }
94 94
 
95 95
 func TestParseError(t *testing.T) {
96
-
97 96
 	testcases := []string{
98 97
 		"",
99 98
 		"garbage text",
@@ -109,6 +108,63 @@ func TestParseError(t *testing.T) {
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 168
 // leaveTempfile leaves |b| in a temporary file on disk and returns the
113 169
 // temp filename. This is useful to recover a profile when the test
114 170
 // fails.