2020-06-18 17:36:38 +00:00
|
|
|
package cephfs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
var samples = []struct {
|
|
|
|
name string
|
|
|
|
value []byte
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "user.xPhrase",
|
|
|
|
value: []byte("june and july"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "user.xHasNulls",
|
|
|
|
value: []byte("\x00got\x00null?\x00"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "user.x2kZeros",
|
|
|
|
value: make([]byte, 2048),
|
|
|
|
},
|
2020-06-18 19:39:54 +00:00
|
|
|
// Ceph's behavior when an empty value is supplied may be considered
|
|
|
|
// to have a bug in some versions. Using an empty value may cause
|
|
|
|
// the xattr to be unset. Please refer to:
|
|
|
|
// https://tracker.ceph.com/issues/46084
|
|
|
|
// So we avoid testing for that case explicitly here.
|
|
|
|
//{
|
|
|
|
// name: "user.xEmpty",
|
|
|
|
// value: []byte(""),
|
|
|
|
//},
|
2020-06-18 17:36:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetSetXattr(t *testing.T) {
|
|
|
|
mount := fsConnect(t)
|
|
|
|
defer fsDisconnect(t, mount)
|
|
|
|
fname := "TestGetSetXattr.txt"
|
|
|
|
|
|
|
|
f, err := mount.Open(fname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
|
|
|
require.NoError(t, err)
|
|
|
|
defer func() {
|
|
|
|
assert.NoError(t, f.Close())
|
|
|
|
assert.NoError(t, mount.Unlink(fname))
|
|
|
|
}()
|
|
|
|
|
2020-06-18 19:39:54 +00:00
|
|
|
for _, s := range samples {
|
2020-06-18 17:36:38 +00:00
|
|
|
t.Run("roundTrip-"+s.name, func(t *testing.T) {
|
|
|
|
err := f.SetXattr(s.name, s.value, XattrDefault)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
b, err := f.GetXattr(s.name)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.EqualValues(t, s.value, b)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Run("missingXattrOnGet", func(t *testing.T) {
|
2020-06-18 19:39:54 +00:00
|
|
|
_, err := f.GetXattr("user.never-set")
|
2020-06-18 17:36:38 +00:00
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("emptyNameGet", func(t *testing.T) {
|
|
|
|
_, err := f.GetXattr("")
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("emptyNameSet", func(t *testing.T) {
|
|
|
|
err := f.SetXattr("", []byte("foo"), XattrDefault)
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("invalidFile", func(t *testing.T) {
|
|
|
|
f1 := &File{}
|
|
|
|
err := f1.SetXattr(samples[0].name, samples[0].value, XattrDefault)
|
|
|
|
assert.Error(t, err)
|
|
|
|
_, err = f1.GetXattr(samples[0].name)
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
2020-06-18 19:19:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestListXattr(t *testing.T) {
|
|
|
|
mount := fsConnect(t)
|
|
|
|
defer fsDisconnect(t, mount)
|
|
|
|
fname := "TestListXattr.txt"
|
|
|
|
|
|
|
|
f, err := mount.Open(fname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
|
|
|
require.NoError(t, err)
|
|
|
|
defer func() {
|
|
|
|
assert.NoError(t, f.Close())
|
|
|
|
assert.NoError(t, mount.Unlink(fname))
|
|
|
|
}()
|
2020-06-18 17:36:38 +00:00
|
|
|
|
2020-06-18 19:19:06 +00:00
|
|
|
t.Run("listXattrs1", func(t *testing.T) {
|
|
|
|
for _, s := range samples[:1] {
|
|
|
|
err := f.SetXattr(s.name, s.value, XattrDefault)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
xl, err := f.ListXattr()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Len(t, xl, 1)
|
|
|
|
assert.Contains(t, xl, samples[0].name)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("listXattrs2", func(t *testing.T) {
|
2020-06-18 19:39:54 +00:00
|
|
|
for _, s := range samples {
|
2020-06-18 19:19:06 +00:00
|
|
|
err := f.SetXattr(s.name, s.value, XattrDefault)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
xl, err := f.ListXattr()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Len(t, xl, 3)
|
|
|
|
assert.Contains(t, xl, samples[0].name)
|
|
|
|
assert.Contains(t, xl, samples[1].name)
|
|
|
|
assert.Contains(t, xl, samples[2].name)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("invalidFile", func(t *testing.T) {
|
|
|
|
f1 := &File{}
|
|
|
|
_, err := f1.ListXattr()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
2020-06-18 17:36:38 +00:00
|
|
|
}
|
2020-06-18 19:35:59 +00:00
|
|
|
|
|
|
|
func TestRemoveXattr(t *testing.T) {
|
|
|
|
mount := fsConnect(t)
|
|
|
|
defer fsDisconnect(t, mount)
|
|
|
|
fname := "TestRemoveXattr.txt"
|
|
|
|
|
|
|
|
f, err := mount.Open(fname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
|
|
|
require.NoError(t, err)
|
|
|
|
defer func() {
|
|
|
|
assert.NoError(t, f.Close())
|
|
|
|
assert.NoError(t, mount.Unlink(fname))
|
|
|
|
}()
|
|
|
|
|
|
|
|
t.Run("removeXattr", func(t *testing.T) {
|
|
|
|
s := samples[0]
|
|
|
|
err := f.SetXattr(s.name, s.value, XattrDefault)
|
|
|
|
err = f.RemoveXattr(s.name)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("removeMissingXattr", func(t *testing.T) {
|
|
|
|
s := samples[1]
|
|
|
|
err := f.RemoveXattr(s.name)
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("emptyName", func(t *testing.T) {
|
|
|
|
err := f.RemoveXattr("")
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("invalidFile", func(t *testing.T) {
|
|
|
|
f1 := &File{}
|
|
|
|
err := f1.RemoveXattr(samples[0].name)
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
}
|