diff --git a/newt/builder/selftest.go b/newt/builder/selftest.go index 1ff1aaea94..fb3621dc6e 100644 --- a/newt/builder/selftest.go +++ b/newt/builder/selftest.go @@ -77,7 +77,7 @@ func (t *TargetBuilder) SelfTestCreateExe() error { return nil } -func (t *TargetBuilder) SelfTestExecute() error { +func (t *TargetBuilder) SelfTestExecute(valgrind bool) error { if err := t.SelfTestCreateExe(); err != nil { return err } @@ -87,7 +87,7 @@ func (t *TargetBuilder) SelfTestExecute() error { return err } - if err := t.AppBuilder.SelfTestExecute(testRpkg); err != nil { + if err := t.AppBuilder.SelfTestExecute(testRpkg, valgrind); err != nil { return err } @@ -140,7 +140,7 @@ func (b *Builder) testOwner(bpkg *BuildPackage) *BuildPackage { } } -func (b *Builder) SelfTestExecute(testRpkg *resolve.ResolvePackage) error { +func (b *Builder) SelfTestExecute(testRpkg *resolve.ResolvePackage, valgrind bool) error { testPath := b.TestExePath() if err := os.Chdir(filepath.Dir(testPath)); err != nil { return err @@ -149,11 +149,16 @@ func (b *Builder) SelfTestExecute(testRpkg *resolve.ResolvePackage) error { util.StatusMessage(util.VERBOSITY_DEFAULT, "Executing test: %s\n", testPath) cmd := []string{testPath} - if _, err := util.ShellCommand(cmd, nil); err != nil { + if valgrind { + cmd = append([]string{"valgrind", "--error-exitcode=1"}, cmd...) + } + if output, err := util.ShellCommand(cmd, nil); err != nil { newtError := err.(*util.NewtError) newtError.Text = fmt.Sprintf("Test failure (%s):\n%s", testRpkg.Lpkg.Name(), newtError.Text) return newtError + } else if valgrind { + util.StatusMessage(util.VERBOSITY_DEFAULT, "%s", output) } return nil diff --git a/newt/cli/build_cmds.go b/newt/cli/build_cmds.go index ce16115368..b5f56cd6e6 100644 --- a/newt/cli/build_cmds.go +++ b/newt/cli/build_cmds.go @@ -22,6 +22,7 @@ package cli import ( "fmt" "os" + "os/exec" "path/filepath" "strings" @@ -235,11 +236,19 @@ func pkgnames(pkgs []*pkg.LocalPackage) string { return s } -func testRunCmd(cmd *cobra.Command, args []string, exclude string, executeShell bool) { +func testRunCmd(cmd *cobra.Command, args []string, exclude string, executeShell bool, valgrind bool) { if len(args) < 1 { NewtUsage(cmd, nil) } + if valgrind == true { + _, err := exec.LookPath("valgrind") + if err != nil { + NewtUsage(nil, util.FmtNewtError("Valgrind is not installed."+ + "Please install it before running tests with --valgrind flag.")) + } + } + util.ExecuteShell = executeShell proj := TryGetProject() @@ -320,7 +329,7 @@ func testRunCmd(cmd *cobra.Command, args []string, exclude string, executeShell util.StatusMessage(util.VERBOSITY_DEFAULT, "Testing package %s\n", pack.FullName()) - err = b.SelfTestExecute() + err = b.SelfTestExecute(valgrind) if err == nil { passedPkgs = append(passedPkgs, pack) } else { @@ -435,6 +444,7 @@ func sizeRunCmd(cmd *cobra.Command, args []string, ram bool, flash bool, section func AddBuildCommands(cmd *cobra.Command) { var printShellCmds bool var executeShell bool + var valgrind bool buildCmd := &cobra.Command{ Use: "build [target-names...]", @@ -474,12 +484,14 @@ func AddBuildCommands(cmd *cobra.Command) { Use: "test [package-names...] | all", Short: "Executes unit tests for one or more packages", Run: func(cmd *cobra.Command, args []string) { - testRunCmd(cmd, args, exclude, executeShell) + testRunCmd(cmd, args, exclude, executeShell, valgrind) }, } testCmd.Flags().StringVarP(&exclude, "exclude", "e", "", "Comma separated list of packages to exclude") testCmd.Flags().BoolVar(&executeShell, "executeShell", false, "Execute build command using /bin/sh (Linux and MacOS only)") + testCmd.Flags().BoolVar(&valgrind, "valgrind", false, + "Run test executables under Valgrind") cmd.AddCommand(testCmd) AddTabCompleteFn(testCmd, func() []string { return append(testablePkgList(), "all", "allexcept")