blob: 7a56b418d3c753aaff867d229202a7b22aea815b [file] [log] [blame]
Darin Petkova4a8a8c2010-07-15 22:21:12 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
Darin Petkov6a5b3222010-07-13 14:55:28 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
6#include <vector>
Darin Petkov0dc8e9a2010-07-14 14:51:57 -07007
Darin Petkov6a5b3222010-07-13 14:55:28 -07008#include <glib.h>
Darin Petkov0dc8e9a2010-07-14 14:51:57 -07009
10#include "base/string_util.h"
Darin Petkov1cbd78f2010-07-29 12:38:34 -070011#include "base/time.h"
Darin Petkov0dc8e9a2010-07-14 14:51:57 -070012#include "gtest/gtest.h"
Darin Petkov6a5b3222010-07-13 14:55:28 -070013#include "update_engine/action_pipe.h"
14#include "update_engine/mock_http_fetcher.h"
15#include "update_engine/omaha_hash_calculator.h"
16#include "update_engine/omaha_request_action.h"
Darin Petkova4a8a8c2010-07-15 22:21:12 -070017#include "update_engine/omaha_request_params.h"
Darin Petkov1cbd78f2010-07-29 12:38:34 -070018#include "update_engine/prefs_mock.h"
Darin Petkov6a5b3222010-07-13 14:55:28 -070019#include "update_engine/test_utils.h"
20
Darin Petkov1cbd78f2010-07-29 12:38:34 -070021using base::Time;
22using base::TimeDelta;
Darin Petkov6a5b3222010-07-13 14:55:28 -070023using std::string;
24using std::vector;
Darin Petkov1cbd78f2010-07-29 12:38:34 -070025using testing::_;
26using testing::AllOf;
27using testing::Ge;
28using testing::Le;
29using testing::Return;
30using testing::SetArgumentPointee;
Darin Petkov6a5b3222010-07-13 14:55:28 -070031
32namespace chromeos_update_engine {
33
34class OmahaRequestActionTest : public ::testing::Test { };
35
36namespace {
Darin Petkov1cbd78f2010-07-29 12:38:34 -070037const OmahaRequestParams kDefaultTestParams(
Darin Petkov1cbd78f2010-07-29 12:38:34 -070038 OmahaRequestParams::kOsPlatform,
39 OmahaRequestParams::kOsVersion,
40 "service_pack",
41 "x86-generic",
42 OmahaRequestParams::kAppId,
43 "0.1.0.0",
44 "en-US",
45 "unittest",
Darin Petkovfbb40092010-07-29 17:05:50 -070046 "OEM MODEL 09235 7471",
Darin Petkov1cbd78f2010-07-29 12:38:34 -070047 false, // delta okay
48 "http://url");
49
Darin Petkov6a5b3222010-07-13 14:55:28 -070050string GetNoUpdateResponse(const string& app_id) {
51 return string(
52 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
53 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
54 "appid=\"") + app_id + "\" status=\"ok\"><ping "
55 "status=\"ok\"/><updatecheck status=\"noupdate\"/></app></gupdate>";
56}
57
58string GetUpdateResponse(const string& app_id,
59 const string& display_version,
60 const string& more_info_url,
61 const string& prompt,
62 const string& codebase,
63 const string& hash,
64 const string& needsadmin,
65 const string& size) {
66 return string("<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
67 "xmlns=\"http://www.google.com/update2/response\" "
68 "protocol=\"2.0\"><app "
69 "appid=\"") + app_id + "\" status=\"ok\"><ping "
70 "status=\"ok\"/><updatecheck DisplayVersion=\"" + display_version + "\" "
71 "MoreInfo=\"" + more_info_url + "\" Prompt=\"" + prompt + "\" "
Andrew de los Reyes3270f742010-07-15 22:28:14 -070072 "IsDelta=\"true\" "
Darin Petkov6a5b3222010-07-13 14:55:28 -070073 "codebase=\"" + codebase + "\" "
74 "hash=\"" + hash + "\" needsadmin=\"" + needsadmin + "\" "
75 "size=\"" + size + "\" status=\"ok\"/></app></gupdate>";
76}
77
78class OmahaRequestActionTestProcessorDelegate : public ActionProcessorDelegate {
79 public:
80 OmahaRequestActionTestProcessorDelegate()
81 : loop_(NULL),
Darin Petkovc1a8b422010-07-19 11:34:49 -070082 expected_code_(kActionCodeSuccess) {}
Darin Petkov6a5b3222010-07-13 14:55:28 -070083 virtual ~OmahaRequestActionTestProcessorDelegate() {
84 }
Darin Petkovc1a8b422010-07-19 11:34:49 -070085 virtual void ProcessingDone(const ActionProcessor* processor,
86 ActionExitCode code) {
Darin Petkov6a5b3222010-07-13 14:55:28 -070087 ASSERT_TRUE(loop_);
88 g_main_loop_quit(loop_);
89 }
90
91 virtual void ActionCompleted(ActionProcessor* processor,
92 AbstractAction* action,
Darin Petkovc1a8b422010-07-19 11:34:49 -070093 ActionExitCode code) {
Darin Petkov6a5b3222010-07-13 14:55:28 -070094 // make sure actions always succeed
95 if (action->Type() == OmahaRequestAction::StaticType())
Darin Petkovc1a8b422010-07-19 11:34:49 -070096 EXPECT_EQ(expected_code_, code);
Darin Petkov6a5b3222010-07-13 14:55:28 -070097 else
Darin Petkovc1a8b422010-07-19 11:34:49 -070098 EXPECT_EQ(kActionCodeSuccess, code);
Darin Petkov6a5b3222010-07-13 14:55:28 -070099 }
100 GMainLoop *loop_;
Darin Petkovc1a8b422010-07-19 11:34:49 -0700101 ActionExitCode expected_code_;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700102};
103
104gboolean StartProcessorInRunLoop(gpointer data) {
105 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
106 processor->StartProcessing();
107 return FALSE;
108}
Darin Petkov6a5b3222010-07-13 14:55:28 -0700109} // namespace {}
110
111class OutputObjectCollectorAction;
112
113template<>
114class ActionTraits<OutputObjectCollectorAction> {
115 public:
116 // Does not take an object for input
117 typedef OmahaResponse InputObjectType;
118 // On success, puts the output path on output
119 typedef NoneType OutputObjectType;
120};
121
122class OutputObjectCollectorAction : public Action<OutputObjectCollectorAction> {
123 public:
124 OutputObjectCollectorAction() : has_input_object_(false) {}
125 void PerformAction() {
126 // copy input object
127 has_input_object_ = HasInputObject();
128 if (has_input_object_)
129 omaha_response_ = GetInputObject();
Darin Petkovc1a8b422010-07-19 11:34:49 -0700130 processor_->ActionComplete(this, kActionCodeSuccess);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700131 }
132 // Should never be called
133 void TerminateProcessing() {
134 CHECK(false);
135 }
136 // Debugging/logging
137 static std::string StaticType() {
138 return "OutputObjectCollectorAction";
139 }
140 std::string Type() const { return StaticType(); }
141 bool has_input_object_;
142 OmahaResponse omaha_response_;
143};
144
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700145// Returns true iff an output response was obtained from the
146// OmahaRequestAction. |prefs| may be NULL, in which case a local
147// PrefsMock is used. out_response may be NULL. out_post_data may be
148// null; if non-null, the post-data received by the mock HttpFetcher
149// is returned.
150bool TestUpdateCheck(PrefsInterface* prefs,
151 const OmahaRequestParams& params,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700152 const string& http_response,
Darin Petkovc1a8b422010-07-19 11:34:49 -0700153 ActionExitCode expected_code,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700154 OmahaResponse* out_response,
155 vector<char>* out_post_data) {
156 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
157 MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700158 http_response.size());
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700159 PrefsMock local_prefs;
160 OmahaRequestAction action(prefs ? prefs : &local_prefs,
161 params,
162 NULL,
163 fetcher);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700164 OmahaRequestActionTestProcessorDelegate delegate;
165 delegate.loop_ = loop;
Darin Petkovc1a8b422010-07-19 11:34:49 -0700166 delegate.expected_code_ = expected_code;
Darin Petkova4a8a8c2010-07-15 22:21:12 -0700167
Darin Petkov6a5b3222010-07-13 14:55:28 -0700168 ActionProcessor processor;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700169 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700170 processor.EnqueueAction(&action);
171
172 OutputObjectCollectorAction collector_action;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700173 BondActions(&action, &collector_action);
174 processor.EnqueueAction(&collector_action);
175
176 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
177 g_main_loop_run(loop);
178 g_main_loop_unref(loop);
179 if (collector_action.has_input_object_ && out_response)
180 *out_response = collector_action.omaha_response_;
181 if (out_post_data)
182 *out_post_data = fetcher->post_data();
183 return collector_action.has_input_object_;
184}
185
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700186// Tests Event requests -- they should always succeed. |out_post_data|
187// may be null; if non-null, the post-data received by the mock
188// HttpFetcher is returned.
189void TestEvent(const OmahaRequestParams& params,
190 OmahaEvent* event,
191 const string& http_response,
192 vector<char>* out_post_data) {
193 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
194 MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
195 http_response.size());
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700196 PrefsMock prefs;
197 OmahaRequestAction action(&prefs, params, event, fetcher);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700198 OmahaRequestActionTestProcessorDelegate delegate;
199 delegate.loop_ = loop;
200 ActionProcessor processor;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700201 processor.set_delegate(&delegate);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700202 processor.EnqueueAction(&action);
203
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700204 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
205 g_main_loop_run(loop);
206 g_main_loop_unref(loop);
207 if (out_post_data)
208 *out_post_data = fetcher->post_data();
209}
210
Darin Petkov6a5b3222010-07-13 14:55:28 -0700211TEST(OmahaRequestActionTest, NoUpdateTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700212 OmahaResponse response;
213 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700214 TestUpdateCheck(NULL, // prefs
215 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700216 GetNoUpdateResponse(OmahaRequestParams::kAppId),
Darin Petkovc1a8b422010-07-19 11:34:49 -0700217 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700218 &response,
219 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700220 EXPECT_FALSE(response.update_exists);
221}
222
223TEST(OmahaRequestActionTest, ValidUpdateTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700224 OmahaResponse response;
225 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700226 TestUpdateCheck(NULL, // prefs
227 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700228 GetUpdateResponse(OmahaRequestParams::kAppId,
229 "1.2.3.4", // version
230 "http://more/info",
231 "true", // prompt
232 "http://code/base", // dl url
233 "HASH1234=", // checksum
234 "false", // needs admin
235 "123"), // size
Darin Petkovc1a8b422010-07-19 11:34:49 -0700236 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700237 &response,
238 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700239 EXPECT_TRUE(response.update_exists);
240 EXPECT_EQ("1.2.3.4", response.display_version);
241 EXPECT_EQ("http://code/base", response.codebase);
242 EXPECT_EQ("http://more/info", response.more_info_url);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700243 EXPECT_TRUE(response.is_delta);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700244 EXPECT_EQ("HASH1234=", response.hash);
245 EXPECT_EQ(123, response.size);
246 EXPECT_FALSE(response.needs_admin);
247 EXPECT_TRUE(response.prompt);
248}
249
250TEST(OmahaRequestActionTest, NoOutputPipeTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700251 const string http_response(GetNoUpdateResponse(OmahaRequestParams::kAppId));
252
253 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
254
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700255 PrefsMock prefs;
256 OmahaRequestAction action(&prefs, kDefaultTestParams, NULL,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700257 new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700258 http_response.size()));
259 OmahaRequestActionTestProcessorDelegate delegate;
260 delegate.loop_ = loop;
261 ActionProcessor processor;
262 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700263 processor.EnqueueAction(&action);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700264
265 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
266 g_main_loop_run(loop);
267 g_main_loop_unref(loop);
268 EXPECT_FALSE(processor.IsRunning());
269}
270
271TEST(OmahaRequestActionTest, InvalidXmlTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700272 OmahaResponse response;
273 ASSERT_FALSE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700274 TestUpdateCheck(NULL, // prefs
275 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700276 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700277 kActionCodeError,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700278 &response,
279 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700280 EXPECT_FALSE(response.update_exists);
281}
282
283TEST(OmahaRequestActionTest, MissingStatusTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700284 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700285 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700286 NULL, // prefs
287 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700288 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
289 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
290 "appid=\"foo\" status=\"ok\"><ping "
291 "status=\"ok\"/><updatecheck/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700292 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700293 &response,
294 NULL));
295 EXPECT_FALSE(response.update_exists);
296}
297
298TEST(OmahaRequestActionTest, InvalidStatusTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700299 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700300 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700301 NULL, // prefs
302 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700303 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
304 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
305 "appid=\"foo\" status=\"ok\"><ping "
306 "status=\"ok\"/><updatecheck status=\"foo\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700307 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700308 &response,
309 NULL));
310 EXPECT_FALSE(response.update_exists);
311}
312
313TEST(OmahaRequestActionTest, MissingNodesetTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700314 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700315 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700316 NULL, // prefs
317 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700318 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
319 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
320 "appid=\"foo\" status=\"ok\"><ping "
321 "status=\"ok\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700322 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700323 &response,
324 NULL));
325 EXPECT_FALSE(response.update_exists);
326}
327
328TEST(OmahaRequestActionTest, MissingFieldTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700329 OmahaResponse response;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700330 ASSERT_TRUE(TestUpdateCheck(NULL, // prefs
331 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700332 string("<?xml version=\"1.0\" "
333 "encoding=\"UTF-8\"?><gupdate "
334 "xmlns=\"http://www.google.com/"
335 "update2/response\" "
336 "protocol=\"2.0\"><app appid=\"") +
337 OmahaRequestParams::kAppId
338 + "\" status=\"ok\"><ping "
339 "status=\"ok\"/><updatecheck "
340 "DisplayVersion=\"1.2.3.4\" "
341 "Prompt=\"false\" "
342 "codebase=\"http://code/base\" "
343 "hash=\"HASH1234=\" needsadmin=\"true\" "
344 "size=\"123\" "
345 "status=\"ok\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700346 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700347 &response,
348 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700349 EXPECT_TRUE(response.update_exists);
350 EXPECT_EQ("1.2.3.4", response.display_version);
351 EXPECT_EQ("http://code/base", response.codebase);
352 EXPECT_EQ("", response.more_info_url);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700353 EXPECT_FALSE(response.is_delta);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700354 EXPECT_EQ("HASH1234=", response.hash);
355 EXPECT_EQ(123, response.size);
356 EXPECT_TRUE(response.needs_admin);
357 EXPECT_FALSE(response.prompt);
358}
359
360namespace {
361class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
362 public:
363 void ProcessingStopped(const ActionProcessor* processor) {
364 ASSERT_TRUE(loop_);
365 g_main_loop_quit(loop_);
366 }
367 GMainLoop *loop_;
368};
369
370gboolean TerminateTransferTestStarter(gpointer data) {
371 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
372 processor->StartProcessing();
373 CHECK(processor->IsRunning());
374 processor->StopProcessing();
375 return FALSE;
376}
377} // namespace {}
378
379TEST(OmahaRequestActionTest, TerminateTransferTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700380 string http_response("doesn't matter");
381 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
382
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700383 PrefsMock prefs;
384 OmahaRequestAction action(&prefs, kDefaultTestParams, NULL,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700385 new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700386 http_response.size()));
387 TerminateEarlyTestProcessorDelegate delegate;
388 delegate.loop_ = loop;
389 ActionProcessor processor;
390 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700391 processor.EnqueueAction(&action);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700392
393 g_timeout_add(0, &TerminateTransferTestStarter, &processor);
394 g_main_loop_run(loop);
395 g_main_loop_unref(loop);
396}
397
398TEST(OmahaRequestActionTest, XmlEncodeTest) {
399 EXPECT_EQ("ab", XmlEncode("ab"));
400 EXPECT_EQ("a&lt;b", XmlEncode("a<b"));
401 EXPECT_EQ("foo-&#x3A9;", XmlEncode("foo-\xce\xa9"));
402 EXPECT_EQ("&lt;&amp;&gt;", XmlEncode("<&>"));
403 EXPECT_EQ("&amp;lt;&amp;amp;&amp;gt;", XmlEncode("&lt;&amp;&gt;"));
404
405 vector<char> post_data;
406
407 // Make sure XML Encode is being called on the params
Darin Petkov84c763c2010-07-29 16:27:58 -0700408 OmahaRequestParams params(OmahaRequestParams::kOsPlatform,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700409 OmahaRequestParams::kOsVersion,
410 "testtheservice_pack>",
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700411 "x86 generic<id",
Darin Petkov6a5b3222010-07-13 14:55:28 -0700412 OmahaRequestParams::kAppId,
413 "0.1.0.0",
414 "en-US",
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700415 "unittest_track&lt;",
Darin Petkovfbb40092010-07-29 17:05:50 -0700416 "<OEM MODEL>",
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700417 false, // delta okay
Darin Petkov6a5b3222010-07-13 14:55:28 -0700418 "http://url");
419 OmahaResponse response;
420 ASSERT_FALSE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700421 TestUpdateCheck(NULL, // prefs
422 params,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700423 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700424 kActionCodeError,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700425 &response,
426 &post_data));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700427 // convert post_data to string
428 string post_str(&post_data[0], post_data.size());
Darin Petkov6a5b3222010-07-13 14:55:28 -0700429 EXPECT_NE(post_str.find("testtheservice_pack&gt;"), string::npos);
430 EXPECT_EQ(post_str.find("testtheservice_pack>"), string::npos);
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700431 EXPECT_NE(post_str.find("x86 generic&lt;id"), string::npos);
432 EXPECT_EQ(post_str.find("x86 generic<id"), string::npos);
433 EXPECT_NE(post_str.find("unittest_track&amp;lt;"), string::npos);
434 EXPECT_EQ(post_str.find("unittest_track&lt;"), string::npos);
Darin Petkovfbb40092010-07-29 17:05:50 -0700435 EXPECT_NE(post_str.find("&lt;OEM MODEL&gt;"), string::npos);
436 EXPECT_EQ(post_str.find("<OEM MODEL>"), string::npos);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700437}
438
439TEST(OmahaRequestActionTest, XmlDecodeTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700440 OmahaResponse response;
441 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700442 TestUpdateCheck(NULL, // prefs
443 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700444 GetUpdateResponse(OmahaRequestParams::kAppId,
445 "1.2.3.4", // version
446 "testthe&lt;url", // more info
447 "true", // prompt
448 "testthe&amp;codebase", // dl url
449 "HASH1234=", // checksum
450 "false", // needs admin
451 "123"), // size
Darin Petkovc1a8b422010-07-19 11:34:49 -0700452 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700453 &response,
454 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700455
456 EXPECT_EQ(response.more_info_url, "testthe<url");
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700457 EXPECT_EQ(response.codebase, "testthe&codebase");
Darin Petkov6a5b3222010-07-13 14:55:28 -0700458}
459
460TEST(OmahaRequestActionTest, ParseIntTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700461 OmahaResponse response;
462 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700463 TestUpdateCheck(NULL, // prefs
464 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700465 GetUpdateResponse(OmahaRequestParams::kAppId,
466 "1.2.3.4", // version
467 "theurl", // more info
468 "true", // prompt
469 "thecodebase", // dl url
470 "HASH1234=", // checksum
471 "false", // needs admin
472 // overflows int32:
473 "123123123123123"), // size
Darin Petkovc1a8b422010-07-19 11:34:49 -0700474 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700475 &response,
476 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700477
478 EXPECT_EQ(response.size, 123123123123123ll);
479}
480
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700481TEST(OmahaRequestActionTest, FormatUpdateCheckOutputTest) {
482 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700483 ASSERT_FALSE(TestUpdateCheck(NULL, // prefs
484 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700485 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700486 kActionCodeError,
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700487 NULL, // response
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700488 &post_data));
489 // convert post_data to string
490 string post_str(&post_data[0], post_data.size());
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700491 EXPECT_NE(post_str.find(" <o:ping a=\"-1\" r=\"-1\"></o:ping>\n"
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700492 " <o:updatecheck></o:updatecheck>\n"),
493 string::npos);
Darin Petkovfbb40092010-07-29 17:05:50 -0700494 EXPECT_NE(post_str.find("hardware_class=\"OEM MODEL 09235 7471\""),
495 string::npos);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700496 EXPECT_EQ(post_str.find("o:event"), string::npos);
497}
498
Darin Petkove17f86b2010-07-20 09:12:01 -0700499TEST(OmahaRequestActionTest, FormatSuccessEventOutputTest) {
500 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700501 TestEvent(kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700502 new OmahaEvent(OmahaEvent::kTypeUpdateDownloadStarted),
503 "invalid xml>",
504 &post_data);
505 // convert post_data to string
506 string post_str(&post_data[0], post_data.size());
507 string expected_event = StringPrintf(
508 " <o:event eventtype=\"%d\" eventresult=\"%d\"></o:event>\n",
509 OmahaEvent::kTypeUpdateDownloadStarted,
510 OmahaEvent::kResultSuccess);
511 EXPECT_NE(post_str.find(expected_event), string::npos);
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700512 EXPECT_EQ(post_str.find("o:ping"), string::npos);
Darin Petkove17f86b2010-07-20 09:12:01 -0700513 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
514}
515
516TEST(OmahaRequestActionTest, FormatErrorEventOutputTest) {
517 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700518 TestEvent(kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700519 new OmahaEvent(OmahaEvent::kTypeDownloadComplete,
520 OmahaEvent::kResultError,
521 kActionCodeError),
522 "invalid xml>",
523 &post_data);
524 // convert post_data to string
525 string post_str(&post_data[0], post_data.size());
526 string expected_event = StringPrintf(
527 " <o:event eventtype=\"%d\" eventresult=\"%d\" "
528 "errorcode=\"%d\"></o:event>\n",
529 OmahaEvent::kTypeDownloadComplete,
530 OmahaEvent::kResultError,
531 kActionCodeError);
532 EXPECT_NE(post_str.find(expected_event), string::npos);
533 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
534}
535
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700536TEST(OmahaRequestActionTest, FormatEventOutputTest) {
537 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700538 TestEvent(kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700539 new OmahaEvent(OmahaEvent::kTypeDownloadComplete,
540 OmahaEvent::kResultError,
Darin Petkove17f86b2010-07-20 09:12:01 -0700541 kActionCodeError),
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700542 "invalid xml>",
543 &post_data);
544 // convert post_data to string
545 string post_str(&post_data[0], post_data.size());
546 string expected_event = StringPrintf(
547 " <o:event eventtype=\"%d\" eventresult=\"%d\" "
548 "errorcode=\"%d\"></o:event>\n",
549 OmahaEvent::kTypeDownloadComplete,
550 OmahaEvent::kResultError,
Darin Petkove17f86b2010-07-20 09:12:01 -0700551 kActionCodeError);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700552 EXPECT_NE(post_str.find(expected_event), string::npos);
553 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
554}
555
556TEST(OmahaRequestActionTest, IsEventTest) {
557 string http_response("doesn't matter");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700558 PrefsMock prefs;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700559 OmahaRequestAction update_check_action(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700560 &prefs,
561 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700562 NULL,
563 new MockHttpFetcher(http_response.data(),
564 http_response.size()));
565 EXPECT_FALSE(update_check_action.IsEvent());
566
567 OmahaRequestAction event_action(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700568 &prefs,
569 kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700570 new OmahaEvent(OmahaEvent::kTypeUpdateComplete),
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700571 new MockHttpFetcher(http_response.data(),
572 http_response.size()));
573 EXPECT_TRUE(event_action.IsEvent());
574}
575
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700576TEST(OmahaRequestActionTest, FormatDeltaOkayOutputTest) {
577 for (int i = 0; i < 2; i++) {
578 bool delta_okay = i == 1;
579 const char* delta_okay_str = delta_okay ? "true" : "false";
580 vector<char> post_data;
Darin Petkov84c763c2010-07-29 16:27:58 -0700581 OmahaRequestParams params(OmahaRequestParams::kOsPlatform,
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700582 OmahaRequestParams::kOsVersion,
583 "service_pack",
584 "x86-generic",
585 OmahaRequestParams::kAppId,
586 "0.1.0.0",
587 "en-US",
588 "unittest_track",
Darin Petkovfbb40092010-07-29 17:05:50 -0700589 "OEM MODEL REV 1234",
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700590 delta_okay,
591 "http://url");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700592 ASSERT_FALSE(TestUpdateCheck(NULL, // prefs
593 params,
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700594 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700595 kActionCodeError,
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700596 NULL,
597 &post_data));
598 // convert post_data to string
599 string post_str(&post_data[0], post_data.size());
600 EXPECT_NE(post_str.find(StringPrintf(" delta_okay=\"%s\"", delta_okay_str)),
601 string::npos)
602 << "i = " << i;
603 }
604}
605
Darin Petkove17f86b2010-07-20 09:12:01 -0700606TEST(OmahaRequestActionTest, OmahaEventTest) {
607 OmahaEvent default_event;
608 EXPECT_EQ(OmahaEvent::kTypeUnknown, default_event.type);
609 EXPECT_EQ(OmahaEvent::kResultError, default_event.result);
610 EXPECT_EQ(kActionCodeError, default_event.error_code);
611
612 OmahaEvent success_event(OmahaEvent::kTypeUpdateDownloadStarted);
613 EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadStarted, success_event.type);
614 EXPECT_EQ(OmahaEvent::kResultSuccess, success_event.result);
615 EXPECT_EQ(kActionCodeSuccess, success_event.error_code);
616
617 OmahaEvent error_event(OmahaEvent::kTypeUpdateDownloadFinished,
618 OmahaEvent::kResultError,
619 kActionCodeError);
620 EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadFinished, error_event.type);
621 EXPECT_EQ(OmahaEvent::kResultError, error_event.result);
622 EXPECT_EQ(kActionCodeError, error_event.error_code);
623}
624
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700625TEST(OmahaRequestActionTest, PingTest) {
626 PrefsMock prefs;
627 // Add a few hours to the day difference to test no rounding, etc.
628 int64_t five_days_ago =
629 (Time::Now() - TimeDelta::FromHours(5 * 24 + 13)).ToInternalValue();
630 int64_t six_days_ago =
631 (Time::Now() - TimeDelta::FromHours(6 * 24 + 11)).ToInternalValue();
632 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
633 .WillOnce(DoAll(SetArgumentPointee<1>(six_days_ago), Return(true)));
634 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
635 .WillOnce(DoAll(SetArgumentPointee<1>(five_days_ago), Return(true)));
636 vector<char> post_data;
637 ASSERT_TRUE(
638 TestUpdateCheck(&prefs,
639 kDefaultTestParams,
640 GetNoUpdateResponse(OmahaRequestParams::kAppId),
641 kActionCodeSuccess,
642 NULL,
643 &post_data));
644 string post_str(&post_data[0], post_data.size());
645 EXPECT_NE(post_str.find("<o:ping a=\"6\" r=\"5\"></o:ping>"), string::npos);
646}
647
648TEST(OmahaRequestActionTest, ActivePingTest) {
649 PrefsMock prefs;
650 int64_t three_days_ago =
651 (Time::Now() - TimeDelta::FromHours(3 * 24 + 12)).ToInternalValue();
652 int64_t now = Time::Now().ToInternalValue();
653 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
654 .WillOnce(DoAll(SetArgumentPointee<1>(three_days_ago), Return(true)));
655 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
656 .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
657 vector<char> post_data;
658 ASSERT_TRUE(
659 TestUpdateCheck(&prefs,
660 kDefaultTestParams,
661 GetNoUpdateResponse(OmahaRequestParams::kAppId),
662 kActionCodeSuccess,
663 NULL,
664 &post_data));
665 string post_str(&post_data[0], post_data.size());
666 EXPECT_NE(post_str.find("<o:ping a=\"3\"></o:ping>"), string::npos);
667}
668
669TEST(OmahaRequestActionTest, RollCallPingTest) {
670 PrefsMock prefs;
671 int64_t four_days_ago =
672 (Time::Now() - TimeDelta::FromHours(4 * 24)).ToInternalValue();
673 int64_t now = Time::Now().ToInternalValue();
674 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
675 .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
676 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
677 .WillOnce(DoAll(SetArgumentPointee<1>(four_days_ago), Return(true)));
678 vector<char> post_data;
679 ASSERT_TRUE(
680 TestUpdateCheck(&prefs,
681 kDefaultTestParams,
682 GetNoUpdateResponse(OmahaRequestParams::kAppId),
683 kActionCodeSuccess,
684 NULL,
685 &post_data));
686 string post_str(&post_data[0], post_data.size());
687 EXPECT_NE(post_str.find("<o:ping r=\"4\"></o:ping>\n"), string::npos);
688}
689
690TEST(OmahaRequestActionTest, NoPingTest) {
691 PrefsMock prefs;
692 int64_t one_hour_ago =
693 (Time::Now() - TimeDelta::FromHours(1)).ToInternalValue();
694 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
695 .WillOnce(DoAll(SetArgumentPointee<1>(one_hour_ago), Return(true)));
696 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
697 .WillOnce(DoAll(SetArgumentPointee<1>(one_hour_ago), Return(true)));
698 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
699 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
700 vector<char> post_data;
701 ASSERT_TRUE(
702 TestUpdateCheck(&prefs,
703 kDefaultTestParams,
704 GetNoUpdateResponse(OmahaRequestParams::kAppId),
705 kActionCodeSuccess,
706 NULL,
707 &post_data));
708 string post_str(&post_data[0], post_data.size());
709 EXPECT_EQ(post_str.find("o:ping"), string::npos);
710}
711
712TEST(OmahaRequestActionTest, BackInTimePingTest) {
713 PrefsMock prefs;
714 int64_t future =
715 (Time::Now() + TimeDelta::FromHours(3 * 24 + 4)).ToInternalValue();
716 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
717 .WillOnce(DoAll(SetArgumentPointee<1>(future), Return(true)));
718 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
719 .WillOnce(DoAll(SetArgumentPointee<1>(future), Return(true)));
720 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _))
721 .WillOnce(Return(true));
722 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _))
723 .WillOnce(Return(true));
724 vector<char> post_data;
725 ASSERT_TRUE(
726 TestUpdateCheck(&prefs,
727 kDefaultTestParams,
728 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
729 "xmlns=\"http://www.google.com/update2/response\" "
730 "protocol=\"2.0\"><daystart elapsed_seconds=\"100\"/>"
731 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
732 "<updatecheck status=\"noupdate\"/></app></gupdate>",
733 kActionCodeSuccess,
734 NULL,
735 &post_data));
736 string post_str(&post_data[0], post_data.size());
737 EXPECT_EQ(post_str.find("o:ping"), string::npos);
738}
739
740TEST(OmahaRequestActionTest, LastPingDayUpdateTest) {
741 // This test checks that the action updates the last ping day to now
Darin Petkov84c763c2010-07-29 16:27:58 -0700742 // minus 200 seconds with a slack of 5 seconds. Therefore, the test
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700743 // may fail if it runs for longer than 5 seconds. It shouldn't run
744 // that long though.
745 int64_t midnight =
746 (Time::Now() - TimeDelta::FromSeconds(200)).ToInternalValue();
747 int64_t midnight_slack =
748 (Time::Now() - TimeDelta::FromSeconds(195)).ToInternalValue();
749 PrefsMock prefs;
750 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay,
751 AllOf(Ge(midnight), Le(midnight_slack))))
752 .WillOnce(Return(true));
753 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay,
754 AllOf(Ge(midnight), Le(midnight_slack))))
755 .WillOnce(Return(true));
756 ASSERT_TRUE(
757 TestUpdateCheck(&prefs,
758 kDefaultTestParams,
759 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
760 "xmlns=\"http://www.google.com/update2/response\" "
761 "protocol=\"2.0\"><daystart elapsed_seconds=\"200\"/>"
762 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
763 "<updatecheck status=\"noupdate\"/></app></gupdate>",
764 kActionCodeSuccess,
765 NULL,
766 NULL));
767}
768
769TEST(OmahaRequestActionTest, NoElapsedSecondsTest) {
770 PrefsMock prefs;
771 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
772 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
773 ASSERT_TRUE(
774 TestUpdateCheck(&prefs,
775 kDefaultTestParams,
776 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
777 "xmlns=\"http://www.google.com/update2/response\" "
778 "protocol=\"2.0\"><daystart blah=\"200\"/>"
779 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
780 "<updatecheck status=\"noupdate\"/></app></gupdate>",
781 kActionCodeSuccess,
782 NULL,
783 NULL));
784}
785
786TEST(OmahaRequestActionTest, BadElapsedSecondsTest) {
787 PrefsMock prefs;
788 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
789 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
790 ASSERT_TRUE(
791 TestUpdateCheck(&prefs,
792 kDefaultTestParams,
793 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
794 "xmlns=\"http://www.google.com/update2/response\" "
795 "protocol=\"2.0\"><daystart elapsed_seconds=\"x\"/>"
796 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
797 "<updatecheck status=\"noupdate\"/></app></gupdate>",
798 kActionCodeSuccess,
799 NULL,
800 NULL));
801}
802
Darin Petkov84c763c2010-07-29 16:27:58 -0700803TEST(OmahaRequestActionTest, NoUniqueIDTest) {
804 vector<char> post_data;
805 ASSERT_FALSE(TestUpdateCheck(NULL, // prefs
806 kDefaultTestParams,
807 "invalid xml>",
808 kActionCodeError,
809 NULL, // response
810 &post_data));
811 // convert post_data to string
812 string post_str(&post_data[0], post_data.size());
813 EXPECT_EQ(post_str.find("machineid="), string::npos);
814 EXPECT_EQ(post_str.find("userid="), string::npos);
815}
816
Darin Petkov6a5b3222010-07-13 14:55:28 -0700817} // namespace chromeos_update_engine