go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/internal/resultdb/resultdb.go (about) 1 // Copyright 2022 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 resultdb contains logic of interacting with resultdb. 16 package resultdb 17 18 import ( 19 "context" 20 "net/http" 21 22 "go.chromium.org/luci/grpc/prpc" 23 rdbpb "go.chromium.org/luci/resultdb/proto/v1" 24 "go.chromium.org/luci/server/auth" 25 26 "go.chromium.org/luci/analysis/internal/scopedauth" 27 ) 28 29 // mockResultDBClientKey is the context key indicates using mocked resultb client in tests. 30 var mockResultDBClientKey = "used in tests only for setting the mock resultdb client" 31 32 func newResultDBClient(ctx context.Context, host string, createTransport func() (http.RoundTripper, error)) (rdbpb.ResultDBClient, error) { 33 if mockClient, ok := ctx.Value(&mockResultDBClientKey).(*rdbpb.MockResultDBClient); ok { 34 return mockClient, nil 35 } 36 37 t, err := createTransport() 38 if err != nil { 39 return nil, err 40 } 41 42 return rdbpb.NewResultDBPRPCClient( 43 &prpc.Client{ 44 C: &http.Client{Transport: t}, 45 Host: host, 46 Options: prpc.DefaultOptions(), 47 MaxContentLength: 100 * 1000 * 1000, // 100 MiB. 48 }), nil 49 } 50 51 // Client is the client to communicate with ResultDB. 52 // It wraps a rdbpb.ResultDBClient. 53 type Client struct { 54 client rdbpb.ResultDBClient 55 } 56 57 // NewClient creates a client to communicate with ResultDB, acting as 58 // the given project. Recommended way to construct a ResultDB client. 59 func NewClient(ctx context.Context, host, project string) (*Client, error) { 60 createTransport := func() (http.RoundTripper, error) { 61 return scopedauth.GetRPCTransport(ctx, project) 62 } 63 64 client, err := newResultDBClient(ctx, host, createTransport) 65 if err != nil { 66 return nil, err 67 } 68 69 return &Client{ 70 client: client, 71 }, nil 72 } 73 74 // NewPrivilegedClient creates a client to communicate with ResultDB, 75 // acting as LUCI Analysis to access data from any project. 76 // 77 // Caution: Callers must take special care to avoid "confused deputy" 78 // issues when using this client, e.g. being tricked by one project 79 // to access the resources of another. ResultDB will not check the 80 // accessed resource is in the project that was intended. 81 func NewPrivilegedClient(ctx context.Context, host string) (*Client, error) { 82 createTransport := func() (http.RoundTripper, error) { 83 return auth.GetRPCTransport(ctx, auth.AsSelf) 84 } 85 86 client, err := newResultDBClient(ctx, host, createTransport) 87 if err != nil { 88 return nil, err 89 } 90 91 return &Client{ 92 client: client, 93 }, nil 94 } 95 96 // QueryTestVariants queries a single page of test variants. 97 func (c *Client) QueryTestVariants(ctx context.Context, req *rdbpb.QueryTestVariantsRequest) (*rdbpb.QueryTestVariantsResponse, error) { 98 return c.client.QueryTestVariants(ctx, req) 99 } 100 101 // GetInvocation retrieves the invocation. 102 func (c *Client) GetInvocation(ctx context.Context, invName string) (*rdbpb.Invocation, error) { 103 inv, err := c.client.GetInvocation(ctx, &rdbpb.GetInvocationRequest{ 104 Name: invName, 105 }) 106 if err != nil { 107 return nil, err 108 } 109 return inv, nil 110 } 111 112 // BatchGetTestVariants retrieves the requested test variants. 113 func (c *Client) BatchGetTestVariants(ctx context.Context, req *rdbpb.BatchGetTestVariantsRequest) ([]*rdbpb.TestVariant, error) { 114 rsp, err := c.client.BatchGetTestVariants(ctx, req) 115 if err != nil { 116 return nil, err 117 } 118 return rsp.GetTestVariants(), nil 119 }