test: ensure consistency of update multiple sequences test (#3501)

This commit is contained in:
Livio Amstutz 2022-04-26 21:41:11 +02:00 committed by GitHub
parent e9e332b909
commit b867eff84c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 19 deletions

View File

@ -3,8 +3,8 @@ package crdb
import ( import (
"database/sql" "database/sql"
"database/sql/driver" "database/sql/driver"
"sort"
"strings" "strings"
"testing"
"time" "time"
"github.com/DATA-DOG/go-sqlmock" "github.com/DATA-DOG/go-sqlmock"
@ -187,27 +187,27 @@ func expectUpdateCurrentSequence(tableName, projection string, seq uint64, aggre
} }
} }
func expectUpdateTwoCurrentSequence(tableName, projection string, sequences currentSequences) func(sqlmock.Sqlmock) { func expectUpdateThreeCurrentSequence(t *testing.T, tableName, projection string, sequences currentSequences) func(sqlmock.Sqlmock) {
//sort them so the args will always have the same order args := make([][]interface{}, 0)
keys := make([]string, 0, len(sequences)) for aggregateType, instanceSequences := range sequences {
for k := range sequences { for _, sequence := range instanceSequences {
keys = append(keys, string(k)) args = append(args, []interface{}{
} projection,
sort.Strings(keys) aggregateType,
args := make([]driver.Value, len(keys)*4) sequence.sequence,
for i, k := range keys { sequence.instanceID,
aggregateType := eventstore.AggregateType(k) })
for _, sequence := range sequences[aggregateType] {
args[i*4] = projection
args[i*4+1] = aggregateType
args[i*4+2] = sequence.sequence
args[i*4+3] = sequence.instanceID
} }
} }
matcher := &currentSequenceMatcher{t: t, seq: args}
matchers := make([]driver.Value, len(args)*4)
for i := 0; i < len(args)*4; i++ {
matchers[i] = matcher
}
return func(m sqlmock.Sqlmock) { return func(m sqlmock.Sqlmock) {
m.ExpectExec("UPSERT INTO " + tableName + ` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\), \(\$5, \$6, \$7, \$8, NOW\(\)\)`). m.ExpectExec("UPSERT INTO " + tableName + ` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\), \(\$5, \$6, \$7, \$8, NOW\(\)\), \(\$9, \$10, \$11, \$12, NOW\(\)\)`).
WithArgs( WithArgs(
args..., matchers...,
). ).
WillReturnResult( WillReturnResult(
sqlmock.NewResult(1, 1), sqlmock.NewResult(1, 1),
@ -215,6 +215,43 @@ func expectUpdateTwoCurrentSequence(tableName, projection string, sequences curr
} }
} }
type currentSequenceMatcher struct {
seq [][]interface{}
i int
t *testing.T
}
func (m *currentSequenceMatcher) Match(value driver.Value) bool {
if m.i%4 == 0 {
m.i = 0
}
left := make([]interface{}, 0, len(m.seq))
for _, seq := range m.seq {
found := seq[m.i]
if found == nil {
continue
}
switch v := value.(type) {
case string:
if found == v || found == eventstore.AggregateType(v) {
seq[m.i] = nil
m.i++
return true
}
case int64:
if found == uint64(v) {
seq[m.i] = nil
m.i++
return true
}
}
left = append(left, found)
}
m.t.Errorf("expected: %v, possible left values: %v", value, left)
m.t.FailNow()
return false
}
func expectUpdateCurrentSequenceErr(tableName, projection string, seq uint64, err error, aggregateType, instanceID string) func(sqlmock.Sqlmock) { func expectUpdateCurrentSequenceErr(tableName, projection string, seq uint64, err error, aggregateType, instanceID string) func(sqlmock.Sqlmock) {
return func(m sqlmock.Sqlmock) { return func(m sqlmock.Sqlmock) {
m.ExpectExec("UPSERT INTO "+tableName+` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\)`). m.ExpectExec("UPSERT INTO "+tableName+` \(projection_name, aggregate_type, current_sequence, instance_id, timestamp\) VALUES \(\$1, \$2, \$3, \$4, NOW\(\)\)`).

View File

@ -1558,6 +1558,10 @@ func TestStatementHandler_updateCurrentSequence(t *testing.T) {
sequence: 6, sequence: 6,
instanceID: "instanceID", instanceID: "instanceID",
}, },
{
sequence: 10,
instanceID: "instanceID2",
},
}, },
}, },
}, },
@ -1566,7 +1570,7 @@ func TestStatementHandler_updateCurrentSequence(t *testing.T) {
return err == nil return err == nil
}, },
expectations: []mockExpectation{ expectations: []mockExpectation{
expectUpdateTwoCurrentSequence("my_table", "my_projection", currentSequences{ expectUpdateThreeCurrentSequence(t, "my_table", "my_projection", currentSequences{
"agg": []*instanceSequence{ "agg": []*instanceSequence{
{ {
sequence: 5, sequence: 5,
@ -1578,6 +1582,10 @@ func TestStatementHandler_updateCurrentSequence(t *testing.T) {
sequence: 6, sequence: 6,
instanceID: "instanceID", instanceID: "instanceID",
}, },
{
sequence: 10,
instanceID: "instanceID2",
},
}, },
}), }),
}, },