Skip to content

Commit d3bca10

Browse files
committed
Add test showing differences between Rosmar and CB Server for the multi-xattr ops
1 parent 45b3bbf commit d3bca10

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

base/collection_xattr_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ package base
1111
import (
1212
"errors"
1313
"fmt"
14+
"maps"
15+
"slices"
1416
"testing"
1517

1618
sgbucket "github.com/couchbase/sg-bucket"
19+
"github.com/stretchr/testify/assert"
1720
"github.com/stretchr/testify/require"
1821
)
1922

@@ -1649,3 +1652,114 @@ func requireDocFoundOrCasMismatchError(t testing.TB, err error) {
16491652
require.Fail(t, errMsg)
16501653
}
16511654
}
1655+
1656+
// TestDeleteWithXattrs tests various combinations of deleting documents (with zero to many xattrs, some of which may not exist) across bucket implementations to ensure consistency in behavior.
1657+
func TestDeleteWithXattrs(t *testing.T) {
1658+
ctx := TestCtx(t)
1659+
bucket := GetTestBucket(t)
1660+
defer bucket.Close(ctx)
1661+
1662+
col := bucket.GetSingleDataStore()
1663+
1664+
tests := []struct {
1665+
name string
1666+
xattrsValues map[string][]byte
1667+
xattrsToDelete []string
1668+
expectedXattrs []string
1669+
}{
1670+
{
1671+
name: "delete with no xattrs",
1672+
xattrsValues: nil,
1673+
xattrsToDelete: nil,
1674+
expectedXattrs: nil,
1675+
},
1676+
{
1677+
name: "delete one only existing xattr",
1678+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`)},
1679+
xattrsToDelete: []string{"xattr1"},
1680+
expectedXattrs: nil,
1681+
},
1682+
{
1683+
name: "delete two existing xattrs",
1684+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`), "xattr2": []byte(`{"c":"d"}`)},
1685+
xattrsToDelete: []string{"xattr1", "xattr2"},
1686+
expectedXattrs: nil,
1687+
},
1688+
{
1689+
name: "delete one xattr and one non-existing xattr",
1690+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`)},
1691+
xattrsToDelete: []string{"xattr1", "notexists"},
1692+
expectedXattrs: nil,
1693+
},
1694+
{
1695+
name: "delete one non-existing xattr",
1696+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`)},
1697+
xattrsToDelete: []string{"notexists"},
1698+
expectedXattrs: []string{"xattr1"},
1699+
},
1700+
{
1701+
name: "create and delete system xattr",
1702+
xattrsValues: map[string][]byte{"_sync": []byte(`{"a":"b"}`)},
1703+
xattrsToDelete: []string{"_sync"},
1704+
expectedXattrs: nil,
1705+
},
1706+
{
1707+
name: "create and delete normal and system xattr",
1708+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`), "_sync": []byte(`{"a":"b"}`)},
1709+
xattrsToDelete: []string{"_sync"},
1710+
expectedXattrs: nil, // user xattrs get removed along with regular delete...
1711+
},
1712+
{
1713+
name: "create normal and system and do regular delete",
1714+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`), "_sync": []byte(`{"a":"b"}`)},
1715+
xattrsToDelete: nil,
1716+
expectedXattrs: []string{"_sync"},
1717+
},
1718+
{
1719+
name: "create normal and system and delete system",
1720+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`), "_sync": []byte(`{"a":"b"}`)},
1721+
xattrsToDelete: []string{"_sync"},
1722+
expectedXattrs: []string{"xattr1"},
1723+
},
1724+
{
1725+
name: "create two system xattrs and delete one",
1726+
xattrsValues: map[string][]byte{"_sync": []byte(`{"a":"b"}`), "_globalSync": []byte(`{"a":"b"}`)},
1727+
xattrsToDelete: []string{"_sync"},
1728+
expectedXattrs: []string{"_globalSync"},
1729+
},
1730+
{
1731+
name: "create normal xattr and two system xattrs and delete one system xattr",
1732+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`), "_sync": []byte(`{"a":"b"}`), "_globalSync": []byte(`{"a":"b"}`)},
1733+
xattrsToDelete: []string{"_sync"},
1734+
expectedXattrs: []string{"_globalSync"}, // user xattrs get removed along with regular delete...
1735+
},
1736+
{
1737+
name: "create xattr and delete non-existing system xattr",
1738+
xattrsValues: map[string][]byte{"xattr1": []byte(`{"a":"b"}`)},
1739+
xattrsToDelete: []string{"_sync"},
1740+
expectedXattrs: []string{"xattr1"},
1741+
},
1742+
}
1743+
1744+
for _, test := range tests {
1745+
t.Run(test.name, func(t *testing.T) {
1746+
docID := t.Name()
1747+
1748+
_, err := col.WriteWithXattrs(ctx, docID, 0, 0, []byte(`{"foo": "bar"}`), test.xattrsValues, nil, nil)
1749+
require.NoError(t, err)
1750+
1751+
err = col.DeleteWithXattrs(ctx, docID, test.xattrsToDelete)
1752+
require.NoError(t, err)
1753+
1754+
v, xv, _, err := col.GetWithXattrs(ctx, docID, slices.Collect(maps.Keys(test.xattrsValues)))
1755+
if len(test.expectedXattrs) == 0 {
1756+
assert.Errorf(t, err, "Expected document and all xattrs to be deleted, but it still exists (no error on get)")
1757+
assert.Truef(t, IsDocNotFoundError(err), "Expected document to be deleted, but got an error other than not found: %v", err)
1758+
} else {
1759+
require.NoErrorf(t, err, "Expected document or at least one xattr to still exist with xattrs after deletion")
1760+
}
1761+
assert.Nil(t, v, "Expected document to be deleted, but it still exists")
1762+
assert.Equal(t, test.expectedXattrs, slices.Collect(maps.Keys(xv)), "Expected xattrs to match expected values after deletion")
1763+
})
1764+
}
1765+
}

0 commit comments

Comments
 (0)