@@ -25,16 +25,19 @@ package test
25
25
import (
26
26
"context"
27
27
"crypto/tls"
28
+ "fmt"
28
29
"log"
29
30
httplib "net/http"
30
31
_ "net/http/pprof"
31
32
"os"
33
+ "runtime"
32
34
"strconv"
33
35
"strings"
34
36
"sync"
35
37
"testing"
36
38
"time"
37
39
40
+ "github.com/pkg/errors"
38
41
"github.com/stretchr/testify/assert"
39
42
"github.com/stretchr/testify/require"
40
43
@@ -500,3 +503,95 @@ func TestCreateClientHttpRepeatConnection(t *testing.T) {
500
503
require .NoError (t , err )
501
504
assert .Equal (t , 2 , requestRepeat .counter )
502
505
}
506
+
507
+ // TestClientConnectionReuse checks that reusing same connection with different auth parameters is possible using
508
+ func TestClientConnectionReuse (t * testing.T ) {
509
+ if os .Getenv ("TEST_CONNECTION" ) == "vst" {
510
+ t .Skip ("not possible with VST connections by design" )
511
+ return
512
+ }
513
+
514
+ c := createClientFromEnv (t , true )
515
+ ctx := context .Background ()
516
+
517
+ prefix := t .Name ()
518
+ dbUsers := map [string ]driver.CreateDatabaseUserOptions {
519
+ prefix + "-db1" : {UserName : prefix + "-user1" , Password : "password1" },
520
+ prefix + "-db2" : {UserName : prefix + "-user2" , Password : "password2" },
521
+ }
522
+ for dbName , userOptions := range dbUsers {
523
+ ensureDatabase (ctx , c , dbName , & driver.CreateDatabaseOptions {
524
+ Users : []driver.CreateDatabaseUserOptions {userOptions },
525
+ Options : driver.CreateDatabaseDefaultOptions {},
526
+ }, t )
527
+ }
528
+
529
+ var wg sync.WaitGroup
530
+ const clientsPerDB = 20
531
+ startTime := time .Now ()
532
+
533
+ const testDuration = time .Second * 10
534
+ if testing .Verbose () {
535
+ wg .Add (1 )
536
+ go func () {
537
+ defer wg .Done ()
538
+
539
+ for {
540
+ stats , _ := c .Statistics (ctx )
541
+ t .Logf ("goroutine count: %d, server connections: %d" , runtime .NumGoroutine (), stats .Client .HTTPConnections )
542
+ if time .Now ().Sub (startTime ) > testDuration {
543
+ break
544
+ }
545
+ time .Sleep (1 * time .Second )
546
+ }
547
+ }()
548
+ }
549
+
550
+ conn := createConnection (t , false )
551
+ for dbName , userOptions := range dbUsers {
552
+ t .Logf ("Starting %d goroutines for DB %s ..." , clientsPerDB , dbName )
553
+ for i := 0 ; i < clientsPerDB ; i ++ {
554
+ wg .Add (1 )
555
+ go func (dbName string , userOptions driver.CreateDatabaseUserOptions , conn driver.Connection ) {
556
+ defer wg .Done ()
557
+ for {
558
+ if time .Now ().Sub (startTime ) > testDuration {
559
+ break
560
+ }
561
+
562
+ // the test will pass only if checkDBAccess is using mutex
563
+ err := checkDBAccess (ctx , conn , dbName , userOptions .UserName , userOptions .Password )
564
+ require .NoError (t , err )
565
+
566
+ time .Sleep (10 * time .Millisecond )
567
+ }
568
+ }(dbName , userOptions , conn )
569
+ }
570
+ }
571
+ wg .Wait ()
572
+ }
573
+
574
+ func checkDBAccess (ctx context.Context , conn driver.Connection , dbName , username , password string ) error {
575
+ client , err := driver .NewClient (driver.ClientConfig {
576
+ Connection : conn ,
577
+ Authentication : driver .BasicAuthentication (username , password ),
578
+ })
579
+ if err != nil {
580
+ return err
581
+ }
582
+
583
+ dbExists , err := client .DatabaseExists (ctx , dbName )
584
+ if err != nil {
585
+ return errors .Wrapf (err , "DatabaseExists failed" )
586
+ }
587
+ if ! dbExists {
588
+ return fmt .Errorf ("db %s must exist for any user" , dbName )
589
+ }
590
+
591
+ _ , err = client .Database (ctx , dbName )
592
+ if err != nil {
593
+ return errors .Wrapf (err , "db %s must be accessible for user %s" , dbName , username )
594
+ }
595
+
596
+ return nil
597
+ }
0 commit comments