From 87eb0b89df82239adde2ce60a4a2ee4dec94fabb Mon Sep 17 00:00:00 2001 From: Garet Halliday <me@garet.holiday> Date: Thu, 14 Sep 2023 14:45:42 -0500 Subject: [PATCH] stress testing --- test/config.go | 3 +++ test/runner.go | 38 +++++++++++++++++++++++++++++++++++++- test/test.go | 4 ++++ test/tester_test.go | 2 ++ test/tests/copy_out.go | 6 ++++-- 5 files changed, 50 insertions(+), 3 deletions(-) diff --git a/test/config.go b/test/config.go index 589910f8..42668081 100644 --- a/test/config.go +++ b/test/config.go @@ -5,5 +5,8 @@ import ( ) type Config struct { + // Stress is how many connections to run simultaneously for stress testing. <= 1 disables stress testing. + Stress int + Modes map[string]dialer.Dialer } diff --git a/test/runner.go b/test/runner.go index bbedd974..5f985f1f 100644 --- a/test/runner.go +++ b/test/runner.go @@ -10,6 +10,7 @@ import ( packets "pggat/lib/fed/packets/v3.0" "pggat/lib/gat/pool/dialer" "pggat/lib/gsql" + "pggat/lib/util/flip" "pggat/test/inst" ) @@ -82,7 +83,7 @@ func (T *Runner) prepare(client *gsql.Client) []Capturer { return results } -func (T *Runner) runMode(dialer dialer.Dialer) ([]Capturer, error) { +func (T *Runner) runModeOnce(dialer dialer.Dialer) ([]Capturer, error) { server, _, err := dialer.Dial() if err != nil { return nil, err @@ -119,6 +120,41 @@ func (T *Runner) runMode(dialer dialer.Dialer) ([]Capturer, error) { return results, nil } +func (T *Runner) runMode(dialer dialer.Dialer) ([]Capturer, error) { + instances := T.config.Stress + if instances < 1 || T.test.SideEffects { + instances = 1 + } + + expected, err := T.runModeOnce(dialer) + if err != nil { + return nil, err + } + + var b flip.Bank + + for i := 0; i < instances-1; i++ { + b.Queue(func() error { + actual, err := T.runModeOnce(dialer) + if err != nil { + return err + } + if len(expected) != len(actual) { + return fmt.Errorf("wrong number of results! expected %d but got %d", len(expected), len(actual)) + } + for i, exp := range expected { + act := actual[i] + if err = exp.Check(&act); err != nil { + return err + } + } + return nil + }) + } + + return expected, b.Wait() +} + func (T *Runner) Run() error { var errs []error diff --git a/test/test.go b/test/test.go index 000fa8ff..2a6d1f9a 100644 --- a/test/test.go +++ b/test/test.go @@ -3,6 +3,10 @@ package test import "pggat/test/inst" type Test struct { + // SideEffects determines whether this test has side effects such as creating or dropping tables. + // This will prevent fail and stress testing, as those would immediately fail. + SideEffects bool + Name string Instructions []inst.Instruction } diff --git a/test/tester_test.go b/test/tester_test.go index 9ba07394..4b1fa6f2 100644 --- a/test/tester_test.go +++ b/test/tester_test.go @@ -141,6 +141,8 @@ func TestTester(t *testing.T) { } tester := test.NewTester(test.Config{ + Stress: 16, + Modes: map[string]dialer.Dialer{ "control": control, "transaction": transactionDialer, diff --git a/test/tests/copy_out.go b/test/tests/copy_out.go index 681e0033..d1d314e8 100644 --- a/test/tests/copy_out.go +++ b/test/tests/copy_out.go @@ -6,7 +6,8 @@ import ( ) var CopyOut0 = test.Test{ - Name: "Copy Out 0", + SideEffects: true, + Name: "Copy Out 0", Instructions: []inst.Instruction{ inst.SimpleQuery("CREATE TABLE test ( x integer NOT NULL, y varchar(40) NOT NULL PRIMARY KEY )"), inst.SimpleQuery("INSERT INTO test VALUES (123, 'hello world')"), @@ -17,7 +18,8 @@ var CopyOut0 = test.Test{ } var CopyOut1 = test.Test{ - Name: "Copy Out 1", + SideEffects: true, + Name: "Copy Out 1", Instructions: []inst.Instruction{ inst.SimpleQuery("CREATE TABLE test ( x integer NOT NULL, y varchar(40) NOT NULL PRIMARY KEY )"), inst.SimpleQuery("INSERT INTO test VALUES (123, 'hello world')"), -- GitLab