storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/storage-rest_test.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2018 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package cmd
    18  
    19  import (
    20  	"context"
    21  	"io/ioutil"
    22  	"net/http/httptest"
    23  	"os"
    24  	"reflect"
    25  	"testing"
    26  
    27  	"github.com/gorilla/mux"
    28  
    29  	"storj.io/minio/cmd/config"
    30  	xnet "storj.io/minio/pkg/net"
    31  )
    32  
    33  ///////////////////////////////////////////////////////////////////////////////
    34  //
    35  // Storage REST server, storageRESTReceiver and StorageRESTClient are
    36  // inter-dependent, below test functions are sufficient to test all of them.
    37  //
    38  ///////////////////////////////////////////////////////////////////////////////
    39  
    40  func testStorageAPIDiskInfo(t *testing.T, storage StorageAPI) {
    41  	testCases := []struct {
    42  		expectErr bool
    43  	}{
    44  		{true},
    45  	}
    46  
    47  	for i, testCase := range testCases {
    48  		_, err := storage.DiskInfo(context.Background())
    49  		expectErr := (err != nil)
    50  
    51  		if expectErr != testCase.expectErr {
    52  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
    53  		}
    54  		if err != errUnformattedDisk {
    55  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, errUnformattedDisk, err)
    56  		}
    57  	}
    58  }
    59  
    60  func testStorageAPIMakeVol(t *testing.T, storage StorageAPI) {
    61  	testCases := []struct {
    62  		volumeName string
    63  		expectErr  bool
    64  	}{
    65  		{"foo", false},
    66  		// volume exists error.
    67  		{"foo", true},
    68  	}
    69  
    70  	for i, testCase := range testCases {
    71  		err := storage.MakeVol(context.Background(), testCase.volumeName)
    72  		expectErr := (err != nil)
    73  
    74  		if expectErr != testCase.expectErr {
    75  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
    76  		}
    77  	}
    78  }
    79  
    80  func testStorageAPIListVols(t *testing.T, storage StorageAPI) {
    81  	testCases := []struct {
    82  		volumeNames    []string
    83  		expectedResult []VolInfo
    84  		expectErr      bool
    85  	}{
    86  		{nil, []VolInfo{{Name: ".minio.sys"}}, false},
    87  		{[]string{"foo"}, []VolInfo{{Name: ".minio.sys"}, {Name: "foo"}}, false},
    88  	}
    89  
    90  	for i, testCase := range testCases {
    91  		for _, volumeName := range testCase.volumeNames {
    92  			err := storage.MakeVol(context.Background(), volumeName)
    93  			if err != nil {
    94  				t.Fatalf("unexpected error %v", err)
    95  			}
    96  		}
    97  
    98  		result, err := storage.ListVols(context.Background())
    99  		expectErr := (err != nil)
   100  
   101  		if expectErr != testCase.expectErr {
   102  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   103  		}
   104  
   105  		if !testCase.expectErr {
   106  			if len(result) != len(testCase.expectedResult) {
   107  				t.Fatalf("case %v: result: expected: %+v, got: %+v", i+1, testCase.expectedResult, result)
   108  			}
   109  		}
   110  	}
   111  }
   112  
   113  func testStorageAPIStatVol(t *testing.T, storage StorageAPI) {
   114  	err := storage.MakeVol(context.Background(), "foo")
   115  	if err != nil {
   116  		t.Fatalf("unexpected error %v", err)
   117  	}
   118  
   119  	testCases := []struct {
   120  		volumeName string
   121  		expectErr  bool
   122  	}{
   123  		{"foo", false},
   124  		// volume not found error.
   125  		{"bar", true},
   126  	}
   127  
   128  	for i, testCase := range testCases {
   129  		result, err := storage.StatVol(context.Background(), testCase.volumeName)
   130  		expectErr := (err != nil)
   131  
   132  		if expectErr != testCase.expectErr {
   133  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   134  		}
   135  
   136  		if !testCase.expectErr {
   137  			if result.Name != testCase.volumeName {
   138  				t.Fatalf("case %v: result: expected: %+v, got: %+v", i+1, testCase.volumeName, result.Name)
   139  			}
   140  		}
   141  	}
   142  }
   143  
   144  func testStorageAPIDeleteVol(t *testing.T, storage StorageAPI) {
   145  	err := storage.MakeVol(context.Background(), "foo")
   146  	if err != nil {
   147  		t.Fatalf("unexpected error %v", err)
   148  	}
   149  
   150  	testCases := []struct {
   151  		volumeName string
   152  		expectErr  bool
   153  	}{
   154  		{"foo", false},
   155  		// volume not found error.
   156  		{"bar", true},
   157  	}
   158  
   159  	for i, testCase := range testCases {
   160  		err := storage.DeleteVol(context.Background(), testCase.volumeName, false)
   161  		expectErr := (err != nil)
   162  
   163  		if expectErr != testCase.expectErr {
   164  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   165  		}
   166  	}
   167  }
   168  
   169  func testStorageAPICheckFile(t *testing.T, storage StorageAPI) {
   170  	err := storage.MakeVol(context.Background(), "foo")
   171  	if err != nil {
   172  		t.Fatalf("unexpected error %v", err)
   173  	}
   174  	err = storage.AppendFile(context.Background(), "foo", pathJoin("myobject", xlStorageFormatFile), []byte("foo"))
   175  	if err != nil {
   176  		t.Fatalf("unexpected error %v", err)
   177  	}
   178  
   179  	testCases := []struct {
   180  		volumeName string
   181  		objectName string
   182  		expectErr  bool
   183  	}{
   184  		{"foo", "myobject", false},
   185  		// file not found error.
   186  		{"foo", "yourobject", true},
   187  	}
   188  
   189  	for i, testCase := range testCases {
   190  		err := storage.CheckFile(context.Background(), testCase.volumeName, testCase.objectName)
   191  		expectErr := (err != nil)
   192  
   193  		if expectErr != testCase.expectErr {
   194  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   195  		}
   196  	}
   197  }
   198  
   199  func testStorageAPIListDir(t *testing.T, storage StorageAPI) {
   200  	err := storage.MakeVol(context.Background(), "foo")
   201  	if err != nil {
   202  		t.Fatalf("unexpected error %v", err)
   203  	}
   204  	err = storage.AppendFile(context.Background(), "foo", "path/to/myobject", []byte("foo"))
   205  	if err != nil {
   206  		t.Fatalf("unexpected error %v", err)
   207  	}
   208  
   209  	testCases := []struct {
   210  		volumeName     string
   211  		prefix         string
   212  		expectedResult []string
   213  		expectErr      bool
   214  	}{
   215  		{"foo", "path", []string{"to/"}, false},
   216  		// prefix not found error.
   217  		{"foo", "nodir", nil, true},
   218  	}
   219  
   220  	for i, testCase := range testCases {
   221  		result, err := storage.ListDir(context.Background(), testCase.volumeName, testCase.prefix, -1)
   222  		expectErr := (err != nil)
   223  
   224  		if expectErr != testCase.expectErr {
   225  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   226  		}
   227  
   228  		if !testCase.expectErr {
   229  			if !reflect.DeepEqual(result, testCase.expectedResult) {
   230  				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, testCase.expectedResult, result)
   231  			}
   232  		}
   233  	}
   234  }
   235  
   236  func testStorageAPIReadAll(t *testing.T, storage StorageAPI) {
   237  	err := storage.MakeVol(context.Background(), "foo")
   238  	if err != nil {
   239  		t.Fatalf("unexpected error %v", err)
   240  	}
   241  	err = storage.AppendFile(context.Background(), "foo", "myobject", []byte("foo"))
   242  	if err != nil {
   243  		t.Fatalf("unexpected error %v", err)
   244  	}
   245  
   246  	testCases := []struct {
   247  		volumeName     string
   248  		objectName     string
   249  		expectedResult []byte
   250  		expectErr      bool
   251  	}{
   252  		{"foo", "myobject", []byte("foo"), false},
   253  		// file not found error.
   254  		{"foo", "yourobject", nil, true},
   255  	}
   256  
   257  	for i, testCase := range testCases {
   258  		result, err := storage.ReadAll(context.Background(), testCase.volumeName, testCase.objectName)
   259  		expectErr := (err != nil)
   260  
   261  		if expectErr != testCase.expectErr {
   262  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   263  		}
   264  
   265  		if !testCase.expectErr {
   266  			if !reflect.DeepEqual(result, testCase.expectedResult) {
   267  				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, string(testCase.expectedResult), string(result))
   268  			}
   269  		}
   270  	}
   271  }
   272  
   273  func testStorageAPIReadFile(t *testing.T, storage StorageAPI) {
   274  	err := storage.MakeVol(context.Background(), "foo")
   275  	if err != nil {
   276  		t.Fatalf("unexpected error %v", err)
   277  	}
   278  	err = storage.AppendFile(context.Background(), "foo", "myobject", []byte("foo"))
   279  	if err != nil {
   280  		t.Fatalf("unexpected error %v", err)
   281  	}
   282  
   283  	testCases := []struct {
   284  		volumeName     string
   285  		objectName     string
   286  		offset         int64
   287  		expectedResult []byte
   288  		expectErr      bool
   289  	}{
   290  		{"foo", "myobject", 0, []byte("foo"), false},
   291  		{"foo", "myobject", 1, []byte("oo"), false},
   292  		// file not found error.
   293  		{"foo", "yourobject", 0, nil, true},
   294  	}
   295  
   296  	result := make([]byte, 100)
   297  	for i, testCase := range testCases {
   298  		result = result[testCase.offset:3]
   299  		_, err := storage.ReadFile(context.Background(), testCase.volumeName, testCase.objectName, testCase.offset, result, nil)
   300  		expectErr := (err != nil)
   301  
   302  		if expectErr != testCase.expectErr {
   303  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   304  		}
   305  
   306  		if !testCase.expectErr {
   307  			if !reflect.DeepEqual(result, testCase.expectedResult) {
   308  				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, string(testCase.expectedResult), string(result))
   309  			}
   310  		}
   311  	}
   312  }
   313  
   314  func testStorageAPIAppendFile(t *testing.T, storage StorageAPI) {
   315  	err := storage.MakeVol(context.Background(), "foo")
   316  	if err != nil {
   317  		t.Fatalf("unexpected error %v", err)
   318  	}
   319  
   320  	testCases := []struct {
   321  		volumeName string
   322  		objectName string
   323  		data       []byte
   324  		expectErr  bool
   325  	}{
   326  		{"foo", "myobject", []byte("foo"), false},
   327  		{"foo", "myobject", []byte{}, false},
   328  		// volume not found error.
   329  		{"bar", "myobject", []byte{}, true},
   330  	}
   331  
   332  	for i, testCase := range testCases {
   333  		err := storage.AppendFile(context.Background(), testCase.volumeName, testCase.objectName, testCase.data)
   334  		expectErr := (err != nil)
   335  
   336  		if expectErr != testCase.expectErr {
   337  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   338  		}
   339  	}
   340  }
   341  
   342  func testStorageAPIDeleteFile(t *testing.T, storage StorageAPI) {
   343  	err := storage.MakeVol(context.Background(), "foo")
   344  	if err != nil {
   345  		t.Fatalf("unexpected error %v", err)
   346  	}
   347  
   348  	err = storage.AppendFile(context.Background(), "foo", "myobject", []byte("foo"))
   349  	if err != nil {
   350  		t.Fatalf("unexpected error %v", err)
   351  	}
   352  
   353  	testCases := []struct {
   354  		volumeName string
   355  		objectName string
   356  		expectErr  bool
   357  	}{
   358  		{"foo", "myobject", false},
   359  		// should removed by above case.
   360  		{"foo", "myobject", true},
   361  		// file not found error
   362  		{"foo", "yourobject", true},
   363  	}
   364  
   365  	for i, testCase := range testCases {
   366  		err := storage.Delete(context.Background(), testCase.volumeName, testCase.objectName, false)
   367  		expectErr := (err != nil)
   368  
   369  		if expectErr != testCase.expectErr {
   370  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   371  		}
   372  	}
   373  }
   374  
   375  func testStorageAPIRenameFile(t *testing.T, storage StorageAPI) {
   376  	err := storage.MakeVol(context.Background(), "foo")
   377  	if err != nil {
   378  		t.Fatalf("unexpected error %v", err)
   379  	}
   380  
   381  	err = storage.MakeVol(context.Background(), "bar")
   382  	if err != nil {
   383  		t.Fatalf("unexpected error %v", err)
   384  	}
   385  
   386  	err = storage.AppendFile(context.Background(), "foo", "myobject", []byte("foo"))
   387  	if err != nil {
   388  		t.Fatalf("unexpected error %v", err)
   389  	}
   390  
   391  	err = storage.AppendFile(context.Background(), "foo", "otherobject", []byte("foo"))
   392  	if err != nil {
   393  		t.Fatalf("unexpected error %v", err)
   394  	}
   395  
   396  	testCases := []struct {
   397  		volumeName     string
   398  		objectName     string
   399  		destVolumeName string
   400  		destObjectName string
   401  		expectErr      bool
   402  	}{
   403  		{"foo", "myobject", "foo", "yourobject", false},
   404  		{"foo", "yourobject", "bar", "myobject", false},
   405  		// overwrite.
   406  		{"foo", "otherobject", "bar", "myobject", false},
   407  	}
   408  
   409  	for i, testCase := range testCases {
   410  		err := storage.RenameFile(context.Background(), testCase.volumeName, testCase.objectName, testCase.destVolumeName, testCase.destObjectName)
   411  		expectErr := (err != nil)
   412  
   413  		if expectErr != testCase.expectErr {
   414  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   415  		}
   416  	}
   417  }
   418  
   419  func newStorageRESTHTTPServerClient(t *testing.T) (*httptest.Server, *storageRESTClient, config.Config, string) {
   420  	prevHost, prevPort := globalMinioHost, globalMinioPort
   421  	defer func() {
   422  		globalMinioHost, globalMinioPort = prevHost, prevPort
   423  	}()
   424  
   425  	endpointPath, err := ioutil.TempDir("", ".TestStorageREST.")
   426  	if err != nil {
   427  		t.Fatalf("unexpected error %v", err)
   428  	}
   429  
   430  	router := mux.NewRouter()
   431  	httpServer := httptest.NewServer(router)
   432  
   433  	url, err := xnet.ParseHTTPURL(httpServer.URL)
   434  	if err != nil {
   435  		t.Fatalf("unexpected error %v", err)
   436  	}
   437  	url.Path = endpointPath
   438  
   439  	globalMinioHost, globalMinioPort = mustSplitHostPort(url.Host)
   440  
   441  	endpoint, err := NewEndpoint(url.String())
   442  	if err != nil {
   443  		t.Fatalf("NewEndpoint failed %v", endpoint)
   444  	}
   445  
   446  	if err = endpoint.UpdateIsLocal(); err != nil {
   447  		t.Fatalf("UpdateIsLocal failed %v", err)
   448  	}
   449  
   450  	registerStorageRESTHandlers(router, []PoolEndpoints{{
   451  		Endpoints: Endpoints{endpoint},
   452  	}})
   453  
   454  	prevGlobalServerConfig := globalServerConfig
   455  	globalServerConfig = newServerConfig()
   456  	lookupConfigs(globalServerConfig, nil)
   457  
   458  	restClient := newStorageRESTClient(endpoint, false)
   459  
   460  	return httpServer, restClient, prevGlobalServerConfig, endpointPath
   461  }
   462  
   463  func TestStorageRESTClientDiskInfo(t *testing.T) {
   464  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   465  	defer httpServer.Close()
   466  	defer func() {
   467  		globalServerConfig = prevGlobalServerConfig
   468  	}()
   469  	defer os.RemoveAll(endpointPath)
   470  
   471  	testStorageAPIDiskInfo(t, restClient)
   472  }
   473  
   474  func TestStorageRESTClientMakeVol(t *testing.T) {
   475  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   476  	defer httpServer.Close()
   477  	defer func() {
   478  		globalServerConfig = prevGlobalServerConfig
   479  	}()
   480  	defer os.RemoveAll(endpointPath)
   481  
   482  	testStorageAPIMakeVol(t, restClient)
   483  }
   484  
   485  func TestStorageRESTClientListVols(t *testing.T) {
   486  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   487  	defer httpServer.Close()
   488  	defer func() {
   489  		globalServerConfig = prevGlobalServerConfig
   490  	}()
   491  	defer os.RemoveAll(endpointPath)
   492  
   493  	testStorageAPIListVols(t, restClient)
   494  }
   495  
   496  func TestStorageRESTClientStatVol(t *testing.T) {
   497  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   498  	defer httpServer.Close()
   499  	defer func() {
   500  		globalServerConfig = prevGlobalServerConfig
   501  	}()
   502  	defer os.RemoveAll(endpointPath)
   503  
   504  	testStorageAPIStatVol(t, restClient)
   505  }
   506  
   507  func TestStorageRESTClientDeleteVol(t *testing.T) {
   508  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   509  	defer httpServer.Close()
   510  	defer func() {
   511  		globalServerConfig = prevGlobalServerConfig
   512  	}()
   513  	defer os.RemoveAll(endpointPath)
   514  
   515  	testStorageAPIDeleteVol(t, restClient)
   516  }
   517  
   518  func TestStorageRESTClientCheckFile(t *testing.T) {
   519  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   520  	defer httpServer.Close()
   521  	defer func() {
   522  		globalServerConfig = prevGlobalServerConfig
   523  	}()
   524  	defer os.RemoveAll(endpointPath)
   525  
   526  	testStorageAPICheckFile(t, restClient)
   527  }
   528  
   529  func TestStorageRESTClientListDir(t *testing.T) {
   530  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   531  	defer httpServer.Close()
   532  	defer func() {
   533  		globalServerConfig = prevGlobalServerConfig
   534  	}()
   535  	defer os.RemoveAll(endpointPath)
   536  
   537  	testStorageAPIListDir(t, restClient)
   538  }
   539  
   540  func TestStorageRESTClientReadAll(t *testing.T) {
   541  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   542  	defer httpServer.Close()
   543  	defer func() {
   544  		globalServerConfig = prevGlobalServerConfig
   545  	}()
   546  	defer os.RemoveAll(endpointPath)
   547  
   548  	testStorageAPIReadAll(t, restClient)
   549  }
   550  
   551  func TestStorageRESTClientReadFile(t *testing.T) {
   552  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   553  	defer httpServer.Close()
   554  	defer func() {
   555  		globalServerConfig = prevGlobalServerConfig
   556  	}()
   557  	defer os.RemoveAll(endpointPath)
   558  
   559  	testStorageAPIReadFile(t, restClient)
   560  }
   561  
   562  func TestStorageRESTClientAppendFile(t *testing.T) {
   563  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   564  	defer httpServer.Close()
   565  	defer func() {
   566  		globalServerConfig = prevGlobalServerConfig
   567  	}()
   568  	defer os.RemoveAll(endpointPath)
   569  
   570  	testStorageAPIAppendFile(t, restClient)
   571  }
   572  
   573  func TestStorageRESTClientDeleteFile(t *testing.T) {
   574  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   575  	defer httpServer.Close()
   576  	defer func() {
   577  		globalServerConfig = prevGlobalServerConfig
   578  	}()
   579  	defer os.RemoveAll(endpointPath)
   580  
   581  	testStorageAPIDeleteFile(t, restClient)
   582  }
   583  
   584  func TestStorageRESTClientRenameFile(t *testing.T) {
   585  	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t)
   586  	defer httpServer.Close()
   587  	defer func() {
   588  		globalServerConfig = prevGlobalServerConfig
   589  	}()
   590  	defer os.RemoveAll(endpointPath)
   591  
   592  	testStorageAPIRenameFile(t, restClient)
   593  }