aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Seymour <rseymour@google.com>2022-07-15 05:14:46 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-07-15 05:14:46 +0000
commit02cd3da89bdc557a2b352176b4c3be42e4ce380e (patch)
tree0c6756bb974fb30ab6fa0621eeeb37015a3f9e62
parent490ba71e5095fe51f5ceac83e936e096c9b697dc (diff)
parentfe5e5983474fb6813dcdd4362e1836c25fa2a076 (diff)
downloadtreble-02cd3da89bdc557a2b352176b4c3be42e4ce380e.tar.gz
Add profile times to treble_build am: a241bc30e4 am: b63cbd19a5 am: 0f25425af7 am: fe5e598347
Original change: https://android-review.googlesource.com/c/platform/tools/treble/+/2153943 Change-Id: I6ad5d5151e2ba2d1fcb5f705d74c5f4a9b5afa97 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--build/treble_build/cmd/main.go54
-rw-r--r--build/treble_build/local/cmd.go17
-rw-r--r--build/treble_build/local/ninja.go55
-rw-r--r--build/treble_build/local/ninja_test.go4
4 files changed, 119 insertions, 11 deletions
diff --git a/build/treble_build/cmd/main.go b/build/treble_build/cmd/main.go
index 0264ff3..d3eb7c6 100644
--- a/build/treble_build/cmd/main.go
+++ b/build/treble_build/cmd/main.go
@@ -26,6 +26,7 @@ import (
"os"
"runtime"
"strings"
+ "time"
"tools/treble/build/report/app"
"tools/treble/build/report/local"
@@ -67,11 +68,14 @@ var (
// Common flags
ninjaDbPtr = flag.String("ninja", local.DefNinjaDb(), "Set the .ninja file to use when building metrics")
ninjaExcPtr = flag.String("ninja_cmd", local.DefNinjaExc(), "Set the ninja executable")
+ ninjaTimeoutStr = flag.String("ninja_timeout", local.DefaultNinjaTimeout, "Default ninja timeout")
+ buildTimeoutStr = flag.String("build_timeout", local.DefaultNinjaBuildTimeout, "Default build timeout")
manifestPtr = flag.String("manifest", local.DefManifest(), "Set the location of the manifest file")
upstreamPtr = flag.String("upstream", "", "Upstream branch to compare files against")
repoBasePtr = flag.String("repo_base", local.DefRepoBase(), "Set the repo base directory")
workerCountPtr = flag.Int("worker_count", runtime.NumCPU(), "Number of worker routines")
buildWorkerCountPtr = flag.Int("build_worker_count", local.MaxNinjaCliWorkers, "Number of build worker routines")
+ clientServerPtr = flag.Bool("client_server", false, "Run client server mode")
buildPtr = flag.Bool("build", false, "Build targets")
jsonPtr = flag.Bool("json", false, "Print json data")
verbosePtr = flag.Bool("v", false, "Print verbose text data")
@@ -82,6 +86,12 @@ var (
pathsFlags = flag.NewFlagSet("paths", flag.ExitOnError)
)
+// Add profiling data
+type profTime struct {
+ Description string `json:"description"`
+ DurationSecs float64 `json:"duration"`
+}
+
type commit struct {
Project app.ProjectCommit `json:"project"`
Commit *app.GitCommit `json:"commit"`
@@ -99,14 +109,32 @@ type response struct {
Query *app.QueryResponse `json:"query,omitempty"`
Paths []*app.BuildPath `json:"build_paths,omitempty"`
Host *app.HostReport `json:"host,omitempty"`
+
+ // Profile data
+ Profile []*profTime `json:"profile"`
}
func main() {
+ startTime := time.Now()
ctx := context.Background()
rsp := &response{}
+ var addProfileData = func(desc string) {
+ rsp.Profile = append(rsp.Profile, &profTime{Description: desc, DurationSecs: time.Since(startTime).Seconds()})
+ startTime = time.Now()
+ }
flag.Parse()
+ ninjaTimeout, err := time.ParseDuration(*ninjaTimeoutStr)
+ if err != nil {
+ log.Fatalf("Invalid ninja timeout %s", *ninjaTimeoutStr)
+ }
+
+ buildTimeout, err := time.ParseDuration(*buildTimeoutStr)
+ if err != nil {
+ log.Fatalf("Invalid build timeout %s", *buildTimeoutStr)
+ }
+
subArgs := flag.Args()
if len(subArgs) < 1 {
// Nothing to do
@@ -115,7 +143,17 @@ func main() {
defBuildTarget := "droid"
log.SetFlags(log.LstdFlags | log.Llongfile)
- ninja := local.NewNinjaCli(*ninjaExcPtr, *ninjaDbPtr)
+ ninja := local.NewNinjaCli(*ninjaExcPtr, *ninjaDbPtr, ninjaTimeout, buildTimeout, *clientServerPtr)
+
+ if *clientServerPtr {
+ go func() {
+ ninjaServ := local.NewNinjaCli(*ninjaExcPtr, *ninjaDbPtr, ninjaTimeout, buildTimeout, false)
+ ninjaServ.StartServer(ctx)
+ }()
+ if err := ninja.WaitForServer(ctx, 60); err != nil {
+ log.Fatalf("Failed to connect to server")
+ }
+ }
rtx := &report.Context{
RepoBase: *repoBasePtr,
Repo: &report.RepoMan{},
@@ -154,8 +192,10 @@ func main() {
default:
rsp.Targets = subArgs
}
-
+ addProfileData("Init")
rtx.ResolveProjectMap(ctx, *manifestPtr, *upstreamPtr)
+ addProfileData("Project Map")
+
// Resolve any commits
if len(commits) > 0 {
log.Printf("Resolving %s", commits.String())
@@ -171,6 +211,7 @@ func main() {
// Add files to list of inputs
rsp.Inputs = append(rsp.Inputs, files...)
}
+ addProfileData("Commit Resolution")
}
// Run any sub tools
@@ -178,6 +219,7 @@ func main() {
if err := subcommand.Run(ctx, rtx, rsp); err != nil {
log.Fatal(err)
}
+ addProfileData(subArgs[0])
}
buildErrors := 0
@@ -185,6 +227,7 @@ func main() {
for _, t := range rsp.Targets {
log.Printf("Building %s\n", t)
res := ninja.Build(ctx, t)
+ addProfileData(fmt.Sprintf("Build %s", t))
log.Printf("%s\n", res.Output)
if res.Success != true {
buildErrors++
@@ -194,10 +237,10 @@ func main() {
}
// Generate report
- var err error
log.Printf("Generating report for targets %s", rsp.Targets)
req := &app.ReportRequest{Targets: rsp.Targets}
rsp.Report, err = report.RunReport(ctx, rtx, req)
+ addProfileData("Report")
if err != nil {
log.Fatal(fmt.Sprintf("Report failure <%s>", err))
}
@@ -294,4 +337,9 @@ func printTextReport(w io.Writer, subcommand tool, rsp *response, verbose bool)
targetPrint(t)
}
+ fmt.Fprintln(w, " Run Times")
+ for _, p := range rsp.Profile {
+ fmt.Fprintf(w, " %-30s : %f secs\n", p.Description, p.DurationSecs)
+ }
+
}
diff --git a/build/treble_build/local/cmd.go b/build/treble_build/local/cmd.go
index 3fc24c8..3d4e9c2 100644
--- a/build/treble_build/local/cmd.go
+++ b/build/treble_build/local/cmd.go
@@ -21,6 +21,7 @@ import (
"errors"
"io"
"os/exec"
+ "syscall"
"time"
)
@@ -66,10 +67,22 @@ func run(ctx context.Context, timeout time.Duration, cmdName string, args []stri
return &outputBuf, nil, ""
}
+// run without timeout, kill when application dies
+func runNoTimeout(ctx context.Context, cmdName string, args []string) error {
+ cmd := exec.CommandContext(ctx, cmdName, args[0:]...)
+ // Kill when app dies
+ cmd.SysProcAttr = &syscall.SysProcAttr{Pdeathsig: syscall.SIGKILL}
+ err := cmd.Start()
+ if err != nil {
+ return err
+ }
+ cmd.Wait()
+ return nil
+}
+
// lineScanner
//
-// Map output lines to strings, with expected number of
-// lines
+// Map output lines to strings, with expected number of lines.
type lineScanner struct {
Lines []string
}
diff --git a/build/treble_build/local/ninja.go b/build/treble_build/local/ninja.go
index 012bcc7..1b9eec6 100644
--- a/build/treble_build/local/ninja.go
+++ b/build/treble_build/local/ninja.go
@@ -18,6 +18,8 @@ import (
"bufio"
"bytes"
"context"
+ "errors"
+ "fmt"
"io"
"io/ioutil"
"strings"
@@ -27,7 +29,11 @@ import (
)
// Performance degrades running multiple CLIs
-const MaxNinjaCliWorkers = 4
+const (
+ MaxNinjaCliWorkers = 4
+ DefaultNinjaTimeout = "100s"
+ DefaultNinjaBuildTimeout = "30m"
+)
// Separate out the executable to allow tests to override the results
type ninjaExec interface {
@@ -37,6 +43,7 @@ type ninjaExec interface {
Path(ctx context.Context, target string, dependency string) (*bytes.Buffer, error)
Paths(ctx context.Context, target string, dependency string) (*bytes.Buffer, error)
Deps(ctx context.Context) (*bytes.Buffer, error)
+ StartServer(ctx context.Context) error
Build(ctx context.Context, target string) (*bytes.Buffer, error)
}
@@ -174,14 +181,23 @@ type ninjaCmd struct {
cmd string
db string
+ clientMode bool
timeout time.Duration
buildTimeout time.Duration
}
func (n *ninjaCmd) runTool(ctx context.Context, tool string, targets []string) (out *bytes.Buffer, err error) {
- args := append([]string{
- "-f", n.db,
- "-t", tool}, targets...)
+
+ args := []string{"-f", n.db}
+
+ if n.clientMode {
+ args = append(args, []string{
+ "-t", "client",
+ "-c", tool}...)
+ } else {
+ args = append(args, []string{"-t", tool}...)
+ }
+ args = append(args, targets...)
data := []byte{}
err, _ = runPipe(ctx, n.timeout, n.cmd, args, func(r io.Reader) {
data, _ = ioutil.ReadAll(r)
@@ -207,6 +223,10 @@ func (n *ninjaCmd) Paths(ctx context.Context, target string, dependency string)
func (n *ninjaCmd) Deps(ctx context.Context) (*bytes.Buffer, error) {
return n.runTool(ctx, "deps", []string{})
}
+func (n *ninjaCmd) StartServer(ctx context.Context) error {
+ args := []string{"-f", n.db, "-t", "server"}
+ return runNoTimeout(ctx, n.cmd, args)
+}
func (n *ninjaCmd) Build(ctx context.Context, target string) (*bytes.Buffer, error) {
@@ -221,6 +241,7 @@ func (n *ninjaCmd) Build(ctx context.Context, target string) (*bytes.Buffer, err
return bytes.NewBuffer(data), err
}
+// Command line ninja
type ninjaCli struct {
n ninjaExec
}
@@ -285,7 +306,29 @@ func (cli *ninjaCli) Build(ctx context.Context, target string) *app.BuildCmdResu
return parseBuild(target, raw, err == nil)
}
-func NewNinjaCli(cmd string, db string) *ninjaCli {
- cli := &ninjaCli{n: &ninjaCmd{cmd: cmd, db: db, timeout: 100000 * time.Millisecond, buildTimeout: 300000 * time.Millisecond}}
+
+// Run server
+func (cli *ninjaCli) StartServer(ctx context.Context) error {
+ return cli.n.StartServer(ctx)
+}
+
+// Wait for server
+func (cli *ninjaCli) WaitForServer(ctx context.Context, maxTries int) error {
+ // Wait for server to response to an empty input request
+ fmt.Printf("Waiting for server.")
+ for i := 0; i < maxTries; i++ {
+ _, err := cli.Input(ctx, "")
+ if err == nil {
+ fmt.Printf("\nConnected\n")
+ return nil
+ }
+ fmt.Printf(".")
+ time.Sleep(time.Second)
+ }
+ fmt.Printf(" failed\n")
+ return errors.New("Failed to connect")
+}
+func NewNinjaCli(cmd string, db string, timeout, buildTimeout time.Duration, client bool) *ninjaCli {
+ cli := &ninjaCli{n: &ninjaCmd{cmd: cmd, db: db, timeout: timeout, buildTimeout: buildTimeout, clientMode: client}}
return cli
}
diff --git a/build/treble_build/local/ninja_test.go b/build/treble_build/local/ninja_test.go
index 40e2043..2b3aabc 100644
--- a/build/treble_build/local/ninja_test.go
+++ b/build/treble_build/local/ninja_test.go
@@ -17,6 +17,7 @@ package local
import (
"bytes"
"context"
+ "errors"
"reflect"
"testing"
@@ -51,6 +52,9 @@ func (n *ninjaTest) Paths(ctx context.Context, target string, dependency string)
func (n *ninjaTest) Deps(ctx context.Context) (*bytes.Buffer, error) {
return bytes.NewBufferString(n.deps.text), n.deps.err
}
+func (n *ninjaTest) StartServer(ctx context.Context) error {
+ return errors.New("server not support")
+}
func (n *ninjaTest) Build(ctx context.Context, target string) (*bytes.Buffer, error) {
return bytes.NewBufferString(n.build.text), n.build.err
}