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

Side by Side Diff: net/url_request/url_request_file_job_unittest.cc

Issue 227943003: Add experiment to measure time to hash extension content as we read it (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: responded to review comments Created 6 years, 8 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/url_request/url_request_file_job.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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/url_request/url_request_file_job.h"
6
7 #include "base/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/run_loop.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/threading/sequenced_worker_pool.h"
12 #include "net/base/net_util.h"
13 #include "net/url_request/url_request_test_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace {
17
18 // A URLRequestFileJob for testing OnSeekComplete / OnReadComplete callbacks.
19 class URLRequestFileJobWithCallbacks : public net::URLRequestFileJob {
20 public:
21 URLRequestFileJobWithCallbacks(
22 net::URLRequest* request,
23 net::NetworkDelegate* network_delegate,
24 const base::FilePath& file_path,
25 const scoped_refptr<base::TaskRunner>& file_task_runner)
26 : URLRequestFileJob(request,
27 network_delegate,
28 file_path,
29 file_task_runner),
30 seek_position_(0) {
31 }
32
33 int64 seek_position() { return seek_position_; }
34 const std::vector<std::string>& data_chunks() { return data_chunks_; }
35
36 protected:
37 virtual ~URLRequestFileJobWithCallbacks() {}
38
39 virtual void OnSeekComplete(int64 result) OVERRIDE {
40 ASSERT_EQ(seek_position_, 0);
41 seek_position_ = result;
42 }
43
44 virtual void OnReadComplete(net::IOBuffer* buf, int result) OVERRIDE {
45 data_chunks_.push_back(std::string(buf->data(), result));
46 }
47
48 int64 seek_position_;
49 std::vector<std::string> data_chunks_;
50 };
51
52 // A URLRequestJobFactory that will return URLRequestFileJobWithCallbacks
53 // instances for file:// scheme URLs.
54 class CallbacksJobFactory : public net::URLRequestJobFactory {
55 public:
56 class JobObserver {
57 public:
58 virtual void OnJobCreated(URLRequestFileJobWithCallbacks* job) = 0;
59 };
60
61 CallbacksJobFactory(const base::FilePath& path, JobObserver* observer)
62 : path_(path), observer_(observer) {
63 }
64
65 virtual ~CallbacksJobFactory() {}
66
67 virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
68 const std::string& scheme,
69 net::URLRequest* request,
70 net::NetworkDelegate* network_delegate) const OVERRIDE {
71 URLRequestFileJobWithCallbacks* job = new URLRequestFileJobWithCallbacks(
72 request,
73 network_delegate,
74 path_,
75 base::MessageLoop::current()->message_loop_proxy());
76 observer_->OnJobCreated(job);
77 return job;
78 }
79
80 virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE {
81 return scheme == "file";
82 }
83
84 virtual bool IsHandledURL(const GURL& url) const OVERRIDE {
85 return IsHandledProtocol(url.scheme());
86 }
87
88 virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE {
89 return false;
90 }
91
92 private:
93 base::FilePath path_;
94 JobObserver* observer_;
95 };
96
97 // Helper function to create a file in |directory| named |filename| filled with
98 // |content|. Returns true on succes and fills in |path| with the full path to
99 // the file. If |directory| does not exist yet, it will be created.
100 bool CreateTempFileWithContent(const std::string& filename,
101 const std::string& content,
102 base::ScopedTempDir* directory,
103 base::FilePath* path) {
104 if (directory == NULL || path == NULL || !IsStringASCII(filename))
105 return false;
106 if (!directory->IsValid() && !directory->CreateUniqueTempDir())
107 return false;
108 *path = directory->path().AppendASCII(filename);
109
110 if (!base::CreateTemporaryFileInDir(directory->path(), path))
rvargas (doing something else) 2014/04/09 23:48:50 doing this makes some of the code above redundant
asargent_no_longer_on_chrome 2014/04/10 00:17:27 Yep, good catch. I've further simplified it - made
111 return false;
112
113 return base::WriteFile(*path, content.c_str(), content.length());
114 }
115
116 class JobObserverImpl : public CallbacksJobFactory::JobObserver {
117 public:
118 virtual void OnJobCreated(URLRequestFileJobWithCallbacks* job) OVERRIDE {
119 jobs_.push_back(job);
120 }
121
122 typedef std::vector<scoped_refptr<URLRequestFileJobWithCallbacks> > JobList;
123
124 const JobList& jobs() { return jobs_; }
125
126 protected:
127 JobList jobs_;
128 };
129
130 // A simple holder for start/end used in http range requests.
131 struct Range {
132 int start;
133 int end;
134
135 Range() {
136 start = 0;
137 end = 0;
138 }
139
140 Range(int start, int end) {
141 this->start = start;
142 this->end = end;
143 }
144 };
145
146 // A superclass for tests of the OnSeekComplete / OnReadComplete functions of
147 // URLRequestFileJob.
148 class URLRequestFileJobEventsTest : public testing::Test {
149 public:
150 URLRequestFileJobEventsTest();
151
152 protected:
153 // This creates a file with |content| as the contents, and then creates and
154 // runs a URLRequestFileJobWithCallbacks job to get the contents out of it,
155 // and makes sure that the callbacks observed the correct bytes. If a Range
156 // is provided, this function will add the appropriate Range http header to
157 // the request and verify that only the bytes in that range (inclusive) were
158 // observed.
159 void RunRequest(const std::string& content, const Range* range);
160
161 JobObserverImpl observer_;
162 net::TestURLRequestContext context_;
163 net::TestDelegate delegate_;
164 };
165
166 URLRequestFileJobEventsTest::URLRequestFileJobEventsTest() {}
167
168 void URLRequestFileJobEventsTest::RunRequest(const std::string& content,
169 const Range* range) {
170 base::ScopedTempDir directory;
171 base::FilePath path;
172 ASSERT_TRUE(
173 CreateTempFileWithContent("file.dat", content, &directory, &path));
174 CallbacksJobFactory factory(path, &observer_);
175 context_.set_job_factory(&factory);
176
177 net::TestURLRequest request(net::FilePathToFileURL(path),
178 net::DEFAULT_PRIORITY,
179 &delegate_,
180 &context_);
181 if (range) {
182 ASSERT_GE(range->start, 0);
183 ASSERT_GE(range->end, 0);
184 ASSERT_LE(range->start, range->end);
185 ASSERT_LT(static_cast<unsigned int>(range->end), content.length());
186 std::string range_value =
187 base::StringPrintf("bytes=%d-%d", range->start, range->end);
188 request.SetExtraRequestHeaderByName(
189 net::HttpRequestHeaders::kRange, range_value, true /*overwrite*/);
190 }
191 request.Start();
192
193 base::RunLoop loop;
194 loop.Run();
195
196 EXPECT_FALSE(delegate_.request_failed());
197 int expected_length =
198 range ? (range->end - range->start + 1) : content.length();
199 EXPECT_EQ(delegate_.bytes_received(), expected_length);
200
201 std::string expected_content;
202 if (range) {
203 expected_content.insert(0, content, range->start, expected_length);
204 } else {
205 expected_content = content;
206 }
207 EXPECT_TRUE(delegate_.data_received() == expected_content);
208
209 ASSERT_EQ(observer_.jobs().size(), 1u);
210 ASSERT_EQ(observer_.jobs().at(0)->seek_position(), range ? range->start : 0);
211
212 std::string observed_content;
213 const std::vector<std::string>& chunks =
214 observer_.jobs().at(0)->data_chunks();
215 for (std::vector<std::string>::const_iterator i = chunks.begin();
216 i != chunks.end();
217 ++i) {
218 observed_content.append(*i);
219 }
220 EXPECT_EQ(expected_content, observed_content);
221 EXPECT_TRUE(expected_content == observed_content);
222 }
223
224 // Helper function to make a character array filled with |size| bytes of
225 // test content.
226 std::string MakeContentOfSize(int size) {
227 EXPECT_GE(size, 0);
228 std::string result;
229 result.reserve(size);
230 for (int i = 0; i < size; i++) {
231 result.append(1, static_cast<char>(i % 256));
232 }
233 return result;
234 }
235
236 } // namespace
237
238 TEST_F(URLRequestFileJobEventsTest, TinyFile) {
239 RunRequest(std::string("hello world"), NULL);
240 }
241
242 TEST_F(URLRequestFileJobEventsTest, SmallFile) {
243 RunRequest(MakeContentOfSize(17 * 1024), NULL);
244 }
245
246 TEST_F(URLRequestFileJobEventsTest, BigFile) {
247 RunRequest(MakeContentOfSize(3 * 1024 * 1024), NULL);
248 }
249
250 TEST_F(URLRequestFileJobEventsTest, Range) {
251 // Use a 15KB content file and read a range chosen somewhat arbitrarily but
252 // not aligned on any likely page boundaries.
253 int size = 15 * 1024;
254 Range range(1701, (6 * 1024) + 3);
255 RunRequest(MakeContentOfSize(size), &range);
256 }
OLDNEW
« no previous file with comments | « net/url_request/url_request_file_job.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698