packagespannerimport("context""fmt""github.com/testcontainers/testcontainers-go/wait""github.com/testcontainers/testcontainers-go")// spannerContainer represents the spanner container type used in the moduletypespannerContainerstruct{testcontainers.ContainerGRPCEndpointstring}// startContainer creates an instance of the spanner container typefuncstartContainer(ctxcontext.Context)(*spannerContainer,error){req:=testcontainers.ContainerRequest{Image:"gcr.io/cloud-spanner-emulator/emulator:1.4.0",ExposedPorts:[]string{"9010/tcp"},WaitingFor:wait.ForLog("Cloud Spanner emulator running"),}container,err:=testcontainers.GenericContainer(ctx,testcontainers.GenericContainerRequest{ContainerRequest:req,Started:true,})iferr!=nil{returnnil,err}mappedPort,err:=container.MappedPort(ctx,"9010")iferr!=nil{returnnil,err}hostIP,err:=container.Host(ctx)iferr!=nil{returnnil,err}grpcEndpoint:=fmt.Sprintf("%s:%s",hostIP,mappedPort.Port())return&spannerContainer{Container:container,GRPCEndpoint:grpcEndpoint},nil}
packagespannerimport("cloud.google.com/go/spanner"database"cloud.google.com/go/spanner/admin/database/apiv1"instance"cloud.google.com/go/spanner/admin/instance/apiv1""context""fmt""google.golang.org/api/option""google.golang.org/api/option/internaloption"databasepb"google.golang.org/genproto/googleapis/spanner/admin/database/v1"instancepb"google.golang.org/genproto/googleapis/spanner/admin/instance/v1""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure""testing")const(projectId="test-project"instanceId="test-instance"databaseName="test-db")funcTestSpanner(t*testing.T){ctx:=context.Background()container,err:=startContainer(ctx)iferr!=nil{t.Fatal(err)}// Clean up the container after the test is completet.Cleanup(func(){iferr:=container.Terminate(ctx);err!=nil{t.Fatalf("failed to terminate container: %s",err)}})options:=[]option.ClientOption{option.WithEndpoint(container.GRPCEndpoint),option.WithGRPCDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())),option.WithoutAuthentication(),internaloption.SkipDialSettingsValidation(),}instanceAdmin,err:=instance.NewInstanceAdminClient(ctx,options...)iferr!=nil{t.Fatal(err)}deferinstanceAdmin.Close()instanceOp,err:=instanceAdmin.CreateInstance(ctx,&instancepb.CreateInstanceRequest{Parent:fmt.Sprintf("projects/%s",projectId),InstanceId:instanceId,Instance:&instancepb.Instance{DisplayName:instanceId,},})iferr!=nil{t.Fatal(err)}_,err=instanceOp.Wait(ctx)iferr!=nil{t.Fatal(err)}c,err:=database.NewDatabaseAdminClient(ctx,options...)iferr!=nil{t.Fatal(err)}deferc.Close()databaseOp,err:=c.CreateDatabase(ctx,&databasepb.CreateDatabaseRequest{Parent:fmt.Sprintf("projects/%s/instances/%s",projectId,instanceId),CreateStatement:fmt.Sprintf("CREATE DATABASE `%s`",databaseName),ExtraStatements:[]string{"CREATE TABLE Languages (Language STRING(MAX), Mascot STRING(MAX)) PRIMARY KEY (Language)",},})iferr!=nil{t.Fatal(err)}_,err=databaseOp.Wait(ctx)iferr!=nil{t.Fatal(err)}db:=fmt.Sprintf("projects/%s/instances/%s/databases/%s",projectId,instanceId,databaseName)client,err:=spanner.NewClient(ctx,db,options...)iferr!=nil{t.Fatal(err)}deferclient.Close()_,err=client.Apply(ctx,[]*spanner.Mutation{spanner.Insert("Languages",[]string{"language","mascot"},[]interface{}{"Go","Gopher"})})iferr!=nil{t.Fatal(err)}row,err:=client.Single().ReadRow(ctx,"Languages",spanner.Key{"Go"},[]string{"mascot"})iferr!=nil{t.Fatal(err)}varmascotstringerr=row.ColumnByName("Mascot",&mascot)iferr!=nil{t.Fatal(err)}// perform assertionsifmascot!="Gopher"{t.Fatalf("Expected value %s. Got %s.","Gopher",mascot)}}