2022-06-15 19:08:19 +00:00
|
|
|
package netmap_test
|
2021-10-27 10:00:35 +00:00
|
|
|
|
|
|
|
import (
|
2023-10-26 10:15:40 +00:00
|
|
|
"strings"
|
2021-10-27 10:00:35 +00:00
|
|
|
"testing"
|
|
|
|
|
2023-03-07 11:20:03 +00:00
|
|
|
. "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
|
|
|
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test"
|
2021-10-27 10:00:35 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2022-06-15 19:08:19 +00:00
|
|
|
func TestPlacementPolicyEncoding(t *testing.T) {
|
|
|
|
v := netmaptest.PlacementPolicy()
|
|
|
|
|
|
|
|
t.Run("binary", func(t *testing.T) {
|
|
|
|
var v2 PlacementPolicy
|
|
|
|
require.NoError(t, v2.Unmarshal(v.Marshal()))
|
|
|
|
|
|
|
|
require.Equal(t, v, v2)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("json", func(t *testing.T) {
|
|
|
|
data, err := v.MarshalJSON()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
var v2 PlacementPolicy
|
|
|
|
require.NoError(t, v2.UnmarshalJSON(data))
|
|
|
|
|
|
|
|
require.Equal(t, v, v2)
|
|
|
|
})
|
|
|
|
}
|
2023-07-13 13:12:47 +00:00
|
|
|
|
2023-10-26 10:15:40 +00:00
|
|
|
func TestPlacementPolicyWriteString(t *testing.T) {
|
2023-11-21 09:57:35 +00:00
|
|
|
testCases := []struct {
|
2023-10-26 10:15:40 +00:00
|
|
|
name string
|
|
|
|
input string
|
|
|
|
output string // If the output is empty, make it equal to input.
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "no compound operators",
|
|
|
|
input: `REP 1
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM Color
|
|
|
|
FILTER Color EQ Red AS Color`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no brackets in single level same-operator chain",
|
|
|
|
input: `REP 1
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM Color
|
|
|
|
FILTER Color EQ Red OR Color EQ Blue OR Color EQ Green AS Color`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no brackets aroung higher precedence op",
|
|
|
|
input: `REP 1
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM Color
|
|
|
|
FILTER Color EQ Red OR Color EQ Blue AND Color NE Green AS Color`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no brackets aroung higher precedence op, even if present in the input",
|
|
|
|
input: `REP 1
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM Color
|
|
|
|
FILTER Color EQ Red OR (Color EQ Blue AND Color NE Green) AS Color`,
|
|
|
|
output: `REP 1
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM Color
|
|
|
|
FILTER Color EQ Red OR Color EQ Blue AND Color NE Green AS Color`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "brackets aroung lower precedence op",
|
|
|
|
input: `REP 1
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM Color
|
|
|
|
FILTER (Color EQ Red OR Color EQ Blue) AND Color NE Green AS Color`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no extra brackets for bracketed same-operator chain",
|
|
|
|
input: `REP 1
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM Color
|
|
|
|
FILTER (Color EQ Red OR Color EQ Blue OR Color EQ Yellow) AND Color NE Green AS Color`,
|
|
|
|
},
|
2024-09-17 14:32:56 +00:00
|
|
|
{
|
|
|
|
name: "non-ascii attributes in SELECT IN",
|
|
|
|
input: `REP 1
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 IN SAME 'Цвет' FROM Colorful
|
|
|
|
FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful`,
|
|
|
|
},
|
2023-10-26 10:15:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
var p PlacementPolicy
|
|
|
|
require.NoError(t, p.DecodeString(tc.input))
|
|
|
|
|
|
|
|
var sb strings.Builder
|
|
|
|
require.NoError(t, p.WriteStringTo(&sb))
|
|
|
|
|
|
|
|
if tc.output == "" {
|
|
|
|
require.Equal(t, tc.input, sb.String())
|
|
|
|
} else {
|
|
|
|
require.Equal(t, tc.output, sb.String())
|
|
|
|
|
|
|
|
var p1 PlacementPolicy
|
|
|
|
require.NoError(t, p1.DecodeString(tc.output))
|
|
|
|
require.Equal(t, p, p1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-13 13:12:47 +00:00
|
|
|
func TestDecodeSelectFilterExpr(t *testing.T) {
|
|
|
|
for _, s := range []string{
|
|
|
|
"SELECT 1 FROM *",
|
|
|
|
"FILTER Color EQ 'Red' AS RedNode",
|
|
|
|
`
|
|
|
|
FILTER Color EQ 'Red' AS RedNode
|
|
|
|
FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode
|
|
|
|
`,
|
|
|
|
`
|
|
|
|
SELECT 1 FROM RedCircleNode
|
|
|
|
FILTER Color EQ 'Red' AS RedNode
|
|
|
|
FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode
|
|
|
|
`,
|
|
|
|
`
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM RedCircleNode
|
|
|
|
FILTER Color EQ 'Red' AS RedNode
|
|
|
|
FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode
|
|
|
|
`,
|
2024-06-24 11:45:59 +00:00
|
|
|
`
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 FROM R
|
|
|
|
FILTER Color LIKE 'R' AS R
|
|
|
|
`,
|
2024-09-17 14:32:56 +00:00
|
|
|
`
|
|
|
|
CBF 1
|
|
|
|
SELECT 1 IN SAME 'Цвет' FROM Colorful
|
|
|
|
FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful
|
|
|
|
`,
|
2023-07-13 13:12:47 +00:00
|
|
|
} {
|
|
|
|
_, err := DecodeSelectFilterString(s)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
}
|