git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/netmap/policy_test.go (about)

     1  package netmap_test
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	. "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
     8  	netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestPlacementPolicyEncoding(t *testing.T) {
    13  	v := netmaptest.PlacementPolicy()
    14  
    15  	t.Run("binary", func(t *testing.T) {
    16  		var v2 PlacementPolicy
    17  		require.NoError(t, v2.Unmarshal(v.Marshal()))
    18  
    19  		require.Equal(t, v, v2)
    20  	})
    21  
    22  	t.Run("json", func(t *testing.T) {
    23  		data, err := v.MarshalJSON()
    24  		require.NoError(t, err)
    25  
    26  		var v2 PlacementPolicy
    27  		require.NoError(t, v2.UnmarshalJSON(data))
    28  
    29  		require.Equal(t, v, v2)
    30  	})
    31  }
    32  
    33  func TestPlacementPolicyWriteString(t *testing.T) {
    34  	testCases := []struct {
    35  		name   string
    36  		input  string
    37  		output string // If the output is empty, make it equal to input.
    38  	}{
    39  		{
    40  			name: "no compound operators",
    41  			input: `REP 1
    42  CBF 1
    43  SELECT 1 FROM Color
    44  FILTER Color EQ Red AS Color`,
    45  		},
    46  		{
    47  			name: "no brackets in single level same-operator chain",
    48  			input: `REP 1
    49  CBF 1
    50  SELECT 1 FROM Color
    51  FILTER Color EQ Red OR Color EQ Blue OR Color EQ Green AS Color`,
    52  		},
    53  		{
    54  			name: "no brackets aroung higher precedence op",
    55  			input: `REP 1
    56  CBF 1
    57  SELECT 1 FROM Color
    58  FILTER Color EQ Red OR Color EQ Blue AND Color NE Green AS Color`,
    59  		},
    60  		{
    61  			name: "no brackets aroung higher precedence op, even if present in the input",
    62  			input: `REP 1
    63  CBF 1
    64  SELECT 1 FROM Color
    65  FILTER Color EQ Red OR (Color EQ Blue AND Color NE Green) AS Color`,
    66  			output: `REP 1
    67  CBF 1
    68  SELECT 1 FROM Color
    69  FILTER Color EQ Red OR Color EQ Blue AND Color NE Green AS Color`,
    70  		},
    71  		{
    72  			name: "brackets aroung lower precedence op",
    73  			input: `REP 1
    74  CBF 1
    75  SELECT 1 FROM Color
    76  FILTER (Color EQ Red OR Color EQ Blue) AND Color NE Green AS Color`,
    77  		},
    78  		{
    79  			name: "no extra brackets for bracketed same-operator chain",
    80  			input: `REP 1
    81  CBF 1
    82  SELECT 1 FROM Color
    83  FILTER (Color EQ Red OR Color EQ Blue OR Color EQ Yellow) AND Color NE Green AS Color`,
    84  		},
    85  		{
    86  			name: "non-ascii attributes in SELECT IN",
    87  			input: `REP 1
    88  CBF 1
    89  SELECT 1 IN SAME 'Цвет' FROM Colorful
    90  FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful`,
    91  		},
    92  	}
    93  
    94  	for _, tc := range testCases {
    95  		var p PlacementPolicy
    96  		require.NoError(t, p.DecodeString(tc.input))
    97  
    98  		var sb strings.Builder
    99  		require.NoError(t, p.WriteStringTo(&sb))
   100  
   101  		if tc.output == "" {
   102  			require.Equal(t, tc.input, sb.String())
   103  		} else {
   104  			require.Equal(t, tc.output, sb.String())
   105  
   106  			var p1 PlacementPolicy
   107  			require.NoError(t, p1.DecodeString(tc.output))
   108  			require.Equal(t, p, p1)
   109  		}
   110  	}
   111  }
   112  
   113  func TestDecodeSelectFilterExpr(t *testing.T) {
   114  	for _, s := range []string{
   115  		"SELECT 1 FROM *",
   116  		"FILTER Color EQ 'Red' AS RedNode",
   117  		`
   118  		  FILTER Color EQ 'Red' AS RedNode
   119  		  FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode
   120  		`,
   121  		`
   122  		  SELECT 1 FROM RedCircleNode
   123  		  FILTER Color EQ 'Red' AS RedNode
   124  		  FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode
   125  		`,
   126  		`
   127  		  CBF 1
   128  		  SELECT 1 FROM RedCircleNode
   129  		  FILTER Color EQ 'Red' AS RedNode
   130  		  FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode
   131  		`,
   132  		`
   133  		  CBF 1
   134  		  SELECT 1 FROM R
   135  		  FILTER Color LIKE 'R' AS R
   136  		`,
   137  		`
   138  		  CBF 1
   139  		  SELECT 1 IN SAME 'Цвет' FROM Colorful
   140  		  FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful
   141  		`,
   142  	} {
   143  		_, err := DecodeSelectFilterString(s)
   144  		require.NoError(t, err)
   145  	}
   146  }