Пример #1
0
func convertProfiles(filenames ...string) error {
	var ps gocovutil.Packages
	for i := range filenames {
		converter := converter{
			packages: make(map[string]*gocov.Package),
		}
		profiles, err := cover.ParseProfiles(filenames[i])
		if err != nil {
			return err
		}
		for _, p := range profiles {
			if err := converter.convertProfile(p); err != nil {
				return err
			}
		}

		for _, pkg := range converter.packages {
			ps.AddPackage(pkg)
		}
	}
	bytes, err := marshalJson(ps)
	if err != nil {
		return err
	}
	fmt.Println(string(bytes))
	return nil
}
Пример #2
0
func instrumentAndTest() (rc int) {
	testFlags.Parse(os.Args[2:])
	packagePaths, gotestArgs, err := packagesAndTestargs()
	if err != nil {
		errorf("failed to process package list: %s\n", err)
		return 1
	}

	tempDir, err := ioutil.TempDir("", "gocov")
	if err != nil {
		errorf("failed to create temporary GOROOT: %s\n", err)
		return 1
	}
	if *testWorkFlag {
		fmt.Fprintf(os.Stderr, "WORK=%s\n", tempDir)
	} else {
		defer func() {
			err := os.RemoveAll(tempDir)
			if err != nil {
				fmt.Fprintf(os.Stderr,
					"warning: failed to delete temporary GOROOT (%s)\n", tempDir)
			}
		}()
	}

	goroot := runtime.GOROOT()
	for _, name := range [...]string{"src", "pkg"} {
		dir := filepath.Join(goroot, name)
		err = symlinkHierarchy(dir, filepath.Join(tempDir, name))
		if err != nil {
			errorf("failed to create $GOROOT/%s: %s\n", name, err)
			return 1
		}
	}

	// Copy gocov into the temporary GOROOT, since otherwise it'll
	// be eclipsed by the instrumented packages root. Use the default
	// build context here since gocov doesn't use custom build tags.
	if p, err := build.Import(gocovPackagePath, "", build.FindOnly); err == nil {
		err = symlinkHierarchy(p.Dir, filepath.Join(tempDir, "src", "pkg", gocovPackagePath))
		if err != nil {
			errorf("failed to symlink gocov: %s\n", err)
			return 1
		}
	} else {
		errorf("failed to locate gocov: %s\n", err)
		return 1
	}

	var excluded []string
	if len(*testExcludeFlag) > 0 {
		excluded = strings.Split(*testExcludeFlag, ",")
		sort.Strings(excluded)
	}

	cwd, err := os.Getwd()
	if err != nil {
		errorf("failed to determine current working directory: %s\n", err)
	}

	context := build.Default
	if *testTagsFlag != "" {
		context.BuildTags = strings.Fields(*testTagsFlag)
	}

	in := &instrumenter{
		goroot:       tempDir,
		context:      context,
		instrumented: make(map[string]*gocov.Package),
		excluded:     excluded,
		processed:    make(map[string]bool),
		workingdir:   cwd,
	}

	instrumentedPackagePaths := make([]string, len(packagePaths))
	for i, packagePath := range packagePaths {
		var absPackagePath string
		absPackagePath, err = in.abspkgpath(packagePath)
		if err != nil {
			errorf("failed to resolve package path(%s): %s\n", packagePath, err)
			return 1
		}
		packagePath = absPackagePath
		err = in.instrumentPackage(packagePath, true)
		if err != nil {
			errorf("failed to instrument package(%s): %s\n", packagePath, err)
			return 1
		}
		instrumentedPackagePaths[i] = instrumentedPackagePath(packagePath)
	}

	ninstrumented := 0
	for _, pkg := range in.instrumented {
		if pkg != nil {
			ninstrumented++
		}
	}
	if ninstrumented == 0 {
		errorf("error: no packages were instrumented\n")
		return 1
	}

	// Run "go test".
	const gocovOutPrefix = "gocov.out"
	env := os.Environ()
	env = putenv(env, "GOCOVOUT", filepath.Join(tempDir, gocovOutPrefix))
	env = putenv(env, "GOROOT", tempDir)

	args := []string{"test"}
	if verbose {
		args = append(args, "-v")
	}
	if verboseX {
		args = append(args, "-x")
	}
	if *testTagsFlag != "" {
		args = append(args, "-tags", *testTagsFlag)
	}
	if *testRunFlag != "" {
		args = append(args, "-run", *testRunFlag)
	}
	if *testTimeoutFlag != "" {
		args = append(args, "-timeout", *testTimeoutFlag)
	}
	args = append(args, "-parallel", fmt.Sprint(*testParallelFlag))
	args = append(args, instrumentedPackagePaths...)
	args = append(args, gotestArgs...)

	// First run with "-i" to avoid the warning
	// about out-of-date packages.
	testiargs := append([]string{args[0], "-i"}, args[1:]...)
	cmd := exec.Command("go", testiargs...)
	cmd.Env = env
	cmd.Stdout = os.Stderr
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		errorf("go test -i failed: %s\n", err)
		return 1
	} else {
		// Now run "go test" normally.
		cmd = exec.Command("go", args...)
		cmd.Env = env
		cmd.Stdout = os.Stderr
		cmd.Stderr = os.Stderr
		err = cmd.Run()
		if err != nil {
			errorf("go test failed: %s\n", err)
			return 1
		}
	}

	tempDirFile, err := os.Open(tempDir)
	if err != nil {
		errorf("failed to open output directory: %s\n", err)
		return 1
	}
	defer tempDirFile.Close()

	names, err := tempDirFile.Readdirnames(-1)
	if err != nil {
		errorf("failed to list output directory: %s\n", err)
		return 1
	}

	var allpackages gocovutil.Packages
	for _, name := range names {
		if !strings.HasPrefix(name, gocovOutPrefix) {
			continue
		}
		outfilePath := filepath.Join(tempDir, name)
		packages, err := parser.ParseTrace(outfilePath)
		if err != nil {
			errorf("failed to parse gocov output: %s\n", err)
			return 1
		}
		for _, p := range packages {
			allpackages.AddPackage(p)
		}
	}

	data, err := marshalJson(allpackages)
	if err != nil {
		errorf("failed to format as JSON: %s\n", err)
		return 1
	} else {
		fmt.Println(string(data))
	}
	return
}