2021-11-08 10:04:45 +00:00
|
|
|
package object_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
2023-04-13 11:15:35 +00:00
|
|
|
"encoding/hex"
|
|
|
|
"fmt"
|
2021-11-08 10:04:45 +00:00
|
|
|
"math/rand"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
v2object "github.com/nspcc-dev/neofs-api-go/v2/object"
|
2023-04-13 11:15:35 +00:00
|
|
|
"github.com/nspcc-dev/neofs-sdk-go/checksum"
|
2021-11-08 10:04:45 +00:00
|
|
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
2022-01-25 16:20:32 +00:00
|
|
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
2023-04-13 11:15:35 +00:00
|
|
|
"github.com/nspcc-dev/tzhash/tz"
|
2021-11-08 10:04:45 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
var eqV2Matches = map[object.SearchMatchType]v2object.MatchType{
|
|
|
|
object.MatchUnknown: v2object.MatchUnknown,
|
|
|
|
object.MatchStringEqual: v2object.MatchStringEqual,
|
|
|
|
object.MatchStringNotEqual: v2object.MatchStringNotEqual,
|
|
|
|
object.MatchNotPresent: v2object.MatchNotPresent,
|
|
|
|
object.MatchCommonPrefix: v2object.MatchCommonPrefix,
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMatch(t *testing.T) {
|
|
|
|
t.Run("known matches", func(t *testing.T) {
|
|
|
|
for matchType, matchTypeV2 := range eqV2Matches {
|
|
|
|
require.Equal(t, matchTypeV2, matchType.ToV2())
|
|
|
|
require.Equal(t, object.SearchMatchFromV2(matchTypeV2), matchType)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("unknown matches", func(t *testing.T) {
|
|
|
|
var unknownMatchType object.SearchMatchType
|
|
|
|
|
|
|
|
for matchType := range eqV2Matches {
|
|
|
|
unknownMatchType += matchType
|
|
|
|
}
|
|
|
|
|
|
|
|
unknownMatchType++
|
|
|
|
|
|
|
|
require.Equal(t, unknownMatchType.ToV2(), v2object.MatchUnknown)
|
|
|
|
|
|
|
|
var unknownMatchTypeV2 v2object.MatchType
|
|
|
|
|
|
|
|
for _, matchTypeV2 := range eqV2Matches {
|
|
|
|
unknownMatchTypeV2 += matchTypeV2
|
|
|
|
}
|
|
|
|
|
|
|
|
unknownMatchTypeV2++
|
|
|
|
|
|
|
|
require.Equal(t, object.SearchMatchFromV2(unknownMatchTypeV2), object.MatchUnknown)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFilter(t *testing.T) {
|
|
|
|
inputs := [][]string{
|
|
|
|
{"user-header", "user-value"},
|
|
|
|
}
|
|
|
|
|
|
|
|
filters := object.NewSearchFilters()
|
|
|
|
for i := range inputs {
|
|
|
|
filters.AddFilter(inputs[i][0], inputs[i][1], object.MatchStringEqual)
|
|
|
|
}
|
|
|
|
|
|
|
|
require.Len(t, filters, len(inputs))
|
|
|
|
for i := range inputs {
|
|
|
|
require.Equal(t, inputs[i][0], filters[i].Header())
|
|
|
|
require.Equal(t, inputs[i][1], filters[i].Value())
|
|
|
|
require.Equal(t, object.MatchStringEqual, filters[i].Operation())
|
|
|
|
}
|
|
|
|
|
|
|
|
v2 := filters.ToV2()
|
|
|
|
newFilters := object.NewSearchFiltersFromV2(v2)
|
|
|
|
require.Equal(t, filters, newFilters)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFilters_AddRootFilter(t *testing.T) {
|
|
|
|
fs := new(object.SearchFilters)
|
|
|
|
|
|
|
|
fs.AddRootFilter()
|
|
|
|
|
|
|
|
require.Len(t, *fs, 1)
|
|
|
|
|
|
|
|
f := (*fs)[0]
|
|
|
|
|
|
|
|
require.Equal(t, object.MatchUnknown, f.Operation())
|
|
|
|
require.Equal(t, v2object.FilterPropertyRoot, f.Header())
|
|
|
|
require.Equal(t, "", f.Value())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFilters_AddPhyFilter(t *testing.T) {
|
|
|
|
fs := new(object.SearchFilters)
|
|
|
|
|
|
|
|
fs.AddPhyFilter()
|
|
|
|
|
|
|
|
require.Len(t, *fs, 1)
|
|
|
|
|
|
|
|
f := (*fs)[0]
|
|
|
|
|
|
|
|
require.Equal(t, object.MatchUnknown, f.Operation())
|
|
|
|
require.Equal(t, v2object.FilterPropertyPhy, f.Header())
|
|
|
|
require.Equal(t, "", f.Value())
|
|
|
|
}
|
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
func testOID() oid.ID {
|
2021-11-08 10:04:45 +00:00
|
|
|
cs := [sha256.Size]byte{}
|
|
|
|
|
|
|
|
rand.Read(cs[:])
|
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
var id oid.ID
|
2021-11-08 10:04:45 +00:00
|
|
|
id.SetSHA256(cs)
|
|
|
|
|
|
|
|
return id
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFilters_AddParentIDFilter(t *testing.T) {
|
|
|
|
par := testOID()
|
|
|
|
|
|
|
|
fs := object.SearchFilters{}
|
|
|
|
fs.AddParentIDFilter(object.MatchStringEqual, par)
|
|
|
|
|
|
|
|
fsV2 := fs.ToV2()
|
|
|
|
|
|
|
|
require.Len(t, fsV2, 1)
|
|
|
|
|
|
|
|
require.Equal(t, v2object.FilterHeaderParent, fsV2[0].GetKey())
|
2022-05-31 06:55:08 +00:00
|
|
|
require.Equal(t, par.EncodeToString(), fsV2[0].GetValue())
|
2021-11-08 10:04:45 +00:00
|
|
|
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFilters_AddObjectIDFilter(t *testing.T) {
|
|
|
|
id := testOID()
|
|
|
|
|
|
|
|
fs := new(object.SearchFilters)
|
|
|
|
fs.AddObjectIDFilter(object.MatchStringEqual, id)
|
|
|
|
|
|
|
|
t.Run("v2", func(t *testing.T) {
|
|
|
|
fsV2 := fs.ToV2()
|
|
|
|
|
|
|
|
require.Len(t, fsV2, 1)
|
|
|
|
|
|
|
|
require.Equal(t, v2object.FilterHeaderObjectID, fsV2[0].GetKey())
|
2022-05-31 06:55:08 +00:00
|
|
|
require.Equal(t, id.EncodeToString(), fsV2[0].GetValue())
|
2021-11-08 10:04:45 +00:00
|
|
|
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFilters_AddSplitIDFilter(t *testing.T) {
|
|
|
|
id := object.NewSplitID()
|
|
|
|
|
|
|
|
fs := new(object.SearchFilters)
|
|
|
|
fs.AddSplitIDFilter(object.MatchStringEqual, id)
|
|
|
|
|
|
|
|
t.Run("v2", func(t *testing.T) {
|
|
|
|
fsV2 := fs.ToV2()
|
|
|
|
|
|
|
|
require.Len(t, fsV2, 1)
|
|
|
|
|
|
|
|
require.Equal(t, v2object.FilterHeaderSplitID, fsV2[0].GetKey())
|
|
|
|
require.Equal(t, id.String(), fsV2[0].GetValue())
|
|
|
|
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFilters_AddTypeFilter(t *testing.T) {
|
|
|
|
typ := object.TypeTombstone
|
|
|
|
|
|
|
|
fs := new(object.SearchFilters)
|
|
|
|
fs.AddTypeFilter(object.MatchStringEqual, typ)
|
|
|
|
|
|
|
|
t.Run("v2", func(t *testing.T) {
|
|
|
|
fsV2 := fs.ToV2()
|
|
|
|
|
|
|
|
require.Len(t, fsV2, 1)
|
|
|
|
|
|
|
|
require.Equal(t, v2object.FilterHeaderObjectType, fsV2[0].GetKey())
|
|
|
|
require.Equal(t, typ.String(), fsV2[0].GetValue())
|
|
|
|
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFiltersEncoding(t *testing.T) {
|
|
|
|
fs := object.NewSearchFilters()
|
|
|
|
fs.AddFilter("key 1", "value 2", object.MatchStringEqual)
|
|
|
|
fs.AddFilter("key 2", "value 2", object.MatchStringNotEqual)
|
|
|
|
fs.AddFilter("key 2", "value 2", object.MatchCommonPrefix)
|
|
|
|
|
|
|
|
t.Run("json", func(t *testing.T) {
|
|
|
|
data, err := fs.MarshalJSON()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
fs2 := object.NewSearchFilters()
|
|
|
|
require.NoError(t, fs2.UnmarshalJSON(data))
|
|
|
|
|
|
|
|
require.Equal(t, fs, fs2)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchMatchType_String(t *testing.T) {
|
|
|
|
toPtr := func(v object.SearchMatchType) *object.SearchMatchType {
|
|
|
|
return &v
|
|
|
|
}
|
|
|
|
|
|
|
|
testEnumStrings(t, new(object.SearchMatchType), []enumStringItem{
|
|
|
|
{val: toPtr(object.MatchCommonPrefix), str: "COMMON_PREFIX"},
|
|
|
|
{val: toPtr(object.MatchStringEqual), str: "STRING_EQUAL"},
|
|
|
|
{val: toPtr(object.MatchStringNotEqual), str: "STRING_NOT_EQUAL"},
|
|
|
|
{val: toPtr(object.MatchNotPresent), str: "NOT_PRESENT"},
|
|
|
|
{val: toPtr(object.MatchUnknown), str: "MATCH_TYPE_UNSPECIFIED"},
|
|
|
|
})
|
|
|
|
}
|
2023-04-13 11:15:35 +00:00
|
|
|
|
|
|
|
func testChecksumSha256() [sha256.Size]byte {
|
|
|
|
cs := [sha256.Size]byte{}
|
|
|
|
rand.Read(cs[:])
|
|
|
|
|
|
|
|
return cs
|
|
|
|
}
|
|
|
|
|
|
|
|
func testChecksumTZ() [tz.Size]byte {
|
|
|
|
cs := [tz.Size]byte{}
|
|
|
|
rand.Read(cs[:])
|
|
|
|
|
|
|
|
return cs
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFilters_AddPayloadHashFilter(t *testing.T) {
|
|
|
|
cs := testChecksumSha256()
|
|
|
|
|
|
|
|
fs := new(object.SearchFilters)
|
|
|
|
fs.AddPayloadHashFilter(object.MatchStringEqual, cs)
|
|
|
|
|
|
|
|
t.Run("v2", func(t *testing.T) {
|
|
|
|
fsV2 := fs.ToV2()
|
|
|
|
|
|
|
|
require.Len(t, fsV2, 1)
|
|
|
|
|
|
|
|
require.Equal(t, v2object.FilterHeaderPayloadHash, fsV2[0].GetKey())
|
|
|
|
require.Equal(t, hex.EncodeToString(cs[:]), fsV2[0].GetValue())
|
|
|
|
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func ExampleSearchFilters_AddPayloadHashFilter() {
|
|
|
|
hash, _ := hex.DecodeString("66842cfea090b1d906b52400fae49d86df078c0670f2bdd059ba289ebe24a498")
|
|
|
|
|
|
|
|
var v [sha256.Size]byte
|
|
|
|
copy(v[:], hash[:sha256.Size])
|
|
|
|
|
|
|
|
var cs checksum.Checksum
|
|
|
|
cs.SetSHA256(v)
|
|
|
|
|
|
|
|
fmt.Println(hex.EncodeToString(cs.Value()))
|
|
|
|
// Output: 66842cfea090b1d906b52400fae49d86df078c0670f2bdd059ba289ebe24a498
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchFilters_AddHomomorphicHashFilter(t *testing.T) {
|
|
|
|
cs := testChecksumTZ()
|
|
|
|
|
|
|
|
fs := new(object.SearchFilters)
|
|
|
|
fs.AddHomomorphicHashFilter(object.MatchStringEqual, cs)
|
|
|
|
|
|
|
|
t.Run("v2", func(t *testing.T) {
|
|
|
|
fsV2 := fs.ToV2()
|
|
|
|
|
|
|
|
require.Len(t, fsV2, 1)
|
|
|
|
|
|
|
|
require.Equal(t, v2object.FilterHeaderHomomorphicHash, fsV2[0].GetKey())
|
|
|
|
require.Equal(t, hex.EncodeToString(cs[:]), fsV2[0].GetValue())
|
|
|
|
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func ExampleSearchFilters_AddHomomorphicHashFilter() {
|
|
|
|
hash, _ := hex.DecodeString("7e302ebb3937e810feb501965580c746048db99cebd095c3ce27022407408bf904dde8d9aa8085d2cf7202345341cc947fa9d722c6b6699760d307f653815d0c")
|
|
|
|
|
|
|
|
var v [tz.Size]byte
|
|
|
|
copy(v[:], hash[:tz.Size])
|
|
|
|
|
|
|
|
var cs checksum.Checksum
|
|
|
|
cs.SetTillichZemor(v)
|
|
|
|
|
|
|
|
fmt.Println(hex.EncodeToString(cs.Value()))
|
|
|
|
// Output: 7e302ebb3937e810feb501965580c746048db99cebd095c3ce27022407408bf904dde8d9aa8085d2cf7202345341cc947fa9d722c6b6699760d307f653815d0c
|
|
|
|
}
|