Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package buildbot | 5 package buildbot |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "encoding/json" | 8 "encoding/json" |
| 9 "errors" | 9 "errors" |
| 10 "fmt" | 10 "fmt" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 case 4: | 59 case 4: |
| 60 status = resp.InfraFailure // Exception | 60 status = resp.InfraFailure // Exception |
| 61 case 5: | 61 case 5: |
| 62 status = resp.WaitingDependency // Retry | 62 status = resp.WaitingDependency // Retry |
| 63 default: | 63 default: |
| 64 panic(fmt.Errorf("Unknown status %d", s)) | 64 panic(fmt.Errorf("Unknown status %d", s)) |
| 65 } | 65 } |
| 66 return | 66 return |
| 67 } | 67 } |
| 68 | 68 |
| 69 // buildbotTimeToTime converts a buildbot time representation (pointer to float | |
| 70 // of seconds since epoch) to a natime time.Time object. | |
|
nodir
2017/03/24 06:23:49
native
hinoka
2017/03/28 18:18:36
Done.
| |
| 71 func buildbotTimeToTime(t *float64) (result time.Time) { | |
| 72 if t != nil { | |
| 73 result = time.Unix(int64(*t), int64(*t*1e9)%1e9).UTC() | |
|
nodir
2017/03/24 06:23:49
I think this needs gofmt
hinoka
2017/03/28 18:18:36
Just did... nothing changed. (It's also a write ho
| |
| 74 } | |
| 75 return | |
| 76 } | |
| 77 | |
| 69 // parseTimes translates a buildbot time tuple (start/end) into a triplet | 78 // parseTimes translates a buildbot time tuple (start/end) into a triplet |
|
nodir
2017/03/24 06:23:49
nit: standard notation is that tuple item separato
hinoka
2017/03/28 18:18:36
Done.
| |
| 70 // of (Started time, Ending time, duration). | 79 // of (Started time, Ending time, duration). |
| 71 func parseTimes(times []*float64) (started, ended time.Time, duration time.Durat ion) { | 80 // If buildFinished is not nil, then all non-specified end duration will be set to |
|
nodir
2017/03/24 06:23:49
it says "all" like there are multiple end duration
hinoka
2017/03/28 18:18:36
Done.
| |
| 81 // buildFinished. This is so that completed builds never have open step ending | |
| 82 // times. | |
| 83 func parseTimes(buildFinished *float64, times []*float64) (started, ended time.T ime, duration time.Duration) { | |
| 72 if len(times) != 2 { | 84 if len(times) != 2 { |
| 73 panic(fmt.Errorf("Expected 2 floats for times, got %v", times)) | 85 panic(fmt.Errorf("Expected 2 floats for times, got %v", times)) |
| 74 } | 86 } |
| 75 if times[0] == nil { | 87 if times[0] == nil { |
| 76 // Some steps don't have timing info. In that case, just return nils. | 88 // Some steps don't have timing info. In that case, just return nils. |
| 77 return | 89 return |
| 78 } | 90 } |
| 79 » started = time.Unix(int64(*times[0]), int64(*times[0]*1e9)%1e9).UTC() | 91 » started = buildbotTimeToTime(times[0]) |
| 80 » if times[1] != nil { | 92 » switch { |
| 81 » » ended = time.Unix(int64(*times[1]), int64(*times[1]*1e9)%1e9).UT C() | 93 » case times[1] != nil: |
| 94 » » ended = buildbotTimeToTime(times[1]) | |
| 82 duration = ended.Sub(started) | 95 duration = ended.Sub(started) |
| 83 » } else { | 96 » case buildFinished != nil: |
| 97 » » ended = buildbotTimeToTime(buildFinished) | |
| 98 » » duration = ended.Sub(started) | |
| 99 » default: | |
| 84 duration = time.Since(started) | 100 duration = time.Since(started) |
| 85 } | 101 } |
| 86 return | 102 return |
| 87 } | 103 } |
| 88 | 104 |
| 89 // getBanner parses the OS information from the build and maybe returns a banner . | 105 // getBanner parses the OS information from the build and maybe returns a banner . |
| 90 func getBanner(c context.Context, b *buildbotBuild) *resp.LogoBanner { | 106 func getBanner(c context.Context, b *buildbotBuild) *resp.LogoBanner { |
| 91 logging.Infof(c, "OS: %s/%s", b.OSFamily, b.OSVersion) | 107 logging.Infof(c, "OS: %s/%s", b.OSFamily, b.OSVersion) |
| 92 osLogo := func() *resp.Logo { | 108 osLogo := func() *resp.Logo { |
| 93 result := &resp.Logo{} | 109 result := &resp.Logo{} |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 119 // TODO(hinoka): use b.toStatus() | 135 // TODO(hinoka): use b.toStatus() |
| 120 // Status | 136 // Status |
| 121 var status resp.Status | 137 var status resp.Status |
| 122 if b.Currentstep != nil { | 138 if b.Currentstep != nil { |
| 123 status = resp.Running | 139 status = resp.Running |
| 124 } else { | 140 } else { |
| 125 status = result2Status(b.Results) | 141 status = result2Status(b.Results) |
| 126 } | 142 } |
| 127 | 143 |
| 128 // Timing info | 144 // Timing info |
| 129 » started, ended, duration := parseTimes(b.Times) | 145 » started, ended, duration := parseTimes(nil, b.Times) |
| 130 | 146 |
| 131 // Link to bot and original build. | 147 // Link to bot and original build. |
| 132 server := "build.chromium.org/p" | 148 server := "build.chromium.org/p" |
| 133 if b.Internal { | 149 if b.Internal { |
| 134 server = "uberchromegw.corp.google.com/i" | 150 server = "uberchromegw.corp.google.com/i" |
| 135 } | 151 } |
| 136 bot := &resp.Link{ | 152 bot := &resp.Link{ |
| 137 Label: b.Slave, | 153 Label: b.Slave, |
| 138 URL: fmt.Sprintf("https://%s/%s/buildslaves/%s", server, b.Mas ter, b.Slave), | 154 URL: fmt.Sprintf("https://%s/%s/buildslaves/%s", server, b.Mas ter, b.Slave), |
| 139 } | 155 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 } | 190 } |
| 175 | 191 |
| 176 return sum | 192 return sum |
| 177 } | 193 } |
| 178 | 194 |
| 179 var rLineBreak = regexp.MustCompile("<br */?>") | 195 var rLineBreak = regexp.MustCompile("<br */?>") |
| 180 | 196 |
| 181 // components takes a full buildbot build struct and extract step info from all | 197 // components takes a full buildbot build struct and extract step info from all |
| 182 // of the steps and returns it as a list of milo Build Components. | 198 // of the steps and returns it as a list of milo Build Components. |
| 183 func components(b *buildbotBuild) (result []*resp.BuildComponent) { | 199 func components(b *buildbotBuild) (result []*resp.BuildComponent) { |
| 200 endingTime := b.Times[1] | |
| 184 for i, step := range b.Steps { | 201 for i, step := range b.Steps { |
| 185 if step.Hidden == true { | 202 if step.Hidden == true { |
| 186 continue | 203 continue |
| 187 } | 204 } |
| 188 bc := &resp.BuildComponent{ | 205 bc := &resp.BuildComponent{ |
| 189 Label: step.Name, | 206 Label: step.Name, |
| 190 } | 207 } |
| 191 // Step text sometimes contains <br>, which we want to parse int o new lines. | 208 // Step text sometimes contains <br>, which we want to parse int o new lines. |
| 192 for _, t := range step.Text { | 209 for _, t := range step.Text { |
| 193 for _, line := range rLineBreak.Split(t, -1) { | 210 for _, line := range rLineBreak.Split(t, -1) { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 baseLink = append(baseLink, aliasLink) | 330 baseLink = append(baseLink, aliasLink) |
| 314 } | 331 } |
| 315 | 332 |
| 316 if len(baseLink) > 0 { | 333 if len(baseLink) > 0 { |
| 317 bc.SubLink = append(bc.SubLink, baseLink ) | 334 bc.SubLink = append(bc.SubLink, baseLink ) |
| 318 } | 335 } |
| 319 } | 336 } |
| 320 } | 337 } |
| 321 | 338 |
| 322 // Figure out the times. | 339 // Figure out the times. |
| 323 » » bc.Started, bc.Finished, bc.Duration = parseTimes(step.Times) | 340 » » bc.Started, bc.Finished, bc.Duration = parseTimes(endingTime, st ep.Times) |
| 324 | 341 |
| 325 result = append(result, bc) | 342 result = append(result, bc) |
| 326 } | 343 } |
| 327 return | 344 return |
| 328 } | 345 } |
| 329 | 346 |
| 330 // parseProp returns a representation of v based off k, and a boolean to | 347 // parseProp returns a representation of v based off k, and a boolean to |
| 331 // specify whether or not to hide it altogether. | 348 // specify whether or not to hide it altogether. |
| 332 func parseProp(prop map[string]Prop, k string, v interface{}) (string, bool) { | 349 func parseProp(prop map[string]Prop, k string, v interface{}) (string, bool) { |
| 333 switch k { | 350 switch k { |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 | 541 |
| 525 // TODO(hinoka): Do all fields concurrently. | 542 // TODO(hinoka): Do all fields concurrently. |
| 526 return &resp.MiloBuild{ | 543 return &resp.MiloBuild{ |
| 527 SourceStamp: sourcestamp(c, b), | 544 SourceStamp: sourcestamp(c, b), |
| 528 Summary: summary(c, b), | 545 Summary: summary(c, b), |
| 529 Components: components(b), | 546 Components: components(b), |
| 530 PropertyGroup: properties(b), | 547 PropertyGroup: properties(b), |
| 531 Blame: blame(b), | 548 Blame: blame(b), |
| 532 }, nil | 549 }, nil |
| 533 } | 550 } |
| OLD | NEW |