You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/12/08 07:31:37 UTC
incubator-mynewt-newt git commit: MYNEWT-245 Allow debug of unittest
via "newt run"
Repository: incubator-mynewt-newt
Updated Branches:
refs/heads/develop 6f1a11a8f -> 199ecc0c7
MYNEWT-245 Allow debug of unittest via "newt run"
The command is:
newt run <unittest-pkg>
This builds the test executable such that a failed test triggers a
failed assert and runs it in gdb. When a test fails, gdb halts at the
point of failure.
This change requires a sibling change to be made to the core repo.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/199ecc0c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/199ecc0c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/199ecc0c
Branch: refs/heads/develop
Commit: 199ecc0c7d1a2beb2152f2d6877cc43b76b59314
Parents: 6f1a11a
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Dec 8 01:26:29 2016 -0600
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Dec 8 01:26:29 2016 -0600
----------------------------------------------------------------------
newt/builder/build.go | 24 +++++++++----
newt/builder/buildutil.go | 4 ---
newt/builder/load.go | 32 ++++++++++++++---
newt/builder/paths.go | 4 +++
newt/builder/targetbuild.go | 30 +++++++++++++++-
newt/cli/build_cmds.go | 4 +--
newt/cli/run_cmds.go | 74 ++++++++++++++++++++++------------------
newt/cli/target_cmds.go | 41 +++-------------------
newt/cli/util.go | 42 +++++++++++++++++++++++
newt/syscfg/syscfg.go | 18 ++++++++--
10 files changed, 181 insertions(+), 92 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/builder/build.go
----------------------------------------------------------------------
diff --git a/newt/builder/build.go b/newt/builder/build.go
index 6114fd4..fae8d66 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -517,29 +517,39 @@ func (b *Builder) testOwner(p *BuildPackage) *BuildPackage {
}
}
-func (b *Builder) Test(p *pkg.LocalPackage) error {
+// @return string Path of generated test executable.
+func (b *Builder) BuildTest(p *pkg.LocalPackage) (string, error) {
// Build the packages alphabetically to ensure a consistent order.
bpkgs := b.sortedBuildPackages()
for _, bpkg := range bpkgs {
if err := b.buildPackage(bpkg); err != nil {
- return err
+ return "", err
}
}
testBpkg := b.PkgMap[p]
- testFilename := b.TestExePath(testBpkg)
- if err := b.link(testFilename, nil, nil); err != nil {
+ testPath := b.TestExePath(testBpkg)
+ if err := b.link(testPath, nil, nil); err != nil {
+ return "", err
+ }
+
+ return testPath, nil
+}
+
+func (b *Builder) Test(p *pkg.LocalPackage) error {
+ testPath, err := b.BuildTest(p)
+ if err != nil {
return err
}
// Run the tests.
- if err := os.Chdir(filepath.Dir(testFilename)); err != nil {
+ if err := os.Chdir(filepath.Dir(testPath)); err != nil {
return err
}
util.StatusMessage(util.VERBOSITY_DEFAULT, "Executing test: %s\n",
- testFilename)
- cmd := []string{testFilename}
+ testPath)
+ cmd := []string{testPath}
if _, err := util.ShellCommand(cmd, nil); err != nil {
newtError := err.(*util.NewtError)
newtError.Text = fmt.Sprintf("Test failure (%s):\n%s", p.Name(),
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/builder/buildutil.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go
index a36d3f2..c66c43a 100644
--- a/newt/builder/buildutil.go
+++ b/newt/builder/buildutil.go
@@ -33,10 +33,6 @@ func TestTargetName(testPkgName string) string {
return strings.Replace(testPkgName, "/", "_", -1)
}
-func (b *Builder) TestExePath(bpkg *BuildPackage) string {
- return b.PkgBinDir(bpkg) + "/" + TestTargetName(bpkg.Name())
-}
-
func (b *Builder) FeatureString() string {
var buffer bytes.Buffer
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/builder/load.go
----------------------------------------------------------------------
diff --git a/newt/builder/load.go b/newt/builder/load.go
index b7ae34e..2473819 100644
--- a/newt/builder/load.go
+++ b/newt/builder/load.go
@@ -151,7 +151,6 @@ func (b *Builder) Load(imageSlot int, extraJtagCmd string) error {
}
func (t *TargetBuilder) Debug(extraJtagCmd string, reset bool, noGDB bool) error {
- //var additional_libs []string
err := t.PrepBuild()
if err != nil {
@@ -164,11 +163,16 @@ func (t *TargetBuilder) Debug(extraJtagCmd string, reset bool, noGDB bool) error
return t.LoaderBuilder.Debug(extraJtagCmd, reset, noGDB)
}
-func (b *Builder) Debug(extraJtagCmd string, reset bool, noGDB bool) error {
- if b.appPkg == nil {
- return util.NewNewtError("app package not specified")
+func (t *TargetBuilder) DebugTest() error {
+ if err := t.PrepTest(); err != nil {
+ return err
}
+ return t.AppBuilder.DebugTest(t.GetTestPkg())
+}
+
+func (b *Builder) debugBin(binPath string, extraJtagCmd string, reset bool,
+ noGDB bool) error {
/*
* Populate the package list and feature sets.
*/
@@ -178,7 +182,7 @@ func (b *Builder) Debug(extraJtagCmd string, reset bool, noGDB bool) error {
}
bspPath := b.bspPkg.BasePath()
- binBaseName := b.AppBinBasePath()
+ binBaseName := binPath
featureString := b.FeatureString()
coreRepo := project.GetProject().FindRepo("apache-mynewt-core")
@@ -210,3 +214,21 @@ func (b *Builder) Debug(extraJtagCmd string, reset bool, noGDB bool) error {
fmt.Printf("%s\n", cmdLine)
return util.ShellInteractiveCommand(cmdLine, envSettings)
}
+
+func (b *Builder) Debug(extraJtagCmd string, reset bool, noGDB bool) error {
+ if b.appPkg == nil {
+ return util.NewNewtError("app package not specified")
+ }
+
+ return b.debugBin(b.AppBinBasePath(), extraJtagCmd, reset, noGDB)
+}
+
+func (b *Builder) DebugTest(lpkg *pkg.LocalPackage) error {
+ bpkg := b.PkgMap[lpkg]
+ if bpkg == nil {
+ panic("internal error: local package \"" + lpkg.FullName() +
+ "\" not built")
+ }
+ return b.debugBin(strings.TrimSuffix(b.TestExePath(bpkg), ".elf"),
+ "", false, false)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/builder/paths.go
----------------------------------------------------------------------
diff --git a/newt/builder/paths.go b/newt/builder/paths.go
index fa9e940..58d1880 100644
--- a/newt/builder/paths.go
+++ b/newt/builder/paths.go
@@ -140,6 +140,10 @@ func (b *Builder) AppPath() string {
return b.PkgBinDir(b.appPkg) + "/"
}
+func (b *Builder) TestExePath(bpkg *BuildPackage) string {
+ return b.PkgBinDir(bpkg) + "/" + TestTargetName(bpkg.Name()) + ".elf"
+}
+
func (b *Builder) ManifestPath() string {
return ManifestPath(b.targetPkg.Name(), b.buildName, b.appPkg.Name())
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 408d90d..9172800 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -535,7 +535,7 @@ func (t *TargetBuilder) RelinkLoader() (error, map[string]bool,
return err, commonPkgs, smMatch
}
-func (t *TargetBuilder) Test() error {
+func (t *TargetBuilder) PrepTest() error {
cfgResolution, err := t.ExportCfg()
if err != nil {
return err
@@ -563,6 +563,26 @@ func (t *TargetBuilder) Test() error {
return err
}
+ return nil
+}
+
+func (t *TargetBuilder) BuildTest() error {
+ if err := t.PrepTest(); err != nil {
+ return err
+ }
+
+ if _, err := t.AppBuilder.BuildTest(t.testPkg); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (t *TargetBuilder) Test() error {
+ if err := t.BuildTest(); err != nil {
+ return err
+ }
+
if err := t.AppBuilder.Test(t.testPkg); err != nil {
return err
}
@@ -574,6 +594,14 @@ func (t *TargetBuilder) GetTarget() *target.Target {
return t.target
}
+func (t *TargetBuilder) GetTestPkg() *pkg.LocalPackage {
+ return t.testPkg
+}
+
+func (t *TargetBuilder) InjectSetting(key string, value string) {
+ t.injectedSettings[key] = value
+}
+
func readManifest(path string) (*image.ImageManifest, error) {
content, err := ioutil.ReadFile(path)
if err != nil {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/cli/build_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/build_cmds.go b/newt/cli/build_cmds.go
index 0951eda..f70f4e1 100644
--- a/newt/cli/build_cmds.go
+++ b/newt/cli/build_cmds.go
@@ -417,8 +417,8 @@ func AddBuildCommands(cmd *cobra.Command) {
Run: debugRunCmd,
}
- debugCmd.PersistentFlags().StringVarP(&extraJtagCmd, "extrajtagcmd", "j", "",
- "extra commands to send to JTAG software")
+ debugCmd.PersistentFlags().StringVarP(&extraJtagCmd, "extrajtagcmd", "j",
+ "", "extra commands to send to JTAG software")
debugCmd.PersistentFlags().BoolVarP(&noGDB_flag, "noGDB", "n", false,
"don't start GDB from command line")
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/cli/run_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/run_cmds.go b/newt/cli/run_cmds.go
index 3d94bd5..b30d5a8 100644
--- a/newt/cli/run_cmds.go
+++ b/newt/cli/run_cmds.go
@@ -23,7 +23,6 @@ import (
"os"
"github.com/spf13/cobra"
- "mynewt.apache.org/newt/newt/builder"
"mynewt.apache.org/newt/util"
)
@@ -34,44 +33,51 @@ func runRunCmd(cmd *cobra.Command, args []string) {
InitProject()
- t := ResolveTarget(args[0])
- if t == nil {
- NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0]))
- }
-
- b, err := builder.NewTargetBuilder(t)
+ b, err := TargetBuilderForTargetOrUnittest(args[0])
if err != nil {
- NewtUsage(nil, err)
- }
-
- if err := b.Build(); err != nil {
- NewtUsage(nil, err)
+ NewtUsage(cmd, err)
}
- /*
- * Run create-image if version number is specified. If no version number,
- * remove .img which would'be been created. This so that download script
- * will barf if it needs an image for this type of target, instead of
- * downloading an older version.
- */
- if len(args) > 1 {
- _, _, err = b.CreateImages(args[1], "", 0)
- if err != nil {
- NewtUsage(cmd, err)
+ testPkg := b.GetTestPkg()
+ if testPkg != nil {
+ b.InjectSetting("TESTUTIL_SYSTEM_ASSERT", "1")
+ if err := b.BuildTest(); err != nil {
+ NewtUsage(nil, err)
+ }
+ if err := b.DebugTest(); err != nil {
+ NewtUsage(nil, err)
}
} else {
- os.Remove(b.AppBuilder.AppImgPath())
+ if err := b.Build(); err != nil {
+ NewtUsage(nil, err)
+ }
+
+ /*
+ * Run create-image if version number is specified. If no version
+ * number, remove .img which would'be been created. This so that
+ * download script will barf if it needs an image for this type of
+ * target, instead of downloading an older version.
+ */
+ if len(args) > 1 {
+ _, _, err = b.CreateImages(args[1], "", 0)
+ if err != nil {
+ NewtUsage(cmd, err)
+ }
+ } else {
+ os.Remove(b.AppBuilder.AppImgPath())
- if b.LoaderBuilder != nil {
- os.Remove(b.LoaderBuilder.AppImgPath())
+ if b.LoaderBuilder != nil {
+ os.Remove(b.LoaderBuilder.AppImgPath())
+ }
}
- }
- if err := b.Load(extraJtagCmd); err != nil {
- NewtUsage(nil, err)
- }
- if err := b.Debug(extraJtagCmd, true, noGDB_flag); err != nil {
- NewtUsage(nil, err)
+ if err := b.Load(extraJtagCmd); err != nil {
+ NewtUsage(nil, err)
+ }
+
+ if err := b.Debug(extraJtagCmd, true, noGDB_flag); err != nil {
+ NewtUsage(nil, err)
+ }
}
}
@@ -91,12 +97,14 @@ func AddRunCommands(cmd *cobra.Command) {
Example: runHelpEx,
Run: runRunCmd,
}
- cmd.AddCommand(runCmd)
- AddTabCompleteFn(runCmd, targetList)
runCmd.PersistentFlags().StringVarP(&extraJtagCmd, "extrajtagcmd", "j", "",
"extra commands to send to JTAG software")
runCmd.PersistentFlags().BoolVarP(&noGDB_flag, "noGDB", "n", false,
"don't start GDB from command line")
+ cmd.AddCommand(runCmd)
+ AddTabCompleteFn(runCmd, func() []string {
+ return append(targetList(), unittestList()...)
+ })
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/cli/target_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/target_cmds.go b/newt/cli/target_cmds.go
index 4b19bbf..d2f6ebb 100644
--- a/newt/cli/target_cmds.go
+++ b/newt/cli/target_cmds.go
@@ -30,7 +30,6 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/spf13/cobra"
- "mynewt.apache.org/newt/newt/builder"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/syscfg"
"mynewt.apache.org/newt/newt/target"
@@ -469,41 +468,9 @@ func targetConfigCmd(cmd *cobra.Command, args []string) {
InitProject()
- var b *builder.TargetBuilder
-
- // Argument can specify either a target or a unittest package. Determine
- // which type the package is and construct a target builder appropriately.
- t, err := resolveExistingTargetArg(args[0])
- if err == nil {
- b, err = builder.NewTargetBuilder(t)
- if err != nil {
- NewtUsage(nil, err)
- }
- } else {
- proj := InitProject()
-
- pack, err := proj.ResolvePackage(proj.LocalRepo(), args[0])
- if err != nil {
- NewtUsage(cmd, util.FmtNewtError(
- "Could not resolve target or unittest \"%s\"", args[0]))
- }
-
- if pack.Type() != pkg.PACKAGE_TYPE_UNITTEST {
- NewtUsage(cmd, util.FmtNewtError(
- "Package \"%s\" is of type %s; "+
- "must be target or unittest", args[0],
- pkg.PackageTypeNames[pack.Type()]))
- }
-
- t, err = ResolveUnittestTarget(pack.Name())
- if err != nil {
- NewtUsage(nil, err)
- }
-
- b, err = builder.NewTargetTester(t, pack)
- if err != nil {
- NewtUsage(nil, err)
- }
+ b, err := TargetBuilderForTargetOrUnittest(args[0])
+ if err != nil {
+ NewtUsage(cmd, err)
}
cfgResolution, err := b.ExportCfg()
@@ -518,7 +485,7 @@ func targetConfigCmd(cmd *cobra.Command, args []string) {
}
}
- printCfg(t.Name(), cfgResolution.Cfg)
+ printCfg(b.GetTarget().Name(), cfgResolution.Cfg)
}
func AddTargetCommands(cmd *cobra.Command) {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/cli/util.go
----------------------------------------------------------------------
diff --git a/newt/cli/util.go b/newt/cli/util.go
index afc5fc2..9b5bfe6 100644
--- a/newt/cli/util.go
+++ b/newt/cli/util.go
@@ -244,3 +244,45 @@ func ResolveUnittestTarget(pkgName string) (*target.Target, error) {
return t, nil
}
+
+func TargetBuilderForTargetOrUnittest(pkgName string) (
+ *builder.TargetBuilder, error) {
+
+ // Argument can specify either a target or a unittest package. Determine
+ // which type the package is and construct a target builder appropriately.
+ t, err := resolveExistingTargetArg(pkgName)
+ if err == nil {
+ b, err := builder.NewTargetBuilder(t)
+ if err != nil {
+ return nil, err
+ }
+
+ return b, nil
+ }
+
+ // Package wasn't a target. Try for a unittest.
+ proj := InitProject()
+ pack, err := proj.ResolvePackage(proj.LocalRepo(), pkgName)
+ if err != nil {
+ return nil, util.FmtNewtError(
+ "Could not resolve target or unittest \"%s\"", pkgName)
+ }
+
+ if pack.Type() != pkg.PACKAGE_TYPE_UNITTEST {
+ return nil, util.FmtNewtError(
+ "Package \"%s\" is of type %s; "+
+ "must be target or unittest", pkgName,
+ pkg.PackageTypeNames[pack.Type()])
+ }
+
+ t, err = ResolveUnittestTarget(pack.Name())
+ if err != nil {
+ return nil, err
+ }
+
+ b, err := builder.NewTargetTester(t, pack)
+ if err != nil {
+ return nil, err
+ }
+ return b, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/199ecc0c/newt/syscfg/syscfg.go
----------------------------------------------------------------------
diff --git a/newt/syscfg/syscfg.go b/newt/syscfg/syscfg.go
index 7b4b00e..0010f56 100644
--- a/newt/syscfg/syscfg.go
+++ b/newt/syscfg/syscfg.go
@@ -182,6 +182,10 @@ func (point CfgPoint) Name() string {
}
}
+func (point CfgPoint) IsInjected() bool {
+ return point.Source == nil
+}
+
func (entry *CfgEntry) IsTrue() bool {
return ValueIsTrue(entry.Value)
}
@@ -326,9 +330,17 @@ func (cfg *Cfg) readDefsOnce(lpkg *pkg.LocalPackage,
lpkg.Name(), err.Error())
}
- if _, exists := cfg.Settings[k]; exists {
- // XXX: Better error message.
- return util.FmtNewtError("setting %s redefined", k)
+ if oldEntry, exists := cfg.Settings[k]; exists {
+ // Setting already defined. Allow this only if the setting is
+ // injected, in which case the injected value takes precedence.
+ point := mostRecentPoint(oldEntry)
+ if !point.IsInjected() {
+ // XXX: Better error message.
+ return util.FmtNewtError("setting %s redefined", k)
+ }
+
+ entry.History = append(entry.History, oldEntry.History...)
+ entry.Value = oldEntry.Value
}
cfg.Settings[k] = entry
}