Browse Source

Breaks profileProtoReader into multiple functions

Wade Simba Khadder 8 years ago
parent
commit
a27767de2f
1 changed files with 20 additions and 32 deletions
  1. 20
    32
      internal/driver/fetch.go

+ 20
- 32
internal/driver/fetch.go View File

358
 		}
358
 		}
359
 		f, err = fetchURL(sourceURL, timeout)
359
 		f, err = fetchURL(sourceURL, timeout)
360
 		src = sourceURL
360
 		src = sourceURL
361
+	} else if isPerf, isPerfErr := isPerfFile(source); isPerf {
362
+		// Since the if statement is a new scope, if isPerfErr is named
363
+		// err, it shadows the err in the return, and does not compile.
364
+		if isPerfErr != nil {
365
+			return nil, "", isPerfErr
366
+		}
367
+		f, err = convertPerfData(source, ui)
361
 	} else {
368
 	} else {
362
-		f, err = profileProtoReader(source, ui)
369
+		f, err = os.Open(source)
363
 	}
370
 	}
364
 	if err == nil {
371
 	if err == nil {
365
 		defer f.Close()
372
 		defer f.Close()
381
 	return resp.Body, nil
388
 	return resp.Body, nil
382
 }
389
 }
383
 
390
 
384
-// profileProtoReader takes a path, and using heuristics, will try to convert
385
-// the file to profile.proto format. It returns a ReadCloser to the
386
-// profile.proto data; however, if the file contents were unknown or conversion
387
-// failed, it may still not be a valid profile.proto.
388
-func profileProtoReader(path string, ui plugin.UI) (io.ReadCloser, error) {
391
+// isPerfFile checks if a file is in perf.data format.
392
+func isPerfFile(path string) (bool, error) {
389
 	sourceFile, openErr := os.Open(path)
393
 	sourceFile, openErr := os.Open(path)
390
 	if openErr != nil {
394
 	if openErr != nil {
391
-		return nil, openErr
395
+		return false, openErr
392
 	}
396
 	}
397
+	defer sourceFile.Close()
393
 
398
 
394
 	// If the file is the output of a perf record command, it should begin
399
 	// If the file is the output of a perf record command, it should begin
395
 	// with the string PERFILE2.
400
 	// with the string PERFILE2.
396
 	perfHeader := []byte("PERFILE2")
401
 	perfHeader := []byte("PERFILE2")
397
 	actualHeader := make([]byte, len(perfHeader))
402
 	actualHeader := make([]byte, len(perfHeader))
398
-	if _, readErr := sourceFile.Read(actualHeader); readErr == io.EOF {
399
-		_, seekErr := sourceFile.Seek(0, 0)
400
-		if seekErr != nil {
401
-			return nil, seekErr
402
-		}
403
-	} else if readErr != nil {
404
-		return nil, readErr
405
-	}
406
-	if bytes.Equal(actualHeader, perfHeader) {
407
-		sourceFile.Close()
408
-		profileFilePath, convertErr := convertPerfData(path, ui)
409
-		if convertErr != nil {
410
-			return nil, convertErr
411
-		}
412
-		profileFile, openErr := os.Open(profileFilePath)
413
-		if openErr != nil {
414
-			return nil, openErr
415
-		}
416
-		return profileFile, nil
403
+	if _, readErr := sourceFile.Read(actualHeader); readErr != nil {
404
+		return false, readErr
417
 	}
405
 	}
418
-	return sourceFile, nil
406
+	return bytes.Equal(actualHeader, perfHeader), nil
419
 }
407
 }
420
 
408
 
421
 // convertPerfData converts the file at path which should be in perf.data format
409
 // convertPerfData converts the file at path which should be in perf.data format
422
-// using the perf_to_profile tool and returns the path to a file containing the
410
+// using the perf_to_profile tool and returns the file containing the
423
 // profile.proto formatted data.
411
 // profile.proto formatted data.
424
-func convertPerfData(perfPath string, ui plugin.UI) (string, error) {
412
+func convertPerfData(perfPath string, ui plugin.UI) (*os.File, error) {
425
 	ui.Print(fmt.Sprintf(
413
 	ui.Print(fmt.Sprintf(
426
 		"Converting %s to a profile.proto... (May take a few minutes)",
414
 		"Converting %s to a profile.proto... (May take a few minutes)",
427
 		perfPath))
415
 		perfPath))
428
 	profilePath, err := newTempFilePath("/tmp", "pprof_", ".pb.gz")
416
 	profilePath, err := newTempFilePath("/tmp", "pprof_", ".pb.gz")
429
 	if err != nil {
417
 	if err != nil {
430
-		return "", err
418
+		return nil, err
431
 	}
419
 	}
432
 	cmd := exec.Command("perf_to_profile", perfPath, profilePath)
420
 	cmd := exec.Command("perf_to_profile", perfPath, profilePath)
433
 	// If perf_to_profile failed before generating the file, this defer
421
 	// If perf_to_profile failed before generating the file, this defer
434
 	// is just a no-op.
422
 	// is just a no-op.
435
 	deferDeleteTempFile(profilePath)
423
 	deferDeleteTempFile(profilePath)
436
 	if err := cmd.Run(); err != nil {
424
 	if err := cmd.Run(); err != nil {
437
-		return "", err
425
+		return nil, err
438
 	}
426
 	}
439
-	return profilePath, nil
427
+	return os.Open(profilePath)
440
 }
428
 }
441
 
429
 
442
 // adjustURL validates if a profile source is a URL and returns an
430
 // adjustURL validates if a profile source is a URL and returns an