From b867eff84c1cef7db063456f87c216cde0bd0ab7 Mon Sep 17 00:00:00 2001 From: Livio Amstutz Date: Tue, 26 Apr 2022 21:41:11 +0200 Subject: [PATCH] test: ensure consistency of update multiple sequences test (#3501) --- .../eventstore/handler/crdb/db_mock_test.go | 73 ++++++++++++++----- .../handler/crdb/handler_stmt_test.go | 10 ++- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/internal/eventstore/handler/crdb/db_mock_test.go b/internal/eventstore/handler/crdb/db_mock_test.go index b0067e3b56..5732f135c8 100644 --- a/internal/eventstore/handler/crdb/db_mock_test.go +++ b/internal/eventstore/handler/crdb/db_mock_test.go @@ -3,8 +3,8 @@ package crdb import ( "database/sql" "database/sql/driver" - "sort" "strings" + "testing" "time" "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) { - //sort them so the args will always have the same order - keys := make([]string, 0, len(sequences)) - for k := range sequences { - keys = append(keys, string(k)) - } - sort.Strings(keys) - args := make([]driver.Value, len(keys)*4) - for i, k := range keys { - 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 +func expectUpdateThreeCurrentSequence(t *testing.T, tableName, projection string, sequences currentSequences) func(sqlmock.Sqlmock) { + args := make([][]interface{}, 0) + for aggregateType, instanceSequences := range sequences { + for _, sequence := range instanceSequences { + args = append(args, []interface{}{ + projection, + aggregateType, + sequence.sequence, + sequence.instanceID, + }) } } + matcher := ¤tSequenceMatcher{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) { - 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( - args..., + matchers..., ). WillReturnResult( 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) { 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\(\)\)`). diff --git a/internal/eventstore/handler/crdb/handler_stmt_test.go b/internal/eventstore/handler/crdb/handler_stmt_test.go index 1fc436483d..845746b7c4 100644 --- a/internal/eventstore/handler/crdb/handler_stmt_test.go +++ b/internal/eventstore/handler/crdb/handler_stmt_test.go @@ -1558,6 +1558,10 @@ func TestStatementHandler_updateCurrentSequence(t *testing.T) { sequence: 6, instanceID: "instanceID", }, + { + sequence: 10, + instanceID: "instanceID2", + }, }, }, }, @@ -1566,7 +1570,7 @@ func TestStatementHandler_updateCurrentSequence(t *testing.T) { return err == nil }, expectations: []mockExpectation{ - expectUpdateTwoCurrentSequence("my_table", "my_projection", currentSequences{ + expectUpdateThreeCurrentSequence(t, "my_table", "my_projection", currentSequences{ "agg": []*instanceSequence{ { sequence: 5, @@ -1578,6 +1582,10 @@ func TestStatementHandler_updateCurrentSequence(t *testing.T) { sequence: 6, instanceID: "instanceID", }, + { + sequence: 10, + instanceID: "instanceID2", + }, }, }), },