[#180] eacl: add EqualTo for table

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
remotes/fyrchik/split-info-format
Denis Kirillov 2022-03-18 13:25:05 +03:00 committed by Alex Vanin
parent 2104945f9e
commit d568458fab
2 changed files with 174 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package eacl
import (
"bytes"
"crypto/sha256"
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
@ -199,3 +200,60 @@ func (t *Table) UnmarshalJSON(data []byte) error {
return nil
}
// EqualTo compares Table between each other.
func (t *Table) EqualTo(table *Table) bool {
if t == nil || table == nil {
return false
}
if !t.cid.Equal(table.cid) {
return false
}
if len(t.records) != len(table.records) {
return false
}
for i := 0; i < len(t.records); i++ {
tRec, tableRec := t.records[i], table.records[i]
if tRec.operation != tableRec.operation ||
tRec.action != tableRec.action {
return false
}
if len(tRec.filters) != len(tableRec.filters) ||
len(tRec.targets) != len(tableRec.targets) {
return false
}
for j := 0; j < len(tRec.filters); j++ {
if tRec.filters[j].from != tableRec.filters[j].from ||
tRec.filters[j].matcher != tableRec.filters[j].matcher ||
tRec.filters[j].Value() != tableRec.filters[j].Value() ||
tRec.filters[j].key.typ != tableRec.filters[j].key.typ ||
tRec.filters[j].key.str != tableRec.filters[j].key.str {
return false
}
}
for j := 0; j < len(tRec.targets); j++ {
if tRec.targets[j].role != tableRec.targets[j].role {
return false
}
if len(tRec.targets[j].keys) != len(tableRec.targets[j].keys) {
return false
}
tKeys, tableKeys := tRec.targets[j].keys, tableRec.targets[j].keys
for k := 0; k < len(tKeys); k++ {
if !bytes.Equal(tKeys[k], tableKeys[k]) {
return false
}
}
}
}
return true
}

View File

@ -0,0 +1,116 @@
package eacltest
import (
"bytes"
"math/rand"
"testing"
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
versiontest "github.com/nspcc-dev/neofs-sdk-go/version/test"
"github.com/stretchr/testify/require"
)
func baseBenchmarkTableBinaryComparison(b *testing.B, factor int) {
t := TableN(factor)
exp, err := t.Marshal()
require.NoError(b, err)
b.StopTimer()
b.ResetTimer()
b.StartTimer()
for i := 0; i < b.N; i++ {
got, _ := t.Marshal()
if !bytes.Equal(exp, got) {
b.Fail()
}
}
}
func baseBenchmarkTableEqualToComparison(b *testing.B, factor int) {
t := TableN(factor)
data, err := t.Marshal()
require.NoError(b, err)
t2 := eacl.NewTable()
err = t2.Unmarshal(data)
require.NoError(b, err)
b.StopTimer()
b.ResetTimer()
b.StartTimer()
for i := 0; i < b.N; i++ {
if !t.EqualTo(t2) {
b.Fail()
}
}
}
func BenchmarkTableBinaryComparison(b *testing.B) {
baseBenchmarkTableBinaryComparison(b, 1)
}
func BenchmarkTableEqualToComparison(b *testing.B) {
baseBenchmarkTableEqualToComparison(b, 1)
}
func BenchmarkTableBinaryComparison10(b *testing.B) {
baseBenchmarkTableBinaryComparison(b, 10)
}
func BenchmarkTableEqualToComparison10(b *testing.B) {
baseBenchmarkTableEqualToComparison(b, 10)
}
func BenchmarkTableBinaryComparison100(b *testing.B) {
baseBenchmarkTableBinaryComparison(b, 100)
}
func BenchmarkTableEqualToComparison100(b *testing.B) {
baseBenchmarkTableEqualToComparison(b, 100)
}
// Target returns random eacl.Target.
func TargetN(n int) *eacl.Target {
x := eacl.NewTarget()
x.SetRole(eacl.RoleSystem)
keys := make([][]byte, n)
for i := 0; i < n; i++ {
keys[i] = make([]byte, 32)
rand.Read(keys[i])
}
x.SetBinaryKeys(keys)
return x
}
// Record returns random eacl.Record.
func RecordN(n int) *eacl.Record {
x := eacl.NewRecord()
x.SetAction(eacl.ActionAllow)
x.SetOperation(eacl.OperationRangeHash)
x.SetTargets(*TargetN(n))
for i := 0; i < n; i++ {
x.AddFilter(eacl.HeaderFromObject, eacl.MatchStringEqual, "", cidtest.ID().String())
}
return x
}
func TableN(n int) *eacl.Table {
x := eacl.NewTable()
x.SetCID(cidtest.ID())
for i := 0; i < n; i++ {
x.AddRecord(RecordN(n))
}
x.SetVersion(*versiontest.Version())
return x
}