From 3cdd33de1cf9cb89597e85ac0b276a5faa309055 Mon Sep 17 00:00:00 2001
From: Garet Halliday <me@garet.holiday>
Date: Thu, 14 Sep 2023 12:38:26 -0500
Subject: [PATCH] spin up full gat and dial it properly

---
 test/config.go      |   4 +-
 test/runner.go      |  52 +++++-----------------
 test/tester_test.go | 104 ++++++++++++++++++++++++++++++++++++--------
 3 files changed, 100 insertions(+), 60 deletions(-)

diff --git a/test/config.go b/test/config.go
index 6ccdb9e5..589910f8 100644
--- a/test/config.go
+++ b/test/config.go
@@ -1,11 +1,9 @@
 package test
 
 import (
-	"pggat/lib/gat/pool"
 	"pggat/lib/gat/pool/dialer"
 )
 
 type Config struct {
-	Modes map[string]pool.Options
-	Peer  dialer.Dialer
+	Modes map[string]dialer.Dialer
 }
diff --git a/test/runner.go b/test/runner.go
index 07689d9a..bbedd974 100644
--- a/test/runner.go
+++ b/test/runner.go
@@ -8,8 +8,7 @@ import (
 	"pggat/lib/bouncer/bouncers/v2"
 	"pggat/lib/fed"
 	packets "pggat/lib/fed/packets/v3.0"
-	"pggat/lib/gat/pool"
-	"pggat/lib/gat/pool/recipe"
+	"pggat/lib/gat/pool/dialer"
 	"pggat/lib/gsql"
 	"pggat/test/inst"
 )
@@ -83,13 +82,13 @@ func (T *Runner) prepare(client *gsql.Client) []Capturer {
 	return results
 }
 
-func (T *Runner) runControl() ([]Capturer, error) {
-	control, _, err := T.config.Peer.Dial()
+func (T *Runner) runMode(dialer dialer.Dialer) ([]Capturer, error) {
+	server, _, err := dialer.Dial()
 	if err != nil {
 		return nil, err
 	}
 	defer func() {
-		_ = control.Close()
+		_ = server.Close()
 	}()
 
 	var client gsql.Client
@@ -108,7 +107,7 @@ func (T *Runner) runControl() ([]Capturer, error) {
 			return nil, err
 		}
 
-		clientErr, serverErr := bouncers.Bounce(&client, control, p)
+		clientErr, serverErr := bouncers.Bounce(&client, server, p)
 		if clientErr != nil {
 			return nil, clientErr
 		}
@@ -120,43 +119,11 @@ func (T *Runner) runControl() ([]Capturer, error) {
 	return results, nil
 }
 
-func (T *Runner) runMode(options pool.Options) ([]Capturer, error) {
-	opts := options
-	// allowing ps sync would mess up testing
-	opts.ParameterStatusSync = pool.ParameterStatusSyncNone
-	p := pool.NewPool(opts)
-	defer p.Close()
-	p.AddRecipe("server", recipe.NewRecipe(
-		recipe.Options{
-			Dialer: T.config.Peer,
-		},
-	))
-
-	var client gsql.Client
-	results := T.prepare(&client)
-	if err := client.Close(); err != nil {
-		return nil, err
-	}
-
-	if err := p.ServeBot(&client); err != nil && !errors.Is(err, io.EOF) {
-		return nil, err
-	}
-
-	return results, nil
-}
-
 func (T *Runner) Run() error {
-	// control
-	expected, err := T.runControl()
-	if err != nil {
-		return ErrorIn{
-			Name: "Control",
-			Err:  err,
-		}
-	}
-
 	var errs []error
 
+	var expected []Capturer
+
 	// modes
 	for name, mode := range T.config.Modes {
 		actual, err := T.runMode(mode)
@@ -168,6 +135,11 @@ func (T *Runner) Run() error {
 			continue
 		}
 
+		if expected == nil {
+			expected = actual
+			continue
+		}
+
 		if len(expected) != len(actual) {
 			errs = append(errs, ErrorIn{
 				Name: name,
diff --git a/test/tester_test.go b/test/tester_test.go
index 1de5b8e6..90a92b5e 100644
--- a/test/tester_test.go
+++ b/test/tester_test.go
@@ -1,40 +1,110 @@
 package test_test
 
 import (
+	"crypto/rand"
+	"encoding/hex"
 	"fmt"
+	"net"
+	"strconv"
 	"testing"
 
 	"pggat/lib/auth/credentials"
 	"pggat/lib/bouncer/backends/v0"
+	"pggat/lib/bouncer/frontends/v0"
+	"pggat/lib/gat"
 	"pggat/lib/gat/pool"
 	"pggat/lib/gat/pool/dialer"
 	"pggat/lib/gat/pool/pools/session"
 	"pggat/lib/gat/pool/pools/transaction"
+	"pggat/lib/gat/pool/recipe"
 	"pggat/test"
 	"pggat/test/tests"
 )
 
 func TestTester(t *testing.T) {
-	tester := test.NewTester(test.Config{
-		Modes: map[string]pool.Options{
-			"transaction": transaction.Apply(pool.Options{}),
-			"session": session.Apply(pool.Options{
-				ServerResetQuery: "discard all",
-			}),
-		},
-		Peer: dialer.Net{
-			Network: "tcp",
-			Address: "localhost:6432",
-			AcceptOptions: backends.AcceptOptions{
-				Credentials: credentials.Cleartext{
-					Username: "postgres",
-					Password: "password",
-				},
-				Database: "postgres",
+	control := dialer.Net{
+		Network: "tcp",
+		Address: "localhost:5432",
+		AcceptOptions: backends.AcceptOptions{
+			Credentials: credentials.Cleartext{
+				Username: "postgres",
+				Password: "password",
 			},
+			Database: "postgres",
+		},
+	}
+
+	// generate random password for testing
+	var raw [32]byte
+	_, err := rand.Read(raw[:])
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	password := hex.EncodeToString(raw[:])
+	creds := credentials.Cleartext{
+		Username: "runner",
+		Password: password,
+	}
+
+	var g gat.PoolsMap
+
+	transactionPool := pool.NewPool(transaction.Apply(pool.Options{
+		Credentials: creds,
+	}))
+	transactionPool.AddRecipe("runner", recipe.NewRecipe(recipe.Options{
+		Dialer: control,
+	}))
+	g.Add("runner", "transaction", transactionPool)
+
+	sessionPool := pool.NewPool(session.Apply(pool.Options{
+		Credentials:      creds,
+		ServerResetQuery: "discard all",
+	}))
+	sessionPool.AddRecipe("runner", recipe.NewRecipe(recipe.Options{
+		Dialer: control,
+	}))
+	g.Add("runner", "session", sessionPool)
+
+	listener, err := gat.Listen("tcp", ":0", frontends.AcceptOptions{})
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	port := listener.Listener.Addr().(*net.TCPAddr).Port
+
+	go func() {
+		err := gat.Serve(listener, &g)
+		if err != nil {
+			t.Error(err)
+		}
+	}()
+
+	transactionDialer := dialer.Net{
+		Network: "tcp",
+		Address: ":" + strconv.Itoa(port),
+		AcceptOptions: backends.AcceptOptions{
+			Credentials: creds,
+			Database:    "transaction",
+		},
+	}
+	sessionDialer := dialer.Net{
+		Network: "tcp",
+		Address: ":" + strconv.Itoa(port),
+		AcceptOptions: backends.AcceptOptions{
+			Credentials: creds,
+			Database:    "session",
+		},
+	}
+
+	tester := test.NewTester(test.Config{
+		Modes: map[string]dialer.Dialer{
+			"control":     control,
+			"transaction": transactionDialer,
+			"session":     sessionDialer,
 		},
 	})
-	if err := tester.Run(
+	if err = tester.Run(
 		tests.SimpleQuery,
 		tests.Transaction,
 		tests.Sync,
-- 
GitLab