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

Side by Side Diff: components/offline_pages/core/prefetch/generate_page_bundle_request_unittest.cc

Issue 2873383004: [Offline Prefetch] Send GeneratePageBundleRequest to the server (Closed)
Patch Set: Address feedback + fix trybots Created 3 years, 7 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
OLDNEW
(Empty)
1 // Copyright 2017 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 "components/offline_pages/core/prefetch/generate_page_bundle_request.h"
6
7 #include "base/test/mock_callback.h"
8 #include "components/offline_pages/core/prefetch/prefetch_request_test_base.h"
9 #include "components/offline_pages/core/prefetch/prefetch_types.h"
10 #include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
11 #include "components/offline_pages/core/prefetch/proto/operation.pb.h"
12 #include "net/http/http_status_code.h"
13 #include "net/url_request/url_request_status.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "url/gurl.h"
16
17 using testing::_;
18 using testing::DoAll;
19 using testing::Eq;
20 using testing::SaveArg;
21
22 namespace offline_pages {
23
24 namespace {
25 const char kPageBundleTypeURL[] = "type.googleapis.com/test.PageBundle";
26 const char kTestURL[] = "http://example.com";
27 const char kTestURL2[] = "http://example.com/2";
28 const char kTestURL3[] = "http://example.com/3";
29 const char kTestURL4[] = "http://example.com/4";
30 const char kTestUserAgent[] = "Test User Agent";
31 const char kTestGCMID[] = "Test GCM ID";
32 const int kTestMaxBundleSize = 100000;
33 const char kTestBodyName[] = "body_name";
34 const int64_t kTestBodyLength = 12345678LL;
35 } // namespace
36
37 class OperationBuilder {
38 public:
39 virtual ~OperationBuilder() {}
40
41 // Builds the opereation with an Any value and returns it in binary serialized
42 // format.
43 virtual std::string BuildFromAny(const std::string& any_type_url,
44 const std::string& any_value) = 0;
45
46 // Builds the opereation with with an Any value filled with page bundle data
47 // and returns it in binary serialized format.
48 std::string BuildFromPageBundle(const proto::PageBundle& bundle) {
49 std::string bundle_data;
50 EXPECT_TRUE(bundle.SerializeToString(&bundle_data));
51 return BuildFromAny(kPageBundleTypeURL, bundle_data);
52 }
53 };
54
55 class DoneOperationBuilder : public OperationBuilder {
dewittj 2017/05/11 21:51:48 Are there any textproto decoders in Chrome? It mig
jianli 2017/05/11 23:07:27 I don't find one.
56 public:
57 ~DoneOperationBuilder() override {}
58
59 std::string BuildFromAny(const std::string& any_type_url,
60 const std::string& any_value) override {
61 proto::Operation operation;
62 operation.set_done(true);
dewittj 2017/05/11 21:51:48 These two builders only differ in one line. Can t
jianli 2017/05/11 23:07:28 Done.
63 proto::Any* response = operation.mutable_response();
64 response->set_type_url(any_type_url);
65 response->set_value(any_value);
66 std::string data;
67 EXPECT_TRUE(operation.SerializeToString(&data));
68 return data;
69 }
70 };
71
72 class PendingOperationBuilder : public OperationBuilder {
73 public:
74 ~PendingOperationBuilder() override {}
75
76 std::string BuildFromAny(const std::string& any_type_url,
77 const std::string& any_value) override {
78 proto::Operation operation;
79 operation.set_done(false);
80 proto::Any* response = operation.mutable_metadata();
81 response->set_type_url(any_type_url);
82 response->set_value(any_value);
83 std::string data;
84 EXPECT_TRUE(operation.SerializeToString(&data));
85 return data;
86 }
87 };
88
89 class GeneratePageBundleRequestTest : public PrefetchRequestTestBase {
90 public:
91 // Sends GeneratePageBundleRequest for single page with |page_url| and
92 // gets back the data in |http_response|.
93 PrefetchRequestStatus GeneratePage(const std::string& page_url,
94 const std::string& http_response);
95
96 // Sends GeneratePageBundleRequest for multiple pages and gets back the data
97 // in |http_response|.
98 PrefetchRequestStatus GenerateMultiplePages(
99 const std::vector<std::string>& page_urls,
100 const std::string& http_response);
101
102 const std::vector<RenderPageInfo>& pages() const { return pages_; }
103
104 private:
105 std::vector<RenderPageInfo> pages_;
106 };
107
108 PrefetchRequestStatus GeneratePageBundleRequestTest::GeneratePage(
109 const std::string& page_url,
110 const std::string& http_response) {
111 std::vector<std::string> page_urls;
112 page_urls.push_back(page_url);
113 return GenerateMultiplePages(page_urls, http_response);
114 }
115
116 PrefetchRequestStatus GeneratePageBundleRequestTest::GenerateMultiplePages(
117 const std::vector<std::string>& page_urls,
118 const std::string& http_response) {
119 base::MockCallback<GeneratePageBundleRequest::FinishedCallback> callback;
120 std::unique_ptr<GeneratePageBundleRequest> fetcher(
121 new GeneratePageBundleRequest(kTestUserAgent, kTestGCMID,
122 kTestMaxBundleSize, page_urls,
123 request_context(), callback.Get()));
124
125 PrefetchRequestStatus status;
126 pages_.clear();
127 EXPECT_CALL(callback, Run(_, _))
128 .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&pages_)));
129 RespondWithData(http_response);
130
131 return status;
132 }
133
134 TEST_F(GeneratePageBundleRequestTest, FailedToParse) {
135 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
136 GeneratePage(kTestURL, "Some data"));
137 EXPECT_TRUE(pages().empty());
138 }
139
140 TEST_F(GeneratePageBundleRequestTest, NoResultInDoneOperation) {
141 proto::Operation operation;
142 operation.set_done(true);
143 std::string data;
144 EXPECT_TRUE(operation.SerializeToString(&data));
145 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
146 GeneratePage(kTestURL, data));
147 EXPECT_TRUE(pages().empty());
148 }
149
150 TEST_F(GeneratePageBundleRequestTest, ErrorCodeInDoneOperation) {
151 proto::Operation operation;
152 operation.set_done(true);
153 operation.mutable_error()->set_code(1);
154 std::string data;
155 EXPECT_TRUE(operation.SerializeToString(&data));
156 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
157 GeneratePage(kTestURL, data));
158 EXPECT_TRUE(pages().empty());
159 }
160
161 template <typename T>
162 class GeneratePageBundleRequestOperationTest
163 : public GeneratePageBundleRequestTest {
164 public:
165 std::string BuildFromAny(const std::string& any_type_url,
166 const std::string& any_value) {
167 return builder_.BuildFromAny(any_type_url, any_value);
168 }
169
170 std::string BuildFromPageBundle(const proto::PageBundle& bundle) {
171 return builder_.BuildFromPageBundle(bundle);
172 }
173
174 private:
175 T builder_;
176 };
177
178 typedef testing::Types<DoneOperationBuilder, PendingOperationBuilder> MyTypes;
179 TYPED_TEST_CASE(GeneratePageBundleRequestOperationTest, MyTypes);
180
181 TYPED_TEST(GeneratePageBundleRequestOperationTest, InvalidTypeUrl) {
182 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
183 this->GeneratePage(kTestURL, this->BuildFromAny("foo", "")));
184 EXPECT_TRUE(this->pages().empty());
185 }
186
187 TYPED_TEST(GeneratePageBundleRequestOperationTest, InvalidValue) {
188 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
189 this->GeneratePage(kTestURL,
190 this->BuildFromAny(kPageBundleTypeURL, "foo")));
191 EXPECT_TRUE(this->pages().empty());
192 }
193
194 TYPED_TEST(GeneratePageBundleRequestOperationTest, EmptyPageBundle) {
195 proto::PageBundle bundle;
196 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
197 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
198 EXPECT_TRUE(this->pages().empty());
199 }
200
201 TYPED_TEST(GeneratePageBundleRequestOperationTest, EmptyArchive) {
202 proto::PageBundle bundle;
203 bundle.add_archives();
204 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
205 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
206 EXPECT_TRUE(this->pages().empty());
207 }
208
209 TYPED_TEST(GeneratePageBundleRequestOperationTest, NoPageInfo) {
210 proto::PageBundle bundle;
211 proto::Archive* archive = bundle.add_archives();
212 archive->set_body_name(kTestBodyName);
213 archive->set_body_length(kTestBodyLength);
214 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
215 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
216 EXPECT_TRUE(this->pages().empty());
217 }
218
219 TYPED_TEST(GeneratePageBundleRequestOperationTest, MissingPageInfoUrl) {
220 proto::PageBundle bundle;
221 proto::Archive* archive = bundle.add_archives();
222 proto::PageInfo* page_info = archive->add_page_infos();
223 page_info->set_redirect_url(kTestURL);
224 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
225 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
226 EXPECT_TRUE(this->pages().empty());
227 }
228
229 TYPED_TEST(GeneratePageBundleRequestOperationTest, SinglePage) {
230 proto::PageBundle bundle;
231 proto::Archive* archive = bundle.add_archives();
232 archive->set_body_name(kTestBodyName);
233 archive->set_body_length(kTestBodyLength);
234 proto::PageInfo* page_info = archive->add_page_infos();
235 page_info->set_url(kTestURL);
236 page_info->set_redirect_url(kTestURL2);
237 page_info->mutable_status()->set_code(proto::OK);
238 page_info->set_transformation(proto::NO_TRANSFORMATION);
239 int64_t ms_since_epoch = base::Time::Now().ToJavaTime();
240 page_info->mutable_render_time()->set_seconds(ms_since_epoch / 1000);
241 page_info->mutable_render_time()->set_nanos((ms_since_epoch % 1000) *
242 1000000);
243 EXPECT_EQ(PrefetchRequestStatus::SUCCESS,
244 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
245 ASSERT_EQ(1u, this->pages().size());
246 EXPECT_EQ(kTestURL, this->pages().back().url);
247 EXPECT_EQ(kTestURL2, this->pages().back().redirect_url);
248 EXPECT_EQ(RenderStatus::RENDERED, this->pages().back().status);
249 EXPECT_EQ(kTestBodyName, this->pages().back().body_name);
250 EXPECT_EQ(kTestBodyLength, this->pages().back().body_length);
251 EXPECT_EQ(ms_since_epoch, this->pages().back().render_time.ToJavaTime());
252 }
253
254 TYPED_TEST(GeneratePageBundleRequestOperationTest, MultiplePages) {
255 proto::PageBundle bundle;
256
257 // Adds a page that is still being rendered.
258 proto::Archive* archive = bundle.add_archives();
259 proto::PageInfo* page_info = archive->add_page_infos();
260 page_info->set_url(kTestURL);
261 page_info->mutable_status()->set_code(proto::NOT_FOUND);
262
263 // Adds a page that failed to render due to bundle size limits.
264 archive = bundle.add_archives();
265 page_info = archive->add_page_infos();
266 page_info->set_url(kTestURL2);
267 page_info->mutable_status()->set_code(proto::FAILED_PRECONDITION);
268
269 // Adds a page that failed to render for any other reason.
270 archive = bundle.add_archives();
271 page_info = archive->add_page_infos();
272 page_info->set_url(kTestURL3);
273 page_info->mutable_status()->set_code(proto::UNKNOWN);
274
275 // Adds a page that was rendered successfully.
276 archive = bundle.add_archives();
277 archive->set_body_name(kTestBodyName);
278 archive->set_body_length(kTestBodyLength);
279 page_info = archive->add_page_infos();
280 page_info->set_url(kTestURL4);
281 page_info->mutable_status()->set_code(proto::OK);
282 page_info->set_transformation(proto::NO_TRANSFORMATION);
283 int64_t ms_since_epoch = base::Time::Now().ToJavaTime();
284 page_info->mutable_render_time()->set_seconds(ms_since_epoch / 1000);
285 page_info->mutable_render_time()->set_nanos((ms_since_epoch % 1000) *
286 1000000);
287
288 std::vector<std::string> page_urls = {kTestURL, kTestURL2, kTestURL3};
289 EXPECT_EQ(PrefetchRequestStatus::SUCCESS,
290 this->GenerateMultiplePages(page_urls,
291 this->BuildFromPageBundle(bundle)));
292 ASSERT_EQ(4u, this->pages().size());
293 EXPECT_EQ(kTestURL, this->pages().at(0).url);
294 EXPECT_EQ(RenderStatus::PENDING, this->pages().at(0).status);
295 EXPECT_EQ(kTestURL2, this->pages().at(1).url);
296 EXPECT_EQ(RenderStatus::EXCEEDED_LIMIT, this->pages().at(1).status);
297 EXPECT_EQ(kTestURL3, this->pages().at(2).url);
298 EXPECT_EQ(RenderStatus::FAILED, this->pages().at(2).status);
299 EXPECT_EQ(kTestURL4, this->pages().at(3).url);
300 EXPECT_EQ(RenderStatus::RENDERED, this->pages().at(3).status);
301 EXPECT_EQ(kTestBodyName, this->pages().at(3).body_name);
302 EXPECT_EQ(kTestBodyLength, this->pages().at(3).body_length);
303 EXPECT_EQ(ms_since_epoch, this->pages().at(3).render_time.ToJavaTime());
304 }
305
306 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698