| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | /* | 
					
						
							|  |  |  |  * Minio Cloud Storage, (C) 2018 Minio, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"net/http/httptest" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"reflect" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	"github.com/gorilla/mux" | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	xnet "github.com/minio/minio/pkg/net" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | // Storage REST server, storageRESTReceiver and StorageRESTClient are
 | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | // inter-dependent, below test functions are sufficient to test all of them.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIDiskInfo(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		expectErr bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{false}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		_, err := storage.DiskInfo() | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIMakeVol(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName string | 
					
						
							|  |  |  | 		expectErr  bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", false}, | 
					
						
							|  |  |  | 		// volume exists error.
 | 
					
						
							|  |  |  | 		{"foo", true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		err := storage.MakeVol(testCase.volumeName) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIListVols(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeNames    []string | 
					
						
							|  |  |  | 		expectedResult []VolInfo | 
					
						
							|  |  |  | 		expectErr      bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{nil, []VolInfo{}, false}, | 
					
						
							|  |  |  | 		{[]string{"foo"}, []VolInfo{{Name: "foo"}}, false}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		for _, volumeName := range testCase.volumeNames { | 
					
						
							|  |  |  | 			err := storage.MakeVol(volumeName) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		result, err := storage.ListVols() | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !testCase.expectErr { | 
					
						
							|  |  |  | 			if len(result) != len(testCase.expectedResult) { | 
					
						
							|  |  |  | 				t.Fatalf("case %v: result: expected: %+v, got: %+v", i+1, testCase.expectedResult, result) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIStatVol(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName string | 
					
						
							|  |  |  | 		expectErr  bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", false}, | 
					
						
							|  |  |  | 		// volume not found error.
 | 
					
						
							|  |  |  | 		{"bar", true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		result, err := storage.StatVol(testCase.volumeName) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !testCase.expectErr { | 
					
						
							|  |  |  | 			if result.Name != testCase.volumeName { | 
					
						
							|  |  |  | 				t.Fatalf("case %v: result: expected: %+v, got: %+v", i+1, testCase.volumeName, result.Name) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIDeleteVol(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName string | 
					
						
							|  |  |  | 		expectErr  bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", false}, | 
					
						
							|  |  |  | 		// volume not found error.
 | 
					
						
							|  |  |  | 		{"bar", true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		err := storage.DeleteVol(testCase.volumeName) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIStatFile(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err = storage.AppendFile("foo", "myobject", []byte("foo")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName string | 
					
						
							|  |  |  | 		objectName string | 
					
						
							|  |  |  | 		expectErr  bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", "myobject", false}, | 
					
						
							|  |  |  | 		// file not found error.
 | 
					
						
							|  |  |  | 		{"foo", "yourobject", true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		result, err := storage.StatFile(testCase.volumeName, testCase.objectName) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !testCase.expectErr { | 
					
						
							|  |  |  | 			if result.Name != testCase.objectName { | 
					
						
							|  |  |  | 				t.Fatalf("case %v: result: expected: %+v, got: %+v", i+1, testCase.objectName, result.Name) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIListDir(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err = storage.AppendFile("foo", "path/to/myobject", []byte("foo")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName     string | 
					
						
							|  |  |  | 		prefix         string | 
					
						
							|  |  |  | 		expectedResult []string | 
					
						
							|  |  |  | 		expectErr      bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", "path", []string{"to/"}, false}, | 
					
						
							|  |  |  | 		// prefix not found error.
 | 
					
						
							|  |  |  | 		{"foo", "nodir", nil, true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		result, err := storage.ListDir(testCase.volumeName, testCase.prefix, -1) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !testCase.expectErr { | 
					
						
							|  |  |  | 			if !reflect.DeepEqual(result, testCase.expectedResult) { | 
					
						
							|  |  |  | 				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, testCase.expectedResult, result) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIReadAll(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err = storage.AppendFile("foo", "myobject", []byte("foo")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName     string | 
					
						
							|  |  |  | 		objectName     string | 
					
						
							|  |  |  | 		expectedResult []byte | 
					
						
							|  |  |  | 		expectErr      bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", "myobject", []byte("foo"), false}, | 
					
						
							|  |  |  | 		// file not found error.
 | 
					
						
							|  |  |  | 		{"foo", "yourobject", nil, true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		result, err := storage.ReadAll(testCase.volumeName, testCase.objectName) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !testCase.expectErr { | 
					
						
							|  |  |  | 			if !reflect.DeepEqual(result, testCase.expectedResult) { | 
					
						
							|  |  |  | 				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, string(testCase.expectedResult), string(result)) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIReadFile(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err = storage.AppendFile("foo", "myobject", []byte("foo")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName     string | 
					
						
							|  |  |  | 		objectName     string | 
					
						
							|  |  |  | 		offset         int64 | 
					
						
							|  |  |  | 		expectedResult []byte | 
					
						
							|  |  |  | 		expectErr      bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", "myobject", 0, []byte("foo"), false}, | 
					
						
							|  |  |  | 		{"foo", "myobject", 1, []byte("oo"), false}, | 
					
						
							|  |  |  | 		// file not found error.
 | 
					
						
							|  |  |  | 		{"foo", "yourobject", 0, nil, true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-07 06:14:08 +08:00
										 |  |  | 	result := make([]byte, 100) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	for i, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2018-08-07 06:14:08 +08:00
										 |  |  | 		result = result[testCase.offset:3] | 
					
						
							|  |  |  | 		_, err := storage.ReadFile(testCase.volumeName, testCase.objectName, testCase.offset, result, nil) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !testCase.expectErr { | 
					
						
							|  |  |  | 			if !reflect.DeepEqual(result, testCase.expectedResult) { | 
					
						
							|  |  |  | 				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, string(testCase.expectedResult), string(result)) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIAppendFile(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName string | 
					
						
							|  |  |  | 		objectName string | 
					
						
							|  |  |  | 		data       []byte | 
					
						
							|  |  |  | 		expectErr  bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", "myobject", []byte("foo"), false}, | 
					
						
							|  |  |  | 		{"foo", "myobject", []byte{}, false}, | 
					
						
							|  |  |  | 		// volume not found error.
 | 
					
						
							|  |  |  | 		{"bar", "myobject", []byte{}, true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		err := storage.AppendFile(testCase.volumeName, testCase.objectName, testCase.data) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIDeleteFile(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = storage.AppendFile("foo", "myobject", []byte("foo")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName string | 
					
						
							|  |  |  | 		objectName string | 
					
						
							|  |  |  | 		expectErr  bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", "myobject", false}, | 
					
						
							|  |  |  | 		// should removed by above case.
 | 
					
						
							|  |  |  | 		{"foo", "myobject", true}, | 
					
						
							|  |  |  | 		// file not found error
 | 
					
						
							|  |  |  | 		{"foo", "yourobject", true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		err := storage.DeleteFile(testCase.volumeName, testCase.objectName) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testStorageAPIRenameFile(t *testing.T, storage StorageAPI) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := storage.MakeVol("foo") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = storage.MakeVol("bar") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = storage.AppendFile("foo", "myobject", []byte("foo")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = storage.AppendFile("foo", "otherobject", []byte("foo")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		volumeName     string | 
					
						
							|  |  |  | 		objectName     string | 
					
						
							|  |  |  | 		destVolumeName string | 
					
						
							|  |  |  | 		destObjectName string | 
					
						
							|  |  |  | 		expectErr      bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo", "myobject", "foo", "yourobject", false}, | 
					
						
							|  |  |  | 		{"foo", "yourobject", "bar", "myobject", false}, | 
					
						
							|  |  |  | 		// overwrite.
 | 
					
						
							|  |  |  | 		{"foo", "otherobject", "bar", "myobject", false}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		err := storage.RenameFile(testCase.volumeName, testCase.objectName, testCase.destVolumeName, testCase.destObjectName) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func newStorageRESTHTTPServerClient(t *testing.T) (*httptest.Server, *storageRESTClient, *serverConfig, string) { | 
					
						
							|  |  |  | 	endpointPath, err := ioutil.TempDir("", ".TestStorageREST.") | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	router := mux.NewRouter() | 
					
						
							|  |  |  | 	httpServer := httptest.NewServer(router) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	url, err := xnet.ParseURL(httpServer.URL) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	url.Path = endpointPath | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	endpoint, err := NewEndpoint(url.String()) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 		t.Fatalf("NewEndpoint failed %v", endpoint) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	registerStorageRESTHandlers(router, EndpointList{endpoint}) | 
					
						
							| 
									
										
										
										
											2019-02-15 09:53:46 +08:00
										 |  |  | 	restClient, err := newStorageRESTClient(endpoint) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("newStorageRESTClient failed for %v, with error %s", endpoint, err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	prevGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	return httpServer, restClient, prevGlobalServerConfig, endpointPath | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientDiskInfo(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIDiskInfo(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientMakeVol(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIMakeVol(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientListVols(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIListVols(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientStatVol(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIStatVol(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientDeleteVol(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIDeleteVol(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientStatFile(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIStatFile(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientListDir(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIListDir(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientReadAll(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIReadAll(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientReadFile(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIReadFile(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientAppendFile(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIAppendFile(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientDeleteFile(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIDeleteFile(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | func TestStorageRESTClientRenameFile(t *testing.T) { | 
					
						
							|  |  |  | 	httpServer, restClient, prevGlobalServerConfig, endpointPath := newStorageRESTHTTPServerClient(t) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = prevGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	defer os.RemoveAll(endpointPath) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 08:44:06 +08:00
										 |  |  | 	testStorageAPIRenameFile(t, restClient) | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | } |