go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/internal/model/milostatus/status.go (about) 1 // Copyright 2017 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:generate stringer -type=Status,BotStatus 16 17 package milostatus 18 19 import ( 20 "encoding/json" 21 22 buildbucketpb "go.chromium.org/luci/buildbucket/proto" 23 ) 24 25 // Status indicates the status of some piece of the CI; builds, steps, builders, 26 // etc. The UI maps this to a color, and some statuses may map to the same 27 // color; however, we attempt to preserve full informational fidelity. 28 type Status int 29 30 const ( 31 // NotRun if the component has not yet been run. E.g. if the component has 32 // been scheduled, but is pending execution. 33 NotRun Status = iota 34 35 // Running if the component is currently running. 36 Running 37 38 // Success if the component has finished executing and accomplished what it 39 // was supposed to. 40 Success 41 42 // Failure if the component has finished executing and failed in 43 // a non-exceptional way. e.g. if a test completed execution, but determined 44 // that the code was bad. 45 Failure 46 47 // Warning if the component has finished executing, but encountered 48 // non-stoppage problems. e.g. if a test completed execution, but determined 49 // that the code was slow (but not slow enough to be a failure). 50 Warning 51 52 // InfraFailure if the component has finished incompletely due to an 53 // infrastructure layer. 54 // 55 // This is used to categorize all unknown errors. 56 InfraFailure 57 58 // Exception if the component has finished incompletely due to an exceptional 59 // error in the task. That means the infrastructure layers executed the task 60 // completely, but the task self-reported that it failed in an exceptional 61 // way. 62 // 63 // DON'T USE THIS IN ANY NEW CODE. Instead, prefer InfraFailure. 64 Exception 65 66 // Expired if the component was never scheduled due to resource exhaustion. 67 Expired 68 69 // Canceled if the component had external intervention to stop it after it 70 // was scheduled, but before it completed on its own. 71 Canceled 72 ) 73 74 // Terminal returns true if the step status won't change. 75 func (s Status) Terminal() bool { 76 switch s { 77 case Success, Failure, InfraFailure, Warning, Expired, Exception, Canceled: 78 return true 79 default: 80 return false 81 } 82 } 83 84 // MarshalJSON renders enums into String rather than an int when marshalling. 85 func (s Status) MarshalJSON() ([]byte, error) { 86 return json.Marshal(s.String()) 87 } 88 89 // statusMap maps buildbucket status to milo status. 90 // Buildbucket statuses not in the map must be treated 91 // as InfraFailure. 92 var statusMap = map[buildbucketpb.Status]Status{ 93 buildbucketpb.Status_SCHEDULED: NotRun, 94 buildbucketpb.Status_STARTED: Running, 95 buildbucketpb.Status_SUCCESS: Success, 96 buildbucketpb.Status_FAILURE: Failure, 97 buildbucketpb.Status_INFRA_FAILURE: InfraFailure, 98 buildbucketpb.Status_CANCELED: Canceled, 99 } 100 101 // FromBuildbucket converts buildbucket status to milo status. 102 // 103 // Note: this mapping between milo status and buildbucket status isn't 104 // one-to-one (i.e. `status == FromBuildbucket(status).ToBuildbucket()` is not 105 // always true). 106 func FromBuildbucket(status buildbucketpb.Status) Status { 107 s, ok := statusMap[status] 108 if !ok { 109 return InfraFailure 110 } 111 return s 112 } 113 114 // bbStatusMap maps milo status to buildbucket status. 115 var bbStatusMap = map[Status]buildbucketpb.Status{ 116 NotRun: buildbucketpb.Status_SCHEDULED, 117 Running: buildbucketpb.Status_STARTED, 118 Success: buildbucketpb.Status_SUCCESS, 119 Warning: buildbucketpb.Status_SUCCESS, 120 Failure: buildbucketpb.Status_FAILURE, 121 InfraFailure: buildbucketpb.Status_INFRA_FAILURE, 122 Exception: buildbucketpb.Status_INFRA_FAILURE, 123 Expired: buildbucketpb.Status_CANCELED, 124 Canceled: buildbucketpb.Status_CANCELED, 125 } 126 127 // ToBuildbucket converts milo status to buildbucket status. 128 // 129 // Note: this mapping between milo status and buildbucket status isn't 130 // one-to-one (i.e. `status == FromBuildbucket(status).ToBuildbucket()` is not 131 // always true). 132 func (status Status) ToBuildbucket() buildbucketpb.Status { 133 return bbStatusMap[status] 134 } 135 136 // BotStatus indicates the status of a machine. 137 type BotStatus int 138 139 const ( 140 // Idle means the bot is ready to accept a job. 141 Idle BotStatus = iota 142 // Busy means the bot is currently running a job, or recently finished 143 // a job and may not be ready to accept a new job yet. 144 Busy 145 // Offline means the bot is dead. 146 Offline 147 // Quarantined means the bot is quarantined. 148 Quarantined 149 )