local: add Metadata support #111
This commit is contained in:
parent
22abd785eb
commit
c556e98f49
15 changed files with 699 additions and 6 deletions
|
@ -3,10 +3,12 @@ package local
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -229,3 +231,138 @@ func TestHashOnDelete(t *testing.T) {
|
|||
_, err = o.Hash(ctx, hash.MD5)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestMetadata(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r := fstest.NewRun(t)
|
||||
defer r.Finalise()
|
||||
const filePath = "metafile.txt"
|
||||
when := time.Now()
|
||||
const dayLength = len("2001-01-01")
|
||||
whenRFC := when.Format(time.RFC3339Nano)
|
||||
r.WriteFile(filePath, "metadata file contents", when)
|
||||
f := r.Flocal.(*Fs)
|
||||
|
||||
// Get the object
|
||||
obj, err := f.NewObject(ctx, filePath)
|
||||
require.NoError(t, err)
|
||||
o := obj.(*Object)
|
||||
|
||||
features := f.Features()
|
||||
|
||||
var hasXID, hasAtime, hasBtime bool
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "freebsd", "netbsd", "linux":
|
||||
hasXID, hasAtime, hasBtime = true, true, true
|
||||
case "openbsd", "solaris":
|
||||
hasXID, hasAtime = true, true
|
||||
case "windows":
|
||||
hasAtime, hasBtime = true, true
|
||||
case "plan9", "js":
|
||||
// nada
|
||||
default:
|
||||
t.Errorf("No test cases for OS %q", runtime.GOOS)
|
||||
}
|
||||
|
||||
assert.True(t, features.ReadMetadata)
|
||||
assert.True(t, features.WriteMetadata)
|
||||
assert.Equal(t, xattrSupported, features.UserMetadata)
|
||||
|
||||
t.Run("Xattr", func(t *testing.T) {
|
||||
if !xattrSupported {
|
||||
t.Skip()
|
||||
}
|
||||
m, err := o.getXattr()
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, m)
|
||||
|
||||
inM := fs.Metadata{
|
||||
"potato": "chips",
|
||||
"cabbage": "soup",
|
||||
}
|
||||
err = o.setXattr(inM)
|
||||
require.NoError(t, err)
|
||||
|
||||
m, err = o.getXattr()
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, m)
|
||||
assert.Equal(t, inM, m)
|
||||
})
|
||||
|
||||
checkTime := func(m fs.Metadata, key string, when time.Time) {
|
||||
mt, ok := o.parseMetadataTime(m, key)
|
||||
assert.True(t, ok)
|
||||
dt := mt.Sub(when)
|
||||
precision := time.Second
|
||||
assert.True(t, dt >= -precision && dt <= precision, fmt.Sprintf("%s: dt %v outside +/- precision %v", key, dt, precision))
|
||||
}
|
||||
|
||||
checkInt := func(m fs.Metadata, key string, base int) int {
|
||||
value, ok := o.parseMetadataInt(m, key, base)
|
||||
assert.True(t, ok)
|
||||
return value
|
||||
}
|
||||
t.Run("Read", func(t *testing.T) {
|
||||
m, err := o.Metadata(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, m)
|
||||
|
||||
// All OSes have these
|
||||
checkInt(m, "mode", 8)
|
||||
checkTime(m, "mtime", when)
|
||||
|
||||
assert.Equal(t, len(whenRFC), len(m["mtime"]))
|
||||
assert.Equal(t, whenRFC[:dayLength], m["mtime"][:dayLength])
|
||||
|
||||
if hasAtime {
|
||||
checkTime(m, "atime", when)
|
||||
}
|
||||
if hasBtime {
|
||||
checkTime(m, "btime", when)
|
||||
}
|
||||
if hasXID {
|
||||
checkInt(m, "uid", 10)
|
||||
checkInt(m, "gid", 10)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Write", func(t *testing.T) {
|
||||
newAtimeString := "2011-12-13T14:15:16.999999999Z"
|
||||
newAtime := fstest.Time(newAtimeString)
|
||||
newMtimeString := "2011-12-12T14:15:16.999999999Z"
|
||||
newMtime := fstest.Time(newMtimeString)
|
||||
newBtimeString := "2011-12-11T14:15:16.999999999Z"
|
||||
newBtime := fstest.Time(newBtimeString)
|
||||
newM := fs.Metadata{
|
||||
"mtime": newMtimeString,
|
||||
"atime": newAtimeString,
|
||||
"btime": newBtimeString,
|
||||
// Can't test uid, gid without being root
|
||||
"mode": "0767",
|
||||
"potato": "wedges",
|
||||
}
|
||||
err := o.writeMetadata(newM)
|
||||
require.NoError(t, err)
|
||||
|
||||
m, err := o.Metadata(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, m)
|
||||
|
||||
mode := checkInt(m, "mode", 8)
|
||||
if runtime.GOOS != "windows" {
|
||||
assert.Equal(t, 0767, mode&0777, fmt.Sprintf("mode wrong - expecting 0767 got 0%o", mode&0777))
|
||||
}
|
||||
|
||||
checkTime(m, "mtime", newMtime)
|
||||
if hasAtime {
|
||||
checkTime(m, "atime", newAtime)
|
||||
}
|
||||
if haveSetBTime {
|
||||
checkTime(m, "btime", newBtime)
|
||||
}
|
||||
if xattrSupported {
|
||||
assert.Equal(t, "wedges", m["potato"])
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue