package placement_test import ( "strconv" "testing" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object_manager/placement" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test" netmapSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" "github.com/stretchr/testify/require" ) func TestContainerNodesCache(t *testing.T) { const size = 3 nodes := [6]netmapSDK.NodeInfo{} for i := range nodes { nodes[i].SetAttribute("ATTR", strconv.Itoa(i)) } nm := func(epoch uint64, nodes []netmapSDK.NodeInfo) *netmapSDK.NetMap { var nm netmapSDK.NetMap nm.SetEpoch(epoch) nm.SetNodes(nodes) return &nm } var pp netmapSDK.PlacementPolicy require.NoError(t, pp.DecodeString("REP 1")) t.Run("update netmap on the new epoch", func(t *testing.T) { c := placement.NewContainerNodesCache(size) cnr := cidtest.ID() res, err := c.ContainerNodes(nm(1, nodes[0:1]), cnr, pp) require.NoError(t, err) // Use other nodes in the argument to ensure the result is taken from cache. resCached, err := c.ContainerNodes(nm(1, nodes[1:2]), cnr, pp) require.NoError(t, err) require.Equal(t, res, resCached) // Update epoch, netmap should be purged. resCached, err = c.ContainerNodes(nm(2, nodes[2:3]), cnr, pp) require.NoError(t, err) require.NotEqual(t, res, resCached) }) t.Run("cache uses container as a key", func(t *testing.T) { c := placement.NewContainerNodesCache(size) res1, err := c.ContainerNodes(nm(1, nodes[0:1]), cidtest.ID(), pp) require.NoError(t, err) res2, err := c.ContainerNodes(nm(1, nodes[1:2]), cidtest.ID(), pp) require.NoError(t, err) require.NotEqual(t, res1, res2) }) t.Run("cache respects size parameter", func(t *testing.T) { c := placement.NewContainerNodesCache(size) nm1 := nm(1, nodes[0:1]) nm2 := nm(1, nodes[1:2]) cnr := [size * 2]cid.ID{} res := [size * 2][][]netmapSDK.NodeInfo{} for i := 0; i < size*2; i++ { cnr[i] = cidtest.ID() var err error res[i], err = c.ContainerNodes(nm1, cnr[i], pp) require.NoError(t, err) } for i := size; i < size*2; i++ { r, err := c.ContainerNodes(nm2, cnr[i], pp) require.NoError(t, err) require.Equal(t, res[i], r) } for i := 0; i < size; i++ { r, err := c.ContainerNodes(nm2, cnr[i], pp) require.NoError(t, err) require.NotEqual(t, res[i], r) } }) t.Run("the error is propagated", func(t *testing.T) { var pp netmapSDK.PlacementPolicy require.NoError(t, pp.DecodeString("REP 1 SELECT 1 FROM X FILTER ATTR EQ 42 AS X")) c := placement.NewContainerNodesCache(size) _, err := c.ContainerNodes(nm(1, nodes[0:1]), cidtest.ID(), pp) require.Error(t, err) }) }