| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  |  * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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 ( | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 	"sync" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/minio/dsync" | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Helper function to test equality of locks (without taking timing info into account)
 | 
					
						
							|  |  |  | func testLockEquality(lriLeft, lriRight []lockRequesterInfo) bool { | 
					
						
							|  |  |  | 	if len(lriLeft) != len(lriRight) { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < len(lriLeft); i++ { | 
					
						
							|  |  |  | 		if lriLeft[i].writer != lriRight[i].writer || | 
					
						
							|  |  |  | 			lriLeft[i].node != lriRight[i].node || | 
					
						
							| 
									
										
										
										
											2017-04-12 01:25:21 +08:00
										 |  |  | 			lriLeft[i].serviceEndpoint != lriRight[i].serviceEndpoint || | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 			lriLeft[i].uid != lriRight[i].uid { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Helper function to create a lock server for testing
 | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | func createLockTestServer(t *testing.T) (string, *lockServer, string) { | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 	testPath, err := newTestConfig(globalMinioDefaultRegion) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unable initialize config file, %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-14 00:01:47 +08:00
										 |  |  | 	locker := &lockServer{ | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 		AuthRPCServer: AuthRPCServer{}, | 
					
						
							|  |  |  | 		ll: localLocker{ | 
					
						
							|  |  |  | 			mutex:           sync.Mutex{}, | 
					
						
							|  |  |  | 			serviceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 			lockMap:         make(map[string][]lockRequesterInfo), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-30 05:12:47 +08:00
										 |  |  | 	creds := globalServerConfig.GetCredential() | 
					
						
							| 
									
										
										
										
											2017-09-20 03:37:56 +08:00
										 |  |  | 	token, err := authenticateNode(creds.AccessKey, creds.SecretKey) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	loginArgs := LoginRPCArgs{ | 
					
						
							| 
									
										
										
										
											2017-09-20 03:37:56 +08:00
										 |  |  | 		AuthToken:   token, | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 		Version:     Version, | 
					
						
							| 
									
										
										
										
											2017-03-19 02:28:41 +08:00
										 |  |  | 		RequestTime: UTCNow(), | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	loginReply := LoginRPCReply{} | 
					
						
							|  |  |  | 	err = locker.Login(&loginArgs, &loginReply) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-12-14 00:01:47 +08:00
										 |  |  | 		t.Fatalf("Failed to login to lock server - %v", err) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	return testPath, locker, token | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test Lock functionality
 | 
					
						
							|  |  |  | func TestLockRpcServerLock(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	testPath, locker, token := createLockTestServer(t) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(testPath) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	la := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "0123-4567", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la.SetAuthToken(token) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Claim a lock
 | 
					
						
							|  |  |  | 	var result bool | 
					
						
							|  |  |  | 	err := locker.Lock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if !result { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 			gotLri, _ := locker.ll.lockMap["name"] | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 			expectedLri := []lockRequesterInfo{ | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2017-04-12 01:25:21 +08:00
										 |  |  | 					writer:          true, | 
					
						
							|  |  |  | 					node:            "node", | 
					
						
							|  |  |  | 					serviceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 					uid:             "0123-4567", | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if !testLockEquality(expectedLri, gotLri) { | 
					
						
							|  |  |  | 				t.Errorf("Expected %#v, got %#v", expectedLri, gotLri) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Try to claim same lock again (will fail)
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	la2 := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "89ab-cdef", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la2.SetAuthToken(token) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 	err = locker.Lock(&la2, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if result { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", false, result) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test Unlock functionality
 | 
					
						
							|  |  |  | func TestLockRpcServerUnlock(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	testPath, locker, token := createLockTestServer(t) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(testPath) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	la := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "0123-4567", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la.SetAuthToken(token) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// First test return of error when attempting to unlock a lock that does not exist
 | 
					
						
							|  |  |  | 	var result bool | 
					
						
							|  |  |  | 	err := locker.Unlock(&la, &result) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected error, got %#v", nil) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Create lock (so that we can release)
 | 
					
						
							|  |  |  | 	err = locker.Lock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else if !result { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Finally test successful release of lock
 | 
					
						
							|  |  |  | 	err = locker.Unlock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if !result { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 			gotLri, _ := locker.ll.lockMap["name"] | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 			expectedLri := []lockRequesterInfo(nil) | 
					
						
							|  |  |  | 			if !testLockEquality(expectedLri, gotLri) { | 
					
						
							|  |  |  | 				t.Errorf("Expected %#v, got %#v", expectedLri, gotLri) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test RLock functionality
 | 
					
						
							|  |  |  | func TestLockRpcServerRLock(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	testPath, locker, token := createLockTestServer(t) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(testPath) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	la := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "0123-4567", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la.SetAuthToken(token) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Claim a lock
 | 
					
						
							|  |  |  | 	var result bool | 
					
						
							|  |  |  | 	err := locker.RLock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if !result { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 			gotLri, _ := locker.ll.lockMap["name"] | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 			expectedLri := []lockRequesterInfo{ | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2017-04-12 01:25:21 +08:00
										 |  |  | 					writer:          false, | 
					
						
							|  |  |  | 					node:            "node", | 
					
						
							|  |  |  | 					serviceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 					uid:             "0123-4567", | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if !testLockEquality(expectedLri, gotLri) { | 
					
						
							|  |  |  | 				t.Errorf("Expected %#v, got %#v", expectedLri, gotLri) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Try to claim same again (will succeed)
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	la2 := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "89ab-cdef", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la2.SetAuthToken(token) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 	err = locker.RLock(&la2, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if !result { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test RUnlock functionality
 | 
					
						
							|  |  |  | func TestLockRpcServerRUnlock(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	testPath, locker, token := createLockTestServer(t) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(testPath) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	la := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "0123-4567", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la.SetAuthToken(token) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// First test return of error when attempting to unlock a read-lock that does not exist
 | 
					
						
							|  |  |  | 	var result bool | 
					
						
							|  |  |  | 	err := locker.Unlock(&la, &result) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected error, got %#v", nil) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Create first lock ... (so that we can release)
 | 
					
						
							|  |  |  | 	err = locker.RLock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else if !result { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	// Try to claim same again (will succeed)
 | 
					
						
							|  |  |  | 	la2 := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "89ab-cdef", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la2.SetAuthToken(token) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// ... and create a second lock on same resource
 | 
					
						
							|  |  |  | 	err = locker.RLock(&la2, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else if !result { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Test successful release of first read lock
 | 
					
						
							|  |  |  | 	err = locker.RUnlock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if !result { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 			gotLri, _ := locker.ll.lockMap["name"] | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 			expectedLri := []lockRequesterInfo{ | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2017-04-12 01:25:21 +08:00
										 |  |  | 					writer:          false, | 
					
						
							|  |  |  | 					node:            "node", | 
					
						
							|  |  |  | 					serviceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 					uid:             "89ab-cdef", | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if !testLockEquality(expectedLri, gotLri) { | 
					
						
							|  |  |  | 				t.Errorf("Expected %#v, got %#v", expectedLri, gotLri) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Finally test successful release of second (and last) read lock
 | 
					
						
							|  |  |  | 	err = locker.RUnlock(&la2, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if !result { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 			gotLri, _ := locker.ll.lockMap["name"] | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 			expectedLri := []lockRequesterInfo(nil) | 
					
						
							|  |  |  | 			if !testLockEquality(expectedLri, gotLri) { | 
					
						
							|  |  |  | 				t.Errorf("Expected %#v, got %#v", expectedLri, gotLri) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 16:53:29 +08:00
										 |  |  | // Test ForceUnlock functionality
 | 
					
						
							|  |  |  | func TestLockRpcServerForceUnlock(t *testing.T) { | 
					
						
							|  |  |  | 	testPath, locker, token := createLockTestServer(t) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(testPath) | 
					
						
							| 
									
										
										
										
											2016-10-17 16:53:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	laForce := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "1234-5678", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	laForce.SetAuthToken(token) | 
					
						
							| 
									
										
										
										
											2016-10-17 16:53:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// First test that UID should be empty
 | 
					
						
							|  |  |  | 	var result bool | 
					
						
							|  |  |  | 	err := locker.ForceUnlock(&laForce, &result) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected error, got %#v", nil) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Then test force unlock of a lock that does not exist (not returning an error)
 | 
					
						
							| 
									
										
										
										
											2017-01-09 12:37:53 +08:00
										 |  |  | 	laForce.LockArgs.UID = "" | 
					
						
							| 
									
										
										
										
											2016-10-17 16:53:29 +08:00
										 |  |  | 	err = locker.ForceUnlock(&laForce, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected no error, got %#v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	la := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "0123-4567", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la.SetAuthToken(token) | 
					
						
							| 
									
										
										
										
											2016-10-17 16:53:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Create lock ... (so that we can force unlock)
 | 
					
						
							|  |  |  | 	err = locker.Lock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else if !result { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Forcefully unlock the lock (not returning an error)
 | 
					
						
							|  |  |  | 	err = locker.ForceUnlock(&laForce, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected no error, got %#v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Try to get lock again (should be granted)
 | 
					
						
							|  |  |  | 	err = locker.Lock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else if !result { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Finally forcefully unlock the lock once again
 | 
					
						
							|  |  |  | 	err = locker.ForceUnlock(&laForce, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected no error, got %#v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | // Test Expired functionality
 | 
					
						
							|  |  |  | func TestLockRpcServerExpired(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	testPath, locker, token := createLockTestServer(t) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(testPath) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	la := newLockArgs(dsync.LockArgs{ | 
					
						
							|  |  |  | 		UID:             "0123-4567", | 
					
						
							|  |  |  | 		Resource:        "name", | 
					
						
							|  |  |  | 		ServerAddr:      "node", | 
					
						
							|  |  |  | 		ServiceEndpoint: "rpc-path", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	la.SetAuthToken(token) | 
					
						
							| 
									
										
										
										
											2016-10-11 01:11:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Unknown lock at server will return expired = true
 | 
					
						
							|  |  |  | 	var expired bool | 
					
						
							|  |  |  | 	err := locker.Expired(&la, &expired) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected no error, got %#v", err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if !expired { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", true, expired) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Create lock (so that we can test that it is not expired)
 | 
					
						
							|  |  |  | 	var result bool | 
					
						
							|  |  |  | 	err = locker.Lock(&la, &result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", nil, err) | 
					
						
							|  |  |  | 	} else if !result { | 
					
						
							|  |  |  | 		t.Errorf("Expected %#v, got %#v", true, result) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = locker.Expired(&la, &expired) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected no error, got %#v", err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if expired { | 
					
						
							|  |  |  | 			t.Errorf("Expected %#v, got %#v", false, expired) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Test initialization of lock servers.
 | 
					
						
							|  |  |  | func TestLockServers(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 	if runtime.GOOS == globalWindowsOSName { | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 	rootPath, err := newTestConfig(globalMinioDefaultRegion) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Init Test config failed") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(rootPath) | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	currentIsDistXL := globalIsDistXL | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalIsDistXL = currentIsDistXL | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	case1Endpoints := mustGetNewEndpointList( | 
					
						
							|  |  |  | 		"http://localhost:9000/mnt/disk1", | 
					
						
							|  |  |  | 		"http://1.1.1.2:9000/mnt/disk2", | 
					
						
							|  |  |  | 		"http://1.1.2.1:9000/mnt/disk3", | 
					
						
							|  |  |  | 		"http://1.1.2.2:9000/mnt/disk4", | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	for i := range case1Endpoints { | 
					
						
							|  |  |  | 		if case1Endpoints[i].Host == "localhost:9000" { | 
					
						
							|  |  |  | 			case1Endpoints[i].IsLocal = true | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case2Endpoints := mustGetNewEndpointList( | 
					
						
							|  |  |  | 		"http://localhost:9000/mnt/disk1", | 
					
						
							|  |  |  | 		"http://localhost:9000/mnt/disk2", | 
					
						
							|  |  |  | 		"http://1.1.2.1:9000/mnt/disk3", | 
					
						
							|  |  |  | 		"http://1.1.2.2:9000/mnt/disk4", | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	for i := range case2Endpoints { | 
					
						
							|  |  |  | 		if case2Endpoints[i].Host == "localhost:9000" { | 
					
						
							|  |  |  | 			case2Endpoints[i].IsLocal = true | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 	globalMinioHost = "" | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	testCases := []struct { | 
					
						
							| 
									
										
										
										
											2016-11-08 04:09:24 +08:00
										 |  |  | 		isDistXL         bool | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		endpoints        EndpointList | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 		totalLockServers int | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		// Test - 1 one lock server initialized.
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		{true, case1Endpoints, 1}, | 
					
						
							| 
									
										
										
										
											2016-11-12 08:36:07 +08:00
										 |  |  | 		// Test - 2 two servers possible.
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		{true, case2Endpoints, 2}, | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Validates lock server initialization.
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2016-11-08 04:09:24 +08:00
										 |  |  | 		globalIsDistXL = testCase.isDistXL | 
					
						
							| 
									
										
										
										
											2017-06-06 03:25:04 +08:00
										 |  |  | 		globalLockServers = nil | 
					
						
							|  |  |  | 		_, _ = newDsyncNodes(testCase.endpoints) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Got unexpected error initializing lock servers: %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(globalLockServers) != testCase.totalLockServers { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Expected total %d, got %d", i+1, testCase.totalLockServers, len(globalLockServers)) | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |