diff --git a/object-api-multipart_test.go b/object-api-multipart_test.go index edddfa504..ea0343344 100644 --- a/object-api-multipart_test.go +++ b/object-api-multipart_test.go @@ -1726,7 +1726,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t * uploadIDs = append(uploadIDs, uploadID) // Parts with size greater than 5 MB. // Generating a 6MB byte array. - validPart := bytes.Repeat([]byte("0123456789abcdef"), 1024*1024) + validPart := bytes.Repeat([]byte("abcdef"), 1024*1024) validPartMD5 := findMD5(validPart) // Create multipart parts. // Need parts to be uploaded before CompleteMultiPartUpload can be called tested. diff --git a/object-api-putobject_test.go b/object-api-putobject_test.go index fae96e1ed..149941509 100644 --- a/object-api-putobject_test.go +++ b/object-api-putobject_test.go @@ -120,7 +120,7 @@ func testObjectAPIPutObject(obj ObjectLayer, instanceType string, t *testing.T) } // Wrapper for calling PutObject tests for both XL multiple disks case -// when quorum is not availabel. +// when quorum is not available. func TestObjectAPIPutObjectDiskNotFound(t *testing.T) { ExecObjectLayerDiskNotFoundTest(t, testObjectAPIPutObjectDiskNotFOund) } diff --git a/server_xl_test.go b/server_xl_test.go index 75b07ae6b..e13f7dd7c 100644 --- a/server_xl_test.go +++ b/server_xl_test.go @@ -27,8 +27,6 @@ import ( "io/ioutil" "math/rand" "net/http" - "net/http/httputil" - "strings" "sync" "time" @@ -110,7 +108,7 @@ func (s *MyAPIXLSuite) TestBucketPolicy(c *C) { }` // generate a random bucket Name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. bucketPolicyStr := fmt.Sprintf(bucketPolicyBuf, bucketName, bucketName) request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) @@ -174,7 +172,7 @@ func (s *MyAPIXLSuite) TestBucketPolicy(c *C) { func (s *MyAPIXLSuite) TestDeleteBucket(c *C) { bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -185,7 +183,7 @@ func (s *MyAPIXLSuite) TestDeleteBucket(c *C) { // assert the response status code. c.Assert(response.StatusCode, Equals, http.StatusOK) - // contruct request to delete the bucket. + // construct request to delete the bucket. request, err = newTestRequest("DELETE", getDeleteBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -202,7 +200,7 @@ func (s *MyAPIXLSuite) TestDeleteBucketNotEmpty(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -245,7 +243,7 @@ func (s *MyAPIXLSuite) TestDeleteBucketNotEmpty(c *C) { func (s *MyAPIXLSuite) TestDeleteObject(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -338,7 +336,7 @@ func (s *MyAPIXLSuite) TestNonExistentBucket(c *C) { func (s *MyAPIXLSuite) TestEmptyObject(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make http request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -387,7 +385,7 @@ func (s *MyAPIXLSuite) TestEmptyObject(c *C) { func (s *MyAPIXLSuite) TestBucket(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -416,7 +414,7 @@ func (s *MyAPIXLSuite) TestGetObject(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() buffer := bytes.NewReader([]byte("hello world")) - // make http request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -465,7 +463,7 @@ func (s *MyAPIXLSuite) TestGetObject(c *C) { func (s *MyAPIXLSuite) TestMultipleObjects(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -626,7 +624,7 @@ func (s *MyAPIXLSuite) TestPutBucket(c *C) { wg.Add(1) go func() { defer wg.Done() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -640,7 +638,7 @@ func (s *MyAPIXLSuite) TestPutBucket(c *C) { bucketName = getRandomBucketName() //Block 2: testing for correctness of the functionality - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -661,7 +659,7 @@ func (s *MyAPIXLSuite) TestPutBucket(c *C) { func (s *MyAPIXLSuite) TestCopyObject(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -720,7 +718,7 @@ func (s *MyAPIXLSuite) TestCopyObject(c *C) { func (s *MyAPIXLSuite) TestPutObject(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -761,11 +759,11 @@ func (s *MyAPIXLSuite) TestPutObject(c *C) { c.Assert(true, Equals, bytes.Equal(buffer2.Bytes(), []byte("hello world"))) } -// TestPutObjectLongName - Tests put object with long object name names. +// TestPutObjectLongName - Long Object name strings are created and uploaded, validated for success. func (s *MyAPIXLSuite) TestPutObjectLongName(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -777,6 +775,7 @@ func (s *MyAPIXLSuite) TestPutObjectLongName(c *C) { c.Assert(response.StatusCode, Equals, http.StatusOK) // content for the object to be uploaded. buffer := bytes.NewReader([]byte("hello world")) + // make long object name. longObjName := fmt.Sprintf("%0255d/%0255d/%0255d", 1, 1, 1) // create new HTTP request to insert the object. request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, longObjName), @@ -786,7 +785,7 @@ func (s *MyAPIXLSuite) TestPutObjectLongName(c *C) { response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - + // make long object name. longObjName = fmt.Sprintf("%0256d", 1) request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, longObjName), int64(buffer.Len()), buffer, s.accessKey, s.secretKey) @@ -797,7 +796,9 @@ func (s *MyAPIXLSuite) TestPutObjectLongName(c *C) { c.Assert(response.StatusCode, Equals, http.StatusNotFound) } -// TestListBuckets - Tests listing of buckets. +// TestListBuckets - Make request for listing of all buckets. +// XML response is parsed. +// Its success verifies the format of the response. func (s *MyAPIXLSuite) TestListBuckets(c *C) { // create HTTP request for listing buckets. request, err := newTestRequest("GET", getListBucketURL(s.endPoint), @@ -818,25 +819,38 @@ func (s *MyAPIXLSuite) TestListBuckets(c *C) { c.Assert(err, IsNil) } +// TestNotBeAbleToCreateObjectInNonexistentBucket - Validates the error response +// on an attempt to upload an object into a non-existent bucket. func (s *MyAPIXLSuite) TestNotBeAbleToCreateObjectInNonexistentBucket(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() + // content of the object to be uploaded. buffer1 := bytes.NewReader([]byte("hello world")) - request, err := newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object", + + // preparing for upload by generating the upload URL. + objectName := "test-object" + request, err := newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) c.Assert(err, IsNil) client := http.Client{} + // Execute the HTTP request. response, err := client.Do(request) c.Assert(err, IsNil) + // Assert the response error message. verifyError(c, response, "NoSuchBucket", "The specified bucket does not exist.", http.StatusNotFound) } -// TestHeadOnObject - Asserts response for HEAD on an object. -func (s *MyAPIXLSuite) TestHeadOnObject(c *C) { +// TestHeadOnObjectLastModified - Asserts response for HEAD on an object. +// HEAD requests on an object validates the existence of the object. +// The responses for fetching the object when If-Modified-Since +// and If-Unmodified-Since headers set are validated. +// If-Modified-Since - Return the object only if it has been modified since the specified time, else return a 304 (not modified). +// If-Unmodified-Since - Return the object only if it has not been modified since the specified time, else return a 412 (precondition failed). +func (s *MyAPIXLSuite) TestHeadOnObjectLastModified(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -847,57 +861,68 @@ func (s *MyAPIXLSuite) TestHeadOnObject(c *C) { c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // preparing for object upload. + objectName := "test-object" + // content for the object to be uploaded. buffer1 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object1", + // obtaining URL for uploading the object. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) c.Assert(err, IsNil) + // executing the HTTP request to download the object. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - - request, err = newTestRequest("HEAD", s.endPoint+"/"+bucketName+"/object1", + // make HTTP request to obtain object info. + request, err = newTestRequest("HEAD", getHeadObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // verify the status of the HTTP response. c.Assert(response.StatusCode, Equals, http.StatusOK) + // retrive the info of last modification time of the object from the response header. lastModified := response.Header.Get("Last-Modified") + // Parse it into time.Time structure. t, err := time.Parse(http.TimeFormat, lastModified) c.Assert(err, IsNil) - request, err = newTestRequest("HEAD", s.endPoint+"/"+bucketName+"/object1", + // make HTTP request to obtain object info. + // But this time set the "If-Modified-Since" header to be a minute more than the actual + // last modified time of the object. + request, err = newTestRequest("HEAD", getHeadObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) request.Header.Set("If-Modified-Since", t.Add(1*time.Minute).UTC().Format(http.TimeFormat)) response, err = client.Do(request) c.Assert(err, IsNil) + // Since the "If-Modified-Since" header was ahead in time compared to the actual modified time of the object + // expecting the response status to be http.StatusNotModified. c.Assert(response.StatusCode, Equals, http.StatusNotModified) - request, err = newTestRequest("HEAD", s.endPoint+"/"+bucketName+"/object1", + // Again, obtain the object info. + // This time setting "If-Unmodified-Since" to a time after the object is modified. + // As documented above, expecting http.StatusPreconditionFailed. + request, err = newTestRequest("HEAD", getHeadObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) request.Header.Set("If-Unmodified-Since", t.Add(-1*time.Minute).UTC().Format(http.TimeFormat)) response, err = client.Do(request) - dump, err := httputil.DumpResponse(response, true) - if err != nil { - panic(err) - } - - c.Logf("%q", dump) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusPreconditionFailed) } // TestHeadOnBucket - Validates response for HEAD on the bucket. +// HEAD request on the bucket validates the existence of the bucket. func (s *MyAPIXLSuite) TestHeadOnBucket(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. - request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), + // HTTP request to create the bucket. + request, err := newTestRequest("PUT", getHEADBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -906,67 +931,23 @@ func (s *MyAPIXLSuite) TestHeadOnBucket(c *C) { response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - - request, err = newTestRequest("HEAD", getMakeBucketURL(s.endPoint, bucketName), + // make HEAD request on the bucket. + request, err = newTestRequest("HEAD", getHEADBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // Asserting the response status for expected value of http.StatusOK. c.Assert(response.StatusCode, Equals, http.StatusOK) } -func (s *MyAPIXLSuite) TestXMLNameNotInBucketListJson(c *C) { - request, err := newTestRequest("GET", s.endPoint+"/", - 0, nil, s.accessKey, s.secretKey) - c.Assert(err, IsNil) - request.Header.Add("Accept", "application/json") - - client := http.Client{} - response, err := client.Do(request) - c.Assert(err, IsNil) - c.Assert(response.StatusCode, Equals, http.StatusOK) - - byteResults, err := ioutil.ReadAll(response.Body) - c.Assert(err, IsNil) - c.Assert(strings.Contains(string(byteResults), "XML"), Equals, false) -} - -func (s *MyAPIXLSuite) TestXMLNameNotInObjectListJson(c *C) { - // generate a random bucket name. - bucketName := getRandomBucketName() - // make HTTP request to create the bucket. - request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), - 0, nil, s.accessKey, s.secretKey) - c.Assert(err, IsNil) - request.Header.Add("Accept", "application/json") - - client := http.Client{} - // execute the HTTP request to create bucket. - response, err := client.Do(request) - c.Assert(err, IsNil) - c.Assert(response.StatusCode, Equals, http.StatusOK) - - request, err = newTestRequest("GET", getMakeBucketURL(s.endPoint, bucketName), - 0, nil, s.accessKey, s.secretKey) - c.Assert(err, IsNil) - request.Header.Add("Accept", "application/json") - - client = http.Client{} - response, err = client.Do(request) - c.Assert(err, IsNil) - c.Assert(response.StatusCode, Equals, http.StatusOK) - - byteResults, err := ioutil.ReadAll(response.Body) - c.Assert(err, IsNil) - c.Assert(strings.Contains(string(byteResults), "XML"), Equals, false) -} - -// Tests if content type persists. +// TestContentTypePersists - Object upload with different Content-type is first done. +// And then a HEAD and GET request on these objects are done to validate if the same Content-Type set during upload persists. func (s *MyAPIXLSuite) TestContentTypePersists(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -977,154 +958,189 @@ func (s *MyAPIXLSuite) TestContentTypePersists(c *C) { c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // Uploading a new object with Content-Type "application/zip". + // content for the object to be uploaded. buffer1 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/one", + objectName := "test-1-object" + // constructing HTTP request for object upload. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) + c.Assert(err, IsNil) + // setting the Content-Type header to be application/zip. + // After object upload a validation will be done to see if the Content-Type set persists. request.Header.Set("Content-Type", "application/zip") - c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request for object upload. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - request, err = newTestRequest("HEAD", s.endPoint+"/"+bucketName+"/one", + // Fetching the object info using HEAD request for the object which was uploaded above. + request, err = newTestRequest("HEAD", getHeadObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) + // Execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // Verify if the Content-Type header is set during the object persists. c.Assert(response.Header.Get("Content-Type"), Equals, "application/zip") - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/one", + // Fetching the object itself and then verify the Content-Type header. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // Execute the HTTP to fetch the object. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // Verify if the Content-Type header is set during the object persists. c.Assert(response.Header.Get("Content-Type"), Equals, "application/zip") + // Uploading a new object with Content-Type "application/json". + objectName = "test-2-object" buffer2 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/two", + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buffer2.Len()), buffer2, s.accessKey, s.secretKey) + // deleting the old header value. delete(request.Header, "Content-Type") + // setting the request header to be application/json. request.Header.Add("Content-Type", "application/json") c.Assert(err, IsNil) + // Execute the HTTP request to upload the object. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - request, err = newTestRequest("HEAD", s.endPoint+"/"+bucketName+"/two", + // Obtain the info of the object which was uploaded above using HEAD request. + request, err = newTestRequest("HEAD", getHeadObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // Execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // Assert if the content-type header set during the object upload persists. c.Assert(response.Header.Get("Content-Type"), Equals, "application/json") - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/two", + // Fetch the object and assert whether the Content-Type header persists. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) + // Execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // Assert if the content-type header set during the object upload persists. c.Assert(response.Header.Get("Content-Type"), Equals, "application/json") } +// TestPartialContent - Validating for GetObject with partial content request. +// By setting the Range header, A request to send specific bytes range of data from an +// already uploaded object can be done. func (s *MyAPIXLSuite) TestPartialContent(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() + // HTTP Request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client := http.Client{} + // execute the HTTP request to create the bucket. response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - + // content for the object to be uploaded. buffer1 := bytes.NewReader([]byte("Hello World")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/bar", + objectName := "test-object" + // make HTTP request to upload the object. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // Execute the HTTP request for object upload. response, err = client.Do(request) + // verify that the upload was successfull. c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - // Prepare request + // Set of cases which will be used to create Get Object requests with specific content range. var table = []struct { byteRange string expectedString string }{ + // Request bytes 6-7 of the uploaded object. + // Since the object content was "Hello World", expecting "Wo" in the response. {"6-7", "Wo"}, + // Request for first 6 bytes of object content. {"6-", "World"}, + // Request for last 7 bytes of the object content. {"-7", "o World"}, } for _, t := range table { - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/bar", + // make HTTP request to fetch the object. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) + // Set the Range header with range of bytes data of the uploaded object to be fetched. request.Header.Add("Range", "bytes="+t.byteRange) client = http.Client{} + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // since the complete object is not fetched, + // http.StatusPartialContent is expected to be the response status. c.Assert(response.StatusCode, Equals, http.StatusPartialContent) + // parse the response body to obtain the partial content requested for. partialObject, err := ioutil.ReadAll(response.Body) c.Assert(err, IsNil) + // asserting the obtained partial content with the expected data. c.Assert(string(partialObject), Equals, t.expectedString) } } +// TestListObjectsHandlerErrors - Setting invalid parameters to List Objects +// and then asserting the error response with the expected one. func (s *MyAPIXLSuite) TestListObjectsHandlerErrors(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - request, err := newTestRequest("GET", s.endPoint+"/"+bucketName+"objecthandlererrors-.", + // HTTP request to create the bucket. + request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client := http.Client{} - response, err := client.Do(request) - c.Assert(err, IsNil) - verifyError(c, response, "InvalidBucketName", "The specified bucket is not valid.", http.StatusBadRequest) - - request, err = newTestRequest("GET", getMakeBucketURL(s.endPoint, bucketName), - 0, nil, s.accessKey, s.secretKey) - c.Assert(err, IsNil) - - client = http.Client{} - response, err = client.Do(request) - c.Assert(err, IsNil) - verifyError(c, response, "NoSuchBucket", "The specified bucket does not exist.", http.StatusNotFound) - - // make HTTP request to create the bucket. - request, err = newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), - 0, nil, s.accessKey, s.secretKey) - c.Assert(err, IsNil) - - client = http.Client{} // execute the HTTP request to create bucket. - response, err = client.Do(request) + response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"?max-keys=-2", + // create HTTP request with invalid value of max-keys parameter. + // max-keys is set to -2. + request, err = newTestRequest("GET", getListObjectsURL(s.endPoint, bucketName, "-2"), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // validating the error response. verifyError(c, response, "InvalidArgument", "Argument maxKeys must be an integer between 0 and 2147483647.", http.StatusBadRequest) } +// TestPutBucketErrors - request for non valid bucket operation +// and validate it with expected error result. func (s *MyAPIXLSuite) TestPutBucketErrors(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() + // generating a HTTP request to create bucket. + // using invalid bucket name. request, err := newTestRequest("PUT", s.endPoint+"/putbucket-.", 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1132,8 +1148,9 @@ func (s *MyAPIXLSuite) TestPutBucketErrors(c *C) { client := http.Client{} response, err := client.Do(request) c.Assert(err, IsNil) + // expected to fail with error message "InvalidBucketName". verifyError(c, response, "InvalidBucketName", "The specified bucket is not valid.", http.StatusBadRequest) - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err = newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1143,7 +1160,7 @@ func (s *MyAPIXLSuite) TestPutBucketErrors(c *C) { response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - // make HTTP request to createthe same bucket again. + // make HTTP request to create the same bucket again. // expected to fail with error message "BucketAlreadyOwnedByYou". request, err = newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) @@ -1154,6 +1171,8 @@ func (s *MyAPIXLSuite) TestPutBucketErrors(c *C) { verifyError(c, response, "BucketAlreadyOwnedByYou", "Your previous request to create the named bucket succeeded and you already own it.", http.StatusConflict) + // request for ACL. + // Since Minio server doesn't support ACL's the request is expected to fail with "NotImplemented" error message. request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"?acl", 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1167,12 +1186,13 @@ func (s *MyAPIXLSuite) TestPutBucketErrors(c *C) { func (s *MyAPIXLSuite) TestGetObjectLarge10MiB(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to createthe same bucket again. + // form HTTP reqest to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client := http.Client{} + // execute the HTTP request to create the bucket. response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) @@ -1193,26 +1213,32 @@ func (s *MyAPIXLSuite) TestGetObjectLarge10MiB(c *C) { } putContent := buffer.String() - // Put object buf := bytes.NewReader([]byte(putContent)) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/big-file-10", + + objectName := "test-big-object" + // create HTTP request for object upload. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buf.Len()), buf, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // Assert the status code to verify successful upload. c.Assert(response.StatusCode, Equals, http.StatusOK) - // Get object - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/big-file-10", + // prepare HTTP requests to download the object. + request, err = newTestRequest("GET", getPutObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to download the object. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // extract the content from response body. getContent, err := ioutil.ReadAll(response.Body) c.Assert(err, IsNil) @@ -1220,15 +1246,17 @@ func (s *MyAPIXLSuite) TestGetObjectLarge10MiB(c *C) { c.Assert(string(getContent), Equals, putContent) } +// TestGetObjectLarge11MiB - Tests validate fetching of an object of size 10MB. func (s *MyAPIXLSuite) TestGetObjectLarge11MiB(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client := http.Client{} + // execute the HTTP request. response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) @@ -1250,107 +1278,142 @@ func (s *MyAPIXLSuite) TestGetObjectLarge11MiB(c *C) { } putMD5 := sumMD5(buffer.Bytes()) + objectName := "test-11Mb-object" // Put object buf := bytes.NewReader(buffer.Bytes()) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/big-file-11", + // create HTTP request foe object upload. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buf.Len()), buf, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request for object upload. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - // Get object - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/big-file-11", + // create HTTP request to download the object. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // fetch the content from response body. getContent, err := ioutil.ReadAll(response.Body) c.Assert(err, IsNil) - getMD5 := sumMD5(getContent) // Get md5. + // Get md5Sum of the response content. + getMD5 := sumMD5(getContent) - // Compare putContent and getContent + // Compare putContent and getContent. c.Assert(hex.EncodeToString(putMD5), Equals, hex.EncodeToString(getMD5)) } // TestGetPartialObjectMisAligned - tests get object partially mis-aligned. +// create a large buffer of mis-aligned data and upload it. +// then make partial range requests to while fetching it back and assert the response content. func (s *MyAPIXLSuite) TestGetPartialObjectMisAligned(c *C) { - // Make bucket for this test. - request, err := newTestRequest("PUT", s.testServer.Server.URL+"/test-bucket-align", + // generate a random bucket name. + bucketName := getRandomBucketName() + // HTTP request to create the bucket. + request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.testServer.AccessKey, s.testServer.SecretKey) c.Assert(err, IsNil) client := http.Client{} + // execute the HTTP request to create the bucket. response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) var buffer bytes.Buffer - line := "1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,123" + line := `1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,123` + rand.Seed(time.Now().UTC().UnixNano()) // Create a misalgined data. for i := 0; i < 13*rand.Intn(1<<16); i++ { buffer.WriteString(fmt.Sprintf("[%05d] %s\n", i, line[:rand.Intn(1<<8)])) } putContent := buffer.String() - - // Put object buf := bytes.NewReader([]byte(putContent)) - request, err = newTestRequest("PUT", s.testServer.Server.URL+"/test-bucket-align/big-file-13", + + objectName := "test-big-file" + // HTTP request to upload the object. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buf.Len()), buf, s.testServer.AccessKey, s.testServer.SecretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to upload the object. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - // Prepare request + // test Cases containing data to make partial range requests. + // also has expected response data. var testCases = []struct { byteRange string expectedString string }{ + // request for byte range 10-11. + // expecting the result to contain only putContent[10:12] bytes. {"10-11", putContent[10:12]}, + // request for object data after the first byte. {"1-", putContent[1:]}, + // request for object data after the first byte. {"6-", putContent[6:]}, + // request for last 2 bytes of th object. {"-2", putContent[len(putContent)-2:]}, + // request for last 7 bytes of the object. {"-7", putContent[len(putContent)-7:]}, } for _, t := range testCases { - // Get object - request, err = newTestRequest("GET", s.testServer.Server.URL+"/test-bucket-align/big-file-13", + // HTTP request to download the object. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.testServer.AccessKey, s.testServer.SecretKey) c.Assert(err, IsNil) - // Get a different byte range. + // Get partial content based on the byte range set. request.Header.Add("Range", "bytes="+t.byteRange) client = http.Client{} + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // Since only part of the object is requested, expecting response status to be http.StatusPartialContent . c.Assert(response.StatusCode, Equals, http.StatusPartialContent) + // parse the HTTP response body. getContent, err := ioutil.ReadAll(response.Body) c.Assert(err, IsNil) - // Compare putContent and getContent + // Compare putContent and getContent. c.Assert(string(getContent), Equals, t.expectedString) } } +// TestGetPartialObjectLarge11MiB - Test validates partial content request for a 11MiB object. func (s *MyAPIXLSuite) TestGetPartialObjectLarge11MiB(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // Make bucket for this test. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client := http.Client{} + // execute the HTTP request to create the bucket. response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) @@ -1373,39 +1436,46 @@ func (s *MyAPIXLSuite) TestGetPartialObjectLarge11MiB(c *C) { } putContent := buffer.String() - // Put object + objectName := "test-large-11Mb-object" + buf := bytes.NewReader([]byte(putContent)) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/big-file-11", + // HTTP request to upload the object. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buf.Len()), buf, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to upload the object. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - // Get object - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/big-file-11", + // HTTP request to download the object. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) // This range spans into first two blocks. request.Header.Add("Range", "bytes=10485750-10485769") client = http.Client{} + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // Since only part of the object is requested, expecting response status to be http.StatusPartialContent . c.Assert(response.StatusCode, Equals, http.StatusPartialContent) + // read the downloaded content from the response body. getContent, err := ioutil.ReadAll(response.Body) c.Assert(err, IsNil) - // Compare putContent and getContent + // Compare putContent and getContent. c.Assert(string(getContent), Equals, putContent[10485750:10485770]) } +// TestGetPartialObjectLarge11MiB - Test validates partial content request for a 10MiB object. func (s *MyAPIXLSuite) TestGetPartialObjectLarge10MiB(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1413,7 +1483,9 @@ func (s *MyAPIXLSuite) TestGetPartialObjectLarge10MiB(c *C) { client := http.Client{} // execute the HTTP request to create bucket. response, err := client.Do(request) + // expecting the error to be nil. c.Assert(err, IsNil) + // expecting the HTTP response status code to 200 OK. c.Assert(response.StatusCode, Equals, http.StatusOK) var buffer bytes.Buffer @@ -1431,58 +1503,65 @@ func (s *MyAPIXLSuite) TestGetPartialObjectLarge10MiB(c *C) { for i := 0; i < 10*1024; i++ { buffer.WriteString(fmt.Sprintf("[%05d] %s\n", i, line)) } - putContent := buffer.String() - // Put object + putContent := buffer.String() buf := bytes.NewReader([]byte(putContent)) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/big-file-10", + + objectName := "test-big-10Mb-file" + // HTTP request to upload the object. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buf.Len()), buf, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to upload the object. response, err = client.Do(request) c.Assert(err, IsNil) + // verify whether upload was successfull. c.Assert(response.StatusCode, Equals, http.StatusOK) - // Get object - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/big-file-10", + // HTTP request to download the object. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) + // Get partial content based on the byte range set. request.Header.Add("Range", "bytes=2048-2058") client = http.Client{} + // execute the HTTP request to download the partila content. response, err = client.Do(request) c.Assert(err, IsNil) + // Since only part of the object is requested, expecting response status to be http.StatusPartialContent . c.Assert(response.StatusCode, Equals, http.StatusPartialContent) + // read the downloaded content from the response body. getContent, err := ioutil.ReadAll(response.Body) c.Assert(err, IsNil) - // Compare putContent and getContent + // Compare putContent and getContent. c.Assert(string(getContent), Equals, putContent[2048:2059]) } +// TestGetObjectErrors - Tests validate error response for invalid object operations. func (s *MyAPIXLSuite) TestGetObjectErrors(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - request, err := newTestRequest("GET", getMakeBucketURL(s.endPoint, bucketName), + + // HTTP request to create the bucket. + request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client := http.Client{} + // execute the HTTP request to create bucket. response, err := client.Do(request) c.Assert(err, IsNil) - verifyError(c, response, "NoSuchBucket", "The specified bucket does not exist.", http.StatusNotFound) - // make HTTP request to create the bucket. - request, err = newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), - 0, nil, s.accessKey, s.secretKey) - c.Assert(err, IsNil) - - client = http.Client{} - response, err = client.Do(request) - c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/bar", + objectName := "test-non-exitent-object" + // HTTP request to download the object. + // Since the specified object doesn't exist in the given bucket, + // expected to fail with error message "NoSuchKey" + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1491,20 +1570,23 @@ func (s *MyAPIXLSuite) TestGetObjectErrors(c *C) { c.Assert(err, IsNil) verifyError(c, response, "NoSuchKey", "The specified key does not exist.", http.StatusNotFound) - request, err = newTestRequest("GET", s.endPoint+"/getobjecterrors-./bar", + // request to download an object, but an invalid bucket name is set. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, "/getobjecterrors-.", objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // expected to fail with "InvalidBucketName". verifyError(c, response, "InvalidBucketName", "The specified bucket is not valid.", http.StatusBadRequest) - } +// TestGetObjectRangeErrors - Validate error response when object is fetched with incorrect byte range value. func (s *MyAPIXLSuite) TestGetObjectRangeErrors(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1515,31 +1597,42 @@ func (s *MyAPIXLSuite) TestGetObjectRangeErrors(c *C) { c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // content for the object to be uploaded. buffer1 := bytes.NewReader([]byte("Hello World")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/bar", + + objectName := "test-object" + // HTTP request to upload the object. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to upload the object. response, err = client.Do(request) c.Assert(err, IsNil) + // verify whether upload was successfull. c.Assert(response.StatusCode, Equals, http.StatusOK) - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/bar", + // HTTP request to download the object. + request, err = newTestRequest("GET", getGetObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) + // invalid byte range set. request.Header.Add("Range", "bytes=7-6") c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request. response, err = client.Do(request) c.Assert(err, IsNil) + // expected to fail with "InvalidRange" error message. verifyError(c, response, "InvalidRange", "The requested range cannot be satisfied.", http.StatusRequestedRangeNotSatisfiable) } +// TestObjectMultipartAbort - Test validates abortion of a multipart upload after uploading 2 parts. func (s *MyAPIXLSuite) TestObjectMultipartAbort(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1548,101 +1641,124 @@ func (s *MyAPIXLSuite) TestObjectMultipartAbort(c *C) { // execute the HTTP request to create bucket. response, err := client.Do(request) c.Assert(err, IsNil) - c.Assert(response.StatusCode, Equals, 200) + c.Assert(response.StatusCode, Equals, http.StatusOK) - request, err = newTestRequest("POST", s.endPoint+"/"+bucketName+"/object?uploads", + objectName := "test-multipart-object" + // construct HTTP request to initiate a NewMultipart upload. + request, err = newTestRequest("POST", getNewMultipartURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) + // execute the HTTP request initiating the new multipart upload. response, err = client.Do(request) c.Assert(response.StatusCode, Equals, http.StatusOK) + // parse the response body and obtain the new upload ID. decoder := xml.NewDecoder(response.Body) newResponse := &InitiateMultipartUploadResponse{} err = decoder.Decode(newResponse) c.Assert(err, IsNil) c.Assert(len(newResponse.UploadID) > 0, Equals, true) + // uploadID to be used for rest of the multipart operations on the object. uploadID := newResponse.UploadID + // content for the part to be uploaded. buffer1 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=1", + // HTTP request for the part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "1"), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request to upload the first part. response1, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response1.StatusCode, Equals, http.StatusOK) + // content for the second part to be uploaded. buffer2 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=2", + // HTTP request for the second part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "2"), int64(buffer2.Len()), buffer2, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request to upload the second part. response2, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response2.StatusCode, Equals, http.StatusOK) - - request, err = newTestRequest("DELETE", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID, + // HTTP request for aborting the multipart upload. + request, err = newTestRequest("DELETE", getAbortMultipartUploadURL(s.endPoint, bucketName, objectName, uploadID), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request to abort the multipart upload. response3, err := client.Do(request) c.Assert(err, IsNil) + // expecting the response status code to be http.StatusNoContent. + // The assertion validates the success of Abort Multipart operation. c.Assert(response3.StatusCode, Equals, http.StatusNoContent) } +// TestBucketMultipartList - Initiates a NewMultipart upload, uploads parts and validates listing of the parts. func (s *MyAPIXLSuite) TestBucketMultipartList(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client := http.Client{} + // execute the HTTP request to create bucket. response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, 200) - request, err = newTestRequest("POST", s.endPoint+"/"+bucketName+"/object?uploads", + objectName := "test-multipart-object" + // construct HTTP request to initiate a NewMultipart upload. + request, err = newTestRequest("POST", getNewMultipartURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - // execute the HTTP request to create bucket. + // execute the HTTP request initiating the new multipart upload. response, err = client.Do(request) c.Assert(err, IsNil) + // expecting the response status code to be http.StatusOK(200 OK) . c.Assert(response.StatusCode, Equals, http.StatusOK) + // parse the response body and obtain the new upload ID. decoder := xml.NewDecoder(response.Body) newResponse := &InitiateMultipartUploadResponse{} err = decoder.Decode(newResponse) c.Assert(err, IsNil) c.Assert(len(newResponse.UploadID) > 0, Equals, true) + // uploadID to be used for rest of the multipart operations on the object. uploadID := newResponse.UploadID + // content for the part to be uploaded. buffer1 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=1", + // HTTP request for the part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "1"), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request to upload the first part. response1, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response1.StatusCode, Equals, http.StatusOK) + // content for the second part to be uploaded. buffer2 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=2", + // HTTP request for the second part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "2"), int64(buffer2.Len()), buffer2, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request to upload the second part. response2, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response2.StatusCode, Equals, http.StatusOK) - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"?uploads", + // HTTP request to ListMultipart Uploads. + request, err = newTestRequest("GET", getListMultipartURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request. response3, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response3.StatusCode, Equals, http.StatusOK) @@ -1682,18 +1798,22 @@ func (s *MyAPIXLSuite) TestBucketMultipartList(c *C) { CommonPrefixes []CommonPrefix } + // parse the response body. decoder = xml.NewDecoder(response3.Body) newResponse3 := &listMultipartUploadsResponse{} err = decoder.Decode(newResponse3) c.Assert(err, IsNil) + // Assert the bucket name in the response with the expected bucketName. c.Assert(newResponse3.Bucket, Equals, bucketName) + // Assert the bucket name in the response with the expected bucketName. + c.Assert(newResponse3.IsTruncated, Equals, false) } // TestMakeBucketLocation - tests make bucket location header response. func (s *MyAPIXLSuite) TestMakeBucketLocation(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1707,10 +1827,11 @@ func (s *MyAPIXLSuite) TestMakeBucketLocation(c *C) { c.Assert(response.Header.Get("Location"), Equals, "/"+bucketName) } +// TestValidateObjectMultipartUploadID - Test Initiates a new multipart upload and validates the uploadID. func (s *MyAPIXLSuite) TestValidateObjectMultipartUploadID(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1721,26 +1842,32 @@ func (s *MyAPIXLSuite) TestValidateObjectMultipartUploadID(c *C) { c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, 200) - request, err = newTestRequest("POST", s.endPoint+"/"+bucketName+"/directory1/directory2/object?uploads", + objectName := "directory1/directory2/object" + // construct HTTP request to initiate a NewMultipart upload. + request, err = newTestRequest("POST", getNewMultipartURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request initiating the new multipart upload. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // parse the response body and obtain the new upload ID. decoder := xml.NewDecoder(response.Body) newResponse := &InitiateMultipartUploadResponse{} - err = decoder.Decode(newResponse) + // expecting the decoding error to be nil. c.Assert(err, IsNil) + // Verifying for Upload ID value to be greater than 0. c.Assert(len(newResponse.UploadID) > 0, Equals, true) } -func (s *MyAPIXLSuite) TestObjectMultipartList(c *C) { +// TestObjectMultipartListError - Initiates a NewMultipart upload, uploads parts and validates +// error response for an incorrect max-parts parameter . +func (s *MyAPIXLSuite) TestObjectMultipartListError(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1751,61 +1878,65 @@ func (s *MyAPIXLSuite) TestObjectMultipartList(c *C) { c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, 200) - request, err = newTestRequest("POST", s.endPoint+"/"+bucketName+"/object?uploads", + objectName := "test-multipart-object" + // construct HTTP request to initiate a NewMultipart upload. + request, err = newTestRequest("POST", getNewMultipartURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request initiating the new multipart upload. response, err = client.Do(request) c.Assert(response.StatusCode, Equals, http.StatusOK) - + // parse the response body and obtain the new upload ID. decoder := xml.NewDecoder(response.Body) newResponse := &InitiateMultipartUploadResponse{} err = decoder.Decode(newResponse) c.Assert(err, IsNil) c.Assert(len(newResponse.UploadID) > 0, Equals, true) + // uploadID to be used for rest of the multipart operations on the object. uploadID := newResponse.UploadID + // content for the part to be uploaded. buffer1 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=1", + // HTTP request for the part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "1"), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request to upload the first part. response1, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response1.StatusCode, Equals, http.StatusOK) + // content for the second part to be uploaded. buffer2 := bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=2", + // HTTP request for the second part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "2"), int64(buffer2.Len()), buffer2, s.accessKey, s.secretKey) c.Assert(err, IsNil) + // execute the HTTP request to upload the second part. response2, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response2.StatusCode, Equals, http.StatusOK) - - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID, + // HTTP request to ListMultipart Uploads. + // max-keys is set to invalid value of -2. + request, err = newTestRequest("GET", getListMultipartURLWithParams(s.endPoint, bucketName, objectName, uploadID, "-2"), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - - response3, err := client.Do(request) - c.Assert(err, IsNil) - c.Assert(response3.StatusCode, Equals, http.StatusOK) - - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/object?max-parts=-2&uploadId="+uploadID, - 0, nil, s.accessKey, s.secretKey) - c.Assert(err, IsNil) - + // execute the HTTP request. response4, err := client.Do(request) c.Assert(err, IsNil) + // Since max-keys parameter in the ListMultipart request set to invalid value of -2, + // its expected to fail with error message "InvalidArgument". verifyError(c, response4, "InvalidArgument", "Argument maxParts must be an integer between 1 and 10000.", http.StatusBadRequest) } -// Tests object multipart. +// TestObjectMultipart - Initiates a NewMultipart upload, uploads 2 parts, +// completes the multipart upload and validates the status of the operation. func (s *MyAPIXLSuite) TestObjectMultipart(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1816,55 +1947,69 @@ func (s *MyAPIXLSuite) TestObjectMultipart(c *C) { c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, 200) - request, err = newTestRequest("POST", s.endPoint+"/"+bucketName+"/object?uploads", + objectName := "test-multipart-object" + // construct HTTP request to initiate a NewMultipart upload. + request, err = newTestRequest("POST", getNewMultipartURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request initiating the new multipart upload. response, err = client.Do(request) c.Assert(err, IsNil) + // expecting the response status code to be http.StatusOK(200 OK). c.Assert(response.StatusCode, Equals, http.StatusOK) - + // parse the response body and obtain the new upload ID. decoder := xml.NewDecoder(response.Body) newResponse := &InitiateMultipartUploadResponse{} err = decoder.Decode(newResponse) c.Assert(err, IsNil) c.Assert(len(newResponse.UploadID) > 0, Equals, true) + // uploadID to be used for rest of the multipart operations on the object. uploadID := newResponse.UploadID + // content for the part to be uploaded. // Create a byte array of 5MB. data := bytes.Repeat([]byte("0123456789abcdef"), 5*1024*1024/16) - + // calculate md5Sum of the data. hasher := md5.New() hasher.Write(data) md5Sum := hasher.Sum(nil) buffer1 := bytes.NewReader(data) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=1", + // HTTP request for the part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "1"), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) + // set the Content-Md5 header to the base64 encoding the md5Sum of the content. request.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(md5Sum)) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to upload the first part. response1, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response1.StatusCode, Equals, http.StatusOK) + // content for the second part to be uploaded. // Create a byte array of 1 byte. data = []byte("0") hasher = md5.New() hasher.Write(data) + // calculate md5Sum of the data. md5Sum = hasher.Sum(nil) buffer2 := bytes.NewReader(data) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=2", + // HTTP request for the second part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "2"), int64(buffer2.Len()), buffer2, s.accessKey, s.secretKey) + // set the Content-Md5 header to the base64 encoding the md5Sum of the content. request.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(md5Sum)) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to upload the second part. response2, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response2.StatusCode, Equals, http.StatusOK) @@ -1885,21 +2030,25 @@ func (s *MyAPIXLSuite) TestObjectMultipart(c *C) { completeBytes, err := xml.Marshal(completeUploads) c.Assert(err, IsNil) - - request, err = newTestRequest("POST", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID, + // Indicating that all parts are uploaded and initiating completeMultipartUpload. + request, err = newTestRequest("POST", getCompleteMultipartUploadURL(s.endPoint, bucketName, objectName, uploadID), int64(len(completeBytes)), bytes.NewReader(completeBytes), s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // Execute the complete multipart request. response, err = client.Do(request) c.Assert(err, IsNil) + // verify whether complete multipart was successfull. c.Assert(response.StatusCode, Equals, http.StatusOK) } -// Tests object multipart overwrite with single put object. +// TestObjectMultipartOverwriteSinglePut - Initiates a NewMultipart upload, uploads 2 parts, +// completes the multipart upload and validates the status of the operation. +// then, after PutObject with same object name on the bucket, +// test validates for successful overwrite. func (s *MyAPIXLSuite) TestObjectMultipartOverwriteSinglePut(c *C) { // generate a random bucket name. bucketName := getRandomBucketName() - // make HTTP request to create the bucket. + // HTTP request to create the bucket. request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1910,60 +2059,74 @@ func (s *MyAPIXLSuite) TestObjectMultipartOverwriteSinglePut(c *C) { c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, 200) - request, err = newTestRequest("POST", s.endPoint+"/"+bucketName+"/object?uploads", + objectName := "test-multipart-object" + + request, err = newTestRequest("POST", getNewMultipartURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request initiating the new multipart upload. response, err = client.Do(request) c.Assert(err, IsNil) + // expecting the response status code to be http.StatusOK(200 OK). c.Assert(response.StatusCode, Equals, http.StatusOK) - + // parse the response body and obtain the new upload ID. decoder := xml.NewDecoder(response.Body) newResponse := &InitiateMultipartUploadResponse{} err = decoder.Decode(newResponse) c.Assert(err, IsNil) c.Assert(len(newResponse.UploadID) > 0, Equals, true) + // uploadID to be used for rest of the multipart operations on the object. uploadID := newResponse.UploadID + // content for the part to be uploaded. // Create a byte array of 5MB. data := bytes.Repeat([]byte("0123456789abcdef"), 5*1024*1024/16) - + // calculate md5Sum of the data. hasher := md5.New() hasher.Write(data) md5Sum := hasher.Sum(nil) buffer1 := bytes.NewReader(data) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=1", + // HTTP request for the part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "1"), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) + // set the Content-Md5 header to the base64 encoding the md5Sum of the content. request.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(md5Sum)) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to upload the first part. response1, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response1.StatusCode, Equals, http.StatusOK) // Create a byte array of 1 byte. + // content for the second part to be uploaded. data = []byte("0") hasher = md5.New() hasher.Write(data) + // calculate md5Sum of the data. md5Sum = hasher.Sum(nil) buffer2 := bytes.NewReader(data) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID+"&partNumber=2", + // HTTP request for the second part to be uploaded. + request, err = newTestRequest("PUT", getPartUploadURL(s.endPoint, bucketName, objectName, uploadID, "2"), int64(buffer2.Len()), buffer2, s.accessKey, s.secretKey) + // set the Content-Md5 header to the base64 encoding the md5Sum of the content. request.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(md5Sum)) c.Assert(err, IsNil) client = http.Client{} + // execute the HTTP request to upload the second part. response2, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response2.StatusCode, Equals, http.StatusOK) - // Complete multipart upload + // Complete multipart upload. completeUploads := &completeMultipartUpload{ Parts: []completePart{ { @@ -1979,8 +2142,8 @@ func (s *MyAPIXLSuite) TestObjectMultipartOverwriteSinglePut(c *C) { completeBytes, err := xml.Marshal(completeUploads) c.Assert(err, IsNil) - - request, err = newTestRequest("POST", s.endPoint+"/"+bucketName+"/object?uploadId="+uploadID, + // Indicating that all parts are uploaded and initiating completeMultipartUpload. + request, err = newTestRequest("POST", getCompleteMultipartUploadURL(s.endPoint, bucketName, objectName, uploadID), int64(len(completeBytes)), bytes.NewReader(completeBytes), s.accessKey, s.secretKey) c.Assert(err, IsNil) @@ -1988,26 +2151,34 @@ func (s *MyAPIXLSuite) TestObjectMultipartOverwriteSinglePut(c *C) { c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // A new object is uploaded with same key as before. + // validation for successful overwrite is done by downloading back the object and reading its content. buffer1 = bytes.NewReader([]byte("hello world")) - request, err = newTestRequest("PUT", s.endPoint+"/"+bucketName+"/object", + // HTTP request for uploading the object. + request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objectName), int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request to upload the object. response, err = client.Do(request) c.Assert(err, IsNil) + // verify whether upload was successfull. c.Assert(response.StatusCode, Equals, http.StatusOK) - - request, err = newTestRequest("GET", s.endPoint+"/"+bucketName+"/object", + // HTTP request for downloading the object. + request, err = newTestRequest("GET", getPutObjectURL(s.endPoint, bucketName, objectName), 0, nil, s.accessKey, s.secretKey) c.Assert(err, IsNil) - + // execute the HTTP request to download the object. response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) + // validate the response content length. c.Assert(response.ContentLength, Equals, int64(len([]byte("hello world")))) var buffer3 bytes.Buffer + // read the response body to obtain the content of downloaded object. n, err := io.Copy(&buffer3, response.Body) c.Assert(err, IsNil) + // validate the downloaded content. + // verify successful overwrite with the new content. c.Assert(n, Equals, int64(len([]byte("hello world")))) c.Assert(true, Equals, bytes.Equal(buffer3.Bytes(), []byte("hello world"))) } diff --git a/test-utils_test.go b/test-utils_test.go index 030ba6d85..3dceb9599 100644 --- a/test-utils_test.go +++ b/test-utils_test.go @@ -439,6 +439,60 @@ func getDeleteBucketURL(endPoint, bucketName string) string { } +// return URL for listing the bucket. +func getListObjectsURL(endPoint, bucketName string, maxKeys string) string { + queryValue := url.Values{} + if maxKeys != "" { + queryValue.Set("max-keys", maxKeys) + } + return makeTestTargetURL(endPoint, bucketName, "", queryValue) +} + +// return URL for a new multipart upload. +func getNewMultipartURL(endPoint, bucketName, objectName string) string { + queryValue := url.Values{} + queryValue.Set("uploads", "") + return makeTestTargetURL(endPoint, bucketName, objectName, queryValue) +} + +// return URL for a new multipart upload. +func getPartUploadURL(endPoint, bucketName, objectName, uploadID, partNumber string) string { + queryValues := url.Values{} + queryValues.Set("uploadId", uploadID) + queryValues.Set("partNumber", partNumber) + return makeTestTargetURL(endPoint, bucketName, objectName, queryValues) +} + +// return URL for aborting multipart upload. +func getAbortMultipartUploadURL(endPoint, bucketName, objectName, uploadID string) string { + queryValue := url.Values{} + queryValue.Set("uploadId", uploadID) + return makeTestTargetURL(endPoint, bucketName, objectName, queryValue) +} + +// return URL for a new multipart upload. +func getListMultipartURL(endPoint, bucketName string) string { + queryValue := url.Values{} + queryValue.Set("uploads", "") + return makeTestTargetURL(endPoint, bucketName, "", queryValue) +} + +// return URL for a new multipart upload. +func getListMultipartURLWithParams(endPoint, bucketName, objectName, uploadID, maxParts string) string { + queryValues := url.Values{} + queryValues.Set("uploadId", uploadID) + queryValues.Set("max-parts", maxParts) + return makeTestTargetURL(endPoint, bucketName, objectName, queryValues) +} + +// return URL for completing multipart upload. +// complete multipart upload request is sent after all parts are uploaded. +func getCompleteMultipartUploadURL(endPoint, bucketName, objectName, uploadID string) string { + queryValue := url.Values{} + queryValue.Set("uploadId", uploadID) + return makeTestTargetURL(endPoint, bucketName, objectName, queryValue) +} + // returns temp root directory. ` func getTestRoot() (string, error) { return ioutil.TempDir(os.TempDir(), "api-")