github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/tests/integration/connection_with_compression_test.go (about)

     1  //go:build integration
     2  // +build integration
     3  
     4  package integration
     5  
     6  import (
     7  	"context"
     8  	"crypto/tls"
     9  	"fmt"
    10  	"os"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Discovery_V1"
    15  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Export_V1"
    16  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Scripting_V1"
    17  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
    18  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Discovery"
    19  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Export"
    20  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Operations"
    21  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Scripting"
    22  	"google.golang.org/grpc"
    23  	"google.golang.org/grpc/encoding/gzip"
    24  	"google.golang.org/grpc/metadata"
    25  	"google.golang.org/protobuf/proto"
    26  	"google.golang.org/protobuf/types/known/durationpb"
    27  
    28  	"github.com/ydb-platform/ydb-go-sdk/v3"
    29  	"github.com/ydb-platform/ydb-go-sdk/v3/config"
    30  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/meta"
    31  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xtest"
    32  	"github.com/ydb-platform/ydb-go-sdk/v3/log"
    33  	"github.com/ydb-platform/ydb-go-sdk/v3/retry"
    34  	"github.com/ydb-platform/ydb-go-sdk/v3/trace"
    35  )
    36  
    37  //nolint:gocyclo
    38  func TestConnectionWithCompression(t *testing.T) {
    39  	const sumColumn = "sum"
    40  	var (
    41  		userAgent     = "connection user agent"
    42  		requestType   = "connection request type"
    43  		checkMedatada = func(ctx context.Context) {
    44  			md, has := metadata.FromOutgoingContext(ctx)
    45  			if !has {
    46  				t.Fatalf("no medatada")
    47  			}
    48  			userAgents := md.Get(meta.HeaderUserAgent)
    49  			if len(userAgents) == 0 {
    50  				t.Fatalf("no user agent")
    51  			}
    52  			if userAgents[0] != userAgent {
    53  				t.Fatalf("unknown user agent: %s", userAgents[0])
    54  			}
    55  			requestTypes := md.Get(meta.HeaderRequestType)
    56  			if len(requestTypes) == 0 {
    57  				t.Fatalf("no request type")
    58  			}
    59  			if requestTypes[0] != requestType {
    60  				t.Fatalf("unknown request type: %s", requestTypes[0])
    61  			}
    62  		}
    63  		ctx = xtest.Context(t)
    64  	)
    65  
    66  	db, err := ydb.Open(ctx,
    67  		"", // corner case for check replacement of endpoint+database+secure
    68  		ydb.WithConnectionString(os.Getenv("YDB_CONNECTION_STRING")),
    69  		ydb.WithAccessTokenCredentials(
    70  			os.Getenv("YDB_ACCESS_TOKEN_CREDENTIALS"),
    71  		),
    72  		ydb.With(
    73  			config.WithOperationTimeout(time.Second*2),
    74  			config.WithOperationCancelAfter(time.Second*2),
    75  		),
    76  		ydb.WithConnectionTTL(time.Millisecond*10000),
    77  		ydb.WithMinTLSVersion(tls.VersionTLS10),
    78  		ydb.WithLogger(
    79  			newLoggerWithMinLevel(t, log.WARN),
    80  			trace.MatchDetails(`ydb\.(driver|discovery|retry|scheme).*`),
    81  		),
    82  		ydb.WithUserAgent(userAgent),
    83  		ydb.WithRequestsType(requestType),
    84  		ydb.With(
    85  			config.WithGrpcOptions(
    86  				grpc.WithUnaryInterceptor(func(
    87  					ctx context.Context,
    88  					method string,
    89  					req, reply interface{},
    90  					cc *grpc.ClientConn,
    91  					invoker grpc.UnaryInvoker,
    92  					opts ...grpc.CallOption,
    93  				) error {
    94  					checkMedatada(ctx)
    95  					return invoker(ctx, method, req, reply, cc, opts...)
    96  				}),
    97  				grpc.WithStreamInterceptor(func(
    98  					ctx context.Context,
    99  					desc *grpc.StreamDesc,
   100  					cc *grpc.ClientConn,
   101  					method string,
   102  					streamer grpc.Streamer,
   103  					opts ...grpc.CallOption,
   104  				) (grpc.ClientStream, error) {
   105  					checkMedatada(ctx)
   106  					return streamer(ctx, desc, cc, method, opts...)
   107  				}),
   108  				grpc.WithDefaultCallOptions(
   109  					grpc.UseCompressor(gzip.Name),
   110  				),
   111  			),
   112  		),
   113  	)
   114  	if err != nil {
   115  		t.Fatal(err)
   116  	}
   117  	defer func() {
   118  		// cleanup connection
   119  		if e := db.Close(ctx); e != nil {
   120  			t.Fatalf("close failed: %+v", e)
   121  		}
   122  	}()
   123  	t.Run("discovery.WhoAmI", func(t *testing.T) {
   124  		if err = retry.Retry(ctx, func(ctx context.Context) (err error) {
   125  			discoveryClient := Ydb_Discovery_V1.NewDiscoveryServiceClient(ydb.GRPCConn(db))
   126  			response, err := discoveryClient.WhoAmI(
   127  				ctx,
   128  				&Ydb_Discovery.WhoAmIRequest{IncludeGroups: true},
   129  			)
   130  			if err != nil {
   131  				return err
   132  			}
   133  			var result Ydb_Discovery.WhoAmIResult
   134  			err = proto.Unmarshal(response.GetOperation().GetResult().GetValue(), &result)
   135  			if err != nil {
   136  				return
   137  			}
   138  			return nil
   139  		}, retry.WithIdempotent(true)); err != nil {
   140  			t.Fatalf("Execute failed: %v", err)
   141  		}
   142  	})
   143  	t.Run("scripting.ExecuteYql", func(t *testing.T) {
   144  		if err = retry.Retry(ctx, func(ctx context.Context) (err error) {
   145  			scriptingClient := Ydb_Scripting_V1.NewScriptingServiceClient(ydb.GRPCConn(db))
   146  			response, err := scriptingClient.ExecuteYql(
   147  				ctx,
   148  				&Ydb_Scripting.ExecuteYqlRequest{Script: "SELECT 1+100 AS sum"},
   149  			)
   150  			if err != nil {
   151  				return err
   152  			}
   153  			var result Ydb_Scripting.ExecuteYqlResult
   154  			err = proto.Unmarshal(response.GetOperation().GetResult().GetValue(), &result)
   155  			if err != nil {
   156  				return
   157  			}
   158  			if len(result.GetResultSets()) != 1 {
   159  				return fmt.Errorf(
   160  					"unexpected result sets count: %d",
   161  					len(result.GetResultSets()),
   162  				)
   163  			}
   164  			if len(result.GetResultSets()[0].GetColumns()) != 1 {
   165  				return fmt.Errorf(
   166  					"unexpected colums count: %d",
   167  					len(result.GetResultSets()[0].GetColumns()),
   168  				)
   169  			}
   170  			if result.GetResultSets()[0].GetColumns()[0].GetName() != sumColumn {
   171  				return fmt.Errorf(
   172  					"unexpected colum name: %s",
   173  					result.GetResultSets()[0].GetColumns()[0].GetName(),
   174  				)
   175  			}
   176  			if len(result.GetResultSets()[0].GetRows()) != 1 {
   177  				return fmt.Errorf(
   178  					"unexpected rows count: %d",
   179  					len(result.GetResultSets()[0].GetRows()),
   180  				)
   181  			}
   182  			if result.GetResultSets()[0].GetRows()[0].GetItems()[0].GetInt32Value() != 101 {
   183  				return fmt.Errorf(
   184  					"unexpected result of select: %d",
   185  					result.GetResultSets()[0].GetRows()[0].GetInt64Value(),
   186  				)
   187  			}
   188  			return nil
   189  		}, retry.WithIdempotent(true)); err != nil {
   190  			t.Fatalf("Execute failed: %v", err)
   191  		}
   192  	})
   193  	t.Run("scripting.StreamExecuteYql", func(t *testing.T) {
   194  		if err = retry.Retry(ctx, func(ctx context.Context) (err error) {
   195  			scriptingClient := Ydb_Scripting_V1.NewScriptingServiceClient(ydb.GRPCConn(db))
   196  			client, err := scriptingClient.StreamExecuteYql(
   197  				ctx,
   198  				&Ydb_Scripting.ExecuteYqlRequest{Script: "SELECT 1+100 AS sum"},
   199  			)
   200  			if err != nil {
   201  				return err
   202  			}
   203  			response, err := client.Recv()
   204  			if err != nil {
   205  				return err
   206  			}
   207  			if len(response.GetResult().GetResultSet().GetColumns()) != 1 {
   208  				return fmt.Errorf(
   209  					"unexpected colums count: %d",
   210  					len(response.GetResult().GetResultSet().GetColumns()),
   211  				)
   212  			}
   213  			if response.GetResult().GetResultSet().GetColumns()[0].GetName() != sumColumn {
   214  				return fmt.Errorf(
   215  					"unexpected colum name: %s",
   216  					response.GetResult().GetResultSet().GetColumns()[0].GetName(),
   217  				)
   218  			}
   219  			if len(response.GetResult().GetResultSet().GetRows()) != 1 {
   220  				return fmt.Errorf(
   221  					"unexpected rows count: %d",
   222  					len(response.GetResult().GetResultSet().GetRows()),
   223  				)
   224  			}
   225  			if response.GetResult().GetResultSet().GetRows()[0].GetItems()[0].GetInt32Value() != 101 {
   226  				return fmt.Errorf(
   227  					"unexpected result of select: %d",
   228  					response.GetResult().GetResultSet().GetRows()[0].GetInt64Value(),
   229  				)
   230  			}
   231  			return nil
   232  		}, retry.WithIdempotent(true)); err != nil {
   233  			t.Fatalf("Stream execute failed: %v", err)
   234  		}
   235  	})
   236  	t.Run("with.scripting.StreamExecuteYql", func(t *testing.T) {
   237  		var childDB *ydb.Driver
   238  		childDB, err = db.With(
   239  			ctx,
   240  			ydb.WithDialTimeout(time.Second*5),
   241  		)
   242  		if err != nil {
   243  			t.Fatalf("failed to open sub-connection: %v", err)
   244  		}
   245  		defer func() {
   246  			_ = childDB.Close(ctx)
   247  		}()
   248  		if err = retry.Retry(ctx, func(ctx context.Context) (err error) {
   249  			scriptingClient := Ydb_Scripting_V1.NewScriptingServiceClient(ydb.GRPCConn(childDB))
   250  			client, err := scriptingClient.StreamExecuteYql(
   251  				ctx,
   252  				&Ydb_Scripting.ExecuteYqlRequest{Script: "SELECT 1+100 AS sum"},
   253  			)
   254  			if err != nil {
   255  				return err
   256  			}
   257  			response, err := client.Recv()
   258  			if err != nil {
   259  				return err
   260  			}
   261  			if len(response.GetResult().GetResultSet().GetColumns()) != 1 {
   262  				return fmt.Errorf(
   263  					"unexpected colums count: %d",
   264  					len(response.GetResult().GetResultSet().GetColumns()),
   265  				)
   266  			}
   267  			if response.GetResult().GetResultSet().GetColumns()[0].GetName() != sumColumn {
   268  				return fmt.Errorf(
   269  					"unexpected colum name: %s",
   270  					response.GetResult().GetResultSet().GetColumns()[0].GetName(),
   271  				)
   272  			}
   273  			if len(response.GetResult().GetResultSet().GetRows()) != 1 {
   274  				return fmt.Errorf(
   275  					"unexpected rows count: %d",
   276  					len(response.GetResult().GetResultSet().GetRows()),
   277  				)
   278  			}
   279  			if response.GetResult().GetResultSet().GetRows()[0].GetItems()[0].GetInt32Value() != 101 {
   280  				return fmt.Errorf(
   281  					"unexpected result of select: %d",
   282  					response.GetResult().GetResultSet().GetRows()[0].GetInt64Value(),
   283  				)
   284  			}
   285  			return nil
   286  		}, retry.WithIdempotent(true)); err != nil {
   287  			t.Fatalf("Stream execute failed: %v", err)
   288  		}
   289  	})
   290  	t.Run("export.ExportToS3", func(t *testing.T) {
   291  		if err = retry.Retry(ctx, func(ctx context.Context) (err error) {
   292  			exportClient := Ydb_Export_V1.NewExportServiceClient(ydb.GRPCConn(db))
   293  			response, err := exportClient.ExportToS3(
   294  				ctx,
   295  				&Ydb_Export.ExportToS3Request{
   296  					OperationParams: &Ydb_Operations.OperationParams{
   297  						OperationTimeout: durationpb.New(time.Second),
   298  						CancelAfter:      durationpb.New(time.Second),
   299  					},
   300  					Settings: &Ydb_Export.ExportToS3Settings{},
   301  				},
   302  			)
   303  			if err != nil {
   304  				return err
   305  			}
   306  			if response.GetOperation().GetStatus() != Ydb.StatusIds_BAD_REQUEST {
   307  				return fmt.Errorf(
   308  					"operation must be BAD_REQUEST: %s",
   309  					response.GetOperation().GetStatus().String(),
   310  				)
   311  			}
   312  			return nil
   313  		}, retry.WithIdempotent(true)); err != nil {
   314  			t.Fatalf("check export failed: %v", err)
   315  		}
   316  	})
   317  }