frostfs-node/pkg/util/attributes/parser_test.go
Alex Vanin f9218bf84f [] util/attributes: Restore escape characters after caching the result
As soon as resulting list and cache operate with the attribute pointer,
we can add attribute structure immediately and set restored key and
value of the attribute later.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
2021-09-01 14:29:26 +03:00

120 lines
3.1 KiB
Go

package attributes_test
import (
"testing"
"github.com/nspcc-dev/neofs-node/pkg/util/attributes"
"github.com/stretchr/testify/require"
)
func TestParseV2Attributes(t *testing.T) {
t.Run("empty", func(t *testing.T) {
attrs, err := attributes.ParseV2Attributes(nil, nil)
require.NoError(t, err)
require.Len(t, attrs, 0)
})
t.Run("non unique bucket keys", func(t *testing.T) {
good := []string{
"StorageType:HDD/RPM:7200",
"StorageType:HDD/SMR:True",
}
_, err := attributes.ParseV2Attributes(good, nil)
require.NoError(t, err)
bad := append(good, "StorageType:SSD/Cell:QLC")
_, err = attributes.ParseV2Attributes(bad, nil)
require.Error(t, err)
})
t.Run("malformed", func(t *testing.T) {
_, err := attributes.ParseV2Attributes([]string{"..."}, nil)
require.Error(t, err)
_, err = attributes.ParseV2Attributes([]string{"a:b", ""}, nil)
require.Error(t, err)
_, err = attributes.ParseV2Attributes([]string{"//"}, nil)
require.Error(t, err)
})
t.Run("unexpected", func(t *testing.T) {
unexpectedBucket := []string{
"Location:Europe/City:Moscow",
"Price:100",
}
_, err := attributes.ParseV2Attributes(unexpectedBucket, []string{"Price"})
require.Error(t, err)
})
t.Run("correct", func(t *testing.T) {
from := []string{
"/Location:Europe/Country:Sweden/City:Stockholm",
"/StorageType:HDD/RPM:7200",
}
attrs, err := attributes.ParseV2Attributes(from, nil)
require.NoError(t, err)
require.Len(t, attrs, 5)
})
t.Run("escape characters", func(t *testing.T) {
from := []string{
`/K\:ey1:V\/alue\\/Ke\/y2:Va\:lue`,
}
attrs, err := attributes.ParseV2Attributes(from, nil)
require.NoError(t, err)
require.Equal(t, `K:ey1`, attrs[0].Key())
require.Equal(t, `V/alue\`, attrs[0].Value())
require.Equal(t, `Ke/y2`, attrs[1].Key())
require.Equal(t, `Va:lue`, attrs[1].Value())
})
t.Run("same attributes", func(t *testing.T) {
from := []string{"/a:b", "/a:b"}
attrs, err := attributes.ParseV2Attributes(from, nil)
require.NoError(t, err)
require.Len(t, attrs, 1)
t.Run("with escape characters", func(t *testing.T) {
from = []string{`/a\::b\/`, `/a\::b\/`}
attrs, err := attributes.ParseV2Attributes(from, nil)
require.NoError(t, err)
require.Len(t, attrs, 1)
})
})
t.Run("multiple parents", func(t *testing.T) {
from := []string{
"/parent1:x/child:x",
"/parent2:x/child:x",
"/parent2:x/child:x/subchild:x",
}
attrs, err := attributes.ParseV2Attributes(from, nil)
require.NoError(t, err)
var flag bool
for _, attr := range attrs {
if attr.Key() == "child" {
flag = true
require.Equal(t, []string{"parent1", "parent2"}, attr.ParentKeys())
}
}
require.True(t, flag)
})
t.Run("consistent order in chain", func(t *testing.T) {
from := []string{"/a:1/b:2/c:3"}
for i := 0; i < 10000; i++ {
attrs, err := attributes.ParseV2Attributes(from, nil)
require.NoError(t, err)
require.Equal(t, "a", attrs[0].Key())
require.Equal(t, "1", attrs[0].Value())
require.Equal(t, "b", attrs[1].Key())
require.Equal(t, "2", attrs[1].Value())
require.Equal(t, "c", attrs[2].Key())
require.Equal(t, "3", attrs[2].Value())
}
})
}