blob: 74c148d3ac4c94c2157af6aa047d277bbafcb13b [file] [log] [blame]
package perfresults
import (
"context"
"fmt"
"net/http"
"time"
"go.chromium.org/luci/common/retry"
"go.chromium.org/luci/grpc/prpc"
swarmingv2 "go.chromium.org/luci/swarming/proto/api_v2"
"go.skia.org/infra/go/httputils"
"go.skia.org/infra/go/skerr"
"golang.org/x/oauth2/google"
)
// swarmingClient wraps swarmingv2.TasksClient to provide convenient functions
type swarmingClient struct {
swarmingv2.TasksClient
}
func newSwarmingClient(ctx context.Context, swarmingHost string, client *http.Client) (*swarmingClient, error) {
if client == nil {
ts, err := google.DefaultTokenSource(ctx)
if err != nil {
return nil, skerr.Wrapf(err, "unable to fetch token source")
}
client = httputils.DefaultClientConfig().WithTokenSource(ts).With2xxOnly().Client()
}
prpc := &prpc.Client{
C: client,
Host: swarmingHost,
Options: &prpc.Options{
Retry: func() retry.Iterator {
return &retry.ExponentialBackoff{
MaxDelay: time.Minute,
Limited: retry.Limited{
Delay: time.Second,
Retries: 1,
},
}
},
PerRPCTimeout: 90 * time.Second,
},
}
return &swarmingClient{
TasksClient: swarmingv2.NewTasksClient(prpc),
}, nil
}
func (client *swarmingClient) findTaskCASOutputs(ctx context.Context, taskIDs ...string) ([]*swarmingv2.CASReference, error) {
all_cas := make([]*swarmingv2.CASReference, len(taskIDs))
for i, t := range taskIDs {
resp, err := client.GetResult(ctx, &swarmingv2.TaskIdWithPerfRequest{
TaskId: t,
})
// We short-cut on any errors occured in the middle, expecting this CAS outputs are
// generally available if the task is completed.
if err != nil {
return nil, skerr.Wrapf(err, "unable to get the cas output")
}
all_cas[i] = resp.GetCasOutputRoot()
}
return all_cas, nil
}
// findChildTaskIds returns all the children taskIds
func (client *swarmingClient) findChildTaskIds(ctx context.Context, taskID string) ([]string, error) {
// We need the task start and completed time to narrow down the results.
parentTask, err := client.TasksClient.GetResult(ctx, &swarmingv2.TaskIdWithPerfRequest{
TaskId: taskID,
})
if err != nil {
return nil, skerr.Wrapf(err, "unable to get parent task details")
}
// runId shares the same prefix but ends with 1
runIdPrefix := parentTask.TaskId
runIdPrefix = runIdPrefix[:len(runIdPrefix)-1]
resp, err := client.TasksClient.ListTasks(ctx, &swarmingv2.TasksWithPerfRequest{
End: parentTask.CompletedTs,
Start: parentTask.CreatedTs,
State: swarmingv2.StateQuery_QUERY_ALL,
Tags: []string{fmt.Sprintf("parent_task_id:%s1", runIdPrefix)},
Limit: 1000, // 1000 is enough to find all the child tasks so we don't need to paginate
})
if err != nil {
return nil, skerr.Wrapf(err, "unable to find all the children tasks")
}
taskIDs := make([]string, len(resp.Items))
for i, t := range resp.Items {
taskIDs[i] = t.TaskId
}
return taskIDs, nil
}