go-ceph/rados/write_op_test.go
John Mulligan 0a67ff8f5a rados: add an initial set of tests for WriteOp operations
Signed-off-by: John Mulligan <jmulligan@redhat.com>
2021-01-12 14:47:30 +00:00

248 lines
6.2 KiB
Go

package rados
import (
"testing"
"github.com/stretchr/testify/assert"
)
// timeStamp generates a dummy Timespec value.
func timeStamp() Timespec {
// Future TODO (maybe?) - vary the value?
return Timespec{342334800, 0}
}
func (suite *RadosTestSuite) TestWriteOpCreate() {
suite.SetupConnection()
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
err := op.Operate(suite.ioctx, "TestWriteOpCreate", OperationNoFlag)
assert.NoError(suite.T(), err)
op2 := CreateWriteOp()
defer op2.Release()
op2.Create(CreateExclusive)
err = op2.Operate(suite.ioctx, "TestWriteOpCreate", OperationNoFlag)
assert.Error(suite.T(), err)
// ensure a nil ioctx triggers a panic
assert.Panics(suite.T(), func() {
op := CreateWriteOp()
defer op.Release()
op.Operate(nil, "foo", OperationNoFlag)
})
}
func (suite *RadosTestSuite) TestWriteOpCreateWithTimestamp() {
suite.SetupConnection()
oid := "TestWriteOpCreateWithTimestamp"
gts := timeStamp()
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
err := op.OperateWithMtime(suite.ioctx, oid, gts, OperationNoFlag)
assert.NoError(suite.T(), err)
s, err := suite.ioctx.Stat(oid)
assert.NoError(suite.T(), err)
statTime := s.ModTime.Unix()
assert.Equal(suite.T(), gts.Sec, statTime)
}
func (suite *RadosTestSuite) TestWriteOpSetOmap() {
suite.SetupConnection()
ta := assert.New(suite.T())
oid := "TestWriteOpSetOmap"
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
op.SetOmap(map[string][]byte{
"alice": []byte("car"),
"boss": []byte("office"),
"catbert": []byte("dungeon"),
})
err := op.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
// the 2nd set of omap values should not be applied because
// the Create will fail to exclusively make the object
op2 := CreateWriteOp()
defer op2.Release()
op.Create(CreateExclusive)
op.SetOmap(map[string][]byte{
"alice": []byte("home"),
"boss": []byte("golf course"),
"catbert": []byte("dungeon"),
})
err = op.Operate(suite.ioctx, oid, OperationNoFlag)
ta.Error(err)
fetched, err := suite.ioctx.GetOmapValues(oid, "", "", 10)
ta.NoError(err)
ta.Equal("car", string(fetched["alice"]))
ta.Equal("office", string(fetched["boss"]))
}
func (suite *RadosTestSuite) TestWriteOpRmOmapKeys() {
suite.SetupConnection()
ta := assert.New(suite.T())
oid := "TestWriteOpRmOmapKeys"
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
op.SetOmap(map[string][]byte{
"alice": []byte("car"),
"boss": []byte("office"),
"catbert": []byte("dungeon"),
})
err := op.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
op2 := CreateWriteOp()
defer op2.Release()
op2.Create(CreateIdempotent)
op2.SetOmap(map[string][]byte{
"dogbert": []byte("lab"),
})
op2.RmOmapKeys([]string{"catbert"})
err = op2.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
fetched, err := suite.ioctx.GetOmapValues(oid, "", "", 10)
ta.NoError(err)
ta.Len(fetched, 3)
ta.Equal("car", string(fetched["alice"]))
ta.Equal("office", string(fetched["boss"]))
ta.Equal("lab", string(fetched["dogbert"]))
ta.NotContains(fetched, "catbert")
}
func (suite *RadosTestSuite) TestWriteOpCleanOmap() {
suite.SetupConnection()
ta := assert.New(suite.T())
oid := "TestWriteOpCleanOmap"
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
op.SetOmap(map[string][]byte{
"alice": []byte("car"),
"boss": []byte("office"),
"catbert": []byte("dungeon"),
})
err := op.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
// this test simulates wanting to start a fresh new set of
// omap keys, atomically clearing and setting a new key & value.
op2 := CreateWriteOp()
defer op2.Release()
op2.Create(CreateIdempotent)
op2.CleanOmap()
op2.SetOmap(map[string][]byte{
"dogbert": []byte("lab"),
})
op2.RmOmapKeys([]string{"catbert"})
err = op2.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
fetched, err := suite.ioctx.GetOmapValues(oid, "", "", 10)
ta.NoError(err)
ta.Len(fetched, 1)
ta.Equal("lab", string(fetched["dogbert"]))
}
func (suite *RadosTestSuite) TestWriteOpAssertExists() {
suite.SetupConnection()
ta := assert.New(suite.T())
oid := "TestWriteOpRmOmapKeys"
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
err := op.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
op2 := CreateWriteOp()
defer op2.Release()
op2.AssertExists()
op2.CleanOmap()
err = op2.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
op3 := CreateWriteOp()
defer op3.Release()
op3.AssertExists()
op3.CleanOmap()
err = op3.Operate(suite.ioctx, oid+"dne", OperationNoFlag)
ta.Error(err)
}
func (suite *RadosTestSuite) TestWriteOpWrite() {
suite.SetupConnection()
ta := assert.New(suite.T())
oid := "TestWriteOpWrite"
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
op.Write([]byte("go-go-gadget"), 0)
op.Write([]byte("ceph project!"), 6)
err := op.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
d := make([]byte, 32)
l, err := suite.ioctx.Read(oid, d, 0)
ta.NoError(err)
ta.Equal("go-go-ceph project!", string(d[:l]))
}
func (suite *RadosTestSuite) TestWriteOpWriteFull() {
suite.SetupConnection()
ta := assert.New(suite.T())
oid := "TestWriteOpWriteFull"
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
op.WriteFull([]byte("one, two"))
op.WriteFull([]byte("buckle my shoe"))
err := op.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
d := make([]byte, 32)
l, err := suite.ioctx.Read(oid, d, 0)
ta.NoError(err)
ta.Equal("buckle my shoe", string(d[:l]))
}
func (suite *RadosTestSuite) TestWriteOpWriteSame() {
suite.SetupConnection()
ta := assert.New(suite.T())
oid := "TestWriteOpWriteSame"
op := CreateWriteOp()
defer op.Release()
op.Create(CreateIdempotent)
op.WriteSame([]byte("repetition "), 44, 0)
op.Write([]byte("is fun"), 44)
err := op.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
d := make([]byte, 64)
l, err := suite.ioctx.Read(oid, d, 0)
ta.NoError(err)
ta.Equal("repetition repetition repetition repetition is fun", string(d[:l]))
}
func TestWriteOpInvalid(t *testing.T) {
r := &WriteOp{}
err := r.Operate(&IOContext{}, "foo", 0)
assert.Error(t, err)
}