Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1434)

Unified Diff: chrome/browser/google_apis/gdata_wapi_operations_unittest.cc

Issue 11308315: google_apis: Add a test for uploading a large file (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/google_apis/gdata_wapi_operations_unittest.cc
diff --git a/chrome/browser/google_apis/gdata_wapi_operations_unittest.cc b/chrome/browser/google_apis/gdata_wapi_operations_unittest.cc
index cb98d4efaa6d7b1aef957e21dce106fbc58214f3..0be382e271720e98b3dde1fcc0b5a4fa717955f9 100644
--- a/chrome/browser/google_apis/gdata_wapi_operations_unittest.cc
+++ b/chrome/browser/google_apis/gdata_wapi_operations_unittest.cc
@@ -8,6 +8,7 @@
#include "base/json/json_reader.h"
#include "base/message_loop_proxy.h"
#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "base/stringprintf.h"
#include "chrome/browser/google_apis/gdata_wapi_operations.h"
#include "chrome/browser/google_apis/gdata_wapi_parser.h"
@@ -131,6 +132,39 @@ bool RemovePrefix(const std::string& input,
return true;
}
+// Parses a value of Content-Range header, which looks like
+// "bytes <start_position>-<end_position>/<length>".
+// Returns true on success.
+bool ParseContentRangeHeader(const std::string& value,
+ int64* start_position,
+ int64* end_position,
+ int64* length) {
+ DCHECK(start_position);
+ DCHECK(end_position);
+ DCHECK(length);
+
+ std::string remaining;
+ if (!RemovePrefix(value, "bytes ", &remaining))
+ return false;
+
+ std::vector<std::string> parts;
+ base::SplitString(remaining, '/', &parts);
+ if (parts.size() != 2U)
+ return false;
+
+ const std::string range = parts[0];
+ if (!base::StringToInt64(parts[1], length))
+ return false;
+
+ parts.clear();
+ base::SplitString(range, '-', &parts);
+ if (parts.size() != 2U)
+ return false;
+
+ return (base::StringToInt64(parts[0], start_position) &&
+ base::StringToInt64(parts[1], end_position));
+}
+
// This class sets a request context getter for testing in
// |testing_browser_process| and then clears the state when an instance of it
// goes out of scope.
@@ -329,8 +363,41 @@ class GDataWapiOperationsTest : public testing::Test {
// TODO(satorux): We should create a correct entry for the uploaded file,
// but for now, just return entry.xml.
- return CreateHttpResponseFromFile(
- test_util::GetTestFilePath("gdata/entry.xml"));
+ scoped_ptr<test_server::HttpResponse> response =
+ CreateHttpResponseFromFile(
+ test_util::GetTestFilePath("gdata/entry.xml"));
+
+ // Check if the Content-Range header is present. This must be present if
+ // the request body is not empty.
+ if (!request.content.empty()) {
+ std::map<std::string, std::string>::const_iterator iter =
+ request.headers.find("Content-Range");
+ if (iter == request.headers.end())
+ return scoped_ptr<test_server::HttpResponse>();
+ int64 start_position = 0;
+ int64 end_position = 0;
+ int64 length = 0;
+ if (!ParseContentRangeHeader(iter->second,
+ &start_position,
+ &end_position,
+ &length)) {
+ return scoped_ptr<test_server::HttpResponse>();
+ }
+
+ // Add Range header to the response, based on the values of
+ // Content-Range header in the request.
+ response->AddCustomHeader(
+ "Range",
+ "bytes=" +
+ base::Int64ToString(start_position) + "-" +
+ base::Int64ToString(end_position));
+
+ // Change the response code if this is not the end of an upload.
+ if (end_position + 1 < length)
+ response->set_code(test_server::RESUME_INCOMPLETE);
+ }
+
+ return response.Pass();
}
MessageLoopForUI message_loop_;
@@ -862,7 +929,6 @@ TEST_F(GDataWapiOperationsTest, UploadNewFile) {
resume_operation->Start(kTestGDataAuthToken, kTestUserAgent);
MessageLoop::current()->Run();
- EXPECT_EQ(HTTP_SUCCESS, result_code);
// METHOD_PUT should be used to upload data.
EXPECT_EQ(test_server::METHOD_PUT, http_request_.method);
// Request should go to the upload URL.
@@ -875,6 +941,134 @@ TEST_F(GDataWapiOperationsTest, UploadNewFile) {
// The upload content should be set in the HTTP request.
EXPECT_TRUE(http_request_.has_content);
EXPECT_EQ(kUploadContent, http_request_.content);
+
+ // Check the response.
+ EXPECT_EQ(HTTP_SUCCESS, response.code);
+ // The start and end positions should be set to -1, if an upload is complete.
+ EXPECT_EQ(-1, response.start_range_received);
+ EXPECT_EQ(-1, response.end_range_received);
+}
+
+// This test exercises InitiateUploadOperation and ResumeUploadOperation for
+// a scenario of uploading a new *large* file, which requires mutiple requests
+// of ResumeUploadOperation.
+TEST_F(GDataWapiOperationsTest, UploadNewLargeFile) {
+ const size_t kMaxNumBytes = 10;
+ // This is big enough to cause multiple requests of ResumeUploadOperation
+ // as we are gonig to send at most kMaxNumBytes at a time.
+ const std::string kUploadContent(kMaxNumBytes + 1, 'a');
+ GDataErrorCode result_code = GDATA_OTHER_ERROR;
+ GURL upload_url;
+
+ // 1) Get the upload URL for uploading a new file.
+ InitiateUploadParams initiate_params(
+ UPLOAD_NEW_FILE,
+ "New file",
+ "text/plain",
+ kUploadContent.size(),
+ test_server_.GetURL("/feeds/upload/create-session/default/private/full"),
+ FilePath::FromUTF8Unsafe("drive/newfile.txt"));
+
+ InitiateUploadOperation* initiate_operation =
+ new InitiateUploadOperation(
+ &operation_registry_,
+ base::Bind(&CopyResultFromInitiateUploadCallbackAndQuit,
+ &result_code,
+ &upload_url),
+ initiate_params);
+
+ initiate_operation->Start(kTestGDataAuthToken, kTestUserAgent);
+ MessageLoop::current()->Run();
+
+ EXPECT_EQ(HTTP_SUCCESS, result_code);
+ EXPECT_EQ(test_server_.GetURL("/upload_url"), upload_url);
+ EXPECT_EQ(test_server::METHOD_POST, http_request_.method);
+ // convert=false should be passed as files should be uploaded as-is.
+ EXPECT_EQ("/feeds/upload/create-session/default/private/full?convert=false",
+ http_request_.relative_url);
+ EXPECT_EQ("text/plain", http_request_.headers["X-Upload-Content-Type"]);
+ EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]);
+ EXPECT_EQ(base::Int64ToString(kUploadContent.size()),
+ http_request_.headers["X-Upload-Content-Length"]);
+
+ EXPECT_TRUE(http_request_.has_content);
+ EXPECT_EQ("<?xml version=\"1.0\"?>\n"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\" "
+ "xmlns:docs=\"http://schemas.google.com/docs/2007\">\n"
+ " <title>New file</title>\n"
+ "</entry>\n",
+ http_request_.content);
+
+ // 2) Upload the content to the upload URL with multiple requests.
+ size_t num_bytes_consumed = 0;
+ for (size_t start_position = 0; start_position < kUploadContent.size();
+ start_position += kMaxNumBytes) {
+ SCOPED_TRACE(testing::Message("start_position: ") << start_position);
+
+ // The payload is at most kMaxNumBytes.
+ const size_t remaining_size = kUploadContent.size() - start_position;
+ const std::string payload = kUploadContent.substr(
+ start_position, std::min(kMaxNumBytes, remaining_size));
+ num_bytes_consumed += payload.size();
+ // The end position is inclusive, hence -1.
+ const size_t end_position = start_position + payload.size() - 1;
+
+ scoped_refptr<net::IOBuffer> buffer = new net::StringIOBuffer(payload);
+ ResumeUploadParams resume_params(
+ UPLOAD_NEW_FILE,
+ start_position, // start_range
+ end_position, // end_range
+ kUploadContent.size(), // content_length,
+ "text/plain", // content_type
+ buffer,
+ upload_url,
+ FilePath::FromUTF8Unsafe("drive/newfile.txt"));
+
+ ResumeUploadResponse response;
+ scoped_ptr<DocumentEntry> new_entry;
+
+ ResumeUploadOperation* resume_operation =
+ new ResumeUploadOperation(
+ &operation_registry_,
+ base::Bind(&CopyResultFromResumeUploadCallbackAndQuit,
+ &response,
+ &new_entry),
+ resume_params);
+
+ resume_operation->Start(kTestGDataAuthToken, kTestUserAgent);
+ MessageLoop::current()->Run();
+
+ // METHOD_PUT should be used to upload data.
+ EXPECT_EQ(test_server::METHOD_PUT, http_request_.method);
+ // Request should go to the upload URL.
+ EXPECT_EQ(upload_url.path(), http_request_.relative_url);
+ // Content-Range header should be added.
+ EXPECT_EQ("bytes " +
+ base::Int64ToString(start_position) + "-" +
+ base::Int64ToString(end_position) + "/" +
+ base::Int64ToString(kUploadContent.size()),
+ http_request_.headers["Content-Range"]);
+ // The upload content should be set in the HTTP request.
+ EXPECT_TRUE(http_request_.has_content);
+ EXPECT_EQ(payload, http_request_.content);
+
+ // Check the response.
+ if (payload.size() == remaining_size) {
+ EXPECT_EQ(HTTP_SUCCESS, response.code);
kinaba 2012/12/03 04:37:57 The expected response code for UPLOAD_NEW_FILE mod
satorux1 2012/12/03 05:02:22 Good catch! Fixed!
+ // The start and end positions should be set to -1, if an upload is
+ // complete.
+ EXPECT_EQ(-1, response.start_range_received);
+ EXPECT_EQ(-1, response.end_range_received);
+ } else {
+ EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
+ EXPECT_EQ(static_cast<int64>(start_position),
+ response.start_range_received);
+ EXPECT_EQ(static_cast<int64>(end_position),
+ response.end_range_received);
+ }
+ }
+
+ EXPECT_EQ(kUploadContent.size(), num_bytes_consumed);
}
// This test exercises InitiateUploadOperation and ResumeUploadOperation for
@@ -952,7 +1146,6 @@ TEST_F(GDataWapiOperationsTest, UploadNewEmptyFile) {
resume_operation->Start(kTestGDataAuthToken, kTestUserAgent);
MessageLoop::current()->Run();
- EXPECT_EQ(HTTP_SUCCESS, result_code);
// METHOD_PUT should be used to upload data.
EXPECT_EQ(test_server::METHOD_PUT, http_request_.method);
// Request should go to the upload URL.
@@ -963,6 +1156,12 @@ TEST_F(GDataWapiOperationsTest, UploadNewEmptyFile) {
// The upload content should be set in the HTTP request.
EXPECT_TRUE(http_request_.has_content);
EXPECT_EQ(kUploadContent, http_request_.content);
+
+ // Check the response.
+ EXPECT_EQ(HTTP_SUCCESS, response.code);
+ // The start and end positions should be set to -1, if an upload is complete.
+ EXPECT_EQ(-1, response.start_range_received);
+ EXPECT_EQ(-1, response.end_range_received);
}
// This test exercises InitiateUploadOperation and ResumeUploadOperation for
@@ -1038,7 +1237,6 @@ TEST_F(GDataWapiOperationsTest, UploadExistingFile) {
resume_operation->Start(kTestGDataAuthToken, kTestUserAgent);
MessageLoop::current()->Run();
- EXPECT_EQ(HTTP_SUCCESS, result_code);
// METHOD_PUT should be used to upload data.
EXPECT_EQ(test_server::METHOD_PUT, http_request_.method);
// Request should go to the upload URL.
@@ -1051,6 +1249,12 @@ TEST_F(GDataWapiOperationsTest, UploadExistingFile) {
// The upload content should be set in the HTTP request.
EXPECT_TRUE(http_request_.has_content);
EXPECT_EQ(kUploadContent, http_request_.content);
+
+ // Check the response.
+ EXPECT_EQ(HTTP_SUCCESS, response.code);
+ // The start and end positions should be set to -1, if an upload is complete.
+ EXPECT_EQ(-1, response.start_range_received);
+ EXPECT_EQ(-1, response.end_range_received);
}
} // namespace google_apis
« no previous file with comments | « chrome/browser/google_apis/gdata_wapi_operations.h ('k') | chrome/browser/google_apis/test_server/http_response.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698