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
19namespace net {
20
21namespace {
22
23const char kTestData[] = "0123456789";
24const int kTestDataSize = arraysize(kTestData) - 1;
25
26}  // namespace
27
28class UploadDataStreamTest : public PlatformTest {
29 public:
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
39TEST_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
47TEST_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
57TEST_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
88void 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
106TEST_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