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  )