diff options
author | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-01 03:46:06 +0000 |
---|---|---|
committer | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-01 03:46:06 +0000 |
commit | ad91dc59050338aab2fd258aea360f96dd7c1ab2 (patch) | |
tree | e4a09db9edf6982a2714d99f5221797ce9e6626e /net/base | |
parent | 0f3a2d136bbe988ad5fa8b5585d2d1b6dfd40aff (diff) | |
download | chromium_src-ad91dc59050338aab2fd258aea360f96dd7c1ab2.zip chromium_src-ad91dc59050338aab2fd258aea360f96dd7c1ab2.tar.gz chromium_src-ad91dc59050338aab2fd258aea360f96dd7c1ab2.tar.bz2 |
net: Move file operation code from UploadData to UploadDataStream
ResetOffset(), GetContentLength() and IsInMemory() are moved from UploadData to UploadDataStream.
This is an intermediate step to make simlar change to UploadElement
BUG=72001
TEST=net_unittests
Review URL: https://chromiumcodereview.appspot.com/10878082
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154594 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/upload_data.cc | 59 | ||||
-rw-r--r-- | net/base/upload_data.h | 26 | ||||
-rw-r--r-- | net/base/upload_data_stream.cc | 31 | ||||
-rw-r--r-- | net/base/upload_data_stream_unittest.cc | 92 | ||||
-rw-r--r-- | net/base/upload_data_unittest.cc | 169 |
5 files changed, 112 insertions, 265 deletions
diff --git a/net/base/upload_data.cc b/net/base/upload_data.cc index f3dc22c..e9619dd 100644 --- a/net/base/upload_data.cc +++ b/net/base/upload_data.cc @@ -11,17 +11,6 @@ namespace net { -namespace { - -// Helper function for GetContentLength(). -void OnGetContentLengthComplete( - const UploadData::ContentLengthCallback& callback, - uint64* content_length) { - callback.Run(*content_length); -} - -} // namespace - UploadData::UploadData() : identifier_(0), chunk_callback_(NULL), @@ -62,58 +51,10 @@ void UploadData::set_chunk_callback(ChunkCallback* callback) { chunk_callback_ = callback; } -void UploadData::GetContentLength(const ContentLengthCallback& callback) { - uint64* result = new uint64(0); - const bool task_is_slow = true; - const bool posted = base::WorkerPool::PostTaskAndReply( - FROM_HERE, - base::Bind(&UploadData::DoGetContentLength, this, result), - base::Bind(&OnGetContentLengthComplete, callback, base::Owned(result)), - task_is_slow); - DCHECK(posted); -} - -uint64 UploadData::GetContentLengthSync() { - uint64 content_length = 0; - DoGetContentLength(&content_length); - return content_length; -} - -bool UploadData::IsInMemory() const { - // Chunks are in memory, but UploadData does not have all the chunks at - // once. Chunks are provided progressively with AppendChunk() as chunks - // are ready. Check is_chunked_ here, rather than relying on the loop - // below, as there is a case that is_chunked_ is set to true, but the - // first chunk is not yet delivered. - if (is_chunked_) - return false; - - for (size_t i = 0; i < elements_.size(); ++i) { - if (elements_[i].type() != UploadElement::TYPE_BYTES) - return false; - } - return true; -} - -void UploadData::ResetOffset() { - for (size_t i = 0; i < elements_.size(); ++i) - elements_[i].ResetOffset(); -} - void UploadData::SetElements(const std::vector<UploadElement>& elements) { elements_ = elements; } -void UploadData::DoGetContentLength(uint64* content_length) { - *content_length = 0; - - if (is_chunked_) - return; - - for (size_t i = 0; i < elements_.size(); ++i) - *content_length += elements_[i].GetContentLength(); -} - UploadData::~UploadData() { } diff --git a/net/base/upload_data.h b/net/base/upload_data.h index 9313181..b35263c 100644 --- a/net/base/upload_data.h +++ b/net/base/upload_data.h @@ -15,7 +15,6 @@ #include "net/base/upload_element.h" class FilePath; -class GURL; namespace base { class Time; @@ -68,28 +67,6 @@ class NET_EXPORT UploadData void set_last_chunk_appended(bool set) { last_chunk_appended_ = set; } bool last_chunk_appended() const { return last_chunk_appended_; } - // Gets the total size in bytes of the data to upload. Computing the - // content length can result in performing file IO hence the operation is - // done asynchronously. Runs the callback with the content length once the - // computation is done. - typedef base::Callback<void(uint64 content_length)> ContentLengthCallback; - void GetContentLength(const ContentLengthCallback& callback); - - // Returns the total size in bytes of the data to upload, for testing. - // This version may perform file IO on the current thread. This function - // will fail if called on a thread where file IO is prohibited. Usually - // used for testing, but Chrome Frame also uses this version. - uint64 GetContentLengthSync(); - - // Returns true if the upload data is entirely in memory (i.e. the - // upload data is not chunked, and all elemnts are of TYPE_BYTES). - bool IsInMemory() const; - - // Resets the offset of each upload data element to zero, so that the - // upload data can be reread. This can happen if the same upload data is - // reused for a new UploadDataStream. - void ResetOffset(); - const std::vector<UploadElement>* elements() const { return &elements_; } @@ -111,9 +88,6 @@ class NET_EXPORT UploadData int64 identifier() const { return identifier_; } private: - // Helper function for GetContentLength(). - void DoGetContentLength(uint64* content_length); - friend class base::RefCounted<UploadData>; virtual ~UploadData(); diff --git a/net/base/upload_data_stream.cc b/net/base/upload_data_stream.cc index 239053f..b96680e 100644 --- a/net/base/upload_data_stream.cc +++ b/net/base/upload_data_stream.cc @@ -34,10 +34,14 @@ UploadDataStream::~UploadDataStream() { int UploadDataStream::Init() { DCHECK(!initialized_successfully_); - + std::vector<UploadElement>* elements = upload_data_->elements_mutable(); { base::ThreadRestrictions::ScopedAllowIO allow_io; - total_size_ = upload_data_->GetContentLengthSync(); + total_size_ = 0; + if (!is_chunked()) { + for (size_t i = 0; i < elements->size(); ++i) + total_size_ += (*elements)[i].GetContentLength(); + } } // If the underlying file has been changed and the expected file @@ -45,9 +49,8 @@ int UploadDataStream::Init() { // modification time from WebKit is based on time_t precision. So we // have to convert both to time_t to compare. This check is used for // sliced files. - const std::vector<UploadElement>& elements = *upload_data_->elements(); - for (size_t i = 0; i < elements.size(); ++i) { - const UploadElement& element = elements[i]; + for (size_t i = 0; i < elements->size(); ++i) { + const UploadElement& element = (*elements)[i]; if (element.type() == UploadElement::TYPE_FILE && !element.expected_file_modification_time().is_null()) { // Temporarily allow until fix: http://crbug.com/72001. @@ -63,7 +66,8 @@ int UploadDataStream::Init() { // Reset the offset, as upload_data_ may already be read (i.e. UploadData // can be reused for a new UploadDataStream). - upload_data_->ResetOffset(); + for (size_t i = 0; i < elements->size(); ++i) + (*elements)[i].ResetOffset(); initialized_successfully_ = true; return OK; @@ -107,9 +111,20 @@ bool UploadDataStream::IsEOF() const { } bool UploadDataStream::IsInMemory() const { - DCHECK(initialized_successfully_); + // Chunks are in memory, but UploadData does not have all the chunks at + // once. Chunks are provided progressively with AppendChunk() as chunks + // are ready. Check is_chunked_ here, rather than relying on the loop + // below, as there is a case that is_chunked_ is set to true, but the + // first chunk is not yet delivered. + if (is_chunked()) + return false; - return upload_data_->IsInMemory(); + const std::vector<UploadElement>& elements = *upload_data_->elements(); + for (size_t i = 0; i < elements.size(); ++i) { + if (elements[i].type() != UploadElement::TYPE_BYTES) + return false; + } + return true; } } // namespace net diff --git a/net/base/upload_data_stream_unittest.cc b/net/base/upload_data_stream_unittest.cc index c6d6120..dc415f84 100644 --- a/net/base/upload_data_stream_unittest.cc +++ b/net/base/upload_data_stream_unittest.cc @@ -55,16 +55,18 @@ TEST_F(UploadDataStreamTest, EmptyUploadData) { upload_data_->AppendBytes("", 0); scoped_ptr<UploadDataStream> stream(new UploadDataStream(upload_data_)); ASSERT_EQ(OK, stream->Init()); + EXPECT_TRUE(stream->IsInMemory()); ASSERT_TRUE(stream.get()); EXPECT_EQ(0U, stream->size()); EXPECT_EQ(0U, stream->position()); EXPECT_TRUE(stream->IsEOF()); } -TEST_F(UploadDataStreamTest, ConsumeAll) { +TEST_F(UploadDataStreamTest, ConsumeAllBytes) { upload_data_->AppendBytes(kTestData, kTestDataSize); scoped_ptr<UploadDataStream> stream(new UploadDataStream(upload_data_)); ASSERT_EQ(OK, stream->Init()); + EXPECT_TRUE(stream->IsInMemory()); ASSERT_TRUE(stream.get()); EXPECT_EQ(kTestDataSize, stream->size()); EXPECT_EQ(0U, stream->position()); @@ -78,6 +80,35 @@ TEST_F(UploadDataStreamTest, ConsumeAll) { ASSERT_TRUE(stream->IsEOF()); } +TEST_F(UploadDataStreamTest, File) { + FilePath temp_file_path; + ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path)); + ASSERT_EQ(static_cast<int>(kTestDataSize), + file_util::WriteFile(temp_file_path, kTestData, kTestDataSize)); + + std::vector<UploadElement> elements; + UploadElement element; + element.SetToFilePath(temp_file_path); + elements.push_back(element); + upload_data_->SetElements(elements); + + scoped_ptr<UploadDataStream> stream(new UploadDataStream(upload_data_)); + ASSERT_EQ(OK, stream->Init()); + EXPECT_FALSE(stream->IsInMemory()); + ASSERT_TRUE(stream.get()); + EXPECT_EQ(kTestDataSize, stream->size()); + EXPECT_EQ(0U, stream->position()); + EXPECT_FALSE(stream->IsEOF()); + scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); + while (!stream->IsEOF()) { + int bytes_read = stream->Read(buf, kTestBufferSize); + ASSERT_LE(0, bytes_read); // Not an error. + } + EXPECT_EQ(kTestDataSize, stream->position()); + ASSERT_TRUE(stream->IsEOF()); + file_util::Delete(temp_file_path, false); +} + TEST_F(UploadDataStreamTest, FileSmallerThanLength) { FilePath temp_file_path; ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path)); @@ -91,10 +122,10 @@ TEST_F(UploadDataStreamTest, FileSmallerThanLength) { element.SetContentLength(kFakeSize); elements.push_back(element); upload_data_->SetElements(elements); - EXPECT_EQ(kFakeSize, upload_data_->GetContentLengthSync()); scoped_ptr<UploadDataStream> stream(new UploadDataStream(upload_data_)); ASSERT_EQ(OK, stream->Init()); + EXPECT_FALSE(stream->IsInMemory()); ASSERT_TRUE(stream.get()); EXPECT_EQ(kFakeSize, stream->size()); EXPECT_EQ(0U, stream->position()); @@ -115,6 +146,60 @@ TEST_F(UploadDataStreamTest, FileSmallerThanLength) { file_util::Delete(temp_file_path, false); } +TEST_F(UploadDataStreamTest, FileAndBytes) { + FilePath temp_file_path; + ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path)); + ASSERT_EQ(static_cast<int>(kTestDataSize), + file_util::WriteFile(temp_file_path, kTestData, kTestDataSize)); + + const uint64 kFileRangeOffset = 1; + const uint64 kFileRangeLength = 4; + upload_data_->AppendFileRange( + temp_file_path, kFileRangeOffset, kFileRangeLength, base::Time()); + + upload_data_->AppendBytes(kTestData, kTestDataSize); + + const uint64 kStreamSize = kTestDataSize + kFileRangeLength; + scoped_ptr<UploadDataStream> stream(new UploadDataStream(upload_data_)); + ASSERT_EQ(OK, stream->Init()); + EXPECT_FALSE(stream->IsInMemory()); + ASSERT_TRUE(stream.get()); + EXPECT_EQ(kStreamSize, stream->size()); + EXPECT_EQ(0U, stream->position()); + EXPECT_FALSE(stream->IsEOF()); + scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); + while (!stream->IsEOF()) { + int bytes_read = stream->Read(buf, kTestBufferSize); + ASSERT_LE(0, bytes_read); // Not an error. + } + EXPECT_EQ(kStreamSize, stream->position()); + ASSERT_TRUE(stream->IsEOF()); + + file_util::Delete(temp_file_path, false); +} + +TEST_F(UploadDataStreamTest, Chunk) { + upload_data_->set_is_chunked(true); + upload_data_->AppendChunk(kTestData, kTestDataSize, false); + upload_data_->AppendChunk(kTestData, kTestDataSize, true); + + const uint64 kStreamSize = kTestDataSize*2; + scoped_ptr<UploadDataStream> stream(new UploadDataStream(upload_data_)); + ASSERT_EQ(OK, stream->Init()); + EXPECT_FALSE(stream->IsInMemory()); + ASSERT_TRUE(stream.get()); + EXPECT_EQ(0U, stream->size()); // Content-Length is 0 for chunked data. + EXPECT_EQ(0U, stream->position()); + EXPECT_FALSE(stream->IsEOF()); + scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); + while (!stream->IsEOF()) { + int bytes_read = stream->Read(buf, kTestBufferSize); + ASSERT_LE(0, bytes_read); // Not an error. + } + EXPECT_EQ(kStreamSize, stream->position()); + ASSERT_TRUE(stream->IsEOF()); +} + void UploadDataStreamTest::FileChangedHelper(const FilePath& file_path, const base::Time& time, bool error_expected) { @@ -167,12 +252,12 @@ TEST_F(UploadDataStreamTest, UploadDataReused) { element.SetToFilePath(temp_file_path); elements.push_back(element); upload_data_->SetElements(elements); - EXPECT_EQ(kTestDataSize, upload_data_->GetContentLengthSync()); // Confirm that the file is read properly. { UploadDataStream stream(upload_data_); ASSERT_EQ(OK, stream.Init()); + EXPECT_EQ(kTestDataSize, stream.size()); EXPECT_EQ(kTestData, ReadFromUploadDataStream(&stream)); } @@ -181,6 +266,7 @@ TEST_F(UploadDataStreamTest, UploadDataReused) { { UploadDataStream stream(upload_data_); ASSERT_EQ(OK, stream.Init()); + EXPECT_EQ(kTestDataSize, stream.size()); EXPECT_EQ(kTestData, ReadFromUploadDataStream(&stream)); } diff --git a/net/base/upload_data_unittest.cc b/net/base/upload_data_unittest.cc deleted file mode 100644 index 98bb23d..0000000 --- a/net/base/upload_data_unittest.cc +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/upload_data.h" - -#include "base/bind.h" -#include "base/file_path.h" -#include "base/file_util.h" -#include "base/message_loop.h" -#include "base/scoped_temp_dir.h" -#include "base/memory/ref_counted.h" -#include "base/threading/thread_restrictions.h" -#include "base/time.h" -#include "googleurl/src/gurl.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -namespace net { - -// Simplified version of TestCompletionCallback for ContentLengthCallback, -// that handles uint64 rather than int. -class TestContentLengthCallback { - public: - TestContentLengthCallback() - : result_(0), - callback_(ALLOW_THIS_IN_INITIALIZER_LIST( - base::Bind(&TestContentLengthCallback::SetResult, - base::Unretained(this)))) { - } - - ~TestContentLengthCallback() {} - - const UploadData::ContentLengthCallback& callback() const { - return callback_; - } - - // Waits for the result and returns it. - uint64 WaitForResult() { - MessageLoop::current()->Run(); - return result_; - } - - private: - // Sets the result and stops the message loop. - void SetResult(uint64 result) { - result_ = result; - MessageLoop::current()->Quit(); - } - - uint64 result_; - const UploadData::ContentLengthCallback callback_; - - DISALLOW_COPY_AND_ASSIGN(TestContentLengthCallback); -}; - -class UploadDataTest : public PlatformTest { - protected: - virtual void SetUp() { - upload_data_= new UploadData; - // To ensure that file IO is not performed on the main thread in the - // test (i.e. GetContentLengthSync() will fail if file IO is performed). - base::ThreadRestrictions::SetIOAllowed(false); - } - - virtual void TearDown() { - base::ThreadRestrictions::SetIOAllowed(true); - } - - // Creates a temporary file with the given data. The temporary file is - // deleted by temp_dir_. Returns true on success. - bool CreateTemporaryFile(const std::string& data, - FilePath* temp_file_path) { - base::ThreadRestrictions::ScopedAllowIO allow_io; - if (!temp_dir_.CreateUniqueTempDir()) - return false; - if (!file_util::CreateTemporaryFileInDir(temp_dir_.path(), temp_file_path)) - return false; - if (static_cast<int>(data.size()) != - file_util::WriteFile(*temp_file_path, data.data(), data.size())) - return false; - - return true; - } - - ScopedTempDir temp_dir_; - scoped_refptr<UploadData> upload_data_; -}; - -TEST_F(UploadDataTest, IsInMemory_Empty) { - ASSERT_TRUE(upload_data_->IsInMemory()); -} - -TEST_F(UploadDataTest, IsInMemory_Bytes) { - upload_data_->AppendBytes("123", 3); - ASSERT_TRUE(upload_data_->IsInMemory()); -} - -TEST_F(UploadDataTest, IsInMemory_File) { - upload_data_->AppendFileRange( - FilePath(FILE_PATH_LITERAL("random_file_name.txt")), - 0, 0, base::Time()); - ASSERT_FALSE(upload_data_->IsInMemory()); -} - -TEST_F(UploadDataTest, IsInMemory_Chunk) { - upload_data_->set_is_chunked(true); - ASSERT_FALSE(upload_data_->IsInMemory()); -} - -TEST_F(UploadDataTest, IsInMemory_Mixed) { - ASSERT_TRUE(upload_data_->IsInMemory()); - - upload_data_->AppendBytes("123", 3); - upload_data_->AppendBytes("abc", 3); - ASSERT_TRUE(upload_data_->IsInMemory()); - - upload_data_->AppendFileRange( - FilePath(FILE_PATH_LITERAL("random_file_name.txt")), - 0, 0, base::Time()); - ASSERT_FALSE(upload_data_->IsInMemory()); -} - -TEST_F(UploadDataTest, GetContentLength_Empty) { - ASSERT_EQ(0U, upload_data_->GetContentLengthSync()); -} - -TEST_F(UploadDataTest, GetContentLength_Bytes) { - upload_data_->AppendBytes("123", 3); - ASSERT_EQ(3U, upload_data_->GetContentLengthSync()); -} - -TEST_F(UploadDataTest, GetContentLength_File) { - // Create a temporary file with some data. - const std::string kData = "hello"; - FilePath temp_file_path; - ASSERT_TRUE(CreateTemporaryFile(kData, &temp_file_path)); - upload_data_->AppendFileRange(temp_file_path, 0, kuint64max, base::Time()); - - // The length is returned asynchronously. - TestContentLengthCallback callback; - upload_data_->GetContentLength(callback.callback()); - ASSERT_EQ(kData.size(), callback.WaitForResult()); -} - -TEST_F(UploadDataTest, GetContentLength_Chunk) { - upload_data_->set_is_chunked(true); - ASSERT_EQ(0U, upload_data_->GetContentLengthSync()); -} - -TEST_F(UploadDataTest, GetContentLength_Mixed) { - upload_data_->AppendBytes("123", 3); - upload_data_->AppendBytes("abc", 3); - - const uint64 content_length = upload_data_->GetContentLengthSync(); - ASSERT_EQ(6U, content_length); - - // Append a file. - const std::string kData = "hello"; - FilePath temp_file_path; - ASSERT_TRUE(CreateTemporaryFile(kData, &temp_file_path)); - upload_data_->AppendFileRange(temp_file_path, 0, kuint64max, base::Time()); - - TestContentLengthCallback callback; - upload_data_->GetContentLength(callback.callback()); - ASSERT_EQ(content_length + kData.size(), callback.WaitForResult()); -} - -} // namespace net |