Newer
Older
"pggat/test/inst"
)
type Runner struct {
config Config
test Test
}
func MakeRunner(config Config, test Test) Runner {
return Runner{
config: config,
test: test,
}
}
func (T *Runner) prepare(client *gsql.Client, until int) []Capturer {
results := make([]Capturer, until)
for i := 0; i < until; i++ {
x := T.test.Instructions[i]
switch v := x.(type) {
case inst.SimpleQuery:
q := packets.Query(v)
case inst.Sync:
client.Do(&results[i], fed.NewPacket(packets.TypeSync))
case inst.Parse:
p := packets.Parse{
Destination: v.Destination,
Query: v.Query,
}
case inst.Bind:
p := packets.Bind{
Destination: v.Destination,
Source: v.Source,
}
case inst.DescribePortal:
p := packets.Describe{
Which: 'P',
Target: string(v),
}
case inst.DescribePreparedStatement:
p := packets.Describe{
Which: 'S',
Target: string(v),
}
case inst.Execute:
p := packets.Execute{
Target: string(v),
}
case inst.ClosePortal:
p := packets.Close{
Which: 'P',
Target: string(v),
}
case inst.ClosePreparedStatement:
p := packets.Close{
Which: 'S',
Target: string(v),
}
case inst.CopyData:
p := packets.CopyData(v)
case inst.CopyDone:
client.Do(&results[i], fed.NewPacket(packets.TypeCopyDone))
func (T *Runner) runModeL1(dialer recipe.Dialer, client *gsql.Client) error {
if err != nil {
if errors.Is(err, io.EOF) {
break
func (T *Runner) runModeOnce(dialer recipe.Dialer) ([]Capturer, error) {
var client gsql.Client
results := T.prepare(&client, len(T.test.Instructions))
if err := client.Close(); err != nil {
return nil, err
}
if err := T.runModeL1(dialer, &client); err != nil {
return nil, err
}
func (T *Runner) runModeFail(dialer recipe.Dialer) error {
for i := 1; i < len(T.test.Instructions)+1; i++ {
var client gsql.Client
T.prepare(&client, i)
if err := client.Close(); err != nil {
return err
}
if err := T.runModeL1(dialer, &client); err != nil && !errors.Is(err, io.EOF) {
return err
}
}
return nil
}
func (T *Runner) runMode(dialer recipe.Dialer) ([]Capturer, error) {
instances := T.config.Stress
if instances < 1 || T.test.SideEffects {
}
expected, err := T.runModeOnce(dialer)
if err != nil {
return nil, err
}
// fail testing
if err = T.runModeFail(dialer); err != nil {
return nil, err
}
// stress test
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
})
}
if err = b.Wait(); err != nil {
return nil, err
}
return expected, nil
// modes
for name, mode := range T.config.Modes {
actual, err := T.runMode(mode)
if err != nil {
errs = append(errs, ErrorIn{
Name: name,
Err: err,
})
continue
if expected == nil {
expected = actual
continue
}
errs = append(errs, ErrorIn{
Name: name,
Err: fmt.Errorf("wrong number of results! expected %d but got %d", len(expected), len(actual)),
})
continue
for i, exp := range expected {
act := actual[i]
if err = exp.Check(&act); err != nil {
modeErrs = append(modeErrs, fmt.Errorf("instruction %d: %s", i+1, err.Error()))
if len(modeErrs) > 0 {
errs = append(errs, ErrorIn{
Name: name,
Err: Errors(modeErrs),
})
}