* Implement AppendFile for FileBackend * Split test into subtests * [MM-26812] Add support for resumable file uploads (#15252) * Implement UploadSession * Implement UploadSessionStore * Add error strings * Implement resumable file uploads * Add UploadType * Fix retry layer tests * Regenerate store layers * Fix store error handling * Use base for filename * Prevent concurrent uploads on the same upload session * Fix erroneus error string * Improve error handling Co-authored-by: Mattermod <mattermod@users.noreply.github.com> * Fix translations Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
214 строки
5.6 KiB
Go
214 строки
5.6 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package storetest
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/mattermost/mattermost-server/v5/model"
|
|
"github.com/mattermost/mattermost-server/v5/store"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestUploadSessionStore(t *testing.T, ss store.Store) {
|
|
t.Run("UploadSessionStoreSaveGet", func(t *testing.T) { testUploadSessionStoreSaveGet(t, ss) })
|
|
t.Run("UploadSessionStoreUpdate", func(t *testing.T) { testUploadSessionStoreUpdate(t, ss) })
|
|
t.Run("UploadSessionStoreGetForUser", func(t *testing.T) { testUploadSessionStoreGetForUser(t, ss) })
|
|
t.Run("UploadSessionStoreDelete", func(t *testing.T) { testUploadSessionStoreDelete(t, ss) })
|
|
}
|
|
|
|
func testUploadSessionStoreSaveGet(t *testing.T, ss store.Store) {
|
|
var session *model.UploadSession
|
|
|
|
t.Run("saving nil session should fail", func(t *testing.T) {
|
|
us, err := ss.UploadSession().Save(nil)
|
|
require.Error(t, err)
|
|
require.Nil(t, us)
|
|
})
|
|
|
|
t.Run("saving empty session should fail", func(t *testing.T) {
|
|
session = &model.UploadSession{}
|
|
us, err := ss.UploadSession().Save(session)
|
|
require.Error(t, err)
|
|
require.Nil(t, us)
|
|
})
|
|
|
|
t.Run("saving valid session should succeed", func(t *testing.T) {
|
|
session = &model.UploadSession{
|
|
Type: model.UploadTypeAttachment,
|
|
UserId: model.NewId(),
|
|
ChannelId: model.NewId(),
|
|
Filename: "test",
|
|
FileSize: 1024,
|
|
Path: "/tmp/test",
|
|
}
|
|
us, err := ss.UploadSession().Save(session)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, us)
|
|
require.NotEmpty(t, us)
|
|
})
|
|
|
|
t.Run("getting non-existing session should fail", func(t *testing.T) {
|
|
us, err := ss.UploadSession().Get("fake")
|
|
require.Error(t, err)
|
|
require.Nil(t, us)
|
|
})
|
|
|
|
t.Run("getting existing session should succeed", func(t *testing.T) {
|
|
us, err := ss.UploadSession().Get(session.Id)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, us)
|
|
require.Equal(t, session, us)
|
|
})
|
|
}
|
|
|
|
func testUploadSessionStoreUpdate(t *testing.T, ss store.Store) {
|
|
session := &model.UploadSession{
|
|
Type: model.UploadTypeAttachment,
|
|
UserId: model.NewId(),
|
|
ChannelId: model.NewId(),
|
|
Filename: "test",
|
|
FileSize: 1024,
|
|
Path: "/tmp/test",
|
|
}
|
|
|
|
t.Run("updating nil session should fail", func(t *testing.T) {
|
|
err := ss.UploadSession().Update(nil)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("updating invalid session should fail", func(t *testing.T) {
|
|
err := ss.UploadSession().Update(&model.UploadSession{})
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("updating non-existing session should fail", func(t *testing.T) {
|
|
err := ss.UploadSession().Update(&model.UploadSession{})
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("updating existing session should succeed", func(t *testing.T) {
|
|
us, err := ss.UploadSession().Save(session)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, us)
|
|
require.NotEmpty(t, us)
|
|
|
|
us.FileOffset = 512
|
|
err = ss.UploadSession().Update(us)
|
|
require.NoError(t, err)
|
|
|
|
updated, err := ss.UploadSession().Get(us.Id)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, us)
|
|
require.Equal(t, us, updated)
|
|
})
|
|
}
|
|
|
|
func testUploadSessionStoreGetForUser(t *testing.T, ss store.Store) {
|
|
userId := model.NewId()
|
|
|
|
sessions := []*model.UploadSession{
|
|
{
|
|
Type: model.UploadTypeAttachment,
|
|
UserId: userId,
|
|
ChannelId: model.NewId(),
|
|
Filename: "test0",
|
|
FileSize: 1024,
|
|
Path: "/tmp/test0",
|
|
},
|
|
{
|
|
Type: model.UploadTypeAttachment,
|
|
UserId: model.NewId(),
|
|
ChannelId: model.NewId(),
|
|
Filename: "test1",
|
|
FileSize: 1024,
|
|
Path: "/tmp/test1",
|
|
},
|
|
{
|
|
Type: model.UploadTypeAttachment,
|
|
UserId: userId,
|
|
ChannelId: model.NewId(),
|
|
Filename: "test2",
|
|
FileSize: 1024,
|
|
Path: "/tmp/test2",
|
|
},
|
|
{
|
|
Type: model.UploadTypeAttachment,
|
|
UserId: userId,
|
|
ChannelId: model.NewId(),
|
|
Filename: "test3",
|
|
FileSize: 1024,
|
|
Path: "/tmp/test3",
|
|
},
|
|
}
|
|
|
|
t.Run("getting invalid userId should fail", func(t *testing.T) {
|
|
us, err := ss.UploadSession().GetForUser("invalidId")
|
|
require.Error(t, err)
|
|
require.Nil(t, us)
|
|
})
|
|
|
|
t.Run("should return no sessions", func(t *testing.T) {
|
|
us, err := ss.UploadSession().GetForUser(userId)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, us)
|
|
require.Empty(t, us)
|
|
})
|
|
|
|
for i := 0; i < len(sessions); i++ {
|
|
us, err := ss.UploadSession().Save(sessions[i])
|
|
require.NoError(t, err)
|
|
require.NotNil(t, us)
|
|
require.NotEmpty(t, us)
|
|
// We need this to make sure the ordering is consistent.
|
|
time.Sleep(1 * time.Millisecond)
|
|
}
|
|
|
|
t.Run("should return existing sessions", func(t *testing.T) {
|
|
us, err := ss.UploadSession().GetForUser(userId)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, us)
|
|
require.NotEmpty(t, us)
|
|
require.Len(t, us, 3)
|
|
|
|
require.Equal(t, sessions[0], us[0])
|
|
require.Equal(t, sessions[2], us[1])
|
|
require.Equal(t, sessions[3], us[2])
|
|
})
|
|
}
|
|
|
|
func testUploadSessionStoreDelete(t *testing.T, ss store.Store) {
|
|
session := &model.UploadSession{
|
|
Id: model.NewId(),
|
|
Type: model.UploadTypeAttachment,
|
|
UserId: model.NewId(),
|
|
ChannelId: model.NewId(),
|
|
Filename: "test",
|
|
FileSize: 1024,
|
|
Path: "/tmp/test",
|
|
}
|
|
|
|
t.Run("deleting invalid id should fail", func(t *testing.T) {
|
|
err := ss.UploadSession().Delete("invalidId")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("deleting existing session should succeed", func(t *testing.T) {
|
|
us, err := ss.UploadSession().Save(session)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, us)
|
|
require.NotEmpty(t, us)
|
|
|
|
err = ss.UploadSession().Delete(session.Id)
|
|
require.NoError(t, err)
|
|
|
|
us, err = ss.UploadSession().Get(us.Id)
|
|
require.Error(t, err)
|
|
require.Nil(t, us)
|
|
require.IsType(t, &store.ErrNotFound{}, err)
|
|
})
|
|
}
|