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

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: 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
OLDNEW
(Empty)
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
rvargas (doing something else) 2014/04/08 16:53:45 I think we don't use (c) anynmore
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Done.
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/files/scoped_temp_dir.h"
8 #include "base/run_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "net/base/net_util.h"
12 #include "net/url_request/url_request_test_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace net {
16 namespace {
17
18 // A URLRequestFileJob for testing OnSeekComplete / OnReadComplete callbacks.
19 class URLRequestFileJobWithCallbacks : public URLRequestFileJob {
20 public:
21 URLRequestFileJobWithCallbacks(
22 URLRequest* request,
23 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) {}
rvargas (doing something else) 2014/04/08 16:53:45 nit: { } (this is not a single line anymore)
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Done.
31
32 int64 seek_position() { return seek_position_; }
33 const std::vector<std::string>& data_chunks() { return data_chunks_; }
34
35 protected:
36 virtual ~URLRequestFileJobWithCallbacks() {}
37
38 virtual void OnSeekComplete(int64 result) OVERRIDE {
39 ASSERT_EQ(seek_position_, 0);
40 seek_position_ = result;
41 }
42
43 virtual void OnReadComplete(IOBuffer* buf, int result) OVERRIDE {
44 data_chunks_.push_back(std::string(buf->data(), result));
45 }
46
47 int64 seek_position_;
48 std::vector<std::string> data_chunks_;
49 };
50
51 // A URLRequestJobFactory that will return URLRequestFileJobWithCallbacks
52 // instances for file:// scheme URLs.
53 class CallbacksJobFactory : public URLRequestJobFactory {
54 public:
55 class JobObserver {
56 public:
57 virtual void OnJobCreated(URLRequestFileJobWithCallbacks* job) = 0;
58 };
59
60 CallbacksJobFactory(const base::FilePath& path, JobObserver* observer)
61 : path_(path), observer_(observer) {}
rvargas (doing something else) 2014/04/08 16:53:45 nit: { } (this is not a single line anymore)
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Done.
62
63 virtual ~CallbacksJobFactory() {}
64
65 virtual URLRequestJob* MaybeCreateJobWithProtocolHandler(
66 const std::string& scheme,
67 URLRequest* request,
68 NetworkDelegate* network_delegate) const OVERRIDE {
69 URLRequestFileJobWithCallbacks* job = new URLRequestFileJobWithCallbacks(
70 request,
71 network_delegate,
72 path_,
73 base::MessageLoop::current()->message_loop_proxy());
74 observer_->OnJobCreated(job);
75 return job;
76 }
77
78 virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE {
79 return scheme == "file";
80 }
81
82 virtual bool IsHandledURL(const GURL& url) const OVERRIDE {
83 return IsHandledProtocol(url.scheme());
84 }
85
86 virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE {
87 return false;
88 }
89
90 private:
91 base::FilePath path_;
92 JobObserver* observer_;
93 };
94
95 // Helper function to create a file in |directory| named |filename| filled with
96 // |content|. Returns true on succes and fills in |path| with the full path to
97 // the file. If |directory| does not exist yet, it will be created.
98 bool CreateTempFileWithContent(const std::string& filename,
99 const std::string& content,
100 base::ScopedTempDir* directory,
101 base::FilePath* path) {
102 if (directory == NULL || path == NULL || !IsStringASCII(filename))
103 return false;
104 if (!directory->IsValid() && !directory->CreateUniqueTempDir())
105 return false;
106 *path = directory->path().AppendASCII(filename);
107
108 base::File file(*path,
109 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND);
rvargas (doing something else) 2014/04/08 16:53:45 Why not CREATE and WRITE? Appending to a file seem
110 int bytes_written = file.WriteAtCurrentPos(content.c_str(), content.length());
rvargas (doing something else) 2014/04/08 16:53:45 file.Write(0, ...) ? (assuming CREATE and WRITE)
rvargas (doing something else) 2014/04/08 16:53:45 should check that the file is valid before using i
111 if (bytes_written <= 0 || (unsigned)bytes_written != content.length())
112 return false;
113 file.Close();
rvargas (doing something else) 2014/04/08 16:53:45 no need to close. btw, this whole block should pr
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Ah, much simpler, thanks for the tip. Done. (this
114
115 return true;
116 }
117
118 // A superclass for tests of the OnSeekComplete / OnReadComplete functions of
119 // URLRequestFileJob.
120 class URLRequestFileJobEventsTest : public testing::Test {
rvargas (doing something else) 2014/04/08 16:53:45 nit: I think this class is too long to have an inl
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Good point. I've moved the JobObserverImpl and Ran
121 public:
122 URLRequestFileJobEventsTest() {}
123
124 class JobObserverImpl : public CallbacksJobFactory::JobObserver {
125 public:
126 virtual void OnJobCreated(URLRequestFileJobWithCallbacks* job) OVERRIDE {
127 jobs_.push_back(job);
128 }
129
130 typedef std::vector<scoped_refptr<URLRequestFileJobWithCallbacks> > JobList;
131
132 const JobList& jobs() { return jobs_; }
133
134 protected:
135 JobList jobs_;
136 };
137
138 // A simple holder for start/end used in http range requests.
139 struct Range {
140 int start;
141 int end;
142
143 Range() {
144 start = 0;
145 end = 0;
146 }
147
148 Range(int start, int end) {
149 this->start = start;
150 this->end = end;
151 }
152 };
153
154 protected:
155 // This creates a file with |content| as the contents, and then creates and
156 // runs a URLRequestFileJobWithCallbacks job to get the contents out of it,
157 // and makes sure that the callbacks observed the correct bytes. If a Range
158 // is provided, this function will add the appropriate Range http header to
159 // the request and verify that only the bytes in that range (inclusive) were
160 // observed.
161 void RunRequest(const std::string& content, const Range* range) {
162 base::ScopedTempDir directory;
163 base::FilePath path;
164 ASSERT_TRUE(
165 CreateTempFileWithContent("file.dat", content, &directory, &path));
166 CallbacksJobFactory factory(path, &observer_);
167 context_.set_job_factory(&factory);
168
169 TestURLRequest request(
170 FilePathToFileURL(path), DEFAULT_PRIORITY, &delegate_, &context_);
171 if (range) {
172 ASSERT_GE(range->start, 0);
173 ASSERT_GE(range->end, 0);
174 ASSERT_LT((unsigned)range->end, content.length());
rvargas (doing something else) 2014/04/08 16:53:45 nit:c++ cast
rvargas (doing something else) 2014/04/08 16:53:45 + assert start <= end ?
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Done.
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Done.
175 std::string range_value =
176 base::StringPrintf("bytes=%d-%d", range->start, range->end);
177 request.SetExtraRequestHeaderByName(
178 HttpRequestHeaders::kRange, range_value, true /*overwrite*/);
179 }
180 request.Start();
181
182 base::RunLoop loop;
183 loop.Run();
184
185 EXPECT_FALSE(delegate_.request_failed());
186 int expected_length =
187 range ? (range->end - range->start + 1) : content.length();
188 EXPECT_EQ(delegate_.bytes_received(), expected_length);
189
190 std::string expected_content;
191 if (range) {
192 expected_content.insert(0, content, range->start, expected_length);
193 } else {
194 expected_content = content;
195 }
196 EXPECT_TRUE(delegate_.data_received() == expected_content);
rvargas (doing something else) 2014/04/08 16:53:45 Doesn't this beeps and prints garbage when it fail
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Nope- notice I used EXPECT_TRUE on single boolean
rvargas (doing something else) 2014/04/09 23:48:50 yes, I missed that!
197
198 ASSERT_EQ(observer_.jobs().size(), 1u);
199 ASSERT_EQ(observer_.jobs().at(0)->seek_position(),
200 range ? range->start : 0);
201
202 std::string observed_content;
203 const std::vector<std::string>& chunks =
204 observer_.jobs().at(0)->data_chunks();
205 for (std::vector<std::string>::const_iterator i = chunks.begin();
206 i != chunks.end();
207 ++i) {
208 observed_content.append(*i);
209 }
210 EXPECT_EQ(expected_content, observed_content);
211 EXPECT_TRUE(expected_content == observed_content);
212 }
213
214 JobObserverImpl observer_;
215 TestURLRequestContext context_;
216 TestDelegate delegate_;
217 };
218
219 // Helper function to make a character array filled with |size| bytes of
220 // test content.
221 std::string MakeContentOfSize(int size) {
222 std::string result;
223 for (int i = 0; i < size; i++) {
224 result.append(1, static_cast<char>(i % 256));
rvargas (doing something else) 2014/04/08 16:53:45 does it make sense to preallocate the string (cons
asargent_no_longer_on_chrome 2014/04/09 20:59:59 Yes, good idea. Done.
225 }
226 return result;
227 }
228
229 TEST_F(URLRequestFileJobEventsTest, TinyFile) {
230 RunRequest(std::string("hello world"), NULL);
231 }
232
233 TEST_F(URLRequestFileJobEventsTest, SmallFile) {
234 RunRequest(MakeContentOfSize(17 * 1024), NULL);
235 }
236
237 TEST_F(URLRequestFileJobEventsTest, BigFile) {
238 RunRequest(MakeContentOfSize(3 * 1024 * 1024), NULL);
239 }
240
241 TEST_F(URLRequestFileJobEventsTest, Range) {
242 // Use a 15KB content file and read a range chosen somewhat arbitrarily but
243 // not aligned on any likely page boundaries.
244 int size = 15 * 1024;
245 Range range(1701, (6 * 1024) + 3);
246 RunRequest(MakeContentOfSize(size), &range);
247 }
248
249 } // namespace
rvargas (doing something else) 2014/04/08 16:53:45 nit: do you mind keeping the actual tests outside
250 } // namespace net
OLDNEW
« net/url_request/url_request_file_job.cc ('K') | « 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