diff --git a/asset/v1beta1/asset_client.go b/asset/v1beta1/asset_client.go
deleted file mode 100644
index a1fdc01..0000000
--- a/asset/v1beta1/asset_client.go
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2018 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.
-
-// AUTO-GENERATED CODE. DO NOT EDIT.
-
-package asset
-
-import (
-	"context"
-	"time"
-
-	"cloud.google.com/go/longrunning"
-	lroauto "cloud.google.com/go/longrunning/autogen"
-	gax "github.com/googleapis/gax-go/v2"
-	"google.golang.org/api/option"
-	"google.golang.org/api/transport"
-	assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1"
-	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/metadata"
-)
-
-// CallOptions contains the retry settings for each method of Client.
-type CallOptions struct {
-	ExportAssets          []gax.CallOption
-	BatchGetAssetsHistory []gax.CallOption
-}
-
-func defaultClientOptions() []option.ClientOption {
-	return []option.ClientOption{
-		option.WithEndpoint("cloudasset.googleapis.com:443"),
-		option.WithScopes(DefaultAuthScopes()...),
-	}
-}
-
-func defaultCallOptions() *CallOptions {
-	retry := map[[2]string][]gax.CallOption{
-		{"default", "idempotent"}: {
-			gax.WithRetry(func() gax.Retryer {
-				return gax.OnCodes([]codes.Code{
-					codes.DeadlineExceeded,
-					codes.Unavailable,
-				}, gax.Backoff{
-					Initial:    100 * time.Millisecond,
-					Max:        60000 * time.Millisecond,
-					Multiplier: 1.3,
-				})
-			}),
-		},
-	}
-	return &CallOptions{
-		ExportAssets:          retry[[2]string{"default", "non_idempotent"}],
-		BatchGetAssetsHistory: retry[[2]string{"default", "idempotent"}],
-	}
-}
-
-// Client is a client for interacting with Cloud Asset API.
-//
-// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
-type Client struct {
-	// The connection to the service.
-	conn *grpc.ClientConn
-
-	// The gRPC API client.
-	client assetpb.AssetServiceClient
-
-	// LROClient is used internally to handle longrunning operations.
-	// It is exposed so that its CallOptions can be modified if required.
-	// Users should not Close this client.
-	LROClient *lroauto.OperationsClient
-
-	// The call options for this service.
-	CallOptions *CallOptions
-
-	// The x-goog-* metadata to be sent with each request.
-	xGoogMetadata metadata.MD
-}
-
-// NewClient creates a new asset service client.
-//
-// Asset service definition.
-func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
-	conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...)
-	if err != nil {
-		return nil, err
-	}
-	c := &Client{
-		conn:        conn,
-		CallOptions: defaultCallOptions(),
-
-		client: assetpb.NewAssetServiceClient(conn),
-	}
-	c.setGoogleClientInfo()
-
-	c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn))
-	if err != nil {
-		// This error "should not happen", since we are just reusing old connection
-		// and never actually need to dial.
-		// If this does happen, we could leak conn. However, we cannot close conn:
-		// If the user invoked the function with option.WithGRPCConn,
-		// we would close a connection that's still in use.
-		// TODO(pongad): investigate error conditions.
-		return nil, err
-	}
-	return c, nil
-}
-
-// Connection returns the client's connection to the API service.
-func (c *Client) Connection() *grpc.ClientConn {
-	return c.conn
-}
-
-// Close closes the connection to the API service. The user should invoke this when
-// the client is no longer required.
-func (c *Client) Close() error {
-	return c.conn.Close()
-}
-
-// setGoogleClientInfo sets the name and version of the application in
-// the `x-goog-api-client` header passed on each request. Intended for
-// use by Google-written clients.
-func (c *Client) setGoogleClientInfo(keyval ...string) {
-	kv := append([]string{"gl-go", versionGo()}, keyval...)
-	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version)
-	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
-}
-
-// ExportAssets exports assets with time and resource types to a given Cloud Storage
-// location. The output format is newline-delimited JSON.
-// This API implements the [google.longrunning.Operation][google.longrunning.Operation] API allowing you
-// to keep track of the export.
-func (c *Client) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest, opts ...gax.CallOption) (*ExportAssetsOperation, error) {
-	ctx = insertMetadata(ctx, c.xGoogMetadata)
-	opts = append(c.CallOptions.ExportAssets[0:len(c.CallOptions.ExportAssets):len(c.CallOptions.ExportAssets)], opts...)
-	var resp *longrunningpb.Operation
-	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
-		var err error
-		resp, err = c.client.ExportAssets(ctx, req, settings.GRPC...)
-		return err
-	}, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return &ExportAssetsOperation{
-		lro: longrunning.InternalNewOperation(c.LROClient, resp),
-	}, nil
-}
-
-// BatchGetAssetsHistory batch gets the update history of assets that overlap a time window.
-// For RESOURCE content, this API outputs history with asset in both
-// non-delete or deleted status.
-// For IAM_POLICY content, this API outputs history when the asset and its
-// attached IAM POLICY both exist. This can create gaps in the output history.
-func (c *Client) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest, opts ...gax.CallOption) (*assetpb.BatchGetAssetsHistoryResponse, error) {
-	ctx = insertMetadata(ctx, c.xGoogMetadata)
-	opts = append(c.CallOptions.BatchGetAssetsHistory[0:len(c.CallOptions.BatchGetAssetsHistory):len(c.CallOptions.BatchGetAssetsHistory)], opts...)
-	var resp *assetpb.BatchGetAssetsHistoryResponse
-	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
-		var err error
-		resp, err = c.client.BatchGetAssetsHistory(ctx, req, settings.GRPC...)
-		return err
-	}, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return resp, nil
-}
-
-// ExportAssetsOperation manages a long-running operation from ExportAssets.
-type ExportAssetsOperation struct {
-	lro *longrunning.Operation
-}
-
-// ExportAssetsOperation returns a new ExportAssetsOperation from a given name.
-// The name must be that of a previously created ExportAssetsOperation, possibly from a different process.
-func (c *Client) ExportAssetsOperation(name string) *ExportAssetsOperation {
-	return &ExportAssetsOperation{
-		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 *ExportAssetsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) {
-	var resp assetpb.ExportAssetsResponse
-	if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, 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 *ExportAssetsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) {
-	var resp assetpb.ExportAssetsResponse
-	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 *ExportAssetsOperation) Metadata() (*assetpb.ExportAssetsRequest, error) {
-	var meta assetpb.ExportAssetsRequest
-	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 *ExportAssetsOperation) 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 *ExportAssetsOperation) Name() string {
-	return op.lro.Name()
-}
diff --git a/asset/v1beta1/asset_client_example_test.go b/asset/v1beta1/asset_client_example_test.go
deleted file mode 100644
index 160f171..0000000
--- a/asset/v1beta1/asset_client_example_test.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2018 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.
-
-// AUTO-GENERATED CODE. DO NOT EDIT.
-
-package asset_test
-
-import (
-	"context"
-
-	asset "cloud.google.com/go/asset/v1beta1"
-	assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1"
-)
-
-func ExampleNewClient() {
-	ctx := context.Background()
-	c, err := asset.NewClient(ctx)
-	if err != nil {
-		// TODO: Handle error.
-	}
-	// TODO: Use client.
-	_ = c
-}
-
-func ExampleClient_ExportAssets() {
-	ctx := context.Background()
-	c, err := asset.NewClient(ctx)
-	if err != nil {
-		// TODO: Handle error.
-	}
-
-	req := &assetpb.ExportAssetsRequest{
-		// TODO: Fill request struct fields.
-	}
-	op, err := c.ExportAssets(ctx, req)
-	if err != nil {
-		// TODO: Handle error.
-	}
-
-	resp, err := op.Wait(ctx)
-	if err != nil {
-		// TODO: Handle error.
-	}
-	// TODO: Use resp.
-	_ = resp
-}
-
-func ExampleClient_BatchGetAssetsHistory() {
-	ctx := context.Background()
-	c, err := asset.NewClient(ctx)
-	if err != nil {
-		// TODO: Handle error.
-	}
-
-	req := &assetpb.BatchGetAssetsHistoryRequest{
-		// TODO: Fill request struct fields.
-	}
-	resp, err := c.BatchGetAssetsHistory(ctx, req)
-	if err != nil {
-		// TODO: Handle error.
-	}
-	// TODO: Use resp.
-	_ = resp
-}
diff --git a/asset/v1beta1/doc.go b/asset/v1beta1/doc.go
deleted file mode 100644
index 7624e5d..0000000
--- a/asset/v1beta1/doc.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2018 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.
-
-// AUTO-GENERATED CODE. DO NOT EDIT.
-
-// Package asset is an auto-generated package for the
-// Cloud Asset API.
-//
-//   NOTE: This package is in alpha. It is not stable, and is likely to change.
-//
-// The cloud asset API manages the history and inventory of cloud resources.
-package asset // import "cloud.google.com/go/asset/v1beta1"
-
-import (
-	"context"
-	"runtime"
-	"strings"
-	"unicode"
-
-	"google.golang.org/grpc/metadata"
-)
-
-func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
-	out, _ := metadata.FromOutgoingContext(ctx)
-	out = out.Copy()
-	for _, md := range mds {
-		for k, v := range md {
-			out[k] = append(out[k], v...)
-		}
-	}
-	return metadata.NewOutgoingContext(ctx, out)
-}
-
-// DefaultAuthScopes reports the default set of authentication scopes to use with this package.
-func DefaultAuthScopes() []string {
-	return []string{
-		"https://www.googleapis.com/auth/cloud-platform",
-	}
-}
-
-// versionGo returns the Go runtime version. The returned string
-// has no whitespace, suitable for reporting in header.
-func versionGo() string {
-	const develPrefix = "devel +"
-
-	s := runtime.Version()
-	if strings.HasPrefix(s, develPrefix) {
-		s = s[len(develPrefix):]
-		if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
-			s = s[:p]
-		}
-		return s
-	}
-
-	notSemverRune := func(r rune) bool {
-		return strings.IndexRune("0123456789.", r) < 0
-	}
-
-	if strings.HasPrefix(s, "go1") {
-		s = s[2:]
-		var prerelease string
-		if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
-			s, prerelease = s[:p], s[p:]
-		}
-		if strings.HasSuffix(s, ".") {
-			s += "0"
-		} else if strings.Count(s, ".") < 2 {
-			s += ".0"
-		}
-		if prerelease != "" {
-			s += "-" + prerelease
-		}
-		return s
-	}
-	return "UNKNOWN"
-}
-
-const versionClient = "20190910"
diff --git a/asset/v1beta1/mock_test.go b/asset/v1beta1/mock_test.go
deleted file mode 100644
index b3c49cc..0000000
--- a/asset/v1beta1/mock_test.go
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2018 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.
-
-// AUTO-GENERATED CODE. DO NOT EDIT.
-
-package asset
-
-import (
-	"context"
-	"flag"
-	"fmt"
-	"io"
-	"log"
-	"net"
-	"os"
-	"strings"
-	"testing"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
-	"google.golang.org/api/option"
-	assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1"
-	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 mockAssetServer struct {
-	// Embed for forward compatibility.
-	// Tests will keep working if more methods are added
-	// in the future.
-	assetpb.AssetServiceServer
-
-	reqs []proto.Message
-
-	// If set, all calls return this error.
-	err error
-
-	// responses to return if err == nil
-	resps []proto.Message
-}
-
-func (s *mockAssetServer) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest) (*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 *mockAssetServer) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest) (*assetpb.BatchGetAssetsHistoryResponse, 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].(*assetpb.BatchGetAssetsHistoryResponse), nil
-}
-
-// clientOpt is the option tests should use to connect to the test server.
-// It is initialized by TestMain.
-var clientOpt option.ClientOption
-
-var (
-	mockAsset mockAssetServer
-)
-
-func TestMain(m *testing.M) {
-	flag.Parse()
-
-	serv := grpc.NewServer()
-	assetpb.RegisterAssetServiceServer(serv, &mockAsset)
-
-	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 TestAssetServiceExportAssets(t *testing.T) {
-	var expectedResponse *assetpb.ExportAssetsResponse = &assetpb.ExportAssetsResponse{}
-
-	mockAsset.err = nil
-	mockAsset.reqs = nil
-
-	any, err := ptypes.MarshalAny(expectedResponse)
-	if err != nil {
-		t.Fatal(err)
-	}
-	mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{
-		Name:   "longrunning-test",
-		Done:   true,
-		Result: &longrunningpb.Operation_Response{Response: any},
-	})
-
-	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
-	var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{}
-	var request = &assetpb.ExportAssetsRequest{
-		Parent:       formattedParent,
-		OutputConfig: outputConfig,
-	}
-
-	c, err := NewClient(context.Background(), clientOpt)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	respLRO, err := c.ExportAssets(context.Background(), request)
-	if err != nil {
-		t.Fatal(err)
-	}
-	resp, err := respLRO.Wait(context.Background())
-
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if want, got := request, mockAsset.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 TestAssetServiceExportAssetsError(t *testing.T) {
-	errCode := codes.PermissionDenied
-	mockAsset.err = nil
-	mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{
-		Name: "longrunning-test",
-		Done: true,
-		Result: &longrunningpb.Operation_Error{
-			Error: &status.Status{
-				Code:    int32(errCode),
-				Message: "test error",
-			},
-		},
-	})
-
-	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
-	var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{}
-	var request = &assetpb.ExportAssetsRequest{
-		Parent:       formattedParent,
-		OutputConfig: outputConfig,
-	}
-
-	c, err := NewClient(context.Background(), clientOpt)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	respLRO, err := c.ExportAssets(context.Background(), request)
-	if err != nil {
-		t.Fatal(err)
-	}
-	resp, err := respLRO.Wait(context.Background())
-
-	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 TestAssetServiceBatchGetAssetsHistory(t *testing.T) {
-	var expectedResponse *assetpb.BatchGetAssetsHistoryResponse = &assetpb.BatchGetAssetsHistoryResponse{}
-
-	mockAsset.err = nil
-	mockAsset.reqs = nil
-
-	mockAsset.resps = append(mockAsset.resps[:0], expectedResponse)
-
-	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
-	var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED
-	var readTimeWindow *assetpb.TimeWindow = &assetpb.TimeWindow{}
-	var request = &assetpb.BatchGetAssetsHistoryRequest{
-		Parent:         formattedParent,
-		ContentType:    contentType,
-		ReadTimeWindow: readTimeWindow,
-	}
-
-	c, err := NewClient(context.Background(), clientOpt)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	resp, err := c.BatchGetAssetsHistory(context.Background(), request)
-
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if want, got := request, mockAsset.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 TestAssetServiceBatchGetAssetsHistoryError(t *testing.T) {
-	errCode := codes.PermissionDenied
-	mockAsset.err = gstatus.Error(errCode, "test error")
-
-	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
-	var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED
-	var readTimeWindow *assetpb.TimeWindow = &assetpb.TimeWindow{}
-	var request = &assetpb.BatchGetAssetsHistoryRequest{
-		Parent:         formattedParent,
-		ContentType:    contentType,
-		ReadTimeWindow: readTimeWindow,
-	}
-
-	c, err := NewClient(context.Background(), clientOpt)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	resp, err := c.BatchGetAssetsHistory(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
-}
