tests: Missing anonymous tests for bucket-handlers. (#2885)

master
Karthic Rao 8 years ago committed by Harshavardhana
parent f5f007e183
commit e213172431
  1. 3
      cmd/bucket-handlers.go
  2. 164
      cmd/bucket-handlers_test.go
  3. 25
      cmd/test-utils_test.go

@ -199,7 +199,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter,
writeSuccessResponse(w, encodedSuccessResponse) writeSuccessResponse(w, encodedSuccessResponse)
} }
// ListBucketsHandler - GET Service // ListBucketsHandler - GET Service.
// ----------- // -----------
// This implementation of the GET operation returns a list of all buckets // This implementation of the GET operation returns a list of all buckets
// owned by the authenticated sender of the request. // owned by the authenticated sender of the request.
@ -502,7 +502,6 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re
writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path)
return return
} }
switch getRequestAuthType(r) { switch getRequestAuthType(r) {
default: default:
// For all unknown auth types return error. // For all unknown auth types return error.

@ -26,32 +26,13 @@ import (
// Wrapper for calling GetBucketPolicy HTTP handler tests for both XL multiple disks and single node setup. // Wrapper for calling GetBucketPolicy HTTP handler tests for both XL multiple disks and single node setup.
func TestGetBucketLocationHandler(t *testing.T) { func TestGetBucketLocationHandler(t *testing.T) {
ExecObjectLayerTest(t, testGetBucketLocationHandler) ExecObjectLayerAPITest(t, testGetBucketLocationHandler, []string{"GetBucketLocation"})
} }
func testGetBucketLocationHandler(obj ObjectLayer, instanceType string, t TestErrHandler) { func testGetBucketLocationHandler(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler,
credentials credential, t *testing.T) {
initBucketPolicies(obj) initBucketPolicies(obj)
// get random bucket name.
bucketName := getRandomBucketName()
// Create bucket.
err := obj.MakeBucket(bucketName)
if err != nil {
// failed to create newbucket, abort.
t.Fatalf("%s : %s", instanceType, err)
}
// Register the API end points with XL/FS object layer.
apiRouter := initTestAPIEndPoints(obj, []string{"GetBucketLocation"})
// initialize the server and obtain the credentials and root.
// credentials are necessary to sign the HTTP request.
rootPath, err := newTestConfig("us-east-1")
if err != nil {
t.Fatalf("Init Test config failed")
}
// remove the root folder after the test ends.
defer removeAll(rootPath)
credentials := serverConfig.GetCredential()
// test cases with sample input and expected output. // test cases with sample input and expected output.
testCases := []struct { testCases := []struct {
bucketName string bucketName string
@ -122,36 +103,29 @@ func testGetBucketLocationHandler(obj ObjectLayer, instanceType string, t TestEr
t.Errorf("Test %d: %s: Expected the error code to be `%s`, but instead found `%s`", i+1, instanceType, testCase.errorResponse.Code, errorResponse.Code) t.Errorf("Test %d: %s: Expected the error code to be `%s`, but instead found `%s`", i+1, instanceType, testCase.errorResponse.Code, errorResponse.Code)
} }
} }
// Test for Anonymous/unsigned http request.
// ListBucketsHandler doesn't support bucket policies, setting the policies shouldn't make any difference.
anonReq, err := newTestRequest("GET", getBucketLocationURL("", bucketName), 0, nil)
if err != nil {
t.Fatalf("Minio %s: Failed to create an anonymous request.", instanceType)
}
// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
// sets the bucket policy using the policy statement generated from `getReadOnlyBucketStatement` so that the
// unsigned request goes through and its validated again.
ExecObjectLayerAPIAnonTest(t, "TestGetBucketLocationHandler", bucketName, "", instanceType, apiRouter, anonReq, getReadOnlyBucketStatement)
} }
// Wrapper for calling HeadBucket HTTP handler tests for both XL multiple disks and single node setup. // Wrapper for calling HeadBucket HTTP handler tests for both XL multiple disks and single node setup.
func TestHeadBucketHandler(t *testing.T) { func TestHeadBucketHandler(t *testing.T) {
ExecObjectLayerTest(t, testHeadBucketHandler) ExecObjectLayerAPITest(t, testHeadBucketHandler, []string{"HeadBucket"})
} }
func testHeadBucketHandler(obj ObjectLayer, instanceType string, t TestErrHandler) { func testHeadBucketHandler(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler,
credentials credential, t *testing.T) {
initBucketPolicies(obj) initBucketPolicies(obj)
// get random bucket name.
bucketName := getRandomBucketName()
// Create bucket.
err := obj.MakeBucket(bucketName)
if err != nil {
// failed to create newbucket, abort.
t.Fatalf("%s : %s", instanceType, err)
}
// Register the API end points with XL/FS object layer.
apiRouter := initTestAPIEndPoints(obj, []string{"HeadBucket"})
// initialize the server and obtain the credentials and root.
// credentials are necessary to sign the HTTP request.
rootPath, err := newTestConfig("us-east-1")
if err != nil {
t.Fatalf("Init Test config failed")
}
// remove the root folder after the test ends.
defer removeAll(rootPath)
credentials := serverConfig.GetCredential()
// test cases with sample input and expected output. // test cases with sample input and expected output.
testCases := []struct { testCases := []struct {
bucketName string bucketName string
@ -198,43 +172,31 @@ func testHeadBucketHandler(obj ObjectLayer, instanceType string, t TestErrHandle
t.Errorf("Test %d: %s: Expected the response status to be `%d`, but instead found `%d`", i+1, instanceType, testCase.expectedRespStatus, rec.Code) t.Errorf("Test %d: %s: Expected the response status to be `%d`, but instead found `%d`", i+1, instanceType, testCase.expectedRespStatus, rec.Code)
} }
} }
// Test for Anonymous/unsigned http request.
anonReq, err := newTestRequest("HEAD", getHEADBucketURL("", bucketName), 0, nil)
if err != nil {
t.Fatalf("Minio %s: Failed to create an anonymous request for bucket \"%s\": <ERROR> %v",
instanceType, bucketName, err)
}
// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
// sets the bucket policy using the policy statement generated from `getReadOnlyBucketStatement` so that the
// unsigned request goes through and its validated again.
ExecObjectLayerAPIAnonTest(t, "TestHeadBucketHandler", bucketName, "", instanceType, apiRouter, anonReq, getReadOnlyBucketStatement)
} }
// Wrapper for calling TestListMultipartUploadsHandler tests for both XL multiple disks and single node setup. // Wrapper for calling TestListMultipartUploadsHandler tests for both XL multiple disks and single node setup.
func TestListMultipartUploadsHandler(t *testing.T) { func TestListMultipartUploadsHandler(t *testing.T) {
ExecObjectLayerTest(t, testListMultipartUploadsHandler) ExecObjectLayerAPITest(t, testListMultipartUploadsHandler, []string{"ListMultipartUploads"})
} }
// testListMultipartUploadsHandler - Tests validate listing of multipart uploads. // testListMultipartUploadsHandler - Tests validate listing of multipart uploads.
func testListMultipartUploadsHandler(obj ObjectLayer, instanceType string, t TestErrHandler) { func testListMultipartUploadsHandler(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler,
credentials credential, t *testing.T) {
initBucketPolicies(obj) initBucketPolicies(obj)
// get random bucket name.
bucketName := getRandomBucketName()
// Register the API end points with XL/FS object layer.
apiRouter := initTestAPIEndPoints(obj, []string{"ListMultipartUploads"})
// initialize the server and obtain the credentials and root.
// credentials are necessary to sign the HTTP request.
rootPath, err := newTestConfig("us-east-1")
if err != nil {
t.Fatalf("Init Test config failed")
}
// remove the root folder after the test ends.
defer removeAll(rootPath)
credentials := serverConfig.GetCredential()
// bucketnames[0].
// objectNames[0].
// uploadIds [0].
// Create bucket before initiating NewMultipartUpload.
err = obj.MakeBucket(bucketName)
if err != nil {
// Failed to create newbucket, abort.
t.Fatalf("%s : %s", instanceType, err.Error())
}
// Collection of non-exhaustive ListMultipartUploads test cases, valid errors // Collection of non-exhaustive ListMultipartUploads test cases, valid errors
// and success responses. // and success responses.
testCases := []struct { testCases := []struct {
@ -299,40 +261,31 @@ func testListMultipartUploadsHandler(obj ObjectLayer, instanceType string, t Tes
if rec.Code != http.StatusForbidden { if rec.Code != http.StatusForbidden {
t.Errorf("Test %s: Expected the response status to be `http.StatusForbidden`, but instead found `%d`", instanceType, rec.Code) t.Errorf("Test %s: Expected the response status to be `http.StatusForbidden`, but instead found `%d`", instanceType, rec.Code)
} }
url := getListMultipartUploadsURLWithParams("", testCases[6].bucket, testCases[6].prefix, testCases[6].keyMarker,
testCases[6].uploadIDMarker, testCases[6].delimiter, testCases[6].maxUploads)
// Test for Anonymous/unsigned http request.
anonReq, err := newTestRequest("GET", url, 0, nil)
if err != nil {
t.Fatalf("Minio %s: Failed to create an anonymous request for bucket \"%s\": <ERROR> %v",
instanceType, bucketName, err)
}
// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
// sets the bucket policy using the policy statement generated from `getWriteOnlyBucketStatement` so that the
// unsigned request goes through and its validated again.
ExecObjectLayerAPIAnonTest(t, "TestListMultipartUploadsHandler", bucketName, "", instanceType, apiRouter, anonReq, getWriteOnlyBucketStatement)
} }
// Wrapper for calling TestListBucketsHandler tests for both XL multiple disks and single node setup. // Wrapper for calling TestListBucketsHandler tests for both XL multiple disks and single node setup.
func TestListBucketsHandler(t *testing.T) { func TestListBucketsHandler(t *testing.T) {
ExecObjectLayerTest(t, testListBuckets) ExecObjectLayerAPITest(t, testListBucketsHandler, []string{"ListBuckets"})
} }
// testListBucketsHandler - Tests validate listing of buckets. // testListBucketsHandler - Tests validate listing of buckets.
func testListBucketsHandler(obj ObjectLayer, instanceType string, t TestErrHandler) { func testListBucketsHandler(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler,
// get random bucket name. credentials credential, t *testing.T) {
bucketName := getRandomBucketName()
// Register the API end points with XL/FS object layer.
apiRouter := initTestAPIEndPoints(obj, []string{"ListBuckets"})
// initialize the server and obtain the credentials and root.
// credentials are necessary to sign the HTTP request.
rootPath, err := newTestConfig("us-east-1")
if err != nil {
t.Fatalf("Init Test config failed")
}
// remove the root folder after the test ends.
defer removeAll(rootPath)
credentials := serverConfig.GetCredential()
// bucketnames[0].
// objectNames[0].
// uploadIds [0].
// Create bucket before initiating NewMultipartUpload.
err = obj.MakeBucket(bucketName)
if err != nil {
// Failed to create newbucket, abort.
t.Fatalf("%s : %s", instanceType, err.Error())
}
testCases := []struct { testCases := []struct {
bucketName string bucketName string
@ -370,4 +323,17 @@ func testListBucketsHandler(obj ObjectLayer, instanceType string, t TestErrHandl
t.Errorf("Test %d: %s: Expected the response status to be `%d`, but instead found `%d`", i+1, instanceType, testCase.expectedRespStatus, rec.Code) t.Errorf("Test %d: %s: Expected the response status to be `%d`, but instead found `%d`", i+1, instanceType, testCase.expectedRespStatus, rec.Code)
} }
} }
// Test for Anonymous/unsigned http request.
// ListBucketsHandler doesn't support bucket policies, setting the policies shouldn't make a difference.
anonReq, err := newTestRequest("GET", getListBucketURL(""), 0, nil)
if err != nil {
t.Fatalf("Minio %s: Failed to create an anonymous request.", instanceType)
}
// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
// unsigned request goes through and its validated again.
ExecObjectLayerAPIAnonTest(t, "ListBucketsHandler", "", "", instanceType, apiRouter, anonReq, getWriteOnlyObjectStatement)
} }

@ -1410,6 +1410,7 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName,
if err != nil { if err != nil {
failTest(err.Error()) failTest(err.Error())
} }
// creating 2 read closer (to set as request body) from the body content. // creating 2 read closer (to set as request body) from the body content.
readerOne := ioutil.NopCloser(bytes.NewBuffer(buf)) readerOne := ioutil.NopCloser(bytes.NewBuffer(buf))
readerTwo := ioutil.NopCloser(bytes.NewBuffer(buf)) readerTwo := ioutil.NopCloser(bytes.NewBuffer(buf))
@ -1428,16 +1429,18 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName,
// expected error response in bytes when objectLayer is not initialized, or set to `nil`. // expected error response in bytes when objectLayer is not initialized, or set to `nil`.
expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrAccessDenied), getGetObjectURL("", bucketName, objectName))) expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrAccessDenied), getGetObjectURL("", bucketName, objectName)))
// read the response body. // HEAD HTTTP request doesn't contain response body.
actualContent, err := ioutil.ReadAll(rec.Body) if anonReq.Method != "HEAD" {
if err != nil { // read the response body.
failTest(fmt.Sprintf("Failed parsing response body: <ERROR> %v", err)) actualContent, err := ioutil.ReadAll(rec.Body)
} if err != nil {
// verify whether actual error response (from the response body), matches the expected error response. failTest(fmt.Sprintf("Failed parsing response body: <ERROR> %v", err))
if !bytes.Equal(expectedErrResponse, actualContent) { }
failTest("Object content differs from expected value.") // verify whether actual error response (from the response body), matches the expected error response.
if !bytes.Equal(expectedErrResponse, actualContent) {
failTest("error response content differs from expected value")
}
} }
// Set write only policy on bucket to allow anonymous HTTP request for the operation under test. // Set write only policy on bucket to allow anonymous HTTP request for the operation under test.
// request to go through. // request to go through.
policy := bucketPolicy{ policy := bucketPolicy{
@ -1457,8 +1460,8 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName,
// expectedHTTPStatus returns 204 (http.StatusNoContent) on success. // expectedHTTPStatus returns 204 (http.StatusNoContent) on success.
if testName == "TestAPIDeleteObjectHandler" { if testName == "TestAPIDeleteObjectHandler" {
expectedHTTPStatus = http.StatusNoContent expectedHTTPStatus = http.StatusNoContent
} else if strings.Contains(testName, "BucketPolicyHandler") { } else if strings.Contains(testName, "BucketPolicyHandler") || testName == "ListBucketsHandler" {
// BucketPolicyHandler's doesn't support anonymous request, policy changes should allow unsigned requests. // BucketPolicyHandlers and `ListBucketsHandler` doesn't support anonymous request, policy changes should allow unsigned requests.
expectedHTTPStatus = http.StatusForbidden expectedHTTPStatus = http.StatusForbidden
} else { } else {
// other API handlers return 200OK on success. // other API handlers return 200OK on success.

Loading…
Cancel
Save