From 9180ee7aa4c433e02030659489adca91bc4c8401 Mon Sep 17 00:00:00 2001 From: Semyon Krestyaninov <krestyaninov@perx.ru> Date: Wed, 17 Jul 2024 18:43:17 +0000 Subject: [PATCH] =?UTF-8?q?chore(core):=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4?= =?UTF-8?q?=D0=B0=D1=87=D0=B0=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B2=20=D0=BA=D1=8D=D1=88=D0=B5=20=D1=81=D0=B5=D1=80?= =?UTF-8?q?=D0=B2=D0=B8=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close #PRXS-2705 --- pkg/clients/middleware/caching_middleware.go | 16 ++-- .../middleware/caching_middleware_test.go | 78 ++++++++++------- pkg/collaborators/collaborator.go | 8 ++ .../middleware/caching_middleware.go | 11 ++- .../middleware/caching_middleware_test.go | 18 ++-- .../middleware/caching_middleware.go | 6 +- .../middleware/caching_middleware_test.go | 72 ++++++++++------ pkg/data/list.go | 8 ++ pkg/environments/environment.go | 2 +- .../middleware/caching_middleware.go | 11 ++- .../middleware/caching_middleware_test.go | 84 ++++++++++++------- pkg/invitations/invitation.go | 13 +++ .../middleware/caching_middleware.go | 5 +- .../middleware/caching_middleware_test.go | 14 +++- pkg/locales/locale.go | 15 ++++ pkg/locales/middleware/caching_middleware.go | 6 +- .../middleware/caching_middleware_test.go | 17 ++-- pkg/members/members.go | 8 ++ pkg/members/middleware/caching_middleware.go | 11 ++- .../middleware/caching_middleware.go | 5 +- .../middleware/caching_middleware_test.go | 16 ++-- pkg/organizations/organization.go | 10 +++ pkg/roles/middleware/caching_middleware.go | 11 ++- .../middleware/caching_middleware_test.go | 30 ++++--- pkg/roles/role.go | 12 +++ pkg/spaces/middleware/caching_middleware.go | 11 ++- .../middleware/caching_middleware_test.go | 42 ++++++---- pkg/users/middleware/caching_middleware.go | 10 ++- .../middleware/caching_middleware_test.go | 30 ++++--- 29 files changed, 401 insertions(+), 179 deletions(-) diff --git a/pkg/clients/middleware/caching_middleware.go b/pkg/clients/middleware/caching_middleware.go index 370061cc..0dd4f15b 100644 --- a/pkg/clients/middleware/caching_middleware.go +++ b/pkg/clients/middleware/caching_middleware.go @@ -6,6 +6,7 @@ import ( "git.perx.ru/perxis/perxis-go/pkg/cache" service "git.perx.ru/perxis/perxis-go/pkg/clients" + "git.perx.ru/perxis/perxis-go/pkg/data" ) func makeKey(ss ...string) string { @@ -40,7 +41,7 @@ func (m cachingMiddleware) Get(ctx context.Context, spaceId string, id string) ( key := makeKey(spaceId, id) value, e := m.cache.Get(key) if e == nil { - return value.(*service.Client), err + return value.(*service.Client).Clone(), nil } cl, err = m.next.Get(ctx, spaceId, id) if err == nil { @@ -48,8 +49,9 @@ func (m cachingMiddleware) Get(ctx context.Context, spaceId string, id string) ( for _, key := range keysFromIdentities(spaceId, cl) { _ = m.cache.Set(key, cl) } + return cl.Clone(), nil } - return cl, err + return nil, err } func (m cachingMiddleware) GetBy(ctx context.Context, spaceId string, params *service.GetByParams) (cl *service.Client, err error) { @@ -60,7 +62,7 @@ func (m cachingMiddleware) GetBy(ctx context.Context, spaceId string, params *se key := getIdentKey(spaceId, params) value, e := m.cache.Get(key) if e == nil { - return value.(*service.Client), err + return value.(*service.Client).Clone(), nil } cl, err = m.next.GetBy(ctx, spaceId, params) if err == nil { @@ -68,21 +70,23 @@ func (m cachingMiddleware) GetBy(ctx context.Context, spaceId string, params *se for _, key := range keysFromIdentities(spaceId, cl) { _ = m.cache.Set(key, cl) } + return cl.Clone(), nil } - return cl, err + return nil, err } func (m cachingMiddleware) List(ctx context.Context, spaceId string) (clients []*service.Client, err error) { value, e := m.cache.Get(spaceId) if e == nil { - return value.([]*service.Client), err + return data.CloneSlice(value.([]*service.Client)), nil } clients, err = m.next.List(ctx, spaceId) if err == nil { _ = m.cache.Set(spaceId, clients) + return data.CloneSlice(clients), nil } - return clients, err + return nil, err } func (m cachingMiddleware) Update(ctx context.Context, client *service.Client) (err error) { diff --git a/pkg/clients/middleware/caching_middleware_test.go b/pkg/clients/middleware/caching_middleware_test.go index 02129d17..821d2cb2 100644 --- a/pkg/clients/middleware/caching_middleware_test.go +++ b/pkg/clients/middleware/caching_middleware_test.go @@ -40,11 +40,13 @@ func TestClientsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, v1, v2) v3, err := svc.GetBy(ctx, spaceID, &clients.GetByParams{OAuthClientID: clientID}) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при запроÑе по ClientID.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при запроÑе по ClientID.") + assert.NotSame(t, v2, v3) cs.AssertExpectations(t) }) @@ -61,11 +63,13 @@ func TestClientsCache(t *testing.T) { v2, err := svc.GetBy(ctx, spaceID, &clients.GetByParams{OAuthClientID: clientID}) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша, поÑле запроÑа Get.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша, поÑле запроÑа Get.") + assert.NotSame(t, v2, v3) cs.AssertExpectations(t) }) @@ -82,7 +86,8 @@ func TestClientsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, vl1[0], vl2[0]) cs.AssertExpectations(t) }) @@ -102,11 +107,13 @@ func TestClientsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) v3, err := svc.GetBy(ctx, spaceID, &clients.GetByParams{OAuthClientID: clientID}) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ClientID.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ClientID.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) @@ -114,7 +121,8 @@ func TestClientsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) assert.Len(t, vl2, 1) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, vl1[0], vl2[0]) cs.On("Update", mock.Anything, mock.Anything).Return(nil).Once() @@ -126,16 +134,17 @@ func TestClientsCache(t *testing.T) { vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotEqual(t, vl2[0], vl3[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") v4, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) - assert.NotSame(t, v2, v4, "Ожидает что поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚ был удален из кÑша и будет запрошен заново из ÑервиÑа.") + assert.NotEqual(t, v2, v4, "Ожидает что поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚ был удален из кÑша и будет запрошен заново из ÑервиÑа.") v5, err := svc.GetBy(ctx, spaceID, &clients.GetByParams{OAuthClientID: clientID}) require.NoError(t, err) - assert.NotSame(t, v3, v5) - assert.Same(t, v4, v5, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚ был удален из кеша и поÑле запроÑа Get в кеш попал объект запрошенный заново из ÑервиÑа.") + assert.NotEqual(t, v3, v5) + assert.Equal(t, v4, v5, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚ был удален из кеша и поÑле запроÑа Get в кеш попал объект запрошенный заново из ÑервиÑа.") + assert.NotSame(t, v4, v5) cs.AssertExpectations(t) }) @@ -153,7 +162,8 @@ func TestClientsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) assert.Len(t, vl2, 1) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, vl1[0], vl2[0]) cs.On("Update", mock.Anything, mock.Anything).Return(nil).Once() @@ -164,7 +174,7 @@ func TestClientsCache(t *testing.T) { vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotEqual(t, vl2[0], vl3[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") cs.AssertExpectations(t) }) @@ -182,18 +192,21 @@ func TestClientsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) v3, err := svc.GetBy(ctx, spaceID, &clients.GetByParams{OAuthClientID: clientID}) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ClientID.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ClientID.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, vl1[0], vl2[0]) cs.On("Delete", mock.Anything, spaceID, cltID).Return(nil).Once() @@ -231,7 +244,8 @@ func TestClientsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, vl1[0], vl2[0]) cs.On("Delete", mock.Anything, spaceID, cltID).Return(nil).Once() @@ -259,7 +273,8 @@ func TestClientsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, vl1[0], vl2[0]) assert.Len(t, vl2, 1, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") cs.On("Create", mock.Anything, mock.Anything).Return(&clients.Client{ID: "cltID2", SpaceID: spaceID, Name: "client_2"}, nil).Once() @@ -290,18 +305,21 @@ func TestClientsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) v3, err := svc.GetBy(ctx, spaceID, &clients.GetByParams{OAuthClientID: clientID}) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ClientID.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ClientID.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, vl1[0], vl2[0]) cs.On("Enable", mock.Anything, spaceID, cltID, tr).Return(nil).Once() @@ -314,15 +332,15 @@ func TestClientsCache(t *testing.T) { v4, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) - assert.NotSame(t, v2, v4, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле активации объект был удален из кÑша и запрошен у ÑервиÑа.") + assert.NotEqual(t, v2, v4, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле активации объект был удален из кÑша и запрошен у ÑервиÑа.") v5, err := svc.GetBy(ctx, spaceID, &clients.GetByParams{OAuthClientID: clientID}) require.NoError(t, err) - assert.NotSame(t, v3, v5, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле активации объект был удален из кеша и поÑле запроÑа Get в кеш попал объект запрошенный заново из ÑервиÑа.") + assert.NotEqual(t, v3, v5, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле активации объект был удален из кеша и поÑле запроÑа Get в кеш попал объект запрошенный заново из ÑервиÑа.") vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле активации объекта, кеш будет очищен и объекты будут запрошены заново из ÑервиÑа.") + assert.NotEqual(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле активации объекта, кеш будет очищен и объекты будут запрошены заново из ÑервиÑа.") cs.AssertExpectations(t) }) @@ -340,7 +358,8 @@ func TestClientsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша, поÑле повторного запроÑа.") + assert.NotSame(t, vl1[0], vl2[0]) cs.On("Enable", mock.Anything, spaceID, cltID, tr).Return(nil).Once() @@ -352,7 +371,7 @@ func TestClientsCache(t *testing.T) { vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле активации объекта, кеш будет очищен и объекты будут запрошены заново из ÑервиÑа.") + assert.NotEqual(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ поÑле активации объекта, кеш будет очищен и объекты будут запрошены заново из ÑервиÑа.") cs.AssertExpectations(t) }) @@ -369,13 +388,16 @@ func TestClientsCache(t *testing.T) { require.NoError(t, err) v2, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша поÑле повторного запроÑа.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша поÑле повторного запроÑа.") + assert.NotSame(t, v1, v2) time.Sleep(2 * ttl) v3, err := svc.Get(ctx, spaceID, cltID) require.NoError(t, err) assert.NotSame(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ Ñлемент был удален из кÑша по иÑтечению ttl и будет запрошен заново из ÑервиÑа.") + assert.Equal(t, v2, v3) + assert.NotSame(t, v2, v3) cs.AssertExpectations(t) }) diff --git a/pkg/collaborators/collaborator.go b/pkg/collaborators/collaborator.go index 701d8e85..5fe1b481 100644 --- a/pkg/collaborators/collaborator.go +++ b/pkg/collaborators/collaborator.go @@ -5,3 +5,11 @@ type Collaborator struct { Subject string `bson:"subject"` Role string `bson:"role"` } + +func (c Collaborator) Clone() *Collaborator { + return &Collaborator{ + SpaceID: c.SpaceID, + Subject: c.Subject, + Role: c.Role, + } +} diff --git a/pkg/collaborators/middleware/caching_middleware.go b/pkg/collaborators/middleware/caching_middleware.go index 25ae89c4..7faeb638 100644 --- a/pkg/collaborators/middleware/caching_middleware.go +++ b/pkg/collaborators/middleware/caching_middleware.go @@ -6,6 +6,7 @@ import ( "git.perx.ru/perxis/perxis-go/pkg/cache" service "git.perx.ru/perxis/perxis-go/pkg/collaborators" + "git.perx.ru/perxis/perxis-go/pkg/data" ) func makeKey(ss ...string) string { @@ -65,24 +66,26 @@ func (m cachingMiddleware) ListCollaborators(ctx context.Context, spaceId string value, e := m.cache.Get(spaceId) if e == nil { - return value.([]*service.Collaborator), err + return data.CloneSlice(value.([]*service.Collaborator)), nil } collaborators, err = m.next.ListCollaborators(ctx, spaceId) if err == nil { _ = m.cache.Set(spaceId, collaborators) + return data.CloneSlice(collaborators), nil } - return collaborators, err + return nil, err } func (m cachingMiddleware) ListSpaces(ctx context.Context, subject string) (collaborators []*service.Collaborator, err error) { value, e := m.cache.Get(subject) if e == nil { - return value.([]*service.Collaborator), err + return data.CloneSlice(value.([]*service.Collaborator)), nil } collaborators, err = m.next.ListSpaces(ctx, subject) if err == nil { _ = m.cache.Set(subject, collaborators) + return data.CloneSlice(collaborators), nil } - return collaborators, err + return nil, err } diff --git a/pkg/collaborators/middleware/caching_middleware_test.go b/pkg/collaborators/middleware/caching_middleware_test.go index 2e453ae6..6b96d0a8 100644 --- a/pkg/collaborators/middleware/caching_middleware_test.go +++ b/pkg/collaborators/middleware/caching_middleware_test.go @@ -56,7 +56,8 @@ func TestCollaboratorsCache(t *testing.T) { require.NoError(t, err) v2, err := svc.ListCollaborators(ctx, spaceID) require.NoError(t, err) - assert.Same(t, v1[0], v2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша при повторном запроÑе.") + assert.Equal(t, v1[0], v2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша при повторном запроÑе.") + assert.NotSame(t, v1[0], v2[0]) cs.AssertExpectations(t) }) @@ -72,7 +73,8 @@ func TestCollaboratorsCache(t *testing.T) { require.NoError(t, err) v2, err := svc.ListSpaces(ctx, userID) require.NoError(t, err) - assert.Same(t, v1[0], v2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша при повторном запроÑе.") + assert.Equal(t, v1[0], v2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша при повторном запроÑе.") + assert.NotSame(t, v1[0], v2[0]) cs.AssertExpectations(t) }) @@ -98,13 +100,15 @@ func TestCollaboratorsCache(t *testing.T) { require.NoError(t, err) lc2, err := svc.ListCollaborators(ctx, spaceID) require.NoError(t, err) - assert.Same(t, lc1[0], lc2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, lc1[0], lc2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, lc1[0], lc2[0]) ls1, err := svc.ListSpaces(ctx, userID) require.NoError(t, err) ls2, err := svc.ListSpaces(ctx, userID) require.NoError(t, err) - assert.Same(t, ls1[0], ls2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, ls1[0], ls2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, ls1[0], ls2[0]) cs.On("Remove", mock.Anything, spaceID, userID).Return(nil).Once() @@ -153,13 +157,15 @@ func TestCollaboratorsCache(t *testing.T) { require.NoError(t, err) lc2, err := svc.ListCollaborators(ctx, spaceID) require.NoError(t, err) - assert.Same(t, lc1[0], lc2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, lc1[0], lc2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, lc1[0], lc2[0]) ls1, err := svc.ListSpaces(ctx, userID) require.NoError(t, err) ls2, err := svc.ListSpaces(ctx, userID) require.NoError(t, err) - assert.Same(t, ls1[0], ls2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, ls1[0], ls2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, ls1[0], ls2[0]) cs.On("Remove", mock.Anything, spaceID, userID).Return(nil).Once() diff --git a/pkg/collections/middleware/caching_middleware.go b/pkg/collections/middleware/caching_middleware.go index 0e329e80..cb95d0d9 100644 --- a/pkg/collections/middleware/caching_middleware.go +++ b/pkg/collections/middleware/caching_middleware.go @@ -44,7 +44,7 @@ func (m cachingMiddleware) Get(ctx context.Context, spaceId string, envId string opts := service.MergeGetOptions(options...) value, e := m.cache.Get(makeKey(spaceId, envId, collectionId, opts.DisableSchemaIncludes)) if e == nil { - return value.(*service.Collection), err + return value.(*service.Collection).Clone(), nil } coll, err = m.next.Get(ctx, spaceId, envId, collectionId, options...) if err == nil { @@ -56,9 +56,9 @@ func (m cachingMiddleware) Get(ctx context.Context, spaceId string, envId string for _, al := range env.Aliases { _ = m.cache.Set(makeKey(coll.SpaceID, al, coll.ID, opts.DisableSchemaIncludes), coll) } - + return coll.Clone(), nil } - return coll, err + return nil, err } func (m cachingMiddleware) List(ctx context.Context, spaceId, envId string, filter *service.Filter) (collections []*service.Collection, err error) { diff --git a/pkg/collections/middleware/caching_middleware_test.go b/pkg/collections/middleware/caching_middleware_test.go index ac284ce5..24646008 100644 --- a/pkg/collections/middleware/caching_middleware_test.go +++ b/pkg/collections/middleware/caching_middleware_test.go @@ -46,11 +46,13 @@ func TestCollections_Cache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша при повторном запроÑе по ID окружениÑ.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша при повторном запроÑе по ID окружениÑ.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.Same(t, v3, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша, при запроÑе того же объекта по alias окружениÑ.") + assert.Equal(t, v3, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша, при запроÑе того же объекта по alias окружениÑ.") + assert.NotSame(t, v3, v2) env.AssertExpectations(t) col.AssertExpectations(t) @@ -70,11 +72,13 @@ func TestCollections_Cache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша при повторном запроÑе по Alias окружениÑ.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша при повторном запроÑе по Alias окружениÑ.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.Same(t, v3, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша, при запроÑе того же объекта по ID окружениÑ.") + assert.Equal(t, v3, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша, при запроÑе того же объекта по ID окружениÑ.") + assert.NotSame(t, v3, v2) env.AssertExpectations(t) col.AssertExpectations(t) @@ -115,12 +119,12 @@ func TestCollections_Cache(t *testing.T) { // vl2, err := svc.List(ctx, spaceID, envID, nil) // require.NoError(t, err) // assert.Len(t, vl2, 1) - // assert.Same(t, vl1[0], vl2[0], "При повторном запроÑе по ID окружениÑ, ожидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ ÑпиÑка объектов из кеша.") + // assert.Equal(t, vl1[0], vl2[0], "При повторном запроÑе по ID окружениÑ, ожидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ ÑпиÑка объектов из кеша.") // // vl3, err := svc.List(ctx, spaceID, envAlias, nil) // require.NoError(t, err) // assert.Len(t, vl3, 1) - // assert.Same(t, vl3[0], vl2[0], "При повторном запроÑе по Alias окружениÑ, ожидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ ÑпиÑка объектов из кеша.") + // assert.Equal(t, vl3[0], vl2[0], "При повторном запроÑе по Alias окружениÑ, ожидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ ÑпиÑка объектов из кеша.") // // env.AssertExpectations(t) // col.AssertExpectations(t) @@ -161,11 +165,13 @@ func TestCollections_Cache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по ID окружениÑ.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по ID окружениÑ.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID, envID, nil) require.NoError(t, err) @@ -181,15 +187,16 @@ func TestCollections_Cache(t *testing.T) { v4, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.NotSame(t, v3, v4, "Ожидает что Ñлемент поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð» удален из кÑша и будет запрошен заново из ÑервиÑа.") + assert.NotEqual(t, v3, v4, "Ожидает что Ñлемент поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð» удален из кÑша и будет запрошен заново из ÑервиÑа.") v5, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.Same(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.Equal(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.NotSame(t, v4, v5) vl2, err := svc.List(ctx, spaceID, envID, nil) require.NoError(t, err) - assert.NotSame(t, vl1[0], vl2[0], "Ожидает что поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñлементы будут запрошены заново из ÑервиÑа.") + assert.NotEqual(t, vl1[0], vl2[0], "Ожидает что поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñлементы будут запрошены заново из ÑервиÑа.") env.AssertExpectations(t) col.AssertExpectations(t) @@ -212,11 +219,13 @@ func TestCollections_Cache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по ID окружениÑ.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по ID окружениÑ.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID, envAlias, nil) require.NoError(t, err) @@ -234,15 +243,16 @@ func TestCollections_Cache(t *testing.T) { v4, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.NotSame(t, v3, v4, "Ожидает что Ñлемент поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð» удален из кÑша и будет запрошен заново из ÑервиÑа.") + assert.NotEqual(t, v3, v4, "Ожидает что Ñлемент поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð» удален из кÑша и будет запрошен заново из ÑервиÑа.") v5, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.Same(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.Equal(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.NotSame(t, v4, v5) vl4, err := svc.List(ctx, spaceID, envAlias, nil) require.NoError(t, err) - assert.NotSame(t, vl1[0], vl4[0], "Ожидает что поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñлементы будут запрошены заново из ÑервиÑа.") + assert.NotEqual(t, vl1[0], vl4[0], "Ожидает что поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñлементы будут запрошены заново из ÑервиÑа.") env.AssertExpectations(t) col.AssertExpectations(t) @@ -264,11 +274,13 @@ func TestCollections_Cache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по ID окружениÑ.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по ID окружениÑ.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID, envID, nil) require.NoError(t, err) @@ -276,7 +288,7 @@ func TestCollections_Cache(t *testing.T) { vl2, err := svc.List(ctx, spaceID, envID, nil) require.NoError(t, err) assert.Len(t, vl2, 1) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кеша по ID окружениÑ.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кеша по ID окружениÑ.") vl3, err := svc.List(ctx, spaceID, envAlias, nil) require.NoError(t, err) @@ -295,15 +307,16 @@ func TestCollections_Cache(t *testing.T) { v4, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.NotSame(t, v3, v4, "Ожидает что Ñлемент поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñхемы был удален из кÑша и будет запрошен заново из ÑервиÑа.") + assert.NotEqual(t, v3, v4, "Ожидает что Ñлемент поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñхемы был удален из кÑша и будет запрошен заново из ÑервиÑа.") v5, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.Same(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.Equal(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.NotSame(t, v4, v5) vl4, err := svc.List(ctx, spaceID, envID, nil) require.NoError(t, err) - assert.NotSame(t, vl4[0], vl3[0], "Ожидает что поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñхемы Ñлементы будут запрошены заново из ÑервиÑа.") + assert.NotEqual(t, vl4[0], vl3[0], "Ожидает что поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñхемы Ñлементы будут запрошены заново из ÑервиÑа.") vl5, err := svc.List(ctx, spaceID, envAlias, nil) require.NoError(t, err) @@ -329,11 +342,13 @@ func TestCollections_Cache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по ID окружениÑ.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по ID окружениÑ.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envAlias, colID) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша по Alias окружениÑ.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID, envID, nil) require.NoError(t, err) @@ -341,7 +356,7 @@ func TestCollections_Cache(t *testing.T) { vl2, err := svc.List(ctx, spaceID, envID, nil) require.NoError(t, err) assert.Len(t, vl2, 1) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кеша по ID окружениÑ.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кеша по ID окружениÑ.") vl3, err := svc.List(ctx, spaceID, envAlias, nil) require.NoError(t, err) @@ -391,7 +406,7 @@ func TestCollections_Cache(t *testing.T) { vl2, err := svc.List(ctx, spaceID, envID, nil) require.NoError(t, err) assert.Len(t, vl2, 1) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кеша по ID окружениÑ.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кеша по ID окружениÑ.") vl3, err := svc.List(ctx, spaceID, envAlias, nil) require.NoError(t, err) @@ -440,7 +455,8 @@ func TestCollections_Cache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша.") + assert.NotSame(t, v1, v2) time.Sleep(2 * ttl) @@ -449,6 +465,8 @@ func TestCollections_Cache(t *testing.T) { v3, err := svc.Get(ctx, spaceID, envID, colID) require.NoError(t, err) assert.NotSame(t, v3, v2, "Ожидает что Ñлемент был удален из кÑша и будет запрошен заново из ÑервиÑа.") + assert.Equal(t, v3, v2) + assert.NotSame(t, v3, v2) env.AssertExpectations(t) col.AssertExpectations(t) diff --git a/pkg/data/list.go b/pkg/data/list.go index e15a20ca..90042506 100644 --- a/pkg/data/list.go +++ b/pkg/data/list.go @@ -184,3 +184,11 @@ func mergeMaps(a, b map[string]interface{}) map[string]interface{} { } return out } + +func CloneSlice[T interface{ Clone() T }](s []T) []T { + result := make([]T, 0, len(s)) + for _, t := range s { + result = append(result, t.Clone()) + } + return result +} diff --git a/pkg/environments/environment.go b/pkg/environments/environment.go index e9d2b96e..465a4091 100644 --- a/pkg/environments/environment.go +++ b/pkg/environments/environment.go @@ -91,4 +91,4 @@ func (e Environment) Clone() *Environment { } return clone -} \ No newline at end of file +} diff --git a/pkg/environments/middleware/caching_middleware.go b/pkg/environments/middleware/caching_middleware.go index 7e4f46d2..c53f45e8 100644 --- a/pkg/environments/middleware/caching_middleware.go +++ b/pkg/environments/middleware/caching_middleware.go @@ -5,6 +5,7 @@ import ( "strings" "git.perx.ru/perxis/perxis-go/pkg/cache" + "git.perx.ru/perxis/perxis-go/pkg/data" service "git.perx.ru/perxis/perxis-go/pkg/environments" ) @@ -39,7 +40,7 @@ func (m cachingMiddleware) Get(ctx context.Context, spaceId string, envId string value, e := m.cache.Get(makeKey(spaceId, envId)) if e == nil { - return value.(*service.Environment), err + return value.(*service.Environment).Clone(), nil } environment, err = m.next.Get(ctx, spaceId, envId) if err == nil { @@ -47,21 +48,23 @@ func (m cachingMiddleware) Get(ctx context.Context, spaceId string, envId string for _, a := range environment.Aliases { _ = m.cache.Set(makeKey(spaceId, a), environment) } + return environment.Clone(), nil } - return environment, err + return nil, err } func (m cachingMiddleware) List(ctx context.Context, spaceId string) (environments []*service.Environment, err error) { value, e := m.cache.Get(spaceId) if e == nil { - return value.([]*service.Environment), err + return data.CloneSlice(value.([]*service.Environment)), nil } environments, err = m.next.List(ctx, spaceId) if err == nil { _ = m.cache.Set(spaceId, environments) + return data.CloneSlice(environments), nil } - return environments, err + return nil, err } func (m cachingMiddleware) Update(ctx context.Context, env *service.Environment) (err error) { diff --git a/pkg/environments/middleware/caching_middleware_test.go b/pkg/environments/middleware/caching_middleware_test.go index 784ce356..cbac3963 100644 --- a/pkg/environments/middleware/caching_middleware_test.go +++ b/pkg/environments/middleware/caching_middleware_test.go @@ -40,11 +40,13 @@ func TestEnvironmentsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при повторном запроÑе по ID.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при повторном запроÑе по ID.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envAlias) require.NoError(t, err) - assert.Same(t, v3, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша, при запроÑе того же объекта по alias окружениÑ.") + assert.Equal(t, v3, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша, при запроÑе того же объекта по alias окружениÑ.") + assert.NotSame(t, v3, v2) envs.AssertExpectations(t) }) @@ -61,11 +63,13 @@ func TestEnvironmentsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envAlias) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по alias.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по alias.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.Same(t, v3, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша, при запроÑе того же объекта по ID окружениÑ.") + assert.Equal(t, v3, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кеша, при запроÑе того же объекта по ID окружениÑ.") + assert.NotSame(t, v3, v2) envs.AssertExpectations(t) }) @@ -82,7 +86,8 @@ func TestEnvironmentsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) envs.AssertExpectations(t) }) @@ -102,14 +107,16 @@ func TestEnvironmentsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) err = svc.SetAlias(ctx, spaceID, envID, envAlias) require.NoError(t, err) @@ -123,11 +130,12 @@ func TestEnvironmentsCache(t *testing.T) { v5, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.Same(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ID.") + assert.Equal(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ID.") + assert.NotSame(t, v4, v5) vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "Ожидает что объекты будут удалены из кÑша и запрошены из ÑервиÑа.") + assert.NotEqual(t, vl2[0], vl3[0], "Ожидает что объекты будут удалены из кÑша и запрошены из ÑервиÑа.") envs.AssertExpectations(t) }) @@ -146,18 +154,21 @@ func TestEnvironmentsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ID.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по ID.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envAlias) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по Alias.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по Alias.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) err = svc.RemoveAlias(ctx, spaceID, envID, envAlias) require.NoError(t, err) @@ -172,11 +183,11 @@ func TestEnvironmentsCache(t *testing.T) { v4, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.NotSame(t, v3, v4, "Ожидает что Ñлемент был удален из кеша и получен из ÑервиÑа по ID.") + assert.NotEqual(t, v3, v4, "Ожидает что Ñлемент был удален из кеша и получен из ÑервиÑа по ID.") vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "Ожидает что объекты будут удалены из кÑша и запрошены из ÑервиÑа.") + assert.NotEqual(t, vl2[0], vl3[0], "Ожидает что объекты будут удалены из кÑша и запрошены из ÑервиÑа.") envs.AssertExpectations(t) }) @@ -195,18 +206,21 @@ func TestEnvironmentsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envAlias) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по Alias.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по Alias.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) err = svc.Update(ctx, &environments.Environment{ID: envID, SpaceID: spaceID, Description: "EnvironmentUPD", Aliases: []string{envAlias}}) require.NoError(t, err) @@ -219,15 +233,16 @@ func TestEnvironmentsCache(t *testing.T) { v4, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.NotSame(t, v2, v4, "Ожидает что Ñлемент был удален из кÑша и будет запрошен заново из ÑервиÑа.") + assert.NotEqual(t, v2, v4, "Ожидает что Ñлемент был удален из кÑша и будет запрошен заново из ÑервиÑа.") v5, err := svc.Get(ctx, spaceID, envAlias) require.NoError(t, err) - assert.Same(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по Alias поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° и Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ ID.") + assert.Equal(t, v4, v5, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по Alias поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° и Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ ID.") + assert.NotSame(t, v4, v5) vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "Ожидает что объекты будут удалены из кÑша и запрошены из ÑервиÑа.") + assert.NotEqual(t, vl2[0], vl3[0], "Ожидает что объекты будут удалены из кÑша и запрошены из ÑервиÑа.") envs.AssertExpectations(t) }) @@ -245,7 +260,8 @@ func TestEnvironmentsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) err = svc.Update(ctx, &environments.Environment{ID: envID, SpaceID: spaceID, Description: "EnvironmentUPD", Aliases: []string{envAlias}}) require.NoError(t, err) @@ -254,7 +270,7 @@ func TestEnvironmentsCache(t *testing.T) { vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "Ожидает что объекты будут удалены из кÑша и запрошены из ÑервиÑа.") + assert.NotEqual(t, vl2[0], vl3[0], "Ожидает что объекты будут удалены из кÑша и запрошены из ÑервиÑа.") envs.AssertExpectations(t) }) @@ -273,18 +289,21 @@ func TestEnvironmentsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, spaceID, envAlias) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по Alias.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша по Alias.") + assert.NotSame(t, v2, v3) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) err = svc.Delete(ctx, spaceID, envID) require.NoError(t, err) @@ -320,7 +339,8 @@ func TestEnvironmentsCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) envs.On("Create", mock.Anything, mock.Anything).Return(&environments.Environment{ID: "envID2", SpaceID: spaceID, Description: "Environment2"}, nil).Once() _, err = svc.Create(ctx, &environments.Environment{ID: "envID2", SpaceID: spaceID, Description: "Environment2"}) @@ -349,15 +369,16 @@ func TestEnvironmentsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, "envID2") require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") - + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) _, err = svc.Get(ctx, spaceID, envID) require.NoError(t, err) v5, err := svc.Get(ctx, spaceID, "envID2") require.NoError(t, err) assert.NotSame(t, v2, v5, "Ожидает что объект был удален из кÑша и будет запрошен заново из ÑервиÑа.") - + assert.Equal(t, v2, v5) + assert.NotSame(t, v2, v5) envs.AssertExpectations(t) }) @@ -372,7 +393,8 @@ func TestEnvironmentsCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) time.Sleep(2 * ttl) @@ -380,6 +402,8 @@ func TestEnvironmentsCache(t *testing.T) { v3, err := svc.Get(ctx, spaceID, envID) require.NoError(t, err) assert.NotSame(t, v2, v3, "Ожидает что объект был удален из кÑша и будет запрошен заново из ÑервиÑа.") + assert.Equal(t, v2, v3) + assert.NotSame(t, v2, v3) envs.AssertExpectations(t) }) diff --git a/pkg/invitations/invitation.go b/pkg/invitations/invitation.go index 5dc59137..a5b91ed0 100644 --- a/pkg/invitations/invitation.go +++ b/pkg/invitations/invitation.go @@ -14,3 +14,16 @@ type Invitation struct { CreatedAt *time.Time `bson:"createdAt"` ValidUntil *time.Time `bson:"validUntil"` } + +func (i Invitation) Clone() *Invitation { + return &Invitation{ + ID: i.ID, + Email: i.Email, + OrgID: i.OrgID, + SpaceID: i.SpaceID, + OwnerID: i.OwnerID, + Role: i.Role, + CreatedAt: i.CreatedAt, + ValidUntil: i.ValidUntil, + } +} diff --git a/pkg/invitations/middleware/caching_middleware.go b/pkg/invitations/middleware/caching_middleware.go index 698ee511..b14a155d 100644 --- a/pkg/invitations/middleware/caching_middleware.go +++ b/pkg/invitations/middleware/caching_middleware.go @@ -30,13 +30,14 @@ func (m cachingMiddleware) Get(ctx context.Context, invitationId string) (inv *s value, e := m.cache.Get(invitationId) if e == nil { - return value.(*service.Invitation), err + return value.(*service.Invitation).Clone(), nil } inv, err = m.next.Get(ctx, invitationId) if err == nil { _ = m.cache.Set(invitationId, inv) + return inv.Clone(), nil } - return inv, err + return nil, err } func (m cachingMiddleware) Accept(ctx context.Context, invitationId string, userId string) (err error) { diff --git a/pkg/invitations/middleware/caching_middleware_test.go b/pkg/invitations/middleware/caching_middleware_test.go index e7fac6f5..46d0a443 100644 --- a/pkg/invitations/middleware/caching_middleware_test.go +++ b/pkg/invitations/middleware/caching_middleware_test.go @@ -41,7 +41,8 @@ func TestLocalesCache(t *testing.T) { v2, err := svc.Get(ctx, invID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объект будет получен из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объект будет получен из кÑша.") + assert.NotSame(t, v1, v2) inv.AssertExpectations(t) }) @@ -59,7 +60,8 @@ func TestLocalesCache(t *testing.T) { v2, err := svc.Get(ctx, invID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объект будет получен из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объект будет получен из кÑша.") + assert.NotSame(t, v1, v2) inv.On("Accept", mock.Anything, invID, usrID).Return(nil).Once() inv.On("Get", mock.Anything, invID).Return(nil, errNotFound).Once() @@ -86,7 +88,8 @@ func TestLocalesCache(t *testing.T) { v2, err := svc.Get(ctx, invID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объект будет получен из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объект будет получен из кÑша.") + assert.NotSame(t, v1, v2) inv.On("Delete", mock.Anything, invID).Return(nil).Once() inv.On("Get", mock.Anything, invID).Return(nil, errNotFound).Once() @@ -113,7 +116,8 @@ func TestLocalesCache(t *testing.T) { v2, err := svc.Get(ctx, invID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объект будет получен из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объект будет получен из кÑша.") + assert.NotSame(t, v1, v2) time.Sleep(2 * ttl) @@ -122,6 +126,8 @@ func TestLocalesCache(t *testing.T) { v3, err := svc.Get(ctx, invID) require.NoError(t, err) assert.NotSame(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при иÑтечении ttl кеш будет очищен..") + assert.Equal(t, v2, v3) + assert.NotSame(t, v2, v3) inv.AssertExpectations(t) }) diff --git a/pkg/locales/locale.go b/pkg/locales/locale.go index f45f1d85..520bc68c 100644 --- a/pkg/locales/locale.go +++ b/pkg/locales/locale.go @@ -23,6 +23,21 @@ type Locale struct { Disabled bool `json:"disabled" bson:"disabled"` // Запретить иÑпользование локали. ÐÐµÐ»ÑŒÐ·Ñ Ñоздавать и редактировать контент Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ локали (кроме default) } +func (l Locale) Clone() *Locale { + return &Locale{ + ID: l.ID, + SpaceID: l.SpaceID, + Name: l.Name, + NativeName: l.NativeName, + Code: l.Code, + Fallback: l.Fallback, + Direction: l.Direction, + Weight: l.Weight, + NoPublish: l.NoPublish, + Disabled: l.Disabled, + } +} + func (locale *Locale) IsDefault() bool { return locale.ID == DefaultID } diff --git a/pkg/locales/middleware/caching_middleware.go b/pkg/locales/middleware/caching_middleware.go index 8a79a152..64f82bc2 100644 --- a/pkg/locales/middleware/caching_middleware.go +++ b/pkg/locales/middleware/caching_middleware.go @@ -4,6 +4,7 @@ import ( "context" "git.perx.ru/perxis/perxis-go/pkg/cache" + "git.perx.ru/perxis/perxis-go/pkg/data" service "git.perx.ru/perxis/perxis-go/pkg/locales" ) @@ -43,13 +44,14 @@ func (m cachingMiddleware) List(ctx context.Context, spaceId string) (locales [] value, e := m.cache.Get(spaceId) if e == nil { - return value.([]*service.Locale), err + return data.CloneSlice(value.([]*service.Locale)), nil } locales, err = m.next.List(ctx, spaceId) if err == nil { _ = m.cache.Set(spaceId, locales) + return data.CloneSlice(locales), nil } - return locales, err + return nil, err } func (m cachingMiddleware) Delete(ctx context.Context, spaceId string, localeId string) (err error) { diff --git a/pkg/locales/middleware/caching_middleware_test.go b/pkg/locales/middleware/caching_middleware_test.go index c738c987..25b542c8 100644 --- a/pkg/locales/middleware/caching_middleware_test.go +++ b/pkg/locales/middleware/caching_middleware_test.go @@ -37,7 +37,8 @@ func TestLocalesCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) loc.AssertExpectations(t) }) @@ -55,7 +56,8 @@ func TestLocalesCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) loc.On("Delete", mock.Anything, spaceID, loc1).Return(nil).Once() @@ -83,7 +85,8 @@ func TestLocalesCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) loc.On("Create", mock.Anything, mock.Anything).Return(&locales.Locale{ID: loc2, Name: "name2", SpaceID: spaceID}, nil).Once() @@ -115,7 +118,8 @@ func TestLocalesCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) loc.On("Update", mock.Anything, mock.Anything).Return(nil).Once() @@ -147,7 +151,8 @@ func TestLocalesCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ при повторном запроÑе объекты будут получены из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) time.Sleep(2 * ttl) loc.On("List", mock.Anything, spaceID).Return([]*locales.Locale{{ID: loc1, Name: "name1", SpaceID: spaceID}}, nil).Once() @@ -155,6 +160,8 @@ func TestLocalesCache(t *testing.T) { vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ Ñлементы будут получены из кÑша.") + assert.Equal(t, vl2[0], vl3[0]) + assert.NotSame(t, vl2[0], vl3[0]) loc.AssertExpectations(t) }) diff --git a/pkg/members/members.go b/pkg/members/members.go index 3013b1ff..28ae060e 100644 --- a/pkg/members/members.go +++ b/pkg/members/members.go @@ -11,6 +11,14 @@ type Member struct { Role Role `bson:"role"` } +func (m Member) Clone() *Member { + return &Member{ + OrgId: m.OrgId, + UserId: m.UserId, + Role: m.Role, + } +} + type Role uint const ( diff --git a/pkg/members/middleware/caching_middleware.go b/pkg/members/middleware/caching_middleware.go index 00ddb61a..4c61bff9 100644 --- a/pkg/members/middleware/caching_middleware.go +++ b/pkg/members/middleware/caching_middleware.go @@ -5,6 +5,7 @@ import ( "strings" "git.perx.ru/perxis/perxis-go/pkg/cache" + "git.perx.ru/perxis/perxis-go/pkg/data" service "git.perx.ru/perxis/perxis-go/pkg/members" ) @@ -79,24 +80,26 @@ func (m cachingMiddleware) ListMembers(ctx context.Context, orgId string) (membe value, e := m.cache.Get(makeKey(orgId)) if e == nil { - return value.([]*service.Member), err + return data.CloneSlice(value.([]*service.Member)), nil } members, err = m.next.ListMembers(ctx, orgId) if err == nil { _ = m.cache.Set(makeKey(orgId), members) + return data.CloneSlice(members), nil } - return members, err + return nil, err } func (m cachingMiddleware) ListOrganizations(ctx context.Context, userId string) (members []*service.Member, err error) { value, e := m.cache.Get(makeKey(userId)) if e == nil { - return value.([]*service.Member), err + return data.CloneSlice(value.([]*service.Member)), nil } members, err = m.next.ListOrganizations(ctx, userId) if err == nil { _ = m.cache.Set(makeKey(userId), members) + return data.CloneSlice(members), nil } - return members, err + return nil, err } diff --git a/pkg/organizations/middleware/caching_middleware.go b/pkg/organizations/middleware/caching_middleware.go index ecee2727..c6503200 100644 --- a/pkg/organizations/middleware/caching_middleware.go +++ b/pkg/organizations/middleware/caching_middleware.go @@ -30,13 +30,14 @@ func (m cachingMiddleware) Get(ctx context.Context, orgId string) (organization value, e := m.cache.Get(orgId) if e == nil { - return value.(*service.Organization), err + return value.(*service.Organization).Clone(), nil } organization, err = m.next.Get(ctx, orgId) if err == nil { _ = m.cache.Set(orgId, organization) + return organization.Clone(), nil } - return organization, err + return nil, err } func (m cachingMiddleware) Update(ctx context.Context, org *service.Organization) (err error) { diff --git a/pkg/organizations/middleware/caching_middleware_test.go b/pkg/organizations/middleware/caching_middleware_test.go index 3f302620..f9999cfc 100644 --- a/pkg/organizations/middleware/caching_middleware_test.go +++ b/pkg/organizations/middleware/caching_middleware_test.go @@ -37,7 +37,8 @@ func TestOrganizationsCache(t *testing.T) { v2, err := svc.Get(ctx, orgId) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) orgs.AssertExpectations(t) }) @@ -54,7 +55,8 @@ func TestOrganizationsCache(t *testing.T) { v2, err := svc.Get(ctx, orgId) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) orgs.On("Update", mock.Anything, mock.Anything).Return(nil).Once() err = svc.Update(ctx, &organizations.Organization{ID: orgId, Name: "OrganizationUPD"}) @@ -64,7 +66,7 @@ func TestOrganizationsCache(t *testing.T) { v3, err := svc.Get(ctx, orgId) require.NoError(t, err) - assert.NotSame(t, v2, v3, "ОжидаетÑÑ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ðµ объекта из кÑша поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ получение заново из ÑервиÑа.") + assert.NotEqual(t, v2, v3, "ОжидаетÑÑ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ðµ объекта из кÑша поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ получение заново из ÑервиÑа.") orgs.AssertExpectations(t) }) @@ -80,7 +82,8 @@ func TestOrganizationsCache(t *testing.T) { v2, err := svc.Get(ctx, orgId) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) orgs.On("Delete", mock.Anything, mock.Anything).Return(nil).Once() err = svc.Delete(ctx, orgId) @@ -105,7 +108,8 @@ func TestOrganizationsCache(t *testing.T) { v2, err := svc.Get(ctx, orgId) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) time.Sleep(2 * ttl) @@ -114,6 +118,8 @@ func TestOrganizationsCache(t *testing.T) { v3, err := svc.Get(ctx, orgId) require.NoError(t, err) assert.NotSame(t, v2, v3, "ОжидаетÑÑ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ðµ объекта из кÑша и получение заново из ÑервиÑа.") + assert.Equal(t, v2, v3) + assert.NotSame(t, v2, v3) orgs.AssertExpectations(t) }) diff --git a/pkg/organizations/organization.go b/pkg/organizations/organization.go index b95daa69..8c6df31c 100644 --- a/pkg/organizations/organization.go +++ b/pkg/organizations/organization.go @@ -8,6 +8,16 @@ type Organization struct { OwnerID *string `bson:"-"` } +func (o Organization) Clone() *Organization { + return &Organization{ + ID: o.ID, + Name: o.Name, + Description: o.Description, + LogoURL: o.LogoURL, + OwnerID: o.OwnerID, + } +} + func (o *Organization) SetOwnerID(s string) *Organization { o.OwnerID = &s return o diff --git a/pkg/roles/middleware/caching_middleware.go b/pkg/roles/middleware/caching_middleware.go index 8537544f..2bcb04d3 100644 --- a/pkg/roles/middleware/caching_middleware.go +++ b/pkg/roles/middleware/caching_middleware.go @@ -5,6 +5,7 @@ import ( "strings" "git.perx.ru/perxis/perxis-go/pkg/cache" + "git.perx.ru/perxis/perxis-go/pkg/data" service "git.perx.ru/perxis/perxis-go/pkg/roles" ) @@ -38,25 +39,27 @@ func (m cachingMiddleware) Get(ctx context.Context, spaceId string, roleId strin key := makeKey(spaceId, roleId) value, e := m.cache.Get(key) if e == nil { - return value.(*service.Role), err + return value.(*service.Role).Clone(), nil } rl, err = m.next.Get(ctx, spaceId, roleId) if err == nil { _ = m.cache.Set(key, rl) + return rl.Clone(), nil } - return rl, err + return nil, err } func (m cachingMiddleware) List(ctx context.Context, spaceId string) (roles []*service.Role, err error) { value, e := m.cache.Get(spaceId) if e == nil { - return value.([]*service.Role), err + return data.CloneSlice(value.([]*service.Role)), nil } roles, err = m.next.List(ctx, spaceId) if err == nil { _ = m.cache.Set(spaceId, roles) + return data.CloneSlice(roles), nil } - return roles, err + return nil, err } func (m cachingMiddleware) Update(ctx context.Context, role *service.Role) (err error) { diff --git a/pkg/roles/middleware/caching_middleware_test.go b/pkg/roles/middleware/caching_middleware_test.go index 9d5d64f4..b9ac8ec8 100644 --- a/pkg/roles/middleware/caching_middleware_test.go +++ b/pkg/roles/middleware/caching_middleware_test.go @@ -39,7 +39,8 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, roleID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.NotSame(t, v1, v2) rl.AssertExpectations(t) }) @@ -56,7 +57,8 @@ func TestRolesCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) rl.AssertExpectations(t) }) @@ -75,14 +77,16 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, roleID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, v1, v2) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) rl.On("Update", mock.Anything, mock.Anything).Return(nil).Once() @@ -94,11 +98,11 @@ func TestRolesCache(t *testing.T) { v3, err := svc.Get(ctx, spaceID, roleID) require.NoError(t, err) - assert.NotSame(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объекта был удален поÑле его Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ объект был запрошен из ÑервиÑа.") + assert.NotEqual(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объекта был удален поÑле его Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ объект был запрошен из ÑервиÑа.") vl3, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объектов был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") + assert.NotEqual(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объектов был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") rl.AssertExpectations(t) }) @@ -116,14 +120,16 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, roleID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.NotSame(t, v1, v2) vl1, err := svc.List(ctx, spaceID) require.NoError(t, err) vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) rl.On("Update", mock.Anything, mock.Anything).Return(nil).Once() @@ -158,7 +164,8 @@ func TestRolesCache(t *testing.T) { vl2, err := svc.List(ctx, spaceID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) rl.On("Create", mock.Anything, mock.Anything).Return(&roles.Role{ID: "roleID2", SpaceID: spaceID, Description: "Role2"}, nil).Once() @@ -186,7 +193,8 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID, roleID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) time.Sleep(2 * ttl) rl.On("Get", mock.Anything, spaceID, roleID).Return(&roles.Role{ID: roleID, SpaceID: spaceID, Description: "Role"}, nil).Once() @@ -194,6 +202,8 @@ func TestRolesCache(t *testing.T) { v3, err := svc.Get(ctx, spaceID, roleID) require.NoError(t, err) assert.NotSame(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ объект был удален из кеша и получен заново из ÑервиÑа.") + assert.Equal(t, v2, v3) + assert.NotSame(t, v2, v3) rl.AssertExpectations(t) }) diff --git a/pkg/roles/role.go b/pkg/roles/role.go index 37047067..579a9664 100644 --- a/pkg/roles/role.go +++ b/pkg/roles/role.go @@ -2,6 +2,7 @@ package roles import ( "context" + "slices" "git.perx.ru/perxis/perxis-go/pkg/data" "git.perx.ru/perxis/perxis-go/pkg/environments" @@ -34,6 +35,17 @@ type Role struct { AllowManagement bool `json:"allow_management" bson:"allow_management"` } +func (r Role) Clone() *Role { + return &Role{ + ID: r.ID, + SpaceID: r.SpaceID, + Description: r.Description, + Environments: slices.Clone(r.Environments), + Rules: data.CloneSlice(r.Rules), + AllowManagement: r.AllowManagement, + } +} + func (r Role) CanAccessEnvironment(ctx context.Context, env *environments.Environment, service environments.Environments) bool { if env.SpaceID == "" || env.ID == "" { return false diff --git a/pkg/spaces/middleware/caching_middleware.go b/pkg/spaces/middleware/caching_middleware.go index 46c9ef46..c7f35de1 100644 --- a/pkg/spaces/middleware/caching_middleware.go +++ b/pkg/spaces/middleware/caching_middleware.go @@ -4,6 +4,7 @@ import ( "context" "git.perx.ru/perxis/perxis-go/pkg/cache" + "git.perx.ru/perxis/perxis-go/pkg/data" "git.perx.ru/perxis/perxis-go/pkg/options" service "git.perx.ru/perxis/perxis-go/pkg/spaces" ) @@ -39,20 +40,21 @@ func (m cachingMiddleware) Get(ctx context.Context, spaceId string) (sp *service value, e := m.cache.Get(spaceId) if e == nil { - return value.(*service.Space), err + return value.(*service.Space).Clone(), nil } sp, err = m.next.Get(ctx, spaceId) if err == nil { _ = m.cache.Set(spaceId, sp) + return sp.Clone(), nil } - return sp, err + return nil, err } func (m cachingMiddleware) List(ctx context.Context, orgId string) (spaces []*service.Space, err error) { value, e := m.cache.Get(orgKey(orgId)) if e == nil { - return value.([]*service.Space), err + return data.CloneSlice(value.([]*service.Space)), nil } spaces, err = m.next.List(ctx, orgId) if err == nil { @@ -60,8 +62,9 @@ func (m cachingMiddleware) List(ctx context.Context, orgId string) (spaces []*se for _, s := range spaces { _ = m.cache.Set(s.ID, s) } + return data.CloneSlice(spaces), nil } - return spaces, err + return nil, err } func (m cachingMiddleware) Find(ctx context.Context, filter *service.Filter, fo *options.FindOptions) (spaces []*service.Space, total int, err error) { diff --git a/pkg/spaces/middleware/caching_middleware_test.go b/pkg/spaces/middleware/caching_middleware_test.go index e87ceb38..0674c932 100644 --- a/pkg/spaces/middleware/caching_middleware_test.go +++ b/pkg/spaces/middleware/caching_middleware_test.go @@ -40,7 +40,8 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.NotSame(t, v1, v2) sp.AssertExpectations(t) }) @@ -57,7 +58,8 @@ func TestRolesCache(t *testing.T) { vl2, err := svc.List(ctx, orgID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) sp.AssertExpectations(t) }) @@ -76,14 +78,16 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.NotSame(t, v1, v2) vl1, err := svc.List(ctx, orgID) require.NoError(t, err) vl2, err := svc.List(ctx, orgID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) sp.On("Update", mock.Anything, mock.Anything).Return(nil).Once() @@ -95,11 +99,11 @@ func TestRolesCache(t *testing.T) { v3, err := svc.Get(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объекта был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") + assert.NotEqual(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объекта был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") vl3, err := svc.List(ctx, orgID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объектов был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") + assert.NotEqual(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объектов был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") sp.AssertExpectations(t) }) @@ -117,14 +121,16 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.NotSame(t, v1, v2) vl1, err := svc.List(ctx, orgID) require.NoError(t, err) vl2, err := svc.List(ctx, orgID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) sp.On("UpdateConfig", mock.Anything, spaceID, mock.Anything).Return(nil).Once() @@ -136,11 +142,11 @@ func TestRolesCache(t *testing.T) { v3, err := svc.Get(ctx, spaceID) require.NoError(t, err) - assert.NotSame(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объекта был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") + assert.NotEqual(t, v2, v3, "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объекта был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") vl3, err := svc.List(ctx, orgID) require.NoError(t, err) - assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объектов был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") + assert.NotEqual(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объектов был удален поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.") sp.AssertExpectations(t) }) @@ -158,14 +164,16 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.NotSame(t, v1, v2) vl1, err := svc.List(ctx, orgID) require.NoError(t, err) vl2, err := svc.List(ctx, orgID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) sp.On("Delete", mock.Anything, spaceID).Return(nil).Once() @@ -198,7 +206,8 @@ func TestRolesCache(t *testing.T) { vl2, err := svc.List(ctx, orgID) require.NoError(t, err) - assert.Same(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.Equal(t, vl1[0], vl2[0], "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объектов из кÑша.") + assert.NotSame(t, vl1[0], vl2[0]) sp.On("Create", mock.Anything, mock.Anything).Return(&spaces.Space{ID: "spaceID2", OrgID: orgID, Name: "Space2"}, nil).Once() @@ -210,6 +219,8 @@ func TestRolesCache(t *testing.T) { vl3, err := svc.List(ctx, orgID) require.NoError(t, err) assert.NotSame(t, vl2[0], vl3[0], "ОжидаетÑÑ Ñ‡Ñ‚Ð¾ кеш объектов был удален поÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ объекта.") + assert.Equal(t, vl2[0], vl3[0]) + assert.NotSame(t, vl2[0], vl3[0]) sp.AssertExpectations(t) }) @@ -226,7 +237,8 @@ func TestRolesCache(t *testing.T) { v2, err := svc.Get(ctx, spaceID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ñ€Ð¸ повторном запроÑе получение объекта из кÑша.") + assert.NotSame(t, v1, v2) time.Sleep(2 * ttl) sp.On("Get", mock.Anything, spaceID).Return(&spaces.Space{ID: spaceID, OrgID: orgID, Name: "Space"}, nil).Once() @@ -234,6 +246,8 @@ func TestRolesCache(t *testing.T) { v3, err := svc.Get(ctx, spaceID) require.NoError(t, err) assert.NotSame(t, v2, v3, "ОжидаетÑÑ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ðµ объекта из кÑша по иÑтечению ttl.") + assert.Equal(t, v2, v3) + assert.NotSame(t, v2, v3) sp.AssertExpectations(t) }) diff --git a/pkg/users/middleware/caching_middleware.go b/pkg/users/middleware/caching_middleware.go index ee0bf4a0..825da6a2 100644 --- a/pkg/users/middleware/caching_middleware.go +++ b/pkg/users/middleware/caching_middleware.go @@ -30,7 +30,7 @@ func (m cachingMiddleware) Get(ctx context.Context, userId string) (user *servic value, e := m.cache.Get(userId) if e == nil { - return value.(*service.User), err + return value.(*service.User).Clone(), nil } user, err = m.next.Get(ctx, userId) if err == nil { @@ -38,8 +38,9 @@ func (m cachingMiddleware) Get(ctx context.Context, userId string) (user *servic for _, i := range user.Identities { _ = m.cache.Set(i, user) } + return user.Clone(), nil } - return user, err + return nil, err } func (m cachingMiddleware) Find(ctx context.Context, filter *service.Filter, options *services.FindOptions) (users []*service.User, total int, err error) { @@ -78,7 +79,7 @@ func (m cachingMiddleware) GetByIdentity(ctx context.Context, identity string) ( value, e := m.cache.Get(identity) if e == nil { - return value.(*service.User), err + return value.(*service.User).Clone(), nil } user, err = m.next.GetByIdentity(ctx, identity) if err == nil { @@ -86,6 +87,7 @@ func (m cachingMiddleware) GetByIdentity(ctx context.Context, identity string) ( for _, i := range user.Identities { _ = m.cache.Set(i, user) } + return user.Clone(), nil } - return user, err + return nil, err } diff --git a/pkg/users/middleware/caching_middleware_test.go b/pkg/users/middleware/caching_middleware_test.go index edc9176b..c5755407 100644 --- a/pkg/users/middleware/caching_middleware_test.go +++ b/pkg/users/middleware/caching_middleware_test.go @@ -38,11 +38,13 @@ func TestUsersCache(t *testing.T) { v2, err := svc.Get(ctx, userID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) v3, err := svc.GetByIdentity(ctx, identity) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при запроÑе по Identity.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при запроÑе по Identity.") + assert.NotSame(t, v2, v3) usrs.AssertExpectations(t) }) @@ -60,11 +62,13 @@ func TestUsersCache(t *testing.T) { v2, err := svc.GetByIdentity(ctx, identity) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) v3, err := svc.Get(ctx, userID) require.NoError(t, err) - assert.Same(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при запроÑе по userID.") + assert.Equal(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при запроÑе по userID.") + assert.NotSame(t, v2, v3) usrs.AssertExpectations(t) }) @@ -84,7 +88,8 @@ func TestUsersCache(t *testing.T) { v2, err := svc.GetByIdentity(ctx, identity) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) err = svc.Update(ctx, &users.User{ID: userID, Name: "New User", Identities: []string{identity}}) require.NoError(t, err) @@ -93,12 +98,13 @@ func TestUsersCache(t *testing.T) { v3, err := svc.GetByIdentity(ctx, identity) require.NoError(t, err) - assert.NotSame(t, v3, v2, "ОжидаетÑÑ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ðµ объекта из кеша поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ получение его заново из ÑервиÑа.") + assert.NotEqual(t, v3, v2, "ОжидаетÑÑ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ðµ объекта из кеша поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ получение его заново из ÑервиÑа.") v4, err := svc.Get(ctx, userID) require.NoError(t, err) - assert.NotSame(t, v4, v2) - assert.Same(t, v4, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ нового обьекта из кеша.") + assert.NotEqual(t, v4, v2) + assert.Equal(t, v4, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ нового обьекта из кеша.") + assert.NotSame(t, v4, v3) usrs.AssertExpectations(t) }) @@ -117,7 +123,8 @@ func TestUsersCache(t *testing.T) { v2, err := svc.GetByIdentity(ctx, identity) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) err = svc.Delete(ctx, userID) require.NoError(t, err) @@ -149,7 +156,8 @@ func TestUsersCache(t *testing.T) { v2, err := svc.Get(ctx, userID) require.NoError(t, err) - assert.Same(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.Equal(t, v1, v2, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша.") + assert.NotSame(t, v1, v2) time.Sleep(2 * ttl) @@ -158,6 +166,8 @@ func TestUsersCache(t *testing.T) { v3, err := svc.Get(ctx, userID) require.NoError(t, err) assert.NotSame(t, v2, v3, "ОжидаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ðµ объекта из кÑша при запроÑе по Identity.") + assert.Equal(t, v2, v3) + assert.NotSame(t, v2, v3) usrs.AssertExpectations(t) }) -- GitLab