1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/upload_data_stream.h"
6
7 #include <vector>
8
9 #include "base/basictypes.h"
10 #include "base/file_path.h"
11 #include "base/file_util.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/time.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/upload_data.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/platform_test.h"
18
19 namespace net {
20
21 namespace {
22
23 const char kTestData[] = "0123456789";
24 const int kTestDataSize = arraysize(kTestData) - 1;
25
26 } // namespace
27
28 class UploadDataStreamTest : public PlatformTest {
29 public:
UploadDataStreamTest()30 UploadDataStreamTest() : upload_data_(new UploadData) { }
31
32 void FileChangedHelper(const FilePath& file_path,
33 const base::Time& time,
34 bool error_expected);
35
36 scoped_refptr<UploadData> upload_data_;
37 };
38
TEST_F(UploadDataStreamTest,EmptyUploadData)39 TEST_F(UploadDataStreamTest, EmptyUploadData) {
40 upload_data_->AppendBytes("", 0);
41 scoped_ptr<UploadDataStream> stream(
42 UploadDataStream::Create(upload_data_, NULL));
43 ASSERT_TRUE(stream.get());
44 EXPECT_TRUE(stream->eof());
45 }
46
TEST_F(UploadDataStreamTest,ConsumeAll)47 TEST_F(UploadDataStreamTest, ConsumeAll) {
48 upload_data_->AppendBytes(kTestData, kTestDataSize);
49 scoped_ptr<UploadDataStream> stream(
50 UploadDataStream::Create(upload_data_, NULL));
51 ASSERT_TRUE(stream.get());
52 while (!stream->eof()) {
53 stream->MarkConsumedAndFillBuffer(stream->buf_len());
54 }
55 }
56
TEST_F(UploadDataStreamTest,FileSmallerThanLength)57 TEST_F(UploadDataStreamTest, FileSmallerThanLength) {
58 FilePath temp_file_path;
59 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
60 ASSERT_EQ(kTestDataSize, file_util::WriteFile(temp_file_path,
61 kTestData, kTestDataSize));
62 const uint64 kFakeSize = kTestDataSize*2;
63
64 std::vector<UploadData::Element> elements;
65 UploadData::Element element;
66 element.SetToFilePath(temp_file_path);
67 element.SetContentLength(kFakeSize);
68 elements.push_back(element);
69 upload_data_->SetElements(elements);
70 EXPECT_EQ(kFakeSize, upload_data_->GetContentLength());
71
72 scoped_ptr<UploadDataStream> stream(
73 UploadDataStream::Create(upload_data_, NULL));
74 ASSERT_TRUE(stream.get());
75 EXPECT_FALSE(stream->eof());
76 uint64 read_counter = 0;
77 while (!stream->eof()) {
78 read_counter += stream->buf_len();
79 stream->MarkConsumedAndFillBuffer(stream->buf_len());
80 }
81 // UpdateDataStream will pad out the file with 0 bytes so that the HTTP
82 // transaction doesn't hang. Therefore we expected the full size.
83 EXPECT_EQ(read_counter, stream->size());
84
85 file_util::Delete(temp_file_path, false);
86 }
87
FileChangedHelper(const FilePath & file_path,const base::Time & time,bool error_expected)88 void UploadDataStreamTest::FileChangedHelper(const FilePath& file_path,
89 const base::Time& time,
90 bool error_expected) {
91 std::vector<UploadData::Element> elements;
92 UploadData::Element element;
93 element.SetToFilePathRange(file_path, 1, 2, time);
94 elements.push_back(element);
95 upload_data_->SetElements(elements);
96
97 int error_code;
98 scoped_ptr<UploadDataStream> stream(
99 UploadDataStream::Create(upload_data_, &error_code));
100 if (error_expected)
101 ASSERT_TRUE(!stream.get() && error_code == ERR_UPLOAD_FILE_CHANGED);
102 else
103 ASSERT_TRUE(stream.get() && error_code == OK);
104 }
105
TEST_F(UploadDataStreamTest,FileChanged)106 TEST_F(UploadDataStreamTest, FileChanged) {
107 FilePath temp_file_path;
108 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
109 ASSERT_EQ(kTestDataSize, file_util::WriteFile(temp_file_path,
110 kTestData, kTestDataSize));
111
112 base::PlatformFileInfo file_info;
113 ASSERT_TRUE(file_util::GetFileInfo(temp_file_path, &file_info));
114
115 // Test file not changed.
116 FileChangedHelper(temp_file_path, file_info.last_modified, false);
117
118 // Test file changed.
119 FileChangedHelper(temp_file_path,
120 file_info.last_modified - base::TimeDelta::FromSeconds(1),
121 true);
122
123 file_util::Delete(temp_file_path, false);
124 }
125
126 } // namespace net
127