diff --git a/Earthfile b/Earthfile index ebf27a9..aa84511 100644 --- a/Earthfile +++ b/Earthfile @@ -81,9 +81,7 @@ lint: local-test: FROM +vendor - WITH DOCKER --pull postgres:11 - RUN go-acc ./... -o coverage.out --ignore egopb,test,example,mocks -- -mod=vendor -timeout 0 -race -v - END + RUN go-acc ./... -o coverage.out --ignore egopb,test,example,mocks -- -mod=vendor -timeout 0 -race -v SAVE ARTIFACT coverage.out AS LOCAL coverage.out diff --git a/durable_state_actor_test.go b/durable_state_actor_test.go index ebd606d..0684c89 100644 --- a/durable_state_actor_test.go +++ b/durable_state_actor_test.go @@ -32,8 +32,6 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - memory "github.com/tochemey/ego-contrib/durablestore/memory" - pgstore "github.com/tochemey/ego-contrib/durablestore/postgres" "github.com/tochemey/goakt/v2/actors" "github.com/tochemey/goakt/v2/log" "google.golang.org/protobuf/proto" @@ -42,6 +40,7 @@ import ( "github.com/tochemey/ego/v3/eventstream" "github.com/tochemey/ego/v3/internal/lib" testpb "github.com/tochemey/ego/v3/test/data/pb/v3" + "github.com/tochemey/ego/v3/testkit" ) func TestDurableStateBehavior(t *testing.T) { @@ -61,7 +60,7 @@ func TestDurableStateBehavior(t *testing.T) { lib.Pause(time.Second) - durableStore := memory.NewStateStore() + durableStore := testkit.NewDurableStore() // create a persistence id persistenceID := uuid.NewString() behavior := NewAccountDurableStateBehavior(persistenceID) @@ -157,7 +156,7 @@ func TestDurableStateBehavior(t *testing.T) { lib.Pause(time.Second) - durableStore := memory.NewStateStore() + durableStore := testkit.NewDurableStore() // create a persistence id persistenceID := uuid.NewString() // create the persistence behavior @@ -246,27 +245,7 @@ func TestDurableStateBehavior(t *testing.T) { lib.Pause(time.Second) - var ( - testDatabase = "testdb" - testUser = "testUser" - testDatabasePassword = "testPass" - ) - - testContainer := pgstore.NewTestContainer(testDatabase, testUser, testDatabasePassword) - db := testContainer.GetTestDB() - require.NoError(t, db.Connect(ctx)) - schemaUtils := pgstore.NewSchemaUtils(db) - require.NoError(t, schemaUtils.CreateTable(ctx)) - - config := &pgstore.Config{ - DBHost: testContainer.Host(), - DBPort: testContainer.Port(), - DBName: testDatabase, - DBUser: testUser, - DBPassword: testDatabasePassword, - DBSchema: testContainer.Schema(), - } - durableStore := pgstore.NewDurableStore(config) + durableStore := testkit.NewDurableStore() require.NoError(t, durableStore.Connect(ctx)) lib.Pause(time.Second) @@ -375,9 +354,7 @@ func TestDurableStateBehavior(t *testing.T) { lib.Pause(time.Second) // free resources - assert.NoError(t, schemaUtils.DropTable(ctx)) assert.NoError(t, durableStore.Disconnect(ctx)) - testContainer.Cleanup() eventStream.Close() }) } diff --git a/engine_test.go b/engine_test.go index ef70673..463aa80 100644 --- a/engine_test.go +++ b/engine_test.go @@ -36,29 +36,26 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tochemey/goakt/v2/actors" - "github.com/travisjeffery/go-dynaport" - "google.golang.org/protobuf/proto" - - memstore "github.com/tochemey/ego-contrib/durablestore/memory" - memory "github.com/tochemey/ego-contrib/eventstore/memory" - offsetstore "github.com/tochemey/ego-contrib/offsetstore/memory" "github.com/tochemey/goakt/v2/log" mockdisco "github.com/tochemey/goakt/v2/mocks/discovery" + "github.com/travisjeffery/go-dynaport" + "google.golang.org/protobuf/proto" "github.com/tochemey/ego/v3/egopb" samplepb "github.com/tochemey/ego/v3/example/pbs/sample/pb/v1" "github.com/tochemey/ego/v3/internal/lib" "github.com/tochemey/ego/v3/projection" testpb "github.com/tochemey/ego/v3/test/data/pb/v3" + testkit2 "github.com/tochemey/ego/v3/testkit" ) func TestEgo(t *testing.T) { t.Run("EventSourced entity With single node cluster enabled", func(t *testing.T) { ctx := context.TODO() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit2.NewEventsStore() require.NoError(t, eventStore.Connect(ctx)) - offsetStore := offsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() require.NoError(t, offsetStore.Connect(ctx)) nodePorts := dynaport.Get(3) @@ -175,7 +172,7 @@ func TestEgo(t *testing.T) { t.Run("EventSourced entity With no cluster enabled", func(t *testing.T) { ctx := context.TODO() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit2.NewEventsStore() // connect to the event store require.NoError(t, eventStore.Connect(ctx)) // create the ego engine @@ -228,7 +225,7 @@ func TestEgo(t *testing.T) { t.Run("EventSourced entity With SendCommand when not started", func(t *testing.T) { ctx := context.TODO() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit2.NewEventsStore() require.NoError(t, eventStore.Connect(ctx)) // create the ego engine @@ -245,7 +242,7 @@ func TestEgo(t *testing.T) { t.Run("EventSourced entity With SendCommand when entityID is not set", func(t *testing.T) { ctx := context.TODO() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit2.NewEventsStore() require.NoError(t, eventStore.Connect(ctx)) // create the ego engine @@ -266,7 +263,7 @@ func TestEgo(t *testing.T) { t.Run("EventSourced entity With SendCommand when entity is not found", func(t *testing.T) { ctx := context.TODO() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit2.NewEventsStore() require.NoError(t, eventStore.Connect(ctx)) // create the ego engine @@ -287,7 +284,7 @@ func TestEgo(t *testing.T) { t.Run("EventSourced entity With IsProjectionRunning when not started", func(t *testing.T) { ctx := context.TODO() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit2.NewEventsStore() require.NoError(t, eventStore.Connect(ctx)) // create the ego engine @@ -303,11 +300,11 @@ func TestEgo(t *testing.T) { t.Run("EventSourced entity With RemoveProjection", func(t *testing.T) { ctx := context.TODO() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit2.NewEventsStore() // connect to the event store require.NoError(t, eventStore.Connect(ctx)) - offsetStore := offsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() require.NoError(t, offsetStore.Connect(ctx)) // create the ego engine @@ -346,7 +343,7 @@ func TestEgo(t *testing.T) { t.Run("EventSourced entity With RemoveProjection when not started", func(t *testing.T) { ctx := context.TODO() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit2.NewEventsStore() require.NoError(t, eventStore.Connect(ctx)) // create the ego engine @@ -361,7 +358,7 @@ func TestEgo(t *testing.T) { t.Run("DurableStore entity With single node cluster enabled", func(t *testing.T) { ctx := context.TODO() - stateStore := memstore.NewStateStore() + stateStore := testkit2.NewDurableStore() require.NoError(t, stateStore.Connect(ctx)) nodePorts := dynaport.Get(3) @@ -457,7 +454,7 @@ func TestEgo(t *testing.T) { }) t.Run("DurableStore entity With no cluster enabled", func(t *testing.T) { ctx := context.TODO() - stateStore := memstore.NewStateStore() + stateStore := testkit2.NewDurableStore() require.NoError(t, stateStore.Connect(ctx)) // create the ego engine @@ -509,7 +506,7 @@ func TestEgo(t *testing.T) { t.Run("DurableStore entity With SendCommand when not started", func(t *testing.T) { ctx := context.TODO() - stateStore := memstore.NewStateStore() + stateStore := testkit2.NewDurableStore() require.NoError(t, stateStore.Connect(ctx)) // create the ego engine @@ -527,7 +524,7 @@ func TestEgo(t *testing.T) { }) t.Run("DurableStore entity With SendCommand when entityID is not set", func(t *testing.T) { ctx := context.TODO() - stateStore := memstore.NewStateStore() + stateStore := testkit2.NewDurableStore() require.NoError(t, stateStore.Connect(ctx)) // create the ego engine @@ -549,7 +546,7 @@ func TestEgo(t *testing.T) { t.Run("DurableStore entity With SendCommand when entity is not found", func(t *testing.T) { ctx := context.TODO() - stateStore := memstore.NewStateStore() + stateStore := testkit2.NewDurableStore() require.NoError(t, stateStore.Connect(ctx)) // create the ego engine diff --git a/event_sourced_actor_test.go b/event_sourced_actor_test.go index f2aecb7..9c42b71 100644 --- a/event_sourced_actor_test.go +++ b/event_sourced_actor_test.go @@ -32,18 +32,16 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/emptypb" - - memory "github.com/tochemey/ego-contrib/eventstore/memory" - pgstore "github.com/tochemey/ego-contrib/eventstore/postgres" "github.com/tochemey/goakt/v2/actors" "github.com/tochemey/goakt/v2/log" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/emptypb" "github.com/tochemey/ego/v3/egopb" "github.com/tochemey/ego/v3/eventstream" "github.com/tochemey/ego/v3/internal/lib" testpb "github.com/tochemey/ego/v3/test/data/pb/v3" + "github.com/tochemey/ego/v3/testkit" ) func TestEventSourcedActor(t *testing.T) { @@ -64,7 +62,7 @@ func TestEventSourcedActor(t *testing.T) { lib.Pause(time.Second) // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit.NewEventsStore() // create a persistence id persistenceID := uuid.NewString() // create the persistence behavior @@ -170,7 +168,7 @@ func TestEventSourcedActor(t *testing.T) { lib.Pause(time.Second) // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit.NewEventsStore() // create a persistence id persistenceID := uuid.NewString() // create the persistence behavior @@ -264,7 +262,7 @@ func TestEventSourcedActor(t *testing.T) { lib.Pause(time.Second) // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit.NewEventsStore() // create a persistence id persistenceID := uuid.NewString() // create the persistence behavior @@ -325,29 +323,7 @@ func TestEventSourcedActor(t *testing.T) { lib.Pause(time.Second) - // create the event store - var ( - testDatabase = "testdb" - testUser = "testUser" - testDatabasePassword = "testPass" - ) - - testContainer := pgstore.NewTestContainer(testDatabase, testUser, testDatabasePassword) - db := testContainer.GetTestDB() - // create the event store table - require.NoError(t, db.Connect(ctx)) - schemaUtils := pgstore.NewSchemaUtils(db) - require.NoError(t, schemaUtils.CreateTable(ctx)) - - config := &pgstore.Config{ - DBHost: testContainer.Host(), - DBPort: testContainer.Port(), - DBName: testDatabase, - DBUser: testUser, - DBPassword: testDatabasePassword, - DBSchema: testContainer.Schema(), - } - eventStore := pgstore.NewEventsStore(config) + eventStore := testkit.NewEventsStore() require.NoError(t, eventStore.Connect(ctx)) lib.Pause(time.Second) @@ -457,9 +433,7 @@ func TestEventSourcedActor(t *testing.T) { assert.True(t, proto.Equal(expected, resultingState)) // free resources - assert.NoError(t, schemaUtils.DropTable(ctx)) assert.NoError(t, eventStore.Disconnect(ctx)) - testContainer.Cleanup() // close the stream eventStream.Close() @@ -486,7 +460,7 @@ func TestEventSourcedActor(t *testing.T) { lib.Pause(time.Second) // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit.NewEventsStore() // create a persistence id persistenceID := uuid.NewString() // create the persistence behavior @@ -613,7 +587,7 @@ func TestEventSourcedActor(t *testing.T) { lib.Pause(time.Second) // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit.NewEventsStore() // create a persistence id persistenceID := uuid.NewString() // create the persistence behavior diff --git a/example/durablestate/main.go b/example/durablestate/main.go index 8898a87..e2ac4e9 100644 --- a/example/durablestate/main.go +++ b/example/durablestate/main.go @@ -34,18 +34,18 @@ import ( "time" "github.com/google/uuid" - memory "github.com/tochemey/ego-contrib/durablestore/memory" "google.golang.org/protobuf/proto" "github.com/tochemey/ego/v3" samplepb "github.com/tochemey/ego/v3/example/pbs/sample/pb/v1" + "github.com/tochemey/ego/v3/testkit" ) func main() { // create the go context ctx := context.Background() // create the event store - durableStore := memory.NewStateStore() + durableStore := testkit.NewDurableStore() // connect the event store _ = durableStore.Connect(ctx) // create the ego engine diff --git a/example/eventssourced/main.go b/example/eventssourced/main.go index b5ec56d..5edbb83 100644 --- a/example/eventssourced/main.go +++ b/example/eventssourced/main.go @@ -34,18 +34,18 @@ import ( "time" "github.com/google/uuid" - memory "github.com/tochemey/ego-contrib/eventstore/memory" "google.golang.org/protobuf/proto" "github.com/tochemey/ego/v3" samplepb "github.com/tochemey/ego/v3/example/pbs/sample/pb/v1" + "github.com/tochemey/ego/v3/testkit" ) func main() { // create the go context ctx := context.Background() // create the event store - eventStore := memory.NewEventsStore() + eventStore := testkit.NewEventsStore() // connect the event store _ = eventStore.Connect(ctx) // create the ego engine diff --git a/go.mod b/go.mod index 032dba2..68fd08e 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,10 @@ module github.com/tochemey/ego/v3 go 1.22.0 require ( + github.com/deckarep/golang-set/v2 v2.7.0 github.com/flowchartsman/retry v1.2.0 github.com/google/uuid v1.6.0 github.com/stretchr/testify v1.10.0 - github.com/tochemey/ego-contrib/durablestore/memory v0.0.0-20241226194523-04ecdcbf3fb3 - github.com/tochemey/ego-contrib/durablestore/postgres v0.0.0-20241226194523-04ecdcbf3fb3 - github.com/tochemey/ego-contrib/eventstore/memory v0.0.0-20241226194523-04ecdcbf3fb3 - github.com/tochemey/ego-contrib/eventstore/postgres v0.0.0-20241226194523-04ecdcbf3fb3 - github.com/tochemey/ego-contrib/offsetstore/memory v0.0.0-20241226194523-04ecdcbf3fb3 github.com/tochemey/goakt/v2 v2.11.0 github.com/travisjeffery/go-dynaport v1.0.0 go.uber.org/atomic v1.11.0 @@ -22,80 +18,49 @@ require ( require ( connectrpc.com/connect v1.17.0 // indirect - dario.cat/mergo v1.0.1 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/Masterminds/squirrel v1.5.4 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/RoaringBitmap/roaring v1.9.4 // indirect github.com/Workiva/go-datastructures v1.1.5 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/bits-and-blooms/bitset v1.20.0 // indirect github.com/buraksezer/consistent v0.10.0 // indirect github.com/buraksezer/olric v0.5.6-0.20240925183822-6ca0e20256e0 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/containerd/continuity v0.4.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.7.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/docker/cli v27.4.1+incompatible // indirect - github.com/docker/docker v27.4.1+incompatible // indirect - github.com/docker/go-connections v0.5.0 // indirect - github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/georgysavva/scany/v2 v2.1.3 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-memdb v1.3.4 // indirect github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-sockaddr v1.0.7 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/memberlist v0.5.1 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.2 // indirect - github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect - github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect - github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/miekg/dns v1.1.62 // indirect - github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/sys/user v0.3.0 // indirect - github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/opencontainers/runc v1.2.3 // indirect - github.com/ory/dockertest/v3 v3.11.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/redis/go-redis/v9 v9.7.0 // indirect github.com/reugn/go-quartz v0.13.0 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/tidwall/btree v1.7.0 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -103,12 +68,8 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.31.0 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect diff --git a/go.sum b/go.sum index cde81a3..315b2de 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,10 @@ connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= -github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/RoaringBitmap/roaring v1.6.0/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE= github.com/RoaringBitmap/roaring v1.9.4 h1:yhEIoH4YezLYT04s1nHehNO64EKFTop/wBhxv2QzDdQ= github.com/RoaringBitmap/roaring v1.9.4/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90= @@ -47,20 +35,12 @@ github.com/buraksezer/consistent v0.10.0 h1:hqBgz1PvNLC5rkWcEBVAL9dFMBWz6I0VgUCW github.com/buraksezer/consistent v0.10.0/go.mod h1:6BrVajWq7wbKZlTOUPs/XVfR8c0maujuPowduSpZqmw= github.com/buraksezer/olric v0.5.6-0.20240925183822-6ca0e20256e0 h1:0oLGcEeK3ew44mabFJ3nrAkg8G83RGM0FaXAIDrKSEQ= github.com/buraksezer/olric v0.5.6-0.20240925183822-6ca0e20256e0/go.mod h1:g9fss7jy1l9W7pPezICBxRAPWDwCiImcPi0ABF1o1R0= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/cockroachdb/cockroach-go/v2 v2.2.0 h1:/5znzg5n373N/3ESjHF5SMLxiW4RKB05Ql//KWfeTFs= -github.com/cockroachdb/cockroach-go/v2 v2.2.0/go.mod h1:u3MiKYGupPPjkn3ozknpMUpxPaNLTFWAya419/zv6eI= -github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4= -github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -72,14 +52,6 @@ github.com/deckarep/golang-set/v2 v2.7.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpO github.com/dgryski/go-ddmin v0.0.0-20210904190556-96a6d69f1034/go.mod h1:zz4KxBkcXUWKjIcrc+uphJ1gPh/t18ymGm3PmQ+VGTk= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/docker/cli v27.4.1+incompatible h1:VzPiUlRJ/xh+otB75gva3r05isHMo5wXDfPRi5/b4hI= -github.com/docker/cli v27.4.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v27.4.1+incompatible h1:ZJvcY7gfwHn1JF48PfbyXg7Jyt9ZCWDW+GGXOIxEwp4= -github.com/docker/docker v27.4.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -87,8 +59,6 @@ github.com/flowchartsman/retry v1.2.0 h1:qDhlw6RNufXz6RGr+IiYimFpMMkt77SUSHY5tgF github.com/flowchartsman/retry v1.2.0/go.mod h1:+sfx8OgCCiAr3t5jh2Gk+T0fRTI+k52edaYxURQxY64= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/georgysavva/scany/v2 v2.1.3 h1:Zd4zm/ej79Den7tBSU2kaTDPAH64suq4qlQdhiBeGds= -github.com/georgysavva/scany/v2 v2.1.3/go.mod h1:fqp9yHZzM/PFVa3/rYEC57VmDx+KDch0LoqrJzkvtos= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -101,15 +71,9 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= -github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -137,8 +101,6 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -148,11 +110,8 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= -github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= github.com/hashicorp/go-msgpack/v2 v2.1.1/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= @@ -167,7 +126,6 @@ github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0Yg github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= @@ -177,14 +135,6 @@ github.com/hashicorp/memberlist v0.5.1/go.mod h1:zGDXV6AqbDTKTM6yxW0I4+JtFzZAJVo github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI= -github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= -github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= -github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -208,12 +158,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= -github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= -github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= -github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= @@ -230,12 +174,6 @@ github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2c github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -262,14 +200,6 @@ github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.2.3 h1:fxE7amCzfZflJO2lHXf4y/y8M1BoAqp+FVmG19oYB80= -github.com/opencontainers/runc v1.2.3/go.mod h1:nSxcWUydXrsBZVYNSkTjoQ/N6rcyTtn+1SD5D4+kRIM= -github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA= -github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -308,8 +238,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -340,26 +268,6 @@ github.com/tidwall/redcon v1.6.2 h1:5qfvrrybgtO85jnhSravmkZyC0D+7WstbfCs3MmPhow= github.com/tidwall/redcon v1.6.2/go.mod h1:p5Wbsgeyi2VSTBWOcA5vRXrOb9arFTcU2+ZzFjqV75Y= github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= -github.com/tochemey/ego-contrib/durablestore/memory v0.0.0-20241226191059-fe9589656e1d h1:WWJeCPdN3fETVHfEIEbDhDBNbBweV3apUH/QOpRTdGg= -github.com/tochemey/ego-contrib/durablestore/memory v0.0.0-20241226191059-fe9589656e1d/go.mod h1:ZiiSRYjYP66Len2QZtQaq2suPCQAg9zLMymJl0zwPBo= -github.com/tochemey/ego-contrib/durablestore/memory v0.0.0-20241226194523-04ecdcbf3fb3 h1:mXAKyQ37qiQdqHyaID+rEvLNePHR9wNKOAqyhFRmzLM= -github.com/tochemey/ego-contrib/durablestore/memory v0.0.0-20241226194523-04ecdcbf3fb3/go.mod h1:ZiiSRYjYP66Len2QZtQaq2suPCQAg9zLMymJl0zwPBo= -github.com/tochemey/ego-contrib/durablestore/postgres v0.0.0-20241226191059-fe9589656e1d h1:5hN0j9oIi41CTZ7nqVOhcOgAp0AqZU9CJAnwxrHiYrY= -github.com/tochemey/ego-contrib/durablestore/postgres v0.0.0-20241226191059-fe9589656e1d/go.mod h1:jWcNje9EmFMgsgyxbue3FEQdCJFv/cdCHVUAoZUnyb8= -github.com/tochemey/ego-contrib/durablestore/postgres v0.0.0-20241226194523-04ecdcbf3fb3 h1:nbVlFznzFcyciZrIM1eThEHchBWe86DS18NafNkozq8= -github.com/tochemey/ego-contrib/durablestore/postgres v0.0.0-20241226194523-04ecdcbf3fb3/go.mod h1:jWcNje9EmFMgsgyxbue3FEQdCJFv/cdCHVUAoZUnyb8= -github.com/tochemey/ego-contrib/eventstore/memory v0.0.0-20241226191059-fe9589656e1d h1:YdOrvoAzsbUZVznJjqP3VDVwjEsYHlfcmXaxq9nFII0= -github.com/tochemey/ego-contrib/eventstore/memory v0.0.0-20241226191059-fe9589656e1d/go.mod h1:fIPRJ0Vh/hltHDOyqCZXqQBv+u1OAeTM3pDQn2Tg5cw= -github.com/tochemey/ego-contrib/eventstore/memory v0.0.0-20241226194523-04ecdcbf3fb3 h1:Zh5ndookRvlRFCS5pjEMw5sjcl2bboRlkQA1Wg+dW+k= -github.com/tochemey/ego-contrib/eventstore/memory v0.0.0-20241226194523-04ecdcbf3fb3/go.mod h1:fIPRJ0Vh/hltHDOyqCZXqQBv+u1OAeTM3pDQn2Tg5cw= -github.com/tochemey/ego-contrib/eventstore/postgres v0.0.0-20241226191059-fe9589656e1d h1:rCcusqecSQt2z8jaGcqu+WnTKL5JCZv8Ti7y/tUAIdc= -github.com/tochemey/ego-contrib/eventstore/postgres v0.0.0-20241226191059-fe9589656e1d/go.mod h1:amP9+eDvwyodN5ZAkeQnek+9PM28n4JxXiaxv2ghnZI= -github.com/tochemey/ego-contrib/eventstore/postgres v0.0.0-20241226194523-04ecdcbf3fb3 h1:blYCCLs8TH812sNyyaHEI1CQpSTk2ubPwOzLlZFzPqs= -github.com/tochemey/ego-contrib/eventstore/postgres v0.0.0-20241226194523-04ecdcbf3fb3/go.mod h1:amP9+eDvwyodN5ZAkeQnek+9PM28n4JxXiaxv2ghnZI= -github.com/tochemey/ego-contrib/offsetstore/memory v0.0.0-20241226191059-fe9589656e1d h1:hd3VCJstrA2N1Mp2j32oUrJhQVoZhjr8pgh7koqv+8U= -github.com/tochemey/ego-contrib/offsetstore/memory v0.0.0-20241226191059-fe9589656e1d/go.mod h1:POUIFQ21A1RJW8HKkntl1cnhPHwZIwRXZn+ArjZM/Kw= -github.com/tochemey/ego-contrib/offsetstore/memory v0.0.0-20241226194523-04ecdcbf3fb3 h1:oljKEGjJsqM1EPVpZ0jM0SajeItf3+J28YgVUXK22ks= -github.com/tochemey/ego-contrib/offsetstore/memory v0.0.0-20241226194523-04ecdcbf3fb3/go.mod h1:POUIFQ21A1RJW8HKkntl1cnhPHwZIwRXZn+ArjZM/Kw= github.com/tochemey/goakt/v2 v2.11.0 h1:4reuqeN8mvsUWu9ecn3Vd+qtpTASj/kEI9W3FRYHofM= github.com/tochemey/goakt/v2 v2.11.0/go.mod h1:gMba2xHDzLSDojw5m1SPHDzVFgNWn1I6G9zoagym5e0= github.com/travisjeffery/go-dynaport v1.0.0 h1:m/qqf5AHgB96CMMSworIPyo1i7NZueRsnwdzdCJ8Ajw= @@ -372,13 +280,6 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -475,10 +376,8 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -566,8 +465,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= k8s.io/api v0.31.4 h1:I2QNzitPVsPeLQvexMEsj945QumYraqv9m74isPDKhM= k8s.io/api v0.31.4/go.mod h1:d+7vgXLvmcdT1BCo79VEgJxHHryww3V5np2OYTr6jdw= k8s.io/apimachinery v0.31.4 h1:8xjE2C4CzhYVm9DGf60yohpNUh5AEBnPxCryPBECmlM= diff --git a/projection/handler.go b/projection/handler.go index 436ee46..0ee55a9 100644 --- a/projection/handler.go +++ b/projection/handler.go @@ -67,6 +67,6 @@ func (x *DiscardHandler) Handle(_ context.Context, persistenceID string, event * } // EventsCount returns the number of events processed -func (x *DiscardHandler) EventsCount() int { - return int(x.eventsCounter.Load()) +func (x *DiscardHandler) EventsCount() int64 { + return x.eventsCounter.Load() } diff --git a/projection/projection_test.go b/projection/projection_test.go index 4dd4227..9ede082 100644 --- a/projection/projection_test.go +++ b/projection/projection_test.go @@ -32,28 +32,27 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tochemey/goakt/v2/actors" + "github.com/tochemey/goakt/v2/log" "go.uber.org/goleak" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/timestamppb" - memory "github.com/tochemey/ego-contrib/eventstore/memory" - memoffsetstore "github.com/tochemey/ego-contrib/offsetstore/memory" - "github.com/tochemey/goakt/v2/actors" - "github.com/tochemey/goakt/v2/log" - "github.com/tochemey/ego/v3/egopb" "github.com/tochemey/ego/v3/internal/lib" testpb "github.com/tochemey/ego/v3/test/data/pb/v3" + testkit2 "github.com/tochemey/ego/v3/testkit" ) func TestProjection(t *testing.T) { t.Run("With happy path", func(t *testing.T) { defer goleak.VerifyNone(t) ctx := context.TODO() + logger := log.DiscardLogger // create an actor system actorSystem, err := actors.NewActorSystem("TestActorSystem", actors.WithPassivationDisabled(), - actors.WithLogger(log.DiscardLogger), + actors.WithLogger(logger), actors.WithActorInitMaxRetries(3)) require.NoError(t, err) assert.NotNil(t, actorSystem) @@ -67,15 +66,14 @@ func TestProjection(t *testing.T) { projectionName := "db-writer" persistenceID := uuid.NewString() shardNumber := uint64(9) - logger := log.DiscardLogger // set up the event store - journalStore := memory.NewEventsStore() + journalStore := testkit2.NewEventsStore() assert.NotNil(t, journalStore) require.NoError(t, journalStore.Connect(ctx)) // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Connect(ctx)) @@ -125,11 +123,11 @@ func TestProjection(t *testing.T) { // let us grab the current offset actual, err := offsetStore.GetCurrentOffset(ctx, projectionID) - assert.NoError(t, err) - assert.NotNil(t, actual) - assert.EqualValues(t, journals[9].GetTimestamp(), actual.GetValue()) + require.NoError(t, err) + require.NotNil(t, actual) + require.EqualValues(t, journals[9].GetTimestamp(), actual.GetValue()) - assert.EqualValues(t, 10, handler.EventsCount()) + require.EqualValues(t, 10, handler.EventsCount()) // free resources assert.NoError(t, journalStore.Disconnect(ctx)) diff --git a/projection/runner_test.go b/projection/runner_test.go index 3e326cb..a5c1b64 100644 --- a/projection/runner_test.go +++ b/projection/runner_test.go @@ -34,20 +34,18 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/tochemey/goakt/v2/log" "go.uber.org/atomic" "go.uber.org/goleak" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/timestamppb" - memory "github.com/tochemey/ego-contrib/eventstore/memory" - memoffsetstore "github.com/tochemey/ego-contrib/offsetstore/memory" - "github.com/tochemey/goakt/v2/log" - "github.com/tochemey/ego/v3/egopb" "github.com/tochemey/ego/v3/internal/lib" mocksoffsetstore "github.com/tochemey/ego/v3/mocks/offsetstore" mockseventstore "github.com/tochemey/ego/v3/mocks/persistence" testpb "github.com/tochemey/ego/v3/test/data/pb/v3" + testkit2 "github.com/tochemey/ego/v3/testkit" ) func TestRunner(t *testing.T) { @@ -57,15 +55,15 @@ func TestRunner(t *testing.T) { projectionName := "db-writer" persistenceID := uuid.NewString() shardNumber := uint64(9) - logger := log.DefaultLogger + logger := log.DiscardLogger // set up the event store - eventsStore := memory.NewEventsStore() + eventsStore := testkit2.NewEventsStore() assert.NotNil(t, eventsStore) require.NoError(t, eventsStore.Connect(ctx)) // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Connect(ctx)) @@ -74,7 +72,7 @@ func TestRunner(t *testing.T) { handler := NewDiscardHandler(logger) // create an instance of the projection - runner := newRunner(projectionName, handler, eventsStore, offsetStore, WithRefreshInterval(time.Millisecond)) + runner := newRunner(projectionName, handler, eventsStore, offsetStore, WithRefreshInterval(time.Millisecond), WithLogger(logger)) // start the projection err := runner.Start(ctx) require.NoError(t, err) @@ -138,12 +136,12 @@ func TestRunner(t *testing.T) { persistenceID := uuid.NewString() // set up the event store - journalStore := memory.NewEventsStore() + journalStore := testkit2.NewEventsStore() assert.NotNil(t, journalStore) require.NoError(t, journalStore.Connect(ctx)) // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Disconnect(ctx)) @@ -200,12 +198,12 @@ func TestRunner(t *testing.T) { persistenceID := uuid.NewString() // set up the event store - journalStore := memory.NewEventsStore() + journalStore := testkit2.NewEventsStore() assert.NotNil(t, journalStore) require.NoError(t, journalStore.Connect(ctx)) // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Disconnect(ctx)) @@ -269,12 +267,12 @@ func TestRunner(t *testing.T) { shard := uint64(8) // set up the event store - journalStore := memory.NewEventsStore() + journalStore := testkit2.NewEventsStore() assert.NotNil(t, journalStore) require.NoError(t, journalStore.Connect(ctx)) // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Connect(ctx)) @@ -345,12 +343,12 @@ func TestRunner(t *testing.T) { shard := uint64(7) // set up the event store - journalStore := memory.NewEventsStore() + journalStore := testkit2.NewEventsStore() assert.NotNil(t, journalStore) require.NoError(t, journalStore.Connect(ctx)) // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Connect(ctx)) @@ -418,7 +416,7 @@ func TestRunner(t *testing.T) { handler := NewDiscardHandler(log.DiscardLogger) projectionName := "db-writer" // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Connect(ctx)) @@ -436,7 +434,7 @@ func TestRunner(t *testing.T) { handler := NewDiscardHandler(log.DiscardLogger) projectionName := "db-writer" // set up the event store - eventsStore := memory.NewEventsStore() + eventsStore := testkit2.NewEventsStore() assert.NotNil(t, eventsStore) require.NoError(t, eventsStore.Connect(ctx)) @@ -454,12 +452,12 @@ func TestRunner(t *testing.T) { handler := NewDiscardHandler(log.DiscardLogger) projectionName := "db-writer" // set up the event store - eventsStore := memory.NewEventsStore() + eventsStore := testkit2.NewEventsStore() assert.NotNil(t, eventsStore) require.NoError(t, eventsStore.Connect(ctx)) // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Connect(ctx)) @@ -484,7 +482,7 @@ func TestRunner(t *testing.T) { projectionName := "db-writer" // set up the offset store - offsetStore := memoffsetstore.NewOffsetStore() + offsetStore := testkit2.NewOffsetStore() assert.NotNil(t, offsetStore) require.NoError(t, offsetStore.Connect(ctx)) @@ -507,7 +505,7 @@ func TestRunner(t *testing.T) { projectionName := "db-writer" // set up the event store - eventsStore := memory.NewEventsStore() + eventsStore := testkit2.NewEventsStore() assert.NotNil(t, eventsStore) require.NoError(t, eventsStore.Connect(ctx)) diff --git a/testkit/durablestore.go b/testkit/durablestore.go new file mode 100644 index 0000000..1b9488a --- /dev/null +++ b/testkit/durablestore.go @@ -0,0 +1,107 @@ +/* + * MIT License + * + * Copyright (c) 2022-2024 Tochemey + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package testkit + +import ( + "context" + "errors" + "sync" + + "go.uber.org/atomic" + + "github.com/tochemey/ego/v3/egopb" + "github.com/tochemey/ego/v3/persistence" +) + +type DurableStore struct { + db *sync.Map + connected *atomic.Bool +} + +// enforce compilation error +var _ persistence.StateStore = (*DurableStore)(nil) + +// NewDurableStore creates an instance DurableStore +func NewDurableStore() *DurableStore { + return &DurableStore{ + db: &sync.Map{}, + connected: atomic.NewBool(false), + } +} + +// Connect connects the durable store +// nolint +func (d *DurableStore) Connect(ctx context.Context) error { + if d.connected.Load() { + return nil + } + d.connected.Store(true) + return nil +} + +// Disconnect disconnect the durable store +// nolint +func (d *DurableStore) Disconnect(ctx context.Context) error { + if !d.connected.Load() { + return nil + } + d.db.Range(func(key interface{}, value interface{}) bool { + d.db.Delete(key) + return true + }) + d.connected.Store(false) + return nil +} + +// Ping verifies a connection to the database is still alive, establishing a connection if necessary. +func (d *DurableStore) Ping(ctx context.Context) error { + if !d.connected.Load() { + return d.Connect(ctx) + } + return nil +} + +// WriteState persist durable state for a given persistenceID. +// nolint +func (d *DurableStore) WriteState(_ context.Context, state *egopb.DurableState) error { + if !d.connected.Load() { + return errors.New("durable store is not connected") + } + d.db.Store(state.GetPersistenceId(), state) + return nil +} + +// GetLatestState fetches the latest durable state +// nolint +func (d *DurableStore) GetLatestState(_ context.Context, persistenceID string) (*egopb.DurableState, error) { + if !d.connected.Load() { + return nil, errors.New("durable store is not connected") + } + value, ok := d.db.Load(persistenceID) + if !ok { + return nil, nil + } + return value.(*egopb.DurableState), nil +} diff --git a/testkit/eventstore.go b/testkit/eventstore.go new file mode 100644 index 0000000..3b91d40 --- /dev/null +++ b/testkit/eventstore.go @@ -0,0 +1,239 @@ +/* + * MIT License + * + * Copyright (c) 2022-2024 Tochemey + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package testkit + +import ( + "context" + "sort" + "sync" + + goset "github.com/deckarep/golang-set/v2" + "go.uber.org/atomic" + + "github.com/tochemey/ego/v3/egopb" + "github.com/tochemey/ego/v3/persistence" +) + +type EventKey struct { + PersistenceID string + SequenceNumber uint64 +} + +type EventStore struct { + db *sync.Map + connected *atomic.Bool +} + +var _ persistence.EventsStore = (*EventStore)(nil) + +func NewEventsStore() *EventStore { + return &EventStore{ + db: &sync.Map{}, + connected: atomic.NewBool(false), + } +} + +func (x *EventStore) Connect(_ context.Context) error { + if x.connected.Load() { + return nil + } + x.connected.Store(true) + return nil +} + +func (x *EventStore) Disconnect(_ context.Context) error { + if !x.connected.Load() { + return nil + } + x.db.Range(func(key interface{}, value interface{}) bool { + x.db.Delete(key) + return true + }) + x.connected.Store(false) + return nil +} + +func (x *EventStore) WriteEvents(_ context.Context, events []*egopb.Event) error { + for _, event := range events { + key := EventKey{ + PersistenceID: event.GetPersistenceId(), + SequenceNumber: event.GetSequenceNumber(), + } + x.db.Store(key, event) + } + return nil +} + +func (x *EventStore) Ping(ctx context.Context) error { + if !x.connected.Load() { + return x.Connect(ctx) + } + return nil +} + +func (x *EventStore) DeleteEvents(_ context.Context, persistenceID string, toSequenceNumber uint64) error { + x.db.Range(func(key interface{}, value interface{}) bool { + k := key.(EventKey) + if k.PersistenceID == persistenceID && k.SequenceNumber <= toSequenceNumber { + x.db.Delete(key) + } + return true + }) + return nil +} + +func (x *EventStore) ReplayEvents(_ context.Context, persistenceID string, fromSequenceNumber, toSequenceNumber uint64, max uint64) ([]*egopb.Event, error) { + var events []*egopb.Event + collect := func(key, value interface{}) bool { + k, ok := key.(EventKey) + if !ok { + return true // Skip if the key is not of type EventKey + } + + if k.PersistenceID == persistenceID && + k.SequenceNumber >= fromSequenceNumber && + k.SequenceNumber <= toSequenceNumber { + events = append(events, value.(*egopb.Event)) + if len(events) >= int(max) { + return false // Stop further iteration + } + } + return true + } + + x.db.Range(collect) + return events, nil +} + +func (x *EventStore) GetLatestEvent(_ context.Context, persistenceID string) (*egopb.Event, error) { + var events []*egopb.Event + x.db.Range(func(key interface{}, value interface{}) bool { + k := key.(EventKey) + if k.PersistenceID == persistenceID { + events = append(events, value.(*egopb.Event)) + } + return true + }) + + sort.SliceStable(events, func(i, j int) bool { + return events[i].SequenceNumber > events[j].SequenceNumber + }) + + if len(events) == 0 { + return nil, nil + } + return events[0], nil +} + +func (x *EventStore) PersistenceIDs(_ context.Context, pageSize uint64, pageToken string) (persistenceIDs []string, nextPageToken string, err error) { + // step 1: collect unique PersistenceIDs using a map + idSet := make(map[string]struct{}) + x.db.Range(func(key, _ interface{}) bool { + k := key.(EventKey) + idSet[k.PersistenceID] = struct{}{} + return true + }) + + // step 2: convert the map to a slice and sort it + keys := make([]string, 0, len(idSet)) + for id := range idSet { + keys = append(keys, id) + } + sort.Strings(keys) + + // step 3: paginate the sorted keys + startIndex := 0 + if pageToken != "" { + // Find the index of the pageToken in the sorted keys + for i, key := range keys { + if key > pageToken { + startIndex = i + break + } + } + } + + // Collect up to pageSize items starting from startIndex + endIndex := startIndex + int(pageSize) + if endIndex > len(keys) { + endIndex = len(keys) + } + persistenceIDs = keys[startIndex:endIndex] + + // step 4: determine the nextPageToken + switch { + case endIndex < len(keys): + nextPageToken = keys[endIndex] + default: + nextPageToken = "" + } + + return persistenceIDs, nextPageToken, nil +} + +func (x *EventStore) GetShardEvents(_ context.Context, shardNumber uint64, offset int64, max uint64) ([]*egopb.Event, int64, error) { + var shardEvents []*egopb.Event + x.db.Range(func(_ interface{}, value interface{}) bool { + event := value.(*egopb.Event) + if event.GetShard() == shardNumber { + shardEvents = append(shardEvents, value.(*egopb.Event)) + } + return true + }) + + if len(shardEvents) == 0 { + return nil, 0, nil + } + + var events []*egopb.Event + for _, event := range shardEvents { + if event.GetTimestamp() > offset { + if len(events) <= int(max) { + events = append(events, event) + } + } + } + + if len(events) == 0 { + return nil, 0, nil + } + + sort.SliceStable(events, func(i, j int) bool { + return events[i].GetTimestamp() <= events[j].GetTimestamp() + }) + + nextOffset := events[len(events)-1].GetTimestamp() + return events, nextOffset, nil +} + +func (x *EventStore) ShardNumbers(context.Context) ([]uint64, error) { + shards := goset.NewSet[uint64]() + x.db.Range(func(_ interface{}, value interface{}) bool { + event := value.(*egopb.Event) + shards.Add(event.GetShard()) + return true + }) + return shards.ToSlice(), nil +} diff --git a/testkit/offsetstore.go b/testkit/offsetstore.go new file mode 100644 index 0000000..97fbf20 --- /dev/null +++ b/testkit/offsetstore.go @@ -0,0 +1,117 @@ +/* + * MIT License + * + * Copyright (c) 2022-2024 Tochemey + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package testkit + +import ( + "context" + "sync" + "time" + + "go.uber.org/atomic" + + "github.com/tochemey/ego/v3/egopb" + "github.com/tochemey/ego/v3/offsetstore" +) + +type OffsetKey struct { + ProjectionName string + ShardNumber uint64 +} +type OffsetStore struct { + db *sync.Map + connected *atomic.Bool +} + +var _ offsetstore.OffsetStore = (*OffsetStore)(nil) + +func NewOffsetStore() *OffsetStore { + return &OffsetStore{ + db: &sync.Map{}, + connected: atomic.NewBool(false), + } +} + +func (x *OffsetStore) Connect(context.Context) error { + if x.connected.Load() { + return nil + } + x.connected.Store(true) + return nil +} + +func (x *OffsetStore) Disconnect(context.Context) error { + if !x.connected.Load() { + return nil + } + x.db.Range(func(key interface{}, value interface{}) bool { + x.db.Delete(key) + return true + }) + x.connected.Store(false) + return nil +} + +func (x *OffsetStore) Ping(ctx context.Context) error { + if !x.connected.Load() { + return x.Connect(ctx) + } + return nil +} + +func (x *OffsetStore) WriteOffset(_ context.Context, offset *egopb.Offset) error { + key := OffsetKey{ + ProjectionName: offset.GetProjectionName(), + ShardNumber: offset.GetShardNumber(), + } + x.db.Store(key, offset) + return nil +} + +func (x *OffsetStore) GetCurrentOffset(_ context.Context, projectionID *egopb.ProjectionId) (currentOffset *egopb.Offset, err error) { + key := OffsetKey{ + ProjectionName: projectionID.GetProjectionName(), + ShardNumber: projectionID.GetShardNumber(), + } + value, ok := x.db.Load(key) + if !ok { + return nil, nil + } + return value.(*egopb.Offset), nil +} + +func (x *OffsetStore) ResetOffset(_ context.Context, projectionName string, value int64) error { + ts := time.Now().UnixMilli() + x.db.Range(func(k interface{}, v interface{}) bool { + key := v.(OffsetKey) + val := v.(*egopb.Offset) + if key.ProjectionName == projectionName { + val.Value = value + val.Timestamp = ts + x.db.Store(key, val) + } + return true + }) + return nil +}