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  }