github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/ais/test/namespace_test.go (about) 1 // Package integration_test. 2 /* 3 * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package integration_test 6 7 import ( 8 "testing" 9 10 "github.com/NVIDIA/aistore/api" 11 "github.com/NVIDIA/aistore/api/apc" 12 "github.com/NVIDIA/aistore/cmn" 13 "github.com/NVIDIA/aistore/tools" 14 "github.com/NVIDIA/aistore/tools/tassert" 15 "github.com/NVIDIA/aistore/tools/tlog" 16 ) 17 18 func listAllBuckets(t *testing.T, baseParams api.BaseParams, includeRemote bool, fltPresence int) cmn.Bcks { 19 buckets, err := api.ListBuckets(baseParams, cmn.QueryBcks{Provider: apc.AIS}, apc.FltPresent) 20 tassert.CheckFatal(t, err) 21 if includeRemote { 22 allRemaisBuckets, err := api.ListBuckets(baseParams, 23 cmn.QueryBcks{Provider: apc.AIS, Ns: cmn.NsAnyRemote}, fltPresence) 24 tassert.CheckFatal(t, err) 25 26 filtered := cmn.Bcks{} 27 for _, bck := range allRemaisBuckets { 28 if bck.Ns.UUID != tools.RemoteCluster.Alias || bck.Ns.UUID == tools.RemoteCluster.UUID { 29 filtered = append(filtered, bck) 30 } 31 } 32 buckets = append(buckets, filtered...) 33 34 // Make sure that listing with specific UUID also works and have similar outcome. 35 remoteClusterBuckets, err := api.ListBuckets(baseParams, 36 cmn.QueryBcks{Provider: apc.AIS, Ns: cmn.Ns{UUID: tools.RemoteCluster.UUID}}, 37 fltPresence) 38 tassert.CheckFatal(t, err) 39 40 // TODO -- FIXME: do intead smth like: `remoteClusterBuckets.Equal(allRemaisBuckets)` 41 tassert.Errorf( 42 t, len(remoteClusterBuckets) == len(allRemaisBuckets), 43 "specific namespace %q => %v, while all-remote %q => %v, where presence=%d\n", 44 cmn.Ns{UUID: tools.RemoteCluster.UUID}, remoteClusterBuckets, 45 cmn.NsAnyRemote, allRemaisBuckets, fltPresence, 46 ) 47 } 48 return buckets 49 } 50 51 func TestNamespace(t *testing.T) { 52 tests := []struct { 53 name string 54 remote bool 55 bck1 cmn.Bck 56 bck2 cmn.Bck 57 }{ 58 { 59 name: "global_and_local_namespace", 60 remote: false, 61 bck1: cmn.Bck{ 62 Name: "tmp", 63 Provider: apc.AIS, 64 }, 65 bck2: cmn.Bck{ 66 Name: "tmp", 67 Provider: apc.AIS, 68 Ns: cmn.Ns{ 69 UUID: "", 70 Name: "namespace", 71 }, 72 }, 73 }, 74 { 75 name: "two_local_namespaces", 76 remote: false, 77 bck1: cmn.Bck{ 78 Name: "tmp", 79 Provider: apc.AIS, 80 Ns: cmn.Ns{ 81 UUID: "", 82 Name: "ns1", 83 }, 84 }, 85 bck2: cmn.Bck{ 86 Name: "tmp", 87 Provider: apc.AIS, 88 Ns: cmn.Ns{ 89 UUID: "", 90 Name: "ns2", 91 }, 92 }, 93 }, 94 { 95 name: "global_namespaces_with_remote_cluster", 96 remote: true, 97 bck1: cmn.Bck{ 98 Name: "tmp", 99 Provider: apc.AIS, 100 }, 101 bck2: cmn.Bck{ 102 Name: "tmp", 103 Provider: apc.AIS, 104 Ns: cmn.Ns{ 105 UUID: tools.RemoteCluster.Alias, 106 Name: cmn.NsGlobal.Name, 107 }, 108 }, 109 }, 110 { 111 name: "namespaces_with_remote_cluster", 112 remote: true, 113 bck1: cmn.Bck{ 114 Name: "tmp", 115 Provider: apc.AIS, 116 Ns: cmn.Ns{ 117 UUID: "", 118 Name: "ns1", 119 }, 120 }, 121 bck2: cmn.Bck{ 122 Name: "tmp", 123 Provider: apc.AIS, 124 Ns: cmn.Ns{ 125 UUID: tools.RemoteCluster.Alias, 126 Name: "ns1", 127 }, 128 }, 129 }, 130 { 131 name: "namespaces_with_only_remote_cluster", 132 remote: true, 133 bck1: cmn.Bck{ 134 Name: "tmp", 135 Provider: apc.AIS, 136 Ns: cmn.Ns{ 137 UUID: tools.RemoteCluster.Alias, 138 Name: "ns1", 139 }, 140 }, 141 bck2: cmn.Bck{ 142 Name: "tmp", 143 Provider: apc.AIS, 144 Ns: cmn.Ns{ 145 UUID: tools.RemoteCluster.Alias, 146 Name: "ns2", 147 }, 148 }, 149 }, 150 } 151 152 var ( 153 proxyURL = tools.RandomProxyURL() 154 baseParams = tools.BaseAPIParams(proxyURL) 155 ) 156 157 for _, test := range tests { 158 t.Run(test.name, func(t *testing.T) { 159 var ( 160 m1 = ioContext{ 161 t: t, 162 num: 100, 163 bck: test.bck1, 164 } 165 m2 = ioContext{ 166 t: t, 167 num: 200, 168 bck: test.bck2, 169 } 170 ) 171 172 tools.CheckSkip(t, &tools.SkipTestArgs{ 173 RequiresRemoteCluster: test.remote, 174 }) 175 176 m1.init(true) 177 m2.init(true) 178 179 origBuckets := listAllBuckets(t, baseParams, test.remote, apc.FltExists) 180 if len(origBuckets) > 0 { 181 tlog.Logf("orig buckets %+v\n", origBuckets) 182 } 183 err := api.CreateBucket(baseParams, m1.bck, nil) 184 tassert.CheckFatal(t, err) 185 defer func() { 186 err = api.DestroyBucket(baseParams, m1.bck) 187 tassert.CheckFatal(t, err) 188 }() 189 190 err = api.CreateBucket(baseParams, m2.bck, nil) 191 tassert.CheckFatal(t, err) 192 defer func() { 193 err := api.DestroyBucket(baseParams, m2.bck) 194 tassert.CheckFatal(t, err) 195 }() 196 197 // Test listing buckets 198 newBuckets := listAllBuckets(t, baseParams, test.remote, apc.FltExists) 199 tlog.Logf("created %+v\n", newBuckets) 200 tassert.Errorf( 201 t, len(newBuckets)-len(origBuckets) == 2, 202 "number of buckets (%d) should be %d", len(newBuckets), len(origBuckets)+2, 203 ) 204 205 m1.puts() 206 m2.puts() 207 208 // Now remote bucket(s) must be present 209 locBuckets := listAllBuckets(t, baseParams, test.remote, apc.FltPresent) 210 tassert.CheckFatal(t, err) 211 tlog.Logf("present in BMD %+v\n", locBuckets) 212 tassert.Errorf( 213 t, len(locBuckets) == len(newBuckets), "number of buckets (%d: %v) should be (%d: %v)\n", 214 len(locBuckets), locBuckets, len(newBuckets), newBuckets, 215 ) 216 217 // Test listing objects 218 objects, err := api.ListObjects(baseParams, m1.bck, nil, api.ListArgs{}) 219 tassert.CheckFatal(t, err) 220 tassert.Errorf( 221 t, len(objects.Entries) == m1.num, 222 "number of entries (%d) should be (%d)", len(objects.Entries), m1.num, 223 ) 224 225 objects, err = api.ListObjects(baseParams, m2.bck, nil, api.ListArgs{}) 226 tassert.CheckFatal(t, err) 227 tassert.Errorf( 228 t, len(objects.Entries) == m2.num, 229 "number of entries (%d) should be (%d)", len(objects.Entries), m2.num, 230 ) 231 232 // Test bucket summary 233 var ( 234 summaries cmn.AllBsummResults 235 xids []string 236 ) 237 for _, bck := range locBuckets { 238 xid, summ, err := api.GetBucketSummary(baseParams, cmn.QueryBcks(bck), 239 nil /*bck present true*/, api.BsummArgs{}) 240 tassert.CheckFatal(t, err) 241 summaries = append(summaries, summ[0]) 242 xids = append(xids, xid) 243 } 244 tassert.Errorf(t, len(summaries) == len(locBuckets), "%s-%v: number of summaries (%d) should be %d", 245 apc.ActSummaryBck, xids, len(summaries), len(locBuckets)) 246 247 bck1Found, bck2Found := false, false 248 for _, summary := range summaries { 249 if m1.bck.Ns.UUID == tools.RemoteCluster.Alias { 250 m1.bck.Ns.UUID = tools.RemoteCluster.UUID 251 } 252 if m2.bck.Ns.UUID == tools.RemoteCluster.Alias { 253 m2.bck.Ns.UUID = tools.RemoteCluster.UUID 254 } 255 256 if summary.Bck.Equal(&m1.bck) { 257 bck1Found = true 258 tassert.Errorf( 259 t, summary.ObjCount.Present == uint64(m1.num), 260 "number of objects (%d) should be (%d)", summary.ObjCount, m1.num, 261 ) 262 } else if summary.Bck.Equal(&m2.bck) { 263 bck2Found = true 264 tassert.Errorf( 265 t, summary.ObjCount.Present == uint64(m2.num), 266 "number of objects (%d) should be (%d)", summary.ObjCount, m2.num, 267 ) 268 } 269 } 270 tassert.Errorf(t, bck1Found, "%s not found in %v summ", m1.bck, summaries) 271 tassert.Errorf(t, bck2Found, "%s not found in %v summ", m2.bck, summaries) 272 m1.gets(nil, false) 273 m2.gets(nil, false) 274 275 m1.ensureNoGetErrors() 276 m2.ensureNoGetErrors() 277 }) 278 } 279 } 280 281 func TestRemoteWithAliasAndUUID(t *testing.T) { 282 tools.CheckSkip(t, &tools.SkipTestArgs{ 283 RequiresRemoteCluster: true, 284 }) 285 286 // TODO: make it work 287 t.Skip("NYI") 288 289 var ( 290 alias = tools.RemoteCluster.Alias 291 uuid = tools.RemoteCluster.UUID 292 293 proxyURL = tools.RandomProxyURL() 294 baseParams = tools.BaseAPIParams(proxyURL) 295 296 m1 = ioContext{ 297 t: t, 298 num: 100, 299 bck: cmn.Bck{Name: "tmp", Ns: cmn.Ns{UUID: alias}}, 300 } 301 m2 = ioContext{ 302 t: t, 303 num: 200, 304 bck: cmn.Bck{Name: "tmp", Ns: cmn.Ns{UUID: uuid}}, 305 } 306 ) 307 308 m1.init(true) 309 m2.init(true) 310 311 err := api.CreateBucket(baseParams, m1.bck, nil) 312 tassert.CheckFatal(t, err) 313 defer func() { 314 err := api.DestroyBucket(baseParams, m1.bck) 315 tassert.CheckFatal(t, err) 316 }() 317 318 m1.puts() 319 m2.puts() 320 321 // TODO: works until this point 322 323 buckets, err := api.ListBuckets(baseParams, cmn.QueryBcks{Provider: apc.AIS}, apc.FltExists) 324 tassert.CheckFatal(t, err) 325 tassert.Fatalf( 326 t, len(buckets) == 1, 327 "number of buckets (%d) should be equal to 1", len(buckets), 328 ) 329 330 for _, bck := range []cmn.Bck{m1.bck, m2.bck} { 331 objects, err := api.ListObjects(baseParams, bck, nil, api.ListArgs{}) 332 tassert.CheckFatal(t, err) 333 tassert.Errorf( 334 t, len(objects.Entries) == m1.num+m2.num, 335 "number of entries (%d) should be equal to (%d)", len(objects.Entries), m1.num+m2.num, 336 ) 337 } 338 } 339 340 func TestRemoteWithSilentBucketDestroy(t *testing.T) { 341 tools.CheckSkip(t, &tools.SkipTestArgs{ 342 RequiresRemoteCluster: true, 343 }) 344 345 // TODO: make it work 346 t.Skip("NYI") 347 348 var ( 349 proxyURL = tools.RandomProxyURL() 350 baseParams = tools.BaseAPIParams(proxyURL) 351 remoteBP = tools.BaseAPIParams(tools.RemoteCluster.URL) 352 353 m = ioContext{ 354 t: t, 355 num: 100, 356 bck: cmn.Bck{Ns: cmn.Ns{UUID: tools.RemoteCluster.Alias}}, 357 } 358 ) 359 360 m.init(true /*cleanup*/) 361 362 err := api.CreateBucket(baseParams, m.bck, nil) 363 tassert.CheckFatal(t, err) 364 defer func() { 365 // Delete just in case something goes wrong (therefore ignoring error) 366 api.DestroyBucket(baseParams, m.bck) 367 }() 368 369 m.puts() 370 m.gets(nil, false) 371 372 err = api.DestroyBucket(remoteBP, cmn.Bck{Name: m.bck.Name}) 373 tassert.CheckFatal(t, err) 374 375 // Check that bucket is still cached 376 buckets, err := api.ListBuckets(baseParams, cmn.QueryBcks{Provider: apc.AIS}, apc.FltPresent) 377 tassert.CheckFatal(t, err) 378 tassert.Fatalf(t, len(buckets) == 1, "number of buckets (%d) should be 1", len(buckets)) 379 380 // Test listing objects 381 _, err = api.ListObjects(baseParams, m.bck, nil, api.ListArgs{}) 382 tassert.Fatalf(t, err != nil, "expected list-objects to fail w/ \"bucket does not exist\"") 383 384 // TODO: it works until this point 385 386 // Check that bucket is no longer present 387 buckets, err = api.ListBuckets(baseParams, cmn.QueryBcks{Provider: apc.AIS}, apc.FltPresent) 388 tassert.CheckFatal(t, err) 389 tassert.Fatalf(t, len(buckets) == 0, "number of buckets (%d) should be 0 (zero)", len(buckets)) 390 }