diff --git a/cloudbuild/apiv1/cloud_build_client.go b/cloudbuild/apiv1/cloud_build_client.go index 9541055a736..79e4b689d3d 100644 --- a/cloudbuild/apiv1/cloud_build_client.go +++ b/cloudbuild/apiv1/cloud_build_client.go @@ -23,6 +23,8 @@ import ( "net/url" "time" + "cloud.google.com/go/longrunning" + lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" @@ -114,6 +116,11 @@ type Client struct { // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD + + // LROClient is used internally to handle long-running operations. + // It is exposed so that its CallOptions can be modified if required. + // Users should not Close this client. + LROClient *lroauto.OperationsClient } // NewClient creates a new cloud build client. @@ -138,6 +145,16 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error client: cloudbuildpb.NewCloudBuildClient(connPool), } c.setGoogleClientInfo() + c.LROClient, err = lroauto.NewOperationsClient(ctx, gtransport.WithConnPool(connPool)) + if err != nil { + // This error "should not happen", since we are just reusing old connection pool + // and never actually need to dial. + // If this does happen, we could leak connp. However, we cannot close conn: + // If the user invoked the constructor with option.WithGRPCConn, + // we would close a connection that's still in use. + // TODO: investigate error conditions. + return nil, err + } return c, nil } @@ -410,10 +427,10 @@ func (c *Client) RetryBuild(ctx context.Context, req *cloudbuildpb.RetryBuildReq // CreateWorkerPool creates a WorkerPool to run the builds, and returns the new worker pool. // // This API is experimental. -func (c *Client) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { +func (c *Client) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest, opts ...gax.CallOption) (*CreateWorkerPoolOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CreateWorkerPool[0:len(c.CallOptions.CreateWorkerPool):len(c.CallOptions.CreateWorkerPool)], opts...) - var resp *cloudbuildpb.WorkerPool + var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateWorkerPool(ctx, req, settings.GRPC...) @@ -422,7 +439,9 @@ func (c *Client) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateW if err != nil { return nil, err } - return resp, nil + return &CreateWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(c.LROClient, resp), + }, nil } // GetWorkerPool returns information about a WorkerPool. @@ -460,10 +479,10 @@ func (c *Client) DeleteWorkerPool(ctx context.Context, req *cloudbuildpb.DeleteW // UpdateWorkerPool update a WorkerPool. // // This API is experimental. -func (c *Client) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { +func (c *Client) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest, opts ...gax.CallOption) (*UpdateWorkerPoolOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateWorkerPool[0:len(c.CallOptions.UpdateWorkerPool):len(c.CallOptions.UpdateWorkerPool)], opts...) - var resp *cloudbuildpb.WorkerPool + var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateWorkerPool(ctx, req, settings.GRPC...) @@ -472,7 +491,9 @@ func (c *Client) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateW if err != nil { return nil, err } - return resp, nil + return &UpdateWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(c.LROClient, resp), + }, nil } // ListWorkerPools list project's WorkerPools. @@ -534,3 +555,141 @@ func (it *BuildIterator) takeBuf() interface{} { it.items = nil return b } + +// CreateWorkerPoolOperation manages a long-running operation from CreateWorkerPool. +type CreateWorkerPoolOperation struct { + lro *longrunning.Operation +} + +// CreateWorkerPoolOperation returns a new CreateWorkerPoolOperation from a given name. +// The name must be that of a previously created CreateWorkerPoolOperation, possibly from a different process. +func (c *Client) CreateWorkerPoolOperation(name string) *CreateWorkerPoolOperation { + return &CreateWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), + } +} + +// Wait blocks until the long-running operation is completed, returning the response and any errors encountered. +// +// See documentation of Poll for error-handling information. +func (op *CreateWorkerPoolOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { + var resp cloudbuildpb.WorkerPool + if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { + return nil, err + } + return &resp, nil +} + +// Poll fetches the latest state of the long-running operation. +// +// Poll also fetches the latest metadata, which can be retrieved by Metadata. +// +// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and +// the operation has completed with failure, the error is returned and op.Done will return true. +// If Poll succeeds and the operation has completed successfully, +// op.Done will return true, and the response of the operation is returned. +// If Poll succeeds and the operation has not completed, the returned response and error are both nil. +func (op *CreateWorkerPoolOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { + var resp cloudbuildpb.WorkerPool + if err := op.lro.Poll(ctx, &resp, opts...); err != nil { + return nil, err + } + if !op.Done() { + return nil, nil + } + return &resp, nil +} + +// Metadata returns metadata associated with the long-running operation. +// Metadata itself does not contact the server, but Poll does. +// To get the latest metadata, call this method after a successful call to Poll. +// If the metadata is not available, the returned metadata and error are both nil. +func (op *CreateWorkerPoolOperation) Metadata() (*cloudbuildpb.CreateWorkerPoolOperationMetadata, error) { + var meta cloudbuildpb.CreateWorkerPoolOperationMetadata + if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { + return nil, nil + } else if err != nil { + return nil, err + } + return &meta, nil +} + +// Done reports whether the long-running operation has completed. +func (op *CreateWorkerPoolOperation) Done() bool { + return op.lro.Done() +} + +// Name returns the name of the long-running operation. +// The name is assigned by the server and is unique within the service from which the operation is created. +func (op *CreateWorkerPoolOperation) Name() string { + return op.lro.Name() +} + +// UpdateWorkerPoolOperation manages a long-running operation from UpdateWorkerPool. +type UpdateWorkerPoolOperation struct { + lro *longrunning.Operation +} + +// UpdateWorkerPoolOperation returns a new UpdateWorkerPoolOperation from a given name. +// The name must be that of a previously created UpdateWorkerPoolOperation, possibly from a different process. +func (c *Client) UpdateWorkerPoolOperation(name string) *UpdateWorkerPoolOperation { + return &UpdateWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), + } +} + +// Wait blocks until the long-running operation is completed, returning the response and any errors encountered. +// +// See documentation of Poll for error-handling information. +func (op *UpdateWorkerPoolOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { + var resp cloudbuildpb.WorkerPool + if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { + return nil, err + } + return &resp, nil +} + +// Poll fetches the latest state of the long-running operation. +// +// Poll also fetches the latest metadata, which can be retrieved by Metadata. +// +// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and +// the operation has completed with failure, the error is returned and op.Done will return true. +// If Poll succeeds and the operation has completed successfully, +// op.Done will return true, and the response of the operation is returned. +// If Poll succeeds and the operation has not completed, the returned response and error are both nil. +func (op *UpdateWorkerPoolOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { + var resp cloudbuildpb.WorkerPool + if err := op.lro.Poll(ctx, &resp, opts...); err != nil { + return nil, err + } + if !op.Done() { + return nil, nil + } + return &resp, nil +} + +// Metadata returns metadata associated with the long-running operation. +// Metadata itself does not contact the server, but Poll does. +// To get the latest metadata, call this method after a successful call to Poll. +// If the metadata is not available, the returned metadata and error are both nil. +func (op *UpdateWorkerPoolOperation) Metadata() (*cloudbuildpb.UpdateWorkerPoolOperationMetadata, error) { + var meta cloudbuildpb.UpdateWorkerPoolOperationMetadata + if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { + return nil, nil + } else if err != nil { + return nil, err + } + return &meta, nil +} + +// Done reports whether the long-running operation has completed. +func (op *UpdateWorkerPoolOperation) Done() bool { + return op.lro.Done() +} + +// Name returns the name of the long-running operation. +// The name is assigned by the server and is unique within the service from which the operation is created. +func (op *UpdateWorkerPoolOperation) Name() string { + return op.lro.Name() +} diff --git a/cloudbuild/apiv1/mock_test.go b/cloudbuild/apiv1/mock_test.go deleted file mode 100644 index 43d03ecfe11..00000000000 --- a/cloudbuild/apiv1/mock_test.go +++ /dev/null @@ -1,1312 +0,0 @@ -// Copyright 2019 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by gapic-generator. DO NOT EDIT. - -package cloudbuild - -import ( - "context" - "flag" - "fmt" - "io" - "log" - "net" - "os" - "strings" - "testing" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" - emptypb "github.com/golang/protobuf/ptypes/empty" - "google.golang.org/api/option" - cloudbuildpb "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1" - longrunningpb "google.golang.org/genproto/googleapis/longrunning" - - status "google.golang.org/genproto/googleapis/rpc/status" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - - gstatus "google.golang.org/grpc/status" -) - -var _ = io.EOF -var _ = ptypes.MarshalAny -var _ status.Status - -type mockCloudBuildServer struct { - // Embed for forward compatibility. - // Tests will keep working if more methods are added - // in the future. - cloudbuildpb.CloudBuildServer - - reqs []proto.Message - - // If set, all calls return this error. - err error - - // responses to return if err == nil - resps []proto.Message -} - -func (s *mockCloudBuildServer) CreateBuild(ctx context.Context, req *cloudbuildpb.CreateBuildRequest) (*longrunningpb.Operation, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*longrunningpb.Operation), nil -} - -func (s *mockCloudBuildServer) GetBuild(ctx context.Context, req *cloudbuildpb.GetBuildRequest) (*cloudbuildpb.Build, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.Build), nil -} - -func (s *mockCloudBuildServer) ListBuilds(ctx context.Context, req *cloudbuildpb.ListBuildsRequest) (*cloudbuildpb.ListBuildsResponse, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.ListBuildsResponse), nil -} - -func (s *mockCloudBuildServer) CancelBuild(ctx context.Context, req *cloudbuildpb.CancelBuildRequest) (*cloudbuildpb.Build, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.Build), nil -} - -func (s *mockCloudBuildServer) RetryBuild(ctx context.Context, req *cloudbuildpb.RetryBuildRequest) (*longrunningpb.Operation, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*longrunningpb.Operation), nil -} - -func (s *mockCloudBuildServer) CreateBuildTrigger(ctx context.Context, req *cloudbuildpb.CreateBuildTriggerRequest) (*cloudbuildpb.BuildTrigger, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.BuildTrigger), nil -} - -func (s *mockCloudBuildServer) GetBuildTrigger(ctx context.Context, req *cloudbuildpb.GetBuildTriggerRequest) (*cloudbuildpb.BuildTrigger, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.BuildTrigger), nil -} - -func (s *mockCloudBuildServer) ListBuildTriggers(ctx context.Context, req *cloudbuildpb.ListBuildTriggersRequest) (*cloudbuildpb.ListBuildTriggersResponse, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.ListBuildTriggersResponse), nil -} - -func (s *mockCloudBuildServer) DeleteBuildTrigger(ctx context.Context, req *cloudbuildpb.DeleteBuildTriggerRequest) (*emptypb.Empty, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*emptypb.Empty), nil -} - -func (s *mockCloudBuildServer) UpdateBuildTrigger(ctx context.Context, req *cloudbuildpb.UpdateBuildTriggerRequest) (*cloudbuildpb.BuildTrigger, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.BuildTrigger), nil -} - -func (s *mockCloudBuildServer) RunBuildTrigger(ctx context.Context, req *cloudbuildpb.RunBuildTriggerRequest) (*longrunningpb.Operation, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*longrunningpb.Operation), nil -} - -func (s *mockCloudBuildServer) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest) (*cloudbuildpb.WorkerPool, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.WorkerPool), nil -} - -func (s *mockCloudBuildServer) GetWorkerPool(ctx context.Context, req *cloudbuildpb.GetWorkerPoolRequest) (*cloudbuildpb.WorkerPool, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.WorkerPool), nil -} - -func (s *mockCloudBuildServer) DeleteWorkerPool(ctx context.Context, req *cloudbuildpb.DeleteWorkerPoolRequest) (*emptypb.Empty, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*emptypb.Empty), nil -} - -func (s *mockCloudBuildServer) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest) (*cloudbuildpb.WorkerPool, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.WorkerPool), nil -} - -func (s *mockCloudBuildServer) ListWorkerPools(ctx context.Context, req *cloudbuildpb.ListWorkerPoolsRequest) (*cloudbuildpb.ListWorkerPoolsResponse, error) { - md, _ := metadata.FromIncomingContext(ctx) - if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { - return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) - } - s.reqs = append(s.reqs, req) - if s.err != nil { - return nil, s.err - } - return s.resps[0].(*cloudbuildpb.ListWorkerPoolsResponse), nil -} - -// clientOpt is the option tests should use to connect to the test server. -// It is initialized by TestMain. -var clientOpt option.ClientOption - -var ( - mockCloudBuild mockCloudBuildServer -) - -func TestMain(m *testing.M) { - flag.Parse() - - serv := grpc.NewServer() - cloudbuildpb.RegisterCloudBuildServer(serv, &mockCloudBuild) - - lis, err := net.Listen("tcp", "localhost:0") - if err != nil { - log.Fatal(err) - } - go serv.Serve(lis) - - conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) - if err != nil { - log.Fatal(err) - } - clientOpt = option.WithGRPCConn(conn) - - os.Exit(m.Run()) -} - -func TestCloudBuildCreateBuild(t *testing.T) { - var name string = "name3373707" - var done bool = true - var expectedResponse = &longrunningpb.Operation{ - Name: name, - Done: done, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var build *cloudbuildpb.Build = &cloudbuildpb.Build{} - var request = &cloudbuildpb.CreateBuildRequest{ - ProjectId: projectId, - Build: build, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.CreateBuild(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildCreateBuildError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var build *cloudbuildpb.Build = &cloudbuildpb.Build{} - var request = &cloudbuildpb.CreateBuildRequest{ - ProjectId: projectId, - Build: build, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.CreateBuild(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildGetBuild(t *testing.T) { - var id2 string = "id23227150" - var projectId2 string = "projectId2939242356" - var statusDetail string = "statusDetail2089931070" - var logsBucket string = "logsBucket1565363834" - var buildTriggerId string = "buildTriggerId1105559411" - var logUrl string = "logUrl342054388" - var expectedResponse = &cloudbuildpb.Build{ - Id: id2, - ProjectId: projectId2, - StatusDetail: statusDetail, - LogsBucket: logsBucket, - BuildTriggerId: buildTriggerId, - LogUrl: logUrl, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var id string = "id3355" - var request = &cloudbuildpb.GetBuildRequest{ - ProjectId: projectId, - Id: id, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.GetBuild(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildGetBuildError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var id string = "id3355" - var request = &cloudbuildpb.GetBuildRequest{ - ProjectId: projectId, - Id: id, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.GetBuild(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildListBuilds(t *testing.T) { - var nextPageToken string = "" - var buildsElement *cloudbuildpb.Build = &cloudbuildpb.Build{} - var builds = []*cloudbuildpb.Build{buildsElement} - var expectedResponse = &cloudbuildpb.ListBuildsResponse{ - NextPageToken: nextPageToken, - Builds: builds, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var request = &cloudbuildpb.ListBuildsRequest{ - ProjectId: projectId, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.ListBuilds(context.Background(), request).Next() - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - want := (interface{})(expectedResponse.Builds[0]) - got := (interface{})(resp) - var ok bool - - switch want := (want).(type) { - case proto.Message: - ok = proto.Equal(want, got.(proto.Message)) - default: - ok = want == got - } - if !ok { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildListBuildsError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var request = &cloudbuildpb.ListBuildsRequest{ - ProjectId: projectId, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.ListBuilds(context.Background(), request).Next() - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildCancelBuild(t *testing.T) { - var id2 string = "id23227150" - var projectId2 string = "projectId2939242356" - var statusDetail string = "statusDetail2089931070" - var logsBucket string = "logsBucket1565363834" - var buildTriggerId string = "buildTriggerId1105559411" - var logUrl string = "logUrl342054388" - var expectedResponse = &cloudbuildpb.Build{ - Id: id2, - ProjectId: projectId2, - StatusDetail: statusDetail, - LogsBucket: logsBucket, - BuildTriggerId: buildTriggerId, - LogUrl: logUrl, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var id string = "id3355" - var request = &cloudbuildpb.CancelBuildRequest{ - ProjectId: projectId, - Id: id, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.CancelBuild(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildCancelBuildError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var id string = "id3355" - var request = &cloudbuildpb.CancelBuildRequest{ - ProjectId: projectId, - Id: id, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.CancelBuild(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildCreateBuildTrigger(t *testing.T) { - var id string = "id3355" - var description string = "description-1724546052" - var name string = "name3373707" - var filename string = "filename-734768633" - var disabled bool = true - var expectedResponse = &cloudbuildpb.BuildTrigger{ - Id: id, - Description: description, - Name: name, - BuildTemplate: &cloudbuildpb.BuildTrigger_Filename{ - Filename: filename, - }, - Disabled: disabled, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var trigger *cloudbuildpb.BuildTrigger = &cloudbuildpb.BuildTrigger{} - var request = &cloudbuildpb.CreateBuildTriggerRequest{ - ProjectId: projectId, - Trigger: trigger, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.CreateBuildTrigger(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildCreateBuildTriggerError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var trigger *cloudbuildpb.BuildTrigger = &cloudbuildpb.BuildTrigger{} - var request = &cloudbuildpb.CreateBuildTriggerRequest{ - ProjectId: projectId, - Trigger: trigger, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.CreateBuildTrigger(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildGetBuildTrigger(t *testing.T) { - var id string = "id3355" - var description string = "description-1724546052" - var name string = "name3373707" - var filename string = "filename-734768633" - var disabled bool = true - var expectedResponse = &cloudbuildpb.BuildTrigger{ - Id: id, - Description: description, - Name: name, - BuildTemplate: &cloudbuildpb.BuildTrigger_Filename{ - Filename: filename, - }, - Disabled: disabled, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var triggerId string = "triggerId1363517698" - var request = &cloudbuildpb.GetBuildTriggerRequest{ - ProjectId: projectId, - TriggerId: triggerId, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.GetBuildTrigger(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildGetBuildTriggerError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var triggerId string = "triggerId1363517698" - var request = &cloudbuildpb.GetBuildTriggerRequest{ - ProjectId: projectId, - TriggerId: triggerId, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.GetBuildTrigger(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildListBuildTriggers(t *testing.T) { - var nextPageToken string = "nextPageToken-1530815211" - var expectedResponse = &cloudbuildpb.ListBuildTriggersResponse{ - NextPageToken: nextPageToken, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var request = &cloudbuildpb.ListBuildTriggersRequest{ - ProjectId: projectId, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.ListBuildTriggers(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildListBuildTriggersError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var request = &cloudbuildpb.ListBuildTriggersRequest{ - ProjectId: projectId, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.ListBuildTriggers(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildDeleteBuildTrigger(t *testing.T) { - var expectedResponse *emptypb.Empty = &emptypb.Empty{} - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var triggerId string = "triggerId1363517698" - var request = &cloudbuildpb.DeleteBuildTriggerRequest{ - ProjectId: projectId, - TriggerId: triggerId, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - err = c.DeleteBuildTrigger(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - -} - -func TestCloudBuildDeleteBuildTriggerError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var triggerId string = "triggerId1363517698" - var request = &cloudbuildpb.DeleteBuildTriggerRequest{ - ProjectId: projectId, - TriggerId: triggerId, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - err = c.DeleteBuildTrigger(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } -} -func TestCloudBuildUpdateBuildTrigger(t *testing.T) { - var id string = "id3355" - var description string = "description-1724546052" - var name string = "name3373707" - var filename string = "filename-734768633" - var disabled bool = true - var expectedResponse = &cloudbuildpb.BuildTrigger{ - Id: id, - Description: description, - Name: name, - BuildTemplate: &cloudbuildpb.BuildTrigger_Filename{ - Filename: filename, - }, - Disabled: disabled, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var triggerId string = "triggerId1363517698" - var trigger *cloudbuildpb.BuildTrigger = &cloudbuildpb.BuildTrigger{} - var request = &cloudbuildpb.UpdateBuildTriggerRequest{ - ProjectId: projectId, - TriggerId: triggerId, - Trigger: trigger, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.UpdateBuildTrigger(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildUpdateBuildTriggerError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var triggerId string = "triggerId1363517698" - var trigger *cloudbuildpb.BuildTrigger = &cloudbuildpb.BuildTrigger{} - var request = &cloudbuildpb.UpdateBuildTriggerRequest{ - ProjectId: projectId, - TriggerId: triggerId, - Trigger: trigger, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.UpdateBuildTrigger(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildRunBuildTrigger(t *testing.T) { - var name string = "name3373707" - var done bool = true - var expectedResponse = &longrunningpb.Operation{ - Name: name, - Done: done, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var triggerId string = "triggerId1363517698" - var source *cloudbuildpb.RepoSource = &cloudbuildpb.RepoSource{} - var request = &cloudbuildpb.RunBuildTriggerRequest{ - ProjectId: projectId, - TriggerId: triggerId, - Source: source, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.RunBuildTrigger(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildRunBuildTriggerError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var triggerId string = "triggerId1363517698" - var source *cloudbuildpb.RepoSource = &cloudbuildpb.RepoSource{} - var request = &cloudbuildpb.RunBuildTriggerRequest{ - ProjectId: projectId, - TriggerId: triggerId, - Source: source, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.RunBuildTrigger(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildRetryBuild(t *testing.T) { - var name string = "name3373707" - var done bool = true - var expectedResponse = &longrunningpb.Operation{ - Name: name, - Done: done, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var projectId string = "projectId-1969970175" - var id string = "id3355" - var request = &cloudbuildpb.RetryBuildRequest{ - ProjectId: projectId, - Id: id, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.RetryBuild(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildRetryBuildError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var projectId string = "projectId-1969970175" - var id string = "id3355" - var request = &cloudbuildpb.RetryBuildRequest{ - ProjectId: projectId, - Id: id, - } - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.RetryBuild(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildCreateWorkerPool(t *testing.T) { - var name string = "name3373707" - var projectId string = "projectId-1969970175" - var serviceAccountEmail string = "serviceAccountEmail-1300473088" - var workerCount int64 = 372044046 - var expectedResponse = &cloudbuildpb.WorkerPool{ - Name: name, - ProjectId: projectId, - ServiceAccountEmail: serviceAccountEmail, - WorkerCount: workerCount, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var request *cloudbuildpb.CreateWorkerPoolRequest = &cloudbuildpb.CreateWorkerPoolRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.CreateWorkerPool(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildCreateWorkerPoolError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var request *cloudbuildpb.CreateWorkerPoolRequest = &cloudbuildpb.CreateWorkerPoolRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.CreateWorkerPool(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildGetWorkerPool(t *testing.T) { - var name string = "name3373707" - var projectId string = "projectId-1969970175" - var serviceAccountEmail string = "serviceAccountEmail-1300473088" - var workerCount int64 = 372044046 - var expectedResponse = &cloudbuildpb.WorkerPool{ - Name: name, - ProjectId: projectId, - ServiceAccountEmail: serviceAccountEmail, - WorkerCount: workerCount, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var request *cloudbuildpb.GetWorkerPoolRequest = &cloudbuildpb.GetWorkerPoolRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.GetWorkerPool(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildGetWorkerPoolError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var request *cloudbuildpb.GetWorkerPoolRequest = &cloudbuildpb.GetWorkerPoolRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.GetWorkerPool(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildDeleteWorkerPool(t *testing.T) { - var expectedResponse *emptypb.Empty = &emptypb.Empty{} - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var request *cloudbuildpb.DeleteWorkerPoolRequest = &cloudbuildpb.DeleteWorkerPoolRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - err = c.DeleteWorkerPool(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - -} - -func TestCloudBuildDeleteWorkerPoolError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var request *cloudbuildpb.DeleteWorkerPoolRequest = &cloudbuildpb.DeleteWorkerPoolRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - err = c.DeleteWorkerPool(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } -} -func TestCloudBuildUpdateWorkerPool(t *testing.T) { - var name string = "name3373707" - var projectId string = "projectId-1969970175" - var serviceAccountEmail string = "serviceAccountEmail-1300473088" - var workerCount int64 = 372044046 - var expectedResponse = &cloudbuildpb.WorkerPool{ - Name: name, - ProjectId: projectId, - ServiceAccountEmail: serviceAccountEmail, - WorkerCount: workerCount, - } - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var request *cloudbuildpb.UpdateWorkerPoolRequest = &cloudbuildpb.UpdateWorkerPoolRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.UpdateWorkerPool(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildUpdateWorkerPoolError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var request *cloudbuildpb.UpdateWorkerPoolRequest = &cloudbuildpb.UpdateWorkerPoolRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.UpdateWorkerPool(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} -func TestCloudBuildListWorkerPools(t *testing.T) { - var expectedResponse *cloudbuildpb.ListWorkerPoolsResponse = &cloudbuildpb.ListWorkerPoolsResponse{} - - mockCloudBuild.err = nil - mockCloudBuild.reqs = nil - - mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) - - var request *cloudbuildpb.ListWorkerPoolsRequest = &cloudbuildpb.ListWorkerPoolsRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.ListWorkerPools(context.Background(), request) - - if err != nil { - t.Fatal(err) - } - - if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { - t.Errorf("wrong request %q, want %q", got, want) - } - - if want, got := expectedResponse, resp; !proto.Equal(want, got) { - t.Errorf("wrong response %q, want %q)", got, want) - } -} - -func TestCloudBuildListWorkerPoolsError(t *testing.T) { - errCode := codes.PermissionDenied - mockCloudBuild.err = gstatus.Error(errCode, "test error") - - var request *cloudbuildpb.ListWorkerPoolsRequest = &cloudbuildpb.ListWorkerPoolsRequest{} - - c, err := NewClient(context.Background(), clientOpt) - if err != nil { - t.Fatal(err) - } - - resp, err := c.ListWorkerPools(context.Background(), request) - - if st, ok := gstatus.FromError(err); !ok { - t.Errorf("got error %v, expected grpc error", err) - } else if c := st.Code(); c != errCode { - t.Errorf("got error code %q, want %q", c, errCode) - } - _ = resp -} diff --git a/cloudbuild/apiv1/v2/cloud_build_client.go b/cloudbuild/apiv1/v2/cloud_build_client.go index 9cbf64437f1..ece20aeabc1 100644 --- a/cloudbuild/apiv1/v2/cloud_build_client.go +++ b/cloudbuild/apiv1/v2/cloud_build_client.go @@ -193,11 +193,14 @@ type internalClient interface { RunBuildTrigger(context.Context, *cloudbuildpb.RunBuildTriggerRequest, ...gax.CallOption) (*RunBuildTriggerOperation, error) RunBuildTriggerOperation(name string) *RunBuildTriggerOperation ReceiveTriggerWebhook(context.Context, *cloudbuildpb.ReceiveTriggerWebhookRequest, ...gax.CallOption) (*cloudbuildpb.ReceiveTriggerWebhookResponse, error) - CreateWorkerPool(context.Context, *cloudbuildpb.CreateWorkerPoolRequest, ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) + CreateWorkerPool(context.Context, *cloudbuildpb.CreateWorkerPoolRequest, ...gax.CallOption) (*CreateWorkerPoolOperation, error) + CreateWorkerPoolOperation(name string) *CreateWorkerPoolOperation GetWorkerPool(context.Context, *cloudbuildpb.GetWorkerPoolRequest, ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) - DeleteWorkerPool(context.Context, *cloudbuildpb.DeleteWorkerPoolRequest, ...gax.CallOption) error - UpdateWorkerPool(context.Context, *cloudbuildpb.UpdateWorkerPoolRequest, ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) - ListWorkerPools(context.Context, *cloudbuildpb.ListWorkerPoolsRequest, ...gax.CallOption) (*cloudbuildpb.ListWorkerPoolsResponse, error) + DeleteWorkerPool(context.Context, *cloudbuildpb.DeleteWorkerPoolRequest, ...gax.CallOption) (*DeleteWorkerPoolOperation, error) + DeleteWorkerPoolOperation(name string) *DeleteWorkerPoolOperation + UpdateWorkerPool(context.Context, *cloudbuildpb.UpdateWorkerPoolRequest, ...gax.CallOption) (*UpdateWorkerPoolOperation, error) + UpdateWorkerPoolOperation(name string) *UpdateWorkerPoolOperation + ListWorkerPools(context.Context, *cloudbuildpb.ListWorkerPoolsRequest, ...gax.CallOption) *WorkerPoolIterator } // Client is a client for interacting with Cloud Build API. @@ -373,38 +376,46 @@ func (c *Client) ReceiveTriggerWebhook(ctx context.Context, req *cloudbuildpb.Re return c.internalClient.ReceiveTriggerWebhook(ctx, req, opts...) } -// CreateWorkerPool creates a WorkerPool to run the builds, and returns the new worker pool. -// -// This API is experimental. -func (c *Client) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { +// CreateWorkerPool creates a WorkerPool. +func (c *Client) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest, opts ...gax.CallOption) (*CreateWorkerPoolOperation, error) { return c.internalClient.CreateWorkerPool(ctx, req, opts...) } -// GetWorkerPool returns information about a WorkerPool. -// -// This API is experimental. +// CreateWorkerPoolOperation returns a new CreateWorkerPoolOperation from a given name. +// The name must be that of a previously created CreateWorkerPoolOperation, possibly from a different process. +func (c *Client) CreateWorkerPoolOperation(name string) *CreateWorkerPoolOperation { + return c.internalClient.CreateWorkerPoolOperation(name) +} + +// GetWorkerPool returns details of a WorkerPool. func (c *Client) GetWorkerPool(ctx context.Context, req *cloudbuildpb.GetWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { return c.internalClient.GetWorkerPool(ctx, req, opts...) } -// DeleteWorkerPool deletes a WorkerPool by its project ID and WorkerPool name. -// -// This API is experimental. -func (c *Client) DeleteWorkerPool(ctx context.Context, req *cloudbuildpb.DeleteWorkerPoolRequest, opts ...gax.CallOption) error { +// DeleteWorkerPool deletes a WorkerPool. +func (c *Client) DeleteWorkerPool(ctx context.Context, req *cloudbuildpb.DeleteWorkerPoolRequest, opts ...gax.CallOption) (*DeleteWorkerPoolOperation, error) { return c.internalClient.DeleteWorkerPool(ctx, req, opts...) } -// UpdateWorkerPool update a WorkerPool. -// -// This API is experimental. -func (c *Client) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { +// DeleteWorkerPoolOperation returns a new DeleteWorkerPoolOperation from a given name. +// The name must be that of a previously created DeleteWorkerPoolOperation, possibly from a different process. +func (c *Client) DeleteWorkerPoolOperation(name string) *DeleteWorkerPoolOperation { + return c.internalClient.DeleteWorkerPoolOperation(name) +} + +// UpdateWorkerPool updates a WorkerPool. +func (c *Client) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest, opts ...gax.CallOption) (*UpdateWorkerPoolOperation, error) { return c.internalClient.UpdateWorkerPool(ctx, req, opts...) } -// ListWorkerPools list project’s WorkerPools. -// -// This API is experimental. -func (c *Client) ListWorkerPools(ctx context.Context, req *cloudbuildpb.ListWorkerPoolsRequest, opts ...gax.CallOption) (*cloudbuildpb.ListWorkerPoolsResponse, error) { +// UpdateWorkerPoolOperation returns a new UpdateWorkerPoolOperation from a given name. +// The name must be that of a previously created UpdateWorkerPoolOperation, possibly from a different process. +func (c *Client) UpdateWorkerPoolOperation(name string) *UpdateWorkerPoolOperation { + return c.internalClient.UpdateWorkerPoolOperation(name) +} + +// ListWorkerPools lists WorkerPools. +func (c *Client) ListWorkerPools(ctx context.Context, req *cloudbuildpb.ListWorkerPoolsRequest, opts ...gax.CallOption) *WorkerPoolIterator { return c.internalClient.ListWorkerPools(ctx, req, opts...) } @@ -798,15 +809,16 @@ func (c *gRPCClient) ReceiveTriggerWebhook(ctx context.Context, req *cloudbuildp return resp, nil } -func (c *gRPCClient) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { +func (c *gRPCClient) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest, opts ...gax.CallOption) (*CreateWorkerPoolOperation, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 600000*time.Millisecond) defer cancel() ctx = cctx } - ctx = insertMetadata(ctx, c.xGoogMetadata) + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).CreateWorkerPool[0:len((*c.CallOptions).CreateWorkerPool):len((*c.CallOptions).CreateWorkerPool)], opts...) - var resp *cloudbuildpb.WorkerPool + var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateWorkerPool(ctx, req, settings.GRPC...) @@ -815,7 +827,9 @@ func (c *gRPCClient) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.Cre if err != nil { return nil, err } - return resp, nil + return &CreateWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(*c.LROClient, resp), + }, nil } func (c *gRPCClient) GetWorkerPool(ctx context.Context, req *cloudbuildpb.GetWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { @@ -824,7 +838,8 @@ func (c *gRPCClient) GetWorkerPool(ctx context.Context, req *cloudbuildpb.GetWor defer cancel() ctx = cctx } - ctx = insertMetadata(ctx, c.xGoogMetadata) + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).GetWorkerPool[0:len((*c.CallOptions).GetWorkerPool):len((*c.CallOptions).GetWorkerPool)], opts...) var resp *cloudbuildpb.WorkerPool err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { @@ -838,31 +853,39 @@ func (c *gRPCClient) GetWorkerPool(ctx context.Context, req *cloudbuildpb.GetWor return resp, nil } -func (c *gRPCClient) DeleteWorkerPool(ctx context.Context, req *cloudbuildpb.DeleteWorkerPoolRequest, opts ...gax.CallOption) error { +func (c *gRPCClient) DeleteWorkerPool(ctx context.Context, req *cloudbuildpb.DeleteWorkerPoolRequest, opts ...gax.CallOption) (*DeleteWorkerPoolOperation, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 600000*time.Millisecond) defer cancel() ctx = cctx } - ctx = insertMetadata(ctx, c.xGoogMetadata) + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).DeleteWorkerPool[0:len((*c.CallOptions).DeleteWorkerPool):len((*c.CallOptions).DeleteWorkerPool)], opts...) + var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error - _, err = c.client.DeleteWorkerPool(ctx, req, settings.GRPC...) + resp, err = c.client.DeleteWorkerPool(ctx, req, settings.GRPC...) return err }, opts...) - return err + if err != nil { + return nil, err + } + return &DeleteWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(*c.LROClient, resp), + }, nil } -func (c *gRPCClient) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { +func (c *gRPCClient) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest, opts ...gax.CallOption) (*UpdateWorkerPoolOperation, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 600000*time.Millisecond) defer cancel() ctx = cctx } - ctx = insertMetadata(ctx, c.xGoogMetadata) + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "worker_pool.name", url.QueryEscape(req.GetWorkerPool().GetName()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).UpdateWorkerPool[0:len((*c.CallOptions).UpdateWorkerPool):len((*c.CallOptions).UpdateWorkerPool)], opts...) - var resp *cloudbuildpb.WorkerPool + var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateWorkerPool(ctx, req, settings.GRPC...) @@ -871,27 +894,49 @@ func (c *gRPCClient) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.Upd if err != nil { return nil, err } - return resp, nil + return &UpdateWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(*c.LROClient, resp), + }, nil } -func (c *gRPCClient) ListWorkerPools(ctx context.Context, req *cloudbuildpb.ListWorkerPoolsRequest, opts ...gax.CallOption) (*cloudbuildpb.ListWorkerPoolsResponse, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 600000*time.Millisecond) - defer cancel() - ctx = cctx - } - ctx = insertMetadata(ctx, c.xGoogMetadata) +func (c *gRPCClient) ListWorkerPools(ctx context.Context, req *cloudbuildpb.ListWorkerPoolsRequest, opts ...gax.CallOption) *WorkerPoolIterator { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListWorkerPools[0:len((*c.CallOptions).ListWorkerPools):len((*c.CallOptions).ListWorkerPools)], opts...) - var resp *cloudbuildpb.ListWorkerPoolsResponse - err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { - var err error - resp, err = c.client.ListWorkerPools(ctx, req, settings.GRPC...) - return err - }, opts...) - if err != nil { - return nil, err + it := &WorkerPoolIterator{} + req = proto.Clone(req).(*cloudbuildpb.ListWorkerPoolsRequest) + it.InternalFetch = func(pageSize int, pageToken string) ([]*cloudbuildpb.WorkerPool, string, error) { + var resp *cloudbuildpb.ListWorkerPoolsResponse + req.PageToken = pageToken + if pageSize > math.MaxInt32 { + req.PageSize = math.MaxInt32 + } else { + req.PageSize = int32(pageSize) + } + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.client.ListWorkerPools(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, "", err + } + + it.Response = resp + return resp.GetWorkerPools(), resp.GetNextPageToken(), nil } - return resp, nil + fetch := func(pageSize int, pageToken string) (string, error) { + items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) + if err != nil { + return "", err + } + it.items = append(it.items, items...) + return nextPageToken, nil + } + it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) + it.pageInfo.MaxSize = int(req.GetPageSize()) + it.pageInfo.Token = req.GetPageToken() + return it } // CreateBuildOperation manages a long-running operation from CreateBuild. @@ -963,6 +1008,133 @@ func (op *CreateBuildOperation) Name() string { return op.lro.Name() } +// CreateWorkerPoolOperation manages a long-running operation from CreateWorkerPool. +type CreateWorkerPoolOperation struct { + lro *longrunning.Operation +} + +// CreateWorkerPoolOperation returns a new CreateWorkerPoolOperation from a given name. +// The name must be that of a previously created CreateWorkerPoolOperation, possibly from a different process. +func (c *gRPCClient) CreateWorkerPoolOperation(name string) *CreateWorkerPoolOperation { + return &CreateWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}), + } +} + +// Wait blocks until the long-running operation is completed, returning the response and any errors encountered. +// +// See documentation of Poll for error-handling information. +func (op *CreateWorkerPoolOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { + var resp cloudbuildpb.WorkerPool + if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { + return nil, err + } + return &resp, nil +} + +// Poll fetches the latest state of the long-running operation. +// +// Poll also fetches the latest metadata, which can be retrieved by Metadata. +// +// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and +// the operation has completed with failure, the error is returned and op.Done will return true. +// If Poll succeeds and the operation has completed successfully, +// op.Done will return true, and the response of the operation is returned. +// If Poll succeeds and the operation has not completed, the returned response and error are both nil. +func (op *CreateWorkerPoolOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { + var resp cloudbuildpb.WorkerPool + if err := op.lro.Poll(ctx, &resp, opts...); err != nil { + return nil, err + } + if !op.Done() { + return nil, nil + } + return &resp, nil +} + +// Metadata returns metadata associated with the long-running operation. +// Metadata itself does not contact the server, but Poll does. +// To get the latest metadata, call this method after a successful call to Poll. +// If the metadata is not available, the returned metadata and error are both nil. +func (op *CreateWorkerPoolOperation) Metadata() (*cloudbuildpb.CreateWorkerPoolOperationMetadata, error) { + var meta cloudbuildpb.CreateWorkerPoolOperationMetadata + if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { + return nil, nil + } else if err != nil { + return nil, err + } + return &meta, nil +} + +// Done reports whether the long-running operation has completed. +func (op *CreateWorkerPoolOperation) Done() bool { + return op.lro.Done() +} + +// Name returns the name of the long-running operation. +// The name is assigned by the server and is unique within the service from which the operation is created. +func (op *CreateWorkerPoolOperation) Name() string { + return op.lro.Name() +} + +// DeleteWorkerPoolOperation manages a long-running operation from DeleteWorkerPool. +type DeleteWorkerPoolOperation struct { + lro *longrunning.Operation +} + +// DeleteWorkerPoolOperation returns a new DeleteWorkerPoolOperation from a given name. +// The name must be that of a previously created DeleteWorkerPoolOperation, possibly from a different process. +func (c *gRPCClient) DeleteWorkerPoolOperation(name string) *DeleteWorkerPoolOperation { + return &DeleteWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}), + } +} + +// Wait blocks until the long-running operation is completed, returning the response and any errors encountered. +// +// See documentation of Poll for error-handling information. +func (op *DeleteWorkerPoolOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { + return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...) +} + +// Poll fetches the latest state of the long-running operation. +// +// Poll also fetches the latest metadata, which can be retrieved by Metadata. +// +// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and +// the operation has completed with failure, the error is returned and op.Done will return true. +// If Poll succeeds and the operation has completed successfully, +// op.Done will return true, and the response of the operation is returned. +// If Poll succeeds and the operation has not completed, the returned response and error are both nil. +func (op *DeleteWorkerPoolOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { + return op.lro.Poll(ctx, nil, opts...) +} + +// Metadata returns metadata associated with the long-running operation. +// Metadata itself does not contact the server, but Poll does. +// To get the latest metadata, call this method after a successful call to Poll. +// If the metadata is not available, the returned metadata and error are both nil. +func (op *DeleteWorkerPoolOperation) Metadata() (*cloudbuildpb.DeleteWorkerPoolOperationMetadata, error) { + var meta cloudbuildpb.DeleteWorkerPoolOperationMetadata + if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { + return nil, nil + } else if err != nil { + return nil, err + } + return &meta, nil +} + +// Done reports whether the long-running operation has completed. +func (op *DeleteWorkerPoolOperation) Done() bool { + return op.lro.Done() +} + +// Name returns the name of the long-running operation. +// The name is assigned by the server and is unique within the service from which the operation is created. +func (op *DeleteWorkerPoolOperation) Name() string { + return op.lro.Name() +} + // RetryBuildOperation manages a long-running operation from RetryBuild. type RetryBuildOperation struct { lro *longrunning.Operation @@ -1101,6 +1273,75 @@ func (op *RunBuildTriggerOperation) Name() string { return op.lro.Name() } +// UpdateWorkerPoolOperation manages a long-running operation from UpdateWorkerPool. +type UpdateWorkerPoolOperation struct { + lro *longrunning.Operation +} + +// UpdateWorkerPoolOperation returns a new UpdateWorkerPoolOperation from a given name. +// The name must be that of a previously created UpdateWorkerPoolOperation, possibly from a different process. +func (c *gRPCClient) UpdateWorkerPoolOperation(name string) *UpdateWorkerPoolOperation { + return &UpdateWorkerPoolOperation{ + lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}), + } +} + +// Wait blocks until the long-running operation is completed, returning the response and any errors encountered. +// +// See documentation of Poll for error-handling information. +func (op *UpdateWorkerPoolOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { + var resp cloudbuildpb.WorkerPool + if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { + return nil, err + } + return &resp, nil +} + +// Poll fetches the latest state of the long-running operation. +// +// Poll also fetches the latest metadata, which can be retrieved by Metadata. +// +// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and +// the operation has completed with failure, the error is returned and op.Done will return true. +// If Poll succeeds and the operation has completed successfully, +// op.Done will return true, and the response of the operation is returned. +// If Poll succeeds and the operation has not completed, the returned response and error are both nil. +func (op *UpdateWorkerPoolOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { + var resp cloudbuildpb.WorkerPool + if err := op.lro.Poll(ctx, &resp, opts...); err != nil { + return nil, err + } + if !op.Done() { + return nil, nil + } + return &resp, nil +} + +// Metadata returns metadata associated with the long-running operation. +// Metadata itself does not contact the server, but Poll does. +// To get the latest metadata, call this method after a successful call to Poll. +// If the metadata is not available, the returned metadata and error are both nil. +func (op *UpdateWorkerPoolOperation) Metadata() (*cloudbuildpb.UpdateWorkerPoolOperationMetadata, error) { + var meta cloudbuildpb.UpdateWorkerPoolOperationMetadata + if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { + return nil, nil + } else if err != nil { + return nil, err + } + return &meta, nil +} + +// Done reports whether the long-running operation has completed. +func (op *UpdateWorkerPoolOperation) Done() bool { + return op.lro.Done() +} + +// Name returns the name of the long-running operation. +// The name is assigned by the server and is unique within the service from which the operation is created. +func (op *UpdateWorkerPoolOperation) Name() string { + return op.lro.Name() +} + // BuildIterator manages a stream of *cloudbuildpb.Build. type BuildIterator struct { items []*cloudbuildpb.Build @@ -1194,3 +1435,50 @@ func (it *BuildTriggerIterator) takeBuf() interface{} { it.items = nil return b } + +// WorkerPoolIterator manages a stream of *cloudbuildpb.WorkerPool. +type WorkerPoolIterator struct { + items []*cloudbuildpb.WorkerPool + pageInfo *iterator.PageInfo + nextFunc func() error + + // Response is the raw response for the current page. + // It must be cast to the RPC response type. + // Calling Next() or InternalFetch() updates this value. + Response interface{} + + // InternalFetch is for use by the Google Cloud Libraries only. + // It is not part of the stable interface of this package. + // + // InternalFetch returns results from a single call to the underlying RPC. + // The number of results is no greater than pageSize. + // If there are no more results, nextPageToken is empty and err is nil. + InternalFetch func(pageSize int, pageToken string) (results []*cloudbuildpb.WorkerPool, nextPageToken string, err error) +} + +// PageInfo supports pagination. See the google.golang.org/api/iterator package for details. +func (it *WorkerPoolIterator) PageInfo() *iterator.PageInfo { + return it.pageInfo +} + +// Next returns the next result. Its second return value is iterator.Done if there are no more +// results. Once Next returns Done, all subsequent calls will return Done. +func (it *WorkerPoolIterator) Next() (*cloudbuildpb.WorkerPool, error) { + var item *cloudbuildpb.WorkerPool + if err := it.nextFunc(); err != nil { + return item, err + } + item = it.items[0] + it.items = it.items[1:] + return item, nil +} + +func (it *WorkerPoolIterator) bufLen() int { + return len(it.items) +} + +func (it *WorkerPoolIterator) takeBuf() interface{} { + b := it.items + it.items = nil + return b +} diff --git a/cloudbuild/apiv1/v2/cloud_build_client_example_test.go b/cloudbuild/apiv1/v2/cloud_build_client_example_test.go index 28506ce04c0..9fa93526625 100644 --- a/cloudbuild/apiv1/v2/cloud_build_client_example_test.go +++ b/cloudbuild/apiv1/v2/cloud_build_client_example_test.go @@ -300,7 +300,12 @@ func ExampleClient_CreateWorkerPool() { req := &cloudbuildpb.CreateWorkerPoolRequest{ // TODO: Fill request struct fields. } - resp, err := c.CreateWorkerPool(ctx, req) + op, err := c.CreateWorkerPool(ctx, req) + if err != nil { + // TODO: Handle error. + } + + resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } @@ -338,7 +343,12 @@ func ExampleClient_DeleteWorkerPool() { req := &cloudbuildpb.DeleteWorkerPoolRequest{ // TODO: Fill request struct fields. } - err = c.DeleteWorkerPool(ctx, req) + op, err := c.DeleteWorkerPool(ctx, req) + if err != nil { + // TODO: Handle error. + } + + err = op.Wait(ctx) if err != nil { // TODO: Handle error. } @@ -355,7 +365,12 @@ func ExampleClient_UpdateWorkerPool() { req := &cloudbuildpb.UpdateWorkerPoolRequest{ // TODO: Fill request struct fields. } - resp, err := c.UpdateWorkerPool(ctx, req) + op, err := c.UpdateWorkerPool(ctx, req) + if err != nil { + // TODO: Handle error. + } + + resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } @@ -374,10 +389,16 @@ func ExampleClient_ListWorkerPools() { req := &cloudbuildpb.ListWorkerPoolsRequest{ // TODO: Fill request struct fields. } - resp, err := c.ListWorkerPools(ctx, req) - if err != nil { - // TODO: Handle error. + it := c.ListWorkerPools(ctx, req) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + // TODO: Handle error. + } + // TODO: Use resp. + _ = resp } - // TODO: Use resp. - _ = resp } diff --git a/go.mod b/go.mod index 04a2fbd5ed8..9e63c3e0ad8 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/text v0.3.6 golang.org/x/tools v0.1.5 google.golang.org/api v0.50.0 - google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492 + google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a google.golang.org/grpc v1.39.0 google.golang.org/protobuf v1.27.1 ) diff --git a/go.sum b/go.sum index 7f25844bd85..5433ef3e3c4 100644 --- a/go.sum +++ b/go.sum @@ -467,8 +467,8 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492 h1:7yQQsvnwjfEahbNNEKcBHv3mR+HnB1ctGY/z1JXzx8M= -google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a h1:17YmRUuEF4d+t2ygJZaDPhqNL2Hf17832xWKcMU7r2I= +google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/internal/gapicgen/cmd/genbot/local.go b/internal/gapicgen/cmd/genbot/local.go index c7cab8bfaa4..83d2c46c3f9 100644 --- a/internal/gapicgen/cmd/genbot/local.go +++ b/internal/gapicgen/cmd/genbot/local.go @@ -37,6 +37,7 @@ type localConfig struct { gapicToGenerate string onlyGapics bool regenOnly bool + forceAll bool } func genLocal(ctx context.Context, c localConfig) error { @@ -74,6 +75,7 @@ func genLocal(ctx context.Context, c localConfig) error { OnlyGenerateGapic: c.onlyGapics, LocalMode: true, RegenOnly: c.regenOnly, + ForceAll: c.forceAll, } if _, err := generator.Generate(ctx, conf); err != nil { log.Printf("Generator ran (and failed) in %s\n", tmpDir) diff --git a/internal/gapicgen/cmd/genbot/main.go b/internal/gapicgen/cmd/genbot/main.go index 89f941959f6..3e099c836ca 100644 --- a/internal/gapicgen/cmd/genbot/main.go +++ b/internal/gapicgen/cmd/genbot/main.go @@ -65,6 +65,7 @@ func main() { gapicToGenerate: *gapicToGenerate, onlyGapics: *onlyGapics, regenOnly: *regenOnly, + forceAll: *forceAll, }); err != nil { log.Fatal(err) } diff --git a/internal/gapicgen/execv/gocmd/gocmd.go b/internal/gapicgen/execv/gocmd/gocmd.go index e0ec2c79c24..7bb85f8a239 100644 --- a/internal/gapicgen/execv/gocmd/gocmd.go +++ b/internal/gapicgen/execv/gocmd/gocmd.go @@ -74,7 +74,13 @@ func Build(dir string) error { log.Println("building generated code") c := execv.Command("go", "build", "./...") c.Dir = dir - return c.Run() + if _, err := c.Output(); err != nil { + if ee, ok := err.(*exec.ExitError); ok { + log.Printf("Error Output: %s", ee.Stderr) + } + return err + } + return nil } // Vet runs linters on all .go files recursively from the given directory. diff --git a/internal/generated/snippets/go.mod b/internal/generated/snippets/go.mod index f1d21bdc545..bfc4a7809fc 100644 --- a/internal/generated/snippets/go.mod +++ b/internal/generated/snippets/go.mod @@ -32,5 +32,5 @@ require ( cloud.google.com/go/pubsublite v0.87.0 cloud.google.com/go/spanner v0.87.0 google.golang.org/api v0.50.0 - google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492 + google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a ) diff --git a/internal/generated/snippets/go.sum b/internal/generated/snippets/go.sum index 9c22096201b..ceb2775d972 100644 --- a/internal/generated/snippets/go.sum +++ b/internal/generated/snippets/go.sum @@ -147,9 +147,9 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210714021259-044028024a4f/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492 h1:7yQQsvnwjfEahbNNEKcBHv3mR+HnB1ctGY/z1JXzx8M= google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a h1:17YmRUuEF4d+t2ygJZaDPhqNL2Hf17832xWKcMU7r2I= +google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/internal/godocfx/go.sum b/internal/godocfx/go.sum index fbc2f3f7576..da06bddb711 100644 --- a/internal/godocfx/go.sum +++ b/internal/godocfx/go.sum @@ -307,8 +307,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200827165113-ac2560b5e952/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492 h1:7yQQsvnwjfEahbNNEKcBHv3mR+HnB1ctGY/z1JXzx8M= -google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a h1:17YmRUuEF4d+t2ygJZaDPhqNL2Hf17832xWKcMU7r2I= +google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=