go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/rpc/v0/runs.go (about)

     1  // Copyright 2021 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  package rpc
    16  
    17  import (
    18  	"context"
    19  
    20  	"google.golang.org/grpc/codes"
    21  
    22  	"go.chromium.org/luci/grpc/appstatus"
    23  
    24  	apiv0pb "go.chromium.org/luci/cv/api/v0"
    25  	"go.chromium.org/luci/cv/internal/common"
    26  	"go.chromium.org/luci/cv/internal/rpc/versioning"
    27  	"go.chromium.org/luci/cv/internal/run"
    28  )
    29  
    30  // RunsServer implements the v0 API.
    31  type RunsServer struct {
    32  	apiv0pb.UnimplementedRunsServer
    33  }
    34  
    35  // populateRunResponse constructs and populates a apiv0pb.Run to use in a response.
    36  func populateRunResponse(ctx context.Context, r *run.Run) (resp *apiv0pb.Run, err error) {
    37  	rcls, err := run.LoadRunCLs(ctx, r.ID, r.CLs)
    38  	if err != nil {
    39  		return nil, appstatus.Attachf(err, codes.Internal, "failed to load cls of the run")
    40  	}
    41  	gcls := make([]*apiv0pb.GerritChange, len(rcls))
    42  	sCLSet := common.MakeCLIDsSet(r.Submission.GetSubmittedCls()...)
    43  	fCLSet := common.MakeCLIDsSet(r.Submission.GetFailedCls()...)
    44  	sCLIndexes := make([]int32, 0, len(fCLSet))
    45  	fCLIndexes := make([]int32, 0, len(sCLSet))
    46  
    47  	for i, rcl := range rcls {
    48  		host, change, err := rcl.ExternalID.ParseGobID()
    49  		switch {
    50  		case err != nil:
    51  			return nil, appstatus.Attachf(err, codes.Unimplemented, "only Gerrit CL is supported")
    52  		case sCLSet.Has(rcl.ID):
    53  			sCLIndexes = append(sCLIndexes, int32(i))
    54  		case fCLSet.Has(rcl.ID):
    55  			fCLIndexes = append(fCLIndexes, int32(i))
    56  		}
    57  		gcls[i] = &apiv0pb.GerritChange{
    58  			Host:     host,
    59  			Change:   change,
    60  			Patchset: rcl.Detail.GetPatchset(),
    61  		}
    62  	}
    63  
    64  	var submission *apiv0pb.Run_Submission
    65  	if len(sCLIndexes) > 0 || len(fCLIndexes) > 0 {
    66  		submission = &apiv0pb.Run_Submission{
    67  			SubmittedClIndexes: sCLIndexes,
    68  			FailedClIndexes:    fCLIndexes,
    69  		}
    70  	}
    71  
    72  	res := &apiv0pb.Run{
    73  		Id:         r.ID.PublicID(),
    74  		Eversion:   int64(r.EVersion),
    75  		Status:     versioning.RunStatusV0(r.Status),
    76  		Mode:       string(r.Mode),
    77  		CreateTime: common.Time2PBNillable(r.CreateTime),
    78  		StartTime:  common.Time2PBNillable(r.StartTime),
    79  		UpdateTime: common.Time2PBNillable(r.UpdateTime),
    80  		EndTime:    common.Time2PBNillable(r.EndTime),
    81  		Owner:      string(r.Owner),
    82  		CreatedBy:  string(r.CreatedBy),
    83  		BilledTo:   string(r.BilledTo),
    84  		Cls:        gcls,
    85  		Tryjobs:    constructLegacyTryjobs(ctx, r),
    86  		Submission: submission,
    87  	}
    88  	res.TryjobInvocations, err = makeTryjobInvocations(ctx, r)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  	return res, nil
    93  }
    94  
    95  func constructLegacyTryjobs(ctx context.Context, r *run.Run) []*apiv0pb.Tryjob {
    96  	var ret []*apiv0pb.Tryjob
    97  	for i, execution := range r.Tryjobs.GetState().GetExecutions() {
    98  		definition := r.Tryjobs.GetState().GetRequirement().GetDefinitions()[i]
    99  		for _, attempt := range execution.GetAttempts() {
   100  			tj := &apiv0pb.Tryjob{
   101  				Status:   versioning.LegacyTryjobStatusV0(attempt.GetStatus()),
   102  				Critical: definition.GetCritical(),
   103  				Reuse:    attempt.GetReused(),
   104  			}
   105  			if result := attempt.GetResult(); result != nil {
   106  				tj.Result = &apiv0pb.Tryjob_Result{
   107  					Status: versioning.LegacyTryjobResultStatusV0(result.GetStatus()),
   108  				}
   109  				if bbid := result.GetBuildbucket().GetId(); bbid != 0 {
   110  					tj.Result.Backend = &apiv0pb.Tryjob_Result_Buildbucket_{
   111  						Buildbucket: &apiv0pb.Tryjob_Result_Buildbucket{
   112  							Id: bbid,
   113  						},
   114  					}
   115  				}
   116  			}
   117  			ret = append(ret, tj)
   118  		}
   119  	}
   120  	return ret
   121  }