s3: fix --s3-versions on individual objects
Before this fix attempting to access an s3 versioned object by name in a subdirectory of root would not find the object. This fixes the problem and introduced an integraton test. See: https://forum.rclone.org/t/s3-versions-cant-retrieve-old-version/36900
This commit is contained in:
parent
d481aa8613
commit
542677d807
2 changed files with 23 additions and 5 deletions
|
@ -3119,6 +3119,7 @@ func (f *Fs) getMetaDataListing(ctx context.Context, wantRemote string) (info *s
|
||||||
err = f.list(ctx, listOpt{
|
err = f.list(ctx, listOpt{
|
||||||
bucket: bucket,
|
bucket: bucket,
|
||||||
directory: bucketPath,
|
directory: bucketPath,
|
||||||
|
prefix: f.rootDirectory,
|
||||||
recurse: true,
|
recurse: true,
|
||||||
withVersions: f.opt.Versions,
|
withVersions: f.opt.Versions,
|
||||||
findFile: true,
|
findFile: true,
|
||||||
|
@ -3524,10 +3525,10 @@ type listOpt struct {
|
||||||
// list lists the objects into the function supplied with the opt
|
// list lists the objects into the function supplied with the opt
|
||||||
// supplied.
|
// supplied.
|
||||||
func (f *Fs) list(ctx context.Context, opt listOpt, fn listFn) error {
|
func (f *Fs) list(ctx context.Context, opt listOpt, fn listFn) error {
|
||||||
|
if opt.prefix != "" {
|
||||||
|
opt.prefix += "/"
|
||||||
|
}
|
||||||
if !opt.findFile {
|
if !opt.findFile {
|
||||||
if opt.prefix != "" {
|
|
||||||
opt.prefix += "/"
|
|
||||||
}
|
|
||||||
if opt.directory != "" {
|
if opt.directory != "" {
|
||||||
opt.directory += "/"
|
opt.directory += "/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,15 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/service/s3"
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
|
"github.com/rclone/rclone/fs/cache"
|
||||||
"github.com/rclone/rclone/fs/hash"
|
"github.com/rclone/rclone/fs/hash"
|
||||||
"github.com/rclone/rclone/fstest"
|
"github.com/rclone/rclone/fstest"
|
||||||
"github.com/rclone/rclone/fstest/fstests"
|
"github.com/rclone/rclone/fstest/fstests"
|
||||||
|
@ -250,7 +253,8 @@ func (f *Fs) InternalTestVersions(t *testing.T) {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
// Create an object
|
// Create an object
|
||||||
const fileName = "test-versions.txt"
|
const dirName = "versions"
|
||||||
|
const fileName = dirName + "/" + "test-versions.txt"
|
||||||
contents := random.String(100)
|
contents := random.String(100)
|
||||||
item := fstest.NewItem(fileName, contents, fstest.Time("2001-05-06T04:05:06.499999999Z"))
|
item := fstest.NewItem(fileName, contents, fstest.Time("2001-05-06T04:05:06.499999999Z"))
|
||||||
obj := fstests.PutTestContents(ctx, t, f, &item, contents, true)
|
obj := fstests.PutTestContents(ctx, t, f, &item, contents, true)
|
||||||
|
@ -280,11 +284,12 @@ func (f *Fs) InternalTestVersions(t *testing.T) {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Read the contents
|
// Read the contents
|
||||||
entries, err := f.List(ctx, "")
|
entries, err := f.List(ctx, dirName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
tests := 0
|
tests := 0
|
||||||
var fileNameVersion string
|
var fileNameVersion string
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
|
t.Log(entry)
|
||||||
remote := entry.Remote()
|
remote := entry.Remote()
|
||||||
if remote == fileName {
|
if remote == fileName {
|
||||||
t.Run("ReadCurrent", func(t *testing.T) {
|
t.Run("ReadCurrent", func(t *testing.T) {
|
||||||
|
@ -309,6 +314,18 @@ func (f *Fs) InternalTestVersions(t *testing.T) {
|
||||||
require.NotNil(t, o)
|
require.NotNil(t, o)
|
||||||
assert.Equal(t, int64(100), o.Size(), o.Remote())
|
assert.Equal(t, int64(100), o.Size(), o.Remote())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Check we can make a NewFs from that object with a version suffix
|
||||||
|
t.Run("NewFs", func(t *testing.T) {
|
||||||
|
newPath := path.Join(fs.ConfigString(f), fileNameVersion)
|
||||||
|
// Make sure --s3-versions is set in the config of the new remote
|
||||||
|
confPath := strings.Replace(newPath, ":", ",versions:", 1)
|
||||||
|
fNew, err := cache.Get(ctx, confPath)
|
||||||
|
// This should return pointing to a file
|
||||||
|
assert.Equal(t, fs.ErrorIsFile, err)
|
||||||
|
// With the directory the directory above
|
||||||
|
assert.Equal(t, dirName, path.Base(fs.ConfigString(fNew)))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("VersionAt", func(t *testing.T) {
|
t.Run("VersionAt", func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue