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 }