[cli] Support gathering code coverage data.
Add support for gathering code coverage data from a special build of the Pulumi CLI. This build takes advantage of `go test` and `TestMain` to build a coverage-instrumented binary.
This commit is contained in:
parent
b14bc09b1c
commit
6ffea35ddc
21
Makefile
21
Makefile
|
@ -31,18 +31,33 @@ generate::
|
|||
$(call STEP_MESSAGE)
|
||||
echo "This command does not do anything anymore. It will be removed in a future version."
|
||||
|
||||
ifeq ($(PULUMI_TEST_COVERAGE_PATH),)
|
||||
build::
|
||||
cd pkg && go install -ldflags "-X github.com/pulumi/pulumi/pkg/v3/version.Version=${VERSION}" ${PROJECT}
|
||||
|
||||
install::
|
||||
cd pkg && GOBIN=$(PULUMI_BIN) go install -ldflags "-X github.com/pulumi/pulumi/pkg/v3/version.Version=${VERSION}" ${PROJECT}
|
||||
else
|
||||
build:: build_cover
|
||||
|
||||
install:: install_cover
|
||||
endif
|
||||
|
||||
build_debug::
|
||||
cd pkg && go install -gcflags="all=-N -l" -ldflags "-X github.com/pulumi/pulumi/pkg/v3/version.Version=${VERSION}" ${PROJECT}
|
||||
|
||||
build_cover::
|
||||
cd pkg && go test -coverpkg github.com/pulumi/pulumi/pkg/v3/...,github.com/pulumi/pulumi/sdk/v3/... -cover -c -o $(shell go env GOPATH)/bin/pulumi -ldflags "-X github.com/pulumi/pulumi/pkg/v3/version.Version=${VERSION}" ${PROJECT}
|
||||
|
||||
install_cover:: build_cover
|
||||
cp $(shell go env GOPATH)/bin/pulumi $(PULUMI_BIN)
|
||||
|
||||
build_covmerge::
|
||||
cd pkg && go install ./cmd/covmerge
|
||||
|
||||
developer_docs::
|
||||
cd developer-docs && make html
|
||||
|
||||
install::
|
||||
cd pkg && GOBIN=$(PULUMI_BIN) go install -ldflags "-X github.com/pulumi/pulumi/pkg/v3/version.Version=${VERSION}" ${PROJECT}
|
||||
|
||||
install_all:: install
|
||||
|
||||
dist:: build
|
||||
|
|
81
pkg/cmd/pulumi/main_test.go
Normal file
81
pkg/cmd/pulumi/main_test.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type noTestDeps int
|
||||
|
||||
func (noTestDeps) ImportPath() string { return "" }
|
||||
func (noTestDeps) MatchString(pat, str string) (bool, error) { return false, nil }
|
||||
func (noTestDeps) SetPanicOnExit0(bool) {}
|
||||
func (noTestDeps) StartCPUProfile(io.Writer) error { return nil }
|
||||
func (noTestDeps) StopCPUProfile() {}
|
||||
func (noTestDeps) StartTestLog(io.Writer) {}
|
||||
func (noTestDeps) StopTestLog() error { return nil }
|
||||
func (noTestDeps) WriteProfileTo(string, io.Writer, int) error { return nil }
|
||||
|
||||
// flushProfiles flushes test profiles to disk.
|
||||
func flushProfiles() {
|
||||
// Redirect Stdout/err temporarily so the testing code doesn't output the
|
||||
// regular:
|
||||
// PASS
|
||||
// coverage: 21.4% of statements
|
||||
oldstdout, oldstderr := os.Stdout, os.Stderr
|
||||
defer func() {
|
||||
os.Stdout, os.Stderr = oldstdout, oldstderr
|
||||
}()
|
||||
os.Stdout, _ = os.Open(os.DevNull)
|
||||
os.Stderr, _ = os.Open(os.DevNull)
|
||||
|
||||
cmdLine := flag.CommandLine
|
||||
defer func() { flag.CommandLine = cmdLine }()
|
||||
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
|
||||
err := flag.CommandLine.Parse(nil)
|
||||
contract.IgnoreError(err)
|
||||
|
||||
m := testing.MainStart(noTestDeps(0), nil, nil, nil)
|
||||
m.Run()
|
||||
}
|
||||
|
||||
func addGoFlag(pf *pflag.FlagSet, f *flag.Flag) {
|
||||
if pf.Lookup(f.Name) != nil || len(f.Name) == 1 && pf.ShorthandLookup(f.Name) != nil {
|
||||
return
|
||||
}
|
||||
pf.AddGoFlag(f)
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// If the binary is invoked as `pulumi`, we are being asked to run the coverage-instrumented program. Otherwise,
|
||||
// we are running tests as usual.
|
||||
if path.Base(os.Args[0]) != "pulumi" {
|
||||
flag.Parse()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
defer panicHandler()
|
||||
|
||||
// Copy the test flags into the Pulumi command's flags.
|
||||
cmd := NewPulumiCmd()
|
||||
flag.CommandLine.VisitAll(func(f *flag.Flag) {
|
||||
addGoFlag(cmd.PersistentFlags(), f)
|
||||
})
|
||||
|
||||
// Now, execute the Pulumi command and dump coverage data if requested.
|
||||
err := cmd.Execute()
|
||||
flushProfiles()
|
||||
|
||||
if err != nil {
|
||||
_, err = fmt.Fprintf(os.Stderr, "An error occurred: %v\n", err)
|
||||
contract.IgnoreError(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -63,6 +63,13 @@ func Flush() {
|
|||
glog.Flush()
|
||||
}
|
||||
|
||||
func maybeSetFlag(name, value string) {
|
||||
if f := flag.Lookup(name); f != nil {
|
||||
err := f.Value.Set(value)
|
||||
assertNoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// InitLogging ensures the logging library has been initialized with the given settings.
|
||||
func InitLogging(logToStderr bool, verbose int, logFlow bool) {
|
||||
// Remember the settings in case someone inquires.
|
||||
|
@ -78,12 +85,10 @@ func InitLogging(logToStderr bool, verbose int, logFlow bool) {
|
|||
assertNoError(err)
|
||||
}
|
||||
if logToStderr {
|
||||
err := flag.Lookup("logtostderr").Value.Set("true")
|
||||
assertNoError(err)
|
||||
maybeSetFlag("logtostderr", "true")
|
||||
}
|
||||
if verbose > 0 {
|
||||
err := flag.Lookup("v").Value.Set(strconv.Itoa(verbose))
|
||||
assertNoError(err)
|
||||
maybeSetFlag("v", strconv.Itoa(verbose))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue