forked from TrueCloudLab/frostfs-contract
[#51] policy: Support Get and ListByPrefix methods
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
dd5919348d
commit
5cc34f98e9
4 changed files with 62 additions and 1 deletions
|
@ -1,2 +1,2 @@
|
||||||
name: "APE"
|
name: "APE"
|
||||||
safemethods: ["listChains"]
|
safemethods: ["listChains","getChain","listChainsByPrefix"]
|
||||||
|
|
|
@ -35,6 +35,17 @@ func AddChain(entity Kind, entityName, name string, chain []byte) {
|
||||||
storage.Put(ctx, key, chain)
|
storage.Put(ctx, key, chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetChain(entity Kind, entityName, name string) []byte {
|
||||||
|
ctx := storage.GetReadOnlyContext()
|
||||||
|
key := storageKey(entity, entityName, name)
|
||||||
|
data := storage.Get(ctx, key).([]byte)
|
||||||
|
if data == nil {
|
||||||
|
panic("not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
func RemoveChain(entity Kind, entityName string, name string) {
|
func RemoveChain(entity Kind, entityName string, name string) {
|
||||||
common.CheckAlphabetWitness()
|
common.CheckAlphabetWitness()
|
||||||
|
|
||||||
|
@ -77,3 +88,18 @@ func ListChains(namespace, container, name string) [][]byte {
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListChainsByPrefix list all chains for the provided kind and entity by prefix.
|
||||||
|
func ListChainsByPrefix(entity Kind, entityName, prefix string) [][]byte {
|
||||||
|
ctx := storage.GetReadOnlyContext()
|
||||||
|
|
||||||
|
result := [][]byte{}
|
||||||
|
|
||||||
|
keyPrefix := storageKey(entity, entityName, prefix)
|
||||||
|
it := storage.Find(ctx, keyPrefix, storage.ValuesOnly)
|
||||||
|
for iterator.Next(it) {
|
||||||
|
result = append(result, iterator.Value(it).([]byte))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
|
@ -52,11 +52,21 @@ func New(actor Actor, hash util.Uint160) *Contract {
|
||||||
return &Contract{ContractReader{actor, hash}, actor, hash}
|
return &Contract{ContractReader{actor, hash}, actor, hash}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetChain invokes `getChain` method of contract.
|
||||||
|
func (c *ContractReader) GetChain(entity *big.Int, entityName string, name string) ([]byte, error) {
|
||||||
|
return unwrap.Bytes(c.invoker.Call(c.hash, "getChain", entity, entityName, name))
|
||||||
|
}
|
||||||
|
|
||||||
// ListChains invokes `listChains` method of contract.
|
// ListChains invokes `listChains` method of contract.
|
||||||
func (c *ContractReader) ListChains(namespace string, container string, name string) ([]stackitem.Item, error) {
|
func (c *ContractReader) ListChains(namespace string, container string, name string) ([]stackitem.Item, error) {
|
||||||
return unwrap.Array(c.invoker.Call(c.hash, "listChains", namespace, container, name))
|
return unwrap.Array(c.invoker.Call(c.hash, "listChains", namespace, container, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListChainsByPrefix invokes `listChainsByPrefix` method of contract.
|
||||||
|
func (c *ContractReader) ListChainsByPrefix(entity *big.Int, entityName string, prefix string) ([]stackitem.Item, error) {
|
||||||
|
return unwrap.Array(c.invoker.Call(c.hash, "listChainsByPrefix", entity, entityName, prefix))
|
||||||
|
}
|
||||||
|
|
||||||
// AddChain creates a transaction invoking `addChain` method of the contract.
|
// AddChain creates a transaction invoking `addChain` method of the contract.
|
||||||
// This transaction is signed and immediately sent to the network.
|
// This transaction is signed and immediately sent to the network.
|
||||||
// The values returned are its hash, ValidUntilBlock value and error if any.
|
// The values returned are its hash, ValidUntilBlock value and error if any.
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package tests
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"path"
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/policy"
|
"git.frostfs.info/TrueCloudLab/frostfs-contract/policy"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -49,7 +51,10 @@ func TestPolicy(t *testing.T) {
|
||||||
checkChains(t, e, "mynamespace", "cnr1", "ingress", [][]byte{p1, p2, p3})
|
checkChains(t, e, "mynamespace", "cnr1", "ingress", [][]byte{p1, p2, p3})
|
||||||
|
|
||||||
e.Invoke(t, stackitem.Null{}, "addChain", policy.Container, "cnr1", "ingress:myrule3", p33)
|
e.Invoke(t, stackitem.Null{}, "addChain", policy.Container, "cnr1", "ingress:myrule3", p33)
|
||||||
|
checkChain(t, e, policy.Container, "cnr1", "ingress:myrule3", p33)
|
||||||
checkChains(t, e, "mynamespace", "cnr1", "ingress", [][]byte{p1, p2, p33}) // Override chain.
|
checkChains(t, e, "mynamespace", "cnr1", "ingress", [][]byte{p1, p2, p33}) // Override chain.
|
||||||
|
checkChainsByPrefix(t, e, policy.Container, "cnr1", "", [][]byte{p2, p33})
|
||||||
|
checkChainsByPrefix(t, e, policy.IAM, "", "", nil)
|
||||||
|
|
||||||
t.Run("removal", func(t *testing.T) {
|
t.Run("removal", func(t *testing.T) {
|
||||||
t.Run("wrong name", func(t *testing.T) {
|
t.Run("wrong name", func(t *testing.T) {
|
||||||
|
@ -70,6 +75,18 @@ func TestPolicy(t *testing.T) {
|
||||||
func checkChains(t *testing.T, e *neotest.ContractInvoker, namespace, container, name string, expected [][]byte) {
|
func checkChains(t *testing.T, e *neotest.ContractInvoker, namespace, container, name string, expected [][]byte) {
|
||||||
s, err := e.TestInvoke(t, "listChains", namespace, container, name)
|
s, err := e.TestInvoke(t, "listChains", namespace, container, name)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
checksChainsOnStack(t, s, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkChainsByPrefix(t *testing.T, e *neotest.ContractInvoker, kind byte, entityName, prefix string, expected [][]byte) {
|
||||||
|
s, err := e.TestInvoke(t, "listChainsByPrefix", kind, entityName, prefix)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
checksChainsOnStack(t, s, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checksChainsOnStack(t *testing.T, s *vm.Stack, expected [][]byte) {
|
||||||
require.Equal(t, 1, s.Len())
|
require.Equal(t, 1, s.Len())
|
||||||
|
|
||||||
if len(expected) == 0 {
|
if len(expected) == 0 {
|
||||||
|
@ -89,3 +106,11 @@ func checkChains(t *testing.T, e *neotest.ContractInvoker, namespace, container,
|
||||||
|
|
||||||
require.ElementsMatch(t, expected, actual)
|
require.ElementsMatch(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkChain(t *testing.T, e *neotest.ContractInvoker, kind byte, entityName, name string, expected []byte) {
|
||||||
|
s, err := e.TestInvoke(t, "getChain", kind, entityName, name)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, s.Len())
|
||||||
|
|
||||||
|
require.True(t, bytes.Equal(expected, s.Pop().Bytes()))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue