Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: go/src/infra/tools/swarming-transition/cmd/swarmbucketcheck/main.go

Issue 2110453002: add swarmbucketcheck (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: add swarmbucketcheck Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « go/src/infra/tools/swarming-transition/cmd/swarmbucketcheck/luci-py-builders ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 package main
Vadim Sh. 2016/06/28 18:17:14 copyright
nodir 2016/06/28 22:08:57 Done.
2
3 import (
4 "flag"
5 "fmt"
6 "net/http"
7 "os"
8 "strings"
9 "time"
10
11 "github.com/luci/luci-go/common/api/buildbucket/buildbucket/v1"
12 )
13
14 var since = flag.Int64("since", 0, "analyze builds since this timestamp. Default s to 10 days ago.")
15 var bucket = flag.String("bucket", "", `buildbucket bucket name, e.g. "master.tr yserver.infra"`)
16 var builders = flag.String("builder", "", `comma-separated list of builder names without swarming suffix, e.g. "Infra Presubmit"`)
17
18 const swarmingSuffix = " (Swarming)"
19
20 func fetchBuilds(bucket, builder string, startingFrom time.Time) ([]*buildbucket .ApiBuildMessage, error) {
21 client, err := buildbucket.New(http.DefaultClient)
22 if err != nil {
23 return nil, err
24 }
25 client.BasePath = "https://cr-buildbucket.appspot.com/_ah/api/buildbucke t/v1/"
26
27 req := client.Search()
28 req.Bucket(bucket)
29 req.Tag("builder:" + builder)
30 req.Status("COMPLETED")
31 req.MaxBuilds(100)
32
33 var result []*buildbucket.ApiBuildMessage
34 for {
35 res, err := req.Do()
36 if err != nil {
37 return result, err
38 }
39 if res.Error != nil {
40 return result, fmt.Errorf(res.Error.Message)
41 }
42
43 for _, b := range res.Builds {
44 createdAt := time.Unix(b.CreatedTs/1000000, 0)
45 if createdAt.Before(startingFrom) {
46 return result, nil
47 }
48 result = append(result, b)
49 }
50
51 if len(res.Builds) == 0 || res.NextCursor == "" {
52 break
53 }
54 req.StartCursor(res.NextCursor)
55 }
56 return result, nil
57 }
58
59 type buildSet struct {
60 builds []*buildbucket.ApiBuildMessage
61 bestResult string
62 }
63
64 // groupBuilds groups builds by buildset tag.
65 func groupBuilds(builds []*buildbucket.ApiBuildMessage) map[string]*buildSet {
66 results := map[string]*buildSet{}
67 for _, b := range builds {
68 tags := parseTags(b.Tags)
69 buildSetName := tags["buildset"]
70 if buildSetName == "" {
71 fmt.Printf("skipped build %d: no buildset tag\n", b.Id)
72 continue
73 }
74 set := results[buildSetName]
75 if set == nil {
76 set = &buildSet{}
77 results[buildSetName] = set
78 }
79
80 set.builds = append(set.builds, b)
81 if set.bestResult == "" || b.Result == "SUCCESS" {
82 set.bestResult = b.Result
83 }
84 }
85 return results
86 }
87
88 func run() error {
89 flag.Parse()
90 if *bucket == "" {
91 return fmt.Errorf("bucket is not specified")
92 }
93 if *builders == "" {
94 return fmt.Errorf("builders are not specified")
95 }
96 if len(flag.Args()) > 0 {
97 return fmt.Errorf("unexpected arguments: %s", flag.Args())
98 }
99
100 var startingFrom time.Time
101 var duration time.Duration
102 if *since == 0 {
103 duration = 240 * time.Hour
104 startingFrom = time.Now().Add(-duration)
105 } else {
106 startingFrom = time.Unix(*since, 0)
107 duration = time.Since(startingFrom)
108 }
109
110 for i, builder := range strings.Split(*builders, ",") {
111 builder = strings.TrimSpace(builder)
112 if builder == "" {
113 continue
114 }
115
116 if i > 0 {
117 fmt.Println()
118 }
119 fmt.Printf("builder %q\n", builder)
120 fmt.Printf("searching for all builds since timestamp %d till %d. ..\n",
121 startingFrom.Unix(), time.Now().Unix())
122 // We will actually fetch builds after after time.Now too, but i t is fine.
123 swarmingBuilds, err := fetchBuilds(*bucket, builder+swarmingSuff ix, startingFrom)
124 if err != nil {
125 return fmt.Errorf("could not fetch builds: %s", err)
126 }
127 if len(swarmingBuilds) == 0 {
128 fmt.Printf("no swarming builds for builder %q\n", builde r)
129 continue
130 }
131 buildbotBuilds, err := fetchBuilds(*bucket, builder, startingFro m)
132 if err != nil {
133 return fmt.Errorf("could not fetch builds: %s", err)
134 }
135
136 swarmingBuildSets := groupBuilds(swarmingBuilds)
137 buildbotBuildSets := groupBuilds(buildbotBuilds)
138
139 consistentN := 0
140 inconsistentN := 0
141 for setName, swarmingSet := range swarmingBuildSets {
142 buildbotSet := buildbotBuildSets[setName]
143 if buildbotSet == nil {
144 fmt.Printf("no buildbot builds for buildset %s\n ", setName)
145 continue
146 }
147 if buildbotSet.bestResult == swarmingSet.bestResult {
148 consistentN++
149 continue
150 }
151 inconsistentN++
152
153 fmt.Printf("%s is inconsistent\n", setName)
154 for _, b := range swarmingSet.builds {
155 fmt.Printf(" %s %s\n", b.Result, b.Url)
156 }
157 for _, b := range buildbotSet.builds {
158 fmt.Printf(" %s %s\n", b.Result, b.Url)
159 }
160 }
161
162 fmt.Printf("%0.2f%% consistent build sets, %d buildbot builds, % d swarming builds\n",
163 100*float64(consistentN)/float64(consistentN+inconsisten tN), len(buildbotBuilds), len(swarmingBuilds))
164 }
165 return nil
166 }
167
168 func main() {
169 if err := run(); err != nil {
170 fmt.Fprintln(os.Stderr, err)
171 os.Exit(1)
172 }
173 }
174
175 func parseTags(tags []string) map[string]string {
176 result := make(map[string]string, len(tags))
177 for _, t := range tags {
178 parts := strings.SplitN(t, ":", 2)
179 if len(parts) == 2 {
180 result[parts[0]] = parts[1]
181 }
182 }
183 return result
184 }
OLDNEW
« no previous file with comments | « go/src/infra/tools/swarming-transition/cmd/swarmbucketcheck/luci-py-builders ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698