git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/object/search_test.go (about) 1 package object_test 2 3 import ( 4 "crypto/rand" 5 "crypto/sha256" 6 "testing" 7 8 v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object" 9 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" 10 oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" 11 "github.com/stretchr/testify/require" 12 ) 13 14 var eqV2Matches = map[object.SearchMatchType]v2object.MatchType{ 15 object.MatchUnknown: v2object.MatchUnknown, 16 object.MatchStringEqual: v2object.MatchStringEqual, 17 object.MatchStringNotEqual: v2object.MatchStringNotEqual, 18 object.MatchNotPresent: v2object.MatchNotPresent, 19 object.MatchCommonPrefix: v2object.MatchCommonPrefix, 20 } 21 22 func TestMatch(t *testing.T) { 23 t.Run("known matches", func(t *testing.T) { 24 for matchType, matchTypeV2 := range eqV2Matches { 25 require.Equal(t, matchTypeV2, matchType.ToV2()) 26 require.Equal(t, object.SearchMatchFromV2(matchTypeV2), matchType) 27 } 28 }) 29 30 t.Run("unknown matches", func(t *testing.T) { 31 var unknownMatchType object.SearchMatchType 32 33 for matchType := range eqV2Matches { 34 unknownMatchType += matchType 35 } 36 37 unknownMatchType++ 38 39 require.Equal(t, unknownMatchType.ToV2(), v2object.MatchUnknown) 40 41 var unknownMatchTypeV2 v2object.MatchType 42 43 for _, matchTypeV2 := range eqV2Matches { 44 unknownMatchTypeV2 += matchTypeV2 45 } 46 47 unknownMatchTypeV2++ 48 49 require.Equal(t, object.SearchMatchFromV2(unknownMatchTypeV2), object.MatchUnknown) 50 }) 51 } 52 53 func TestFilter(t *testing.T) { 54 inputs := [][]string{ 55 {"user-header", "user-value"}, 56 } 57 58 filters := object.NewSearchFilters() 59 for i := range inputs { 60 filters.AddFilter(inputs[i][0], inputs[i][1], object.MatchStringEqual) 61 } 62 63 require.Len(t, filters, len(inputs)) 64 for i := range inputs { 65 require.Equal(t, inputs[i][0], filters[i].Header()) 66 require.Equal(t, inputs[i][1], filters[i].Value()) 67 require.Equal(t, object.MatchStringEqual, filters[i].Operation()) 68 } 69 70 v2 := filters.ToV2() 71 newFilters := object.NewSearchFiltersFromV2(v2) 72 require.Equal(t, filters, newFilters) 73 } 74 75 func TestSearchFilters_AddRootFilter(t *testing.T) { 76 fs := new(object.SearchFilters) 77 78 fs.AddRootFilter() 79 80 require.Len(t, *fs, 1) 81 82 f := (*fs)[0] 83 84 require.Equal(t, object.MatchUnknown, f.Operation()) 85 require.Equal(t, v2object.FilterPropertyRoot, f.Header()) 86 require.Equal(t, "", f.Value()) 87 } 88 89 func TestSearchFilters_AddPhyFilter(t *testing.T) { 90 fs := new(object.SearchFilters) 91 92 fs.AddPhyFilter() 93 94 require.Len(t, *fs, 1) 95 96 f := (*fs)[0] 97 98 require.Equal(t, object.MatchUnknown, f.Operation()) 99 require.Equal(t, v2object.FilterPropertyPhy, f.Header()) 100 require.Equal(t, "", f.Value()) 101 } 102 103 func testOID() oid.ID { 104 cs := [sha256.Size]byte{} 105 106 rand.Read(cs[:]) 107 108 var id oid.ID 109 id.SetSHA256(cs) 110 111 return id 112 } 113 114 func TestSearchFilters_AddParentIDFilter(t *testing.T) { 115 par := testOID() 116 117 fs := object.SearchFilters{} 118 fs.AddParentIDFilter(object.MatchStringEqual, par) 119 120 fsV2 := fs.ToV2() 121 122 require.Len(t, fsV2, 1) 123 124 require.Equal(t, v2object.FilterHeaderParent, fsV2[0].GetKey()) 125 require.Equal(t, par.EncodeToString(), fsV2[0].GetValue()) 126 require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) 127 } 128 129 func TestSearchFilters_AddObjectIDFilter(t *testing.T) { 130 id := testOID() 131 132 fs := new(object.SearchFilters) 133 fs.AddObjectIDFilter(object.MatchStringEqual, id) 134 135 t.Run("v2", func(t *testing.T) { 136 fsV2 := fs.ToV2() 137 138 require.Len(t, fsV2, 1) 139 140 require.Equal(t, v2object.FilterHeaderObjectID, fsV2[0].GetKey()) 141 require.Equal(t, id.EncodeToString(), fsV2[0].GetValue()) 142 require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) 143 }) 144 } 145 146 func TestSearchFilters_AddSplitIDFilter(t *testing.T) { 147 id := object.NewSplitID() 148 149 fs := new(object.SearchFilters) 150 fs.AddSplitIDFilter(object.MatchStringEqual, id) 151 152 t.Run("v2", func(t *testing.T) { 153 fsV2 := fs.ToV2() 154 155 require.Len(t, fsV2, 1) 156 157 require.Equal(t, v2object.FilterHeaderSplitID, fsV2[0].GetKey()) 158 require.Equal(t, id.String(), fsV2[0].GetValue()) 159 require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) 160 }) 161 } 162 163 func TestSearchFilters_AddECParentFilter(t *testing.T) { 164 id := testOID() 165 166 fs := new(object.SearchFilters) 167 fs.AddECParentFilter(object.MatchStringEqual, id) 168 169 t.Run("v2", func(t *testing.T) { 170 fsV2 := fs.ToV2() 171 172 require.Len(t, fsV2, 1) 173 174 require.Equal(t, v2object.FilterHeaderECParent, fsV2[0].GetKey()) 175 require.Equal(t, id.String(), fsV2[0].GetValue()) 176 require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) 177 }) 178 } 179 180 func TestSearchFilters_AddTypeFilter(t *testing.T) { 181 typ := object.TypeTombstone 182 183 fs := new(object.SearchFilters) 184 fs.AddTypeFilter(object.MatchStringEqual, typ) 185 186 t.Run("v2", func(t *testing.T) { 187 fsV2 := fs.ToV2() 188 189 require.Len(t, fsV2, 1) 190 191 require.Equal(t, v2object.FilterHeaderObjectType, fsV2[0].GetKey()) 192 require.Equal(t, typ.String(), fsV2[0].GetValue()) 193 require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType()) 194 }) 195 } 196 197 func TestSearchFiltersEncoding(t *testing.T) { 198 fs := object.NewSearchFilters() 199 fs.AddFilter("key 1", "value 2", object.MatchStringEqual) 200 fs.AddFilter("key 2", "value 2", object.MatchStringNotEqual) 201 fs.AddFilter("key 2", "value 2", object.MatchCommonPrefix) 202 203 t.Run("json", func(t *testing.T) { 204 data, err := fs.MarshalJSON() 205 require.NoError(t, err) 206 207 fs2 := object.NewSearchFilters() 208 require.NoError(t, fs2.UnmarshalJSON(data)) 209 210 require.Equal(t, fs, fs2) 211 }) 212 } 213 214 func TestSearchMatchType_String(t *testing.T) { 215 toPtr := func(v object.SearchMatchType) *object.SearchMatchType { 216 return &v 217 } 218 219 testEnumStrings(t, new(object.SearchMatchType), []enumStringItem{ 220 {val: toPtr(object.MatchCommonPrefix), str: "COMMON_PREFIX"}, 221 {val: toPtr(object.MatchStringEqual), str: "STRING_EQUAL"}, 222 {val: toPtr(object.MatchStringNotEqual), str: "STRING_NOT_EQUAL"}, 223 {val: toPtr(object.MatchNotPresent), str: "NOT_PRESENT"}, 224 {val: toPtr(object.MatchUnknown), str: "MATCH_TYPE_UNSPECIFIED"}, 225 }) 226 }