blob: f4dcd1e9050077304e268707ab71e64129afb8dd [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",
46 false, // delta okay
47 "http://url");
48
Darin Petkov6a5b3222010-07-13 14:55:28 -070049string GetNoUpdateResponse(const string& app_id) {
50 return string(
51 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
52 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
53 "appid=\"") + app_id + "\" status=\"ok\"><ping "
54 "status=\"ok\"/><updatecheck status=\"noupdate\"/></app></gupdate>";
55}
56
57string GetUpdateResponse(const string& app_id,
58 const string& display_version,
59 const string& more_info_url,
60 const string& prompt,
61 const string& codebase,
62 const string& hash,
63 const string& needsadmin,
64 const string& size) {
65 return string("<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
66 "xmlns=\"http://www.google.com/update2/response\" "
67 "protocol=\"2.0\"><app "
68 "appid=\"") + app_id + "\" status=\"ok\"><ping "
69 "status=\"ok\"/><updatecheck DisplayVersion=\"" + display_version + "\" "
70 "MoreInfo=\"" + more_info_url + "\" Prompt=\"" + prompt + "\" "
Andrew de los Reyes3270f742010-07-15 22:28:14 -070071 "IsDelta=\"true\" "
Darin Petkov6a5b3222010-07-13 14:55:28 -070072 "codebase=\"" + codebase + "\" "
73 "hash=\"" + hash + "\" needsadmin=\"" + needsadmin + "\" "
74 "size=\"" + size + "\" status=\"ok\"/></app></gupdate>";
75}
76
77class OmahaRequestActionTestProcessorDelegate : public ActionProcessorDelegate {
78 public:
79 OmahaRequestActionTestProcessorDelegate()
80 : loop_(NULL),
Darin Petkovc1a8b422010-07-19 11:34:49 -070081 expected_code_(kActionCodeSuccess) {}
Darin Petkov6a5b3222010-07-13 14:55:28 -070082 virtual ~OmahaRequestActionTestProcessorDelegate() {
83 }
Darin Petkovc1a8b422010-07-19 11:34:49 -070084 virtual void ProcessingDone(const ActionProcessor* processor,
85 ActionExitCode code) {
Darin Petkov6a5b3222010-07-13 14:55:28 -070086 ASSERT_TRUE(loop_);
87 g_main_loop_quit(loop_);
88 }
89
90 virtual void ActionCompleted(ActionProcessor* processor,
91 AbstractAction* action,
Darin Petkovc1a8b422010-07-19 11:34:49 -070092 ActionExitCode code) {
Darin Petkov6a5b3222010-07-13 14:55:28 -070093 // make sure actions always succeed
94 if (action->Type() == OmahaRequestAction::StaticType())
Darin Petkovc1a8b422010-07-19 11:34:49 -070095 EXPECT_EQ(expected_code_, code);
Darin Petkov6a5b3222010-07-13 14:55:28 -070096 else
Darin Petkovc1a8b422010-07-19 11:34:49 -070097 EXPECT_EQ(kActionCodeSuccess, code);
Darin Petkov6a5b3222010-07-13 14:55:28 -070098 }
99 GMainLoop *loop_;
Darin Petkovc1a8b422010-07-19 11:34:49 -0700100 ActionExitCode expected_code_;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700101};
102
103gboolean StartProcessorInRunLoop(gpointer data) {
104 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
105 processor->StartProcessing();
106 return FALSE;
107}
Darin Petkov6a5b3222010-07-13 14:55:28 -0700108} // namespace {}
109
110class OutputObjectCollectorAction;
111
112template<>
113class ActionTraits<OutputObjectCollectorAction> {
114 public:
115 // Does not take an object for input
116 typedef OmahaResponse InputObjectType;
117 // On success, puts the output path on output
118 typedef NoneType OutputObjectType;
119};
120
121class OutputObjectCollectorAction : public Action<OutputObjectCollectorAction> {
122 public:
123 OutputObjectCollectorAction() : has_input_object_(false) {}
124 void PerformAction() {
125 // copy input object
126 has_input_object_ = HasInputObject();
127 if (has_input_object_)
128 omaha_response_ = GetInputObject();
Darin Petkovc1a8b422010-07-19 11:34:49 -0700129 processor_->ActionComplete(this, kActionCodeSuccess);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700130 }
131 // Should never be called
132 void TerminateProcessing() {
133 CHECK(false);
134 }
135 // Debugging/logging
136 static std::string StaticType() {
137 return "OutputObjectCollectorAction";
138 }
139 std::string Type() const { return StaticType(); }
140 bool has_input_object_;
141 OmahaResponse omaha_response_;
142};
143
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700144// Returns true iff an output response was obtained from the
145// OmahaRequestAction. |prefs| may be NULL, in which case a local
146// PrefsMock is used. out_response may be NULL. out_post_data may be
147// null; if non-null, the post-data received by the mock HttpFetcher
148// is returned.
149bool TestUpdateCheck(PrefsInterface* prefs,
150 const OmahaRequestParams& params,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700151 const string& http_response,
Darin Petkovc1a8b422010-07-19 11:34:49 -0700152 ActionExitCode expected_code,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700153 OmahaResponse* out_response,
154 vector<char>* out_post_data) {
155 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
156 MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700157 http_response.size());
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700158 PrefsMock local_prefs;
159 OmahaRequestAction action(prefs ? prefs : &local_prefs,
160 params,
161 NULL,
162 fetcher);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700163 OmahaRequestActionTestProcessorDelegate delegate;
164 delegate.loop_ = loop;
Darin Petkovc1a8b422010-07-19 11:34:49 -0700165 delegate.expected_code_ = expected_code;
Darin Petkova4a8a8c2010-07-15 22:21:12 -0700166
Darin Petkov6a5b3222010-07-13 14:55:28 -0700167 ActionProcessor processor;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700168 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700169 processor.EnqueueAction(&action);
170
171 OutputObjectCollectorAction collector_action;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700172 BondActions(&action, &collector_action);
173 processor.EnqueueAction(&collector_action);
174
175 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
176 g_main_loop_run(loop);
177 g_main_loop_unref(loop);
178 if (collector_action.has_input_object_ && out_response)
179 *out_response = collector_action.omaha_response_;
180 if (out_post_data)
181 *out_post_data = fetcher->post_data();
182 return collector_action.has_input_object_;
183}
184
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700185// Tests Event requests -- they should always succeed. |out_post_data|
186// may be null; if non-null, the post-data received by the mock
187// HttpFetcher is returned.
188void TestEvent(const OmahaRequestParams& params,
189 OmahaEvent* event,
190 const string& http_response,
191 vector<char>* out_post_data) {
192 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
193 MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
194 http_response.size());
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700195 PrefsMock prefs;
196 OmahaRequestAction action(&prefs, params, event, fetcher);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700197 OmahaRequestActionTestProcessorDelegate delegate;
198 delegate.loop_ = loop;
199 ActionProcessor processor;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700200 processor.set_delegate(&delegate);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700201 processor.EnqueueAction(&action);
202
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700203 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
204 g_main_loop_run(loop);
205 g_main_loop_unref(loop);
206 if (out_post_data)
207 *out_post_data = fetcher->post_data();
208}
209
Darin Petkov6a5b3222010-07-13 14:55:28 -0700210TEST(OmahaRequestActionTest, NoUpdateTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700211 OmahaResponse response;
212 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700213 TestUpdateCheck(NULL, // prefs
214 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700215 GetNoUpdateResponse(OmahaRequestParams::kAppId),
Darin Petkovc1a8b422010-07-19 11:34:49 -0700216 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700217 &response,
218 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700219 EXPECT_FALSE(response.update_exists);
220}
221
222TEST(OmahaRequestActionTest, ValidUpdateTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700223 OmahaResponse response;
224 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700225 TestUpdateCheck(NULL, // prefs
226 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700227 GetUpdateResponse(OmahaRequestParams::kAppId,
228 "1.2.3.4", // version
229 "http://more/info",
230 "true", // prompt
231 "http://code/base", // dl url
232 "HASH1234=", // checksum
233 "false", // needs admin
234 "123"), // size
Darin Petkovc1a8b422010-07-19 11:34:49 -0700235 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700236 &response,
237 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700238 EXPECT_TRUE(response.update_exists);
239 EXPECT_EQ("1.2.3.4", response.display_version);
240 EXPECT_EQ("http://code/base", response.codebase);
241 EXPECT_EQ("http://more/info", response.more_info_url);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700242 EXPECT_TRUE(response.is_delta);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700243 EXPECT_EQ("HASH1234=", response.hash);
244 EXPECT_EQ(123, response.size);
245 EXPECT_FALSE(response.needs_admin);
246 EXPECT_TRUE(response.prompt);
247}
248
249TEST(OmahaRequestActionTest, NoOutputPipeTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700250 const string http_response(GetNoUpdateResponse(OmahaRequestParams::kAppId));
251
252 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
253
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700254 PrefsMock prefs;
255 OmahaRequestAction action(&prefs, kDefaultTestParams, NULL,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700256 new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700257 http_response.size()));
258 OmahaRequestActionTestProcessorDelegate delegate;
259 delegate.loop_ = loop;
260 ActionProcessor processor;
261 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700262 processor.EnqueueAction(&action);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700263
264 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
265 g_main_loop_run(loop);
266 g_main_loop_unref(loop);
267 EXPECT_FALSE(processor.IsRunning());
268}
269
270TEST(OmahaRequestActionTest, InvalidXmlTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700271 OmahaResponse response;
272 ASSERT_FALSE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700273 TestUpdateCheck(NULL, // prefs
274 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700275 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700276 kActionCodeError,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700277 &response,
278 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700279 EXPECT_FALSE(response.update_exists);
280}
281
282TEST(OmahaRequestActionTest, MissingStatusTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700283 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700284 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700285 NULL, // prefs
286 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700287 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
288 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
289 "appid=\"foo\" status=\"ok\"><ping "
290 "status=\"ok\"/><updatecheck/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700291 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700292 &response,
293 NULL));
294 EXPECT_FALSE(response.update_exists);
295}
296
297TEST(OmahaRequestActionTest, InvalidStatusTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700298 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700299 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700300 NULL, // prefs
301 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700302 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
303 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
304 "appid=\"foo\" status=\"ok\"><ping "
305 "status=\"ok\"/><updatecheck status=\"foo\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700306 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700307 &response,
308 NULL));
309 EXPECT_FALSE(response.update_exists);
310}
311
312TEST(OmahaRequestActionTest, MissingNodesetTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700313 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700314 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700315 NULL, // prefs
316 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700317 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
318 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
319 "appid=\"foo\" status=\"ok\"><ping "
320 "status=\"ok\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700321 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700322 &response,
323 NULL));
324 EXPECT_FALSE(response.update_exists);
325}
326
327TEST(OmahaRequestActionTest, MissingFieldTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700328 OmahaResponse response;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700329 ASSERT_TRUE(TestUpdateCheck(NULL, // prefs
330 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700331 string("<?xml version=\"1.0\" "
332 "encoding=\"UTF-8\"?><gupdate "
333 "xmlns=\"http://www.google.com/"
334 "update2/response\" "
335 "protocol=\"2.0\"><app appid=\"") +
336 OmahaRequestParams::kAppId
337 + "\" status=\"ok\"><ping "
338 "status=\"ok\"/><updatecheck "
339 "DisplayVersion=\"1.2.3.4\" "
340 "Prompt=\"false\" "
341 "codebase=\"http://code/base\" "
342 "hash=\"HASH1234=\" needsadmin=\"true\" "
343 "size=\"123\" "
344 "status=\"ok\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700345 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700346 &response,
347 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700348 EXPECT_TRUE(response.update_exists);
349 EXPECT_EQ("1.2.3.4", response.display_version);
350 EXPECT_EQ("http://code/base", response.codebase);
351 EXPECT_EQ("", response.more_info_url);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700352 EXPECT_FALSE(response.is_delta);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700353 EXPECT_EQ("HASH1234=", response.hash);
354 EXPECT_EQ(123, response.size);
355 EXPECT_TRUE(response.needs_admin);
356 EXPECT_FALSE(response.prompt);
357}
358
359namespace {
360class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
361 public:
362 void ProcessingStopped(const ActionProcessor* processor) {
363 ASSERT_TRUE(loop_);
364 g_main_loop_quit(loop_);
365 }
366 GMainLoop *loop_;
367};
368
369gboolean TerminateTransferTestStarter(gpointer data) {
370 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
371 processor->StartProcessing();
372 CHECK(processor->IsRunning());
373 processor->StopProcessing();
374 return FALSE;
375}
376} // namespace {}
377
378TEST(OmahaRequestActionTest, TerminateTransferTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700379 string http_response("doesn't matter");
380 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
381
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700382 PrefsMock prefs;
383 OmahaRequestAction action(&prefs, kDefaultTestParams, NULL,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700384 new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700385 http_response.size()));
386 TerminateEarlyTestProcessorDelegate delegate;
387 delegate.loop_ = loop;
388 ActionProcessor processor;
389 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700390 processor.EnqueueAction(&action);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700391
392 g_timeout_add(0, &TerminateTransferTestStarter, &processor);
393 g_main_loop_run(loop);
394 g_main_loop_unref(loop);
395}
396
397TEST(OmahaRequestActionTest, XmlEncodeTest) {
398 EXPECT_EQ("ab", XmlEncode("ab"));
399 EXPECT_EQ("a&lt;b", XmlEncode("a<b"));
400 EXPECT_EQ("foo-&#x3A9;", XmlEncode("foo-\xce\xa9"));
401 EXPECT_EQ("&lt;&amp;&gt;", XmlEncode("<&>"));
402 EXPECT_EQ("&amp;lt;&amp;amp;&amp;gt;", XmlEncode("&lt;&amp;&gt;"));
403
404 vector<char> post_data;
405
406 // Make sure XML Encode is being called on the params
Darin Petkov84c763c2010-07-29 16:27:58 -0700407 OmahaRequestParams params(OmahaRequestParams::kOsPlatform,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700408 OmahaRequestParams::kOsVersion,
409 "testtheservice_pack>",
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700410 "x86 generic<id",
Darin Petkov6a5b3222010-07-13 14:55:28 -0700411 OmahaRequestParams::kAppId,
412 "0.1.0.0",
413 "en-US",
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700414 "unittest_track&lt;",
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700415 false, // delta okay
Darin Petkov6a5b3222010-07-13 14:55:28 -0700416 "http://url");
417 OmahaResponse response;
418 ASSERT_FALSE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700419 TestUpdateCheck(NULL, // prefs
420 params,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700421 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700422 kActionCodeError,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700423 &response,
424 &post_data));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700425 // convert post_data to string
426 string post_str(&post_data[0], post_data.size());
Darin Petkov6a5b3222010-07-13 14:55:28 -0700427 EXPECT_NE(post_str.find("testtheservice_pack&gt;"), string::npos);
428 EXPECT_EQ(post_str.find("testtheservice_pack>"), string::npos);
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700429 EXPECT_NE(post_str.find("x86 generic&lt;id"), string::npos);
430 EXPECT_EQ(post_str.find("x86 generic<id"), string::npos);
431 EXPECT_NE(post_str.find("unittest_track&amp;lt;"), string::npos);
432 EXPECT_EQ(post_str.find("unittest_track&lt;"), string::npos);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700433}
434
435TEST(OmahaRequestActionTest, XmlDecodeTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700436 OmahaResponse response;
437 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700438 TestUpdateCheck(NULL, // prefs
439 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700440 GetUpdateResponse(OmahaRequestParams::kAppId,
441 "1.2.3.4", // version
442 "testthe&lt;url", // more info
443 "true", // prompt
444 "testthe&amp;codebase", // dl url
445 "HASH1234=", // checksum
446 "false", // needs admin
447 "123"), // size
Darin Petkovc1a8b422010-07-19 11:34:49 -0700448 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700449 &response,
450 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700451
452 EXPECT_EQ(response.more_info_url, "testthe<url");
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700453 EXPECT_EQ(response.codebase, "testthe&codebase");
Darin Petkov6a5b3222010-07-13 14:55:28 -0700454}
455
456TEST(OmahaRequestActionTest, ParseIntTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700457 OmahaResponse response;
458 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700459 TestUpdateCheck(NULL, // prefs
460 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700461 GetUpdateResponse(OmahaRequestParams::kAppId,
462 "1.2.3.4", // version
463 "theurl", // more info
464 "true", // prompt
465 "thecodebase", // dl url
466 "HASH1234=", // checksum
467 "false", // needs admin
468 // overflows int32:
469 "123123123123123"), // size
Darin Petkovc1a8b422010-07-19 11:34:49 -0700470 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700471 &response,
472 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700473
474 EXPECT_EQ(response.size, 123123123123123ll);
475}
476
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700477TEST(OmahaRequestActionTest, FormatUpdateCheckOutputTest) {
478 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700479 ASSERT_FALSE(TestUpdateCheck(NULL, // prefs
480 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700481 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700482 kActionCodeError,
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700483 NULL, // response
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700484 &post_data));
485 // convert post_data to string
486 string post_str(&post_data[0], post_data.size());
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700487 EXPECT_NE(post_str.find(" <o:ping a=\"-1\" r=\"-1\"></o:ping>\n"
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700488 " <o:updatecheck></o:updatecheck>\n"),
489 string::npos);
490 EXPECT_EQ(post_str.find("o:event"), string::npos);
491}
492
Darin Petkove17f86b2010-07-20 09:12:01 -0700493TEST(OmahaRequestActionTest, FormatSuccessEventOutputTest) {
494 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700495 TestEvent(kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700496 new OmahaEvent(OmahaEvent::kTypeUpdateDownloadStarted),
497 "invalid xml>",
498 &post_data);
499 // convert post_data to string
500 string post_str(&post_data[0], post_data.size());
501 string expected_event = StringPrintf(
502 " <o:event eventtype=\"%d\" eventresult=\"%d\"></o:event>\n",
503 OmahaEvent::kTypeUpdateDownloadStarted,
504 OmahaEvent::kResultSuccess);
505 EXPECT_NE(post_str.find(expected_event), string::npos);
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700506 EXPECT_EQ(post_str.find("o:ping"), string::npos);
Darin Petkove17f86b2010-07-20 09:12:01 -0700507 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
508}
509
510TEST(OmahaRequestActionTest, FormatErrorEventOutputTest) {
511 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700512 TestEvent(kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700513 new OmahaEvent(OmahaEvent::kTypeDownloadComplete,
514 OmahaEvent::kResultError,
515 kActionCodeError),
516 "invalid xml>",
517 &post_data);
518 // convert post_data to string
519 string post_str(&post_data[0], post_data.size());
520 string expected_event = StringPrintf(
521 " <o:event eventtype=\"%d\" eventresult=\"%d\" "
522 "errorcode=\"%d\"></o:event>\n",
523 OmahaEvent::kTypeDownloadComplete,
524 OmahaEvent::kResultError,
525 kActionCodeError);
526 EXPECT_NE(post_str.find(expected_event), string::npos);
527 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
528}
529
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700530TEST(OmahaRequestActionTest, FormatEventOutputTest) {
531 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700532 TestEvent(kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700533 new OmahaEvent(OmahaEvent::kTypeDownloadComplete,
534 OmahaEvent::kResultError,
Darin Petkove17f86b2010-07-20 09:12:01 -0700535 kActionCodeError),
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700536 "invalid xml>",
537 &post_data);
538 // convert post_data to string
539 string post_str(&post_data[0], post_data.size());
540 string expected_event = StringPrintf(
541 " <o:event eventtype=\"%d\" eventresult=\"%d\" "
542 "errorcode=\"%d\"></o:event>\n",
543 OmahaEvent::kTypeDownloadComplete,
544 OmahaEvent::kResultError,
Darin Petkove17f86b2010-07-20 09:12:01 -0700545 kActionCodeError);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700546 EXPECT_NE(post_str.find(expected_event), string::npos);
547 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
548}
549
550TEST(OmahaRequestActionTest, IsEventTest) {
551 string http_response("doesn't matter");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700552 PrefsMock prefs;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700553 OmahaRequestAction update_check_action(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700554 &prefs,
555 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700556 NULL,
557 new MockHttpFetcher(http_response.data(),
558 http_response.size()));
559 EXPECT_FALSE(update_check_action.IsEvent());
560
561 OmahaRequestAction event_action(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700562 &prefs,
563 kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700564 new OmahaEvent(OmahaEvent::kTypeUpdateComplete),
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700565 new MockHttpFetcher(http_response.data(),
566 http_response.size()));
567 EXPECT_TRUE(event_action.IsEvent());
568}
569
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700570TEST(OmahaRequestActionTest, FormatDeltaOkayOutputTest) {
571 for (int i = 0; i < 2; i++) {
572 bool delta_okay = i == 1;
573 const char* delta_okay_str = delta_okay ? "true" : "false";
574 vector<char> post_data;
Darin Petkov84c763c2010-07-29 16:27:58 -0700575 OmahaRequestParams params(OmahaRequestParams::kOsPlatform,
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700576 OmahaRequestParams::kOsVersion,
577 "service_pack",
578 "x86-generic",
579 OmahaRequestParams::kAppId,
580 "0.1.0.0",
581 "en-US",
582 "unittest_track",
583 delta_okay,
584 "http://url");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700585 ASSERT_FALSE(TestUpdateCheck(NULL, // prefs
586 params,
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700587 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700588 kActionCodeError,
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700589 NULL,
590 &post_data));
591 // convert post_data to string
592 string post_str(&post_data[0], post_data.size());
593 EXPECT_NE(post_str.find(StringPrintf(" delta_okay=\"%s\"", delta_okay_str)),
594 string::npos)
595 << "i = " << i;
596 }
597}
598
Darin Petkove17f86b2010-07-20 09:12:01 -0700599TEST(OmahaRequestActionTest, OmahaEventTest) {
600 OmahaEvent default_event;
601 EXPECT_EQ(OmahaEvent::kTypeUnknown, default_event.type);
602 EXPECT_EQ(OmahaEvent::kResultError, default_event.result);
603 EXPECT_EQ(kActionCodeError, default_event.error_code);
604
605 OmahaEvent success_event(OmahaEvent::kTypeUpdateDownloadStarted);
606 EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadStarted, success_event.type);
607 EXPECT_EQ(OmahaEvent::kResultSuccess, success_event.result);
608 EXPECT_EQ(kActionCodeSuccess, success_event.error_code);
609
610 OmahaEvent error_event(OmahaEvent::kTypeUpdateDownloadFinished,
611 OmahaEvent::kResultError,
612 kActionCodeError);
613 EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadFinished, error_event.type);
614 EXPECT_EQ(OmahaEvent::kResultError, error_event.result);
615 EXPECT_EQ(kActionCodeError, error_event.error_code);
616}
617
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700618TEST(OmahaRequestActionTest, PingTest) {
619 PrefsMock prefs;
620 // Add a few hours to the day difference to test no rounding, etc.
621 int64_t five_days_ago =
622 (Time::Now() - TimeDelta::FromHours(5 * 24 + 13)).ToInternalValue();
623 int64_t six_days_ago =
624 (Time::Now() - TimeDelta::FromHours(6 * 24 + 11)).ToInternalValue();
625 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
626 .WillOnce(DoAll(SetArgumentPointee<1>(six_days_ago), Return(true)));
627 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
628 .WillOnce(DoAll(SetArgumentPointee<1>(five_days_ago), Return(true)));
629 vector<char> post_data;
630 ASSERT_TRUE(
631 TestUpdateCheck(&prefs,
632 kDefaultTestParams,
633 GetNoUpdateResponse(OmahaRequestParams::kAppId),
634 kActionCodeSuccess,
635 NULL,
636 &post_data));
637 string post_str(&post_data[0], post_data.size());
638 EXPECT_NE(post_str.find("<o:ping a=\"6\" r=\"5\"></o:ping>"), string::npos);
639}
640
641TEST(OmahaRequestActionTest, ActivePingTest) {
642 PrefsMock prefs;
643 int64_t three_days_ago =
644 (Time::Now() - TimeDelta::FromHours(3 * 24 + 12)).ToInternalValue();
645 int64_t now = Time::Now().ToInternalValue();
646 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
647 .WillOnce(DoAll(SetArgumentPointee<1>(three_days_ago), Return(true)));
648 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
649 .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
650 vector<char> post_data;
651 ASSERT_TRUE(
652 TestUpdateCheck(&prefs,
653 kDefaultTestParams,
654 GetNoUpdateResponse(OmahaRequestParams::kAppId),
655 kActionCodeSuccess,
656 NULL,
657 &post_data));
658 string post_str(&post_data[0], post_data.size());
659 EXPECT_NE(post_str.find("<o:ping a=\"3\"></o:ping>"), string::npos);
660}
661
662TEST(OmahaRequestActionTest, RollCallPingTest) {
663 PrefsMock prefs;
664 int64_t four_days_ago =
665 (Time::Now() - TimeDelta::FromHours(4 * 24)).ToInternalValue();
666 int64_t now = Time::Now().ToInternalValue();
667 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
668 .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
669 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
670 .WillOnce(DoAll(SetArgumentPointee<1>(four_days_ago), Return(true)));
671 vector<char> post_data;
672 ASSERT_TRUE(
673 TestUpdateCheck(&prefs,
674 kDefaultTestParams,
675 GetNoUpdateResponse(OmahaRequestParams::kAppId),
676 kActionCodeSuccess,
677 NULL,
678 &post_data));
679 string post_str(&post_data[0], post_data.size());
680 EXPECT_NE(post_str.find("<o:ping r=\"4\"></o:ping>\n"), string::npos);
681}
682
683TEST(OmahaRequestActionTest, NoPingTest) {
684 PrefsMock prefs;
685 int64_t one_hour_ago =
686 (Time::Now() - TimeDelta::FromHours(1)).ToInternalValue();
687 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
688 .WillOnce(DoAll(SetArgumentPointee<1>(one_hour_ago), Return(true)));
689 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
690 .WillOnce(DoAll(SetArgumentPointee<1>(one_hour_ago), Return(true)));
691 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
692 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
693 vector<char> post_data;
694 ASSERT_TRUE(
695 TestUpdateCheck(&prefs,
696 kDefaultTestParams,
697 GetNoUpdateResponse(OmahaRequestParams::kAppId),
698 kActionCodeSuccess,
699 NULL,
700 &post_data));
701 string post_str(&post_data[0], post_data.size());
702 EXPECT_EQ(post_str.find("o:ping"), string::npos);
703}
704
705TEST(OmahaRequestActionTest, BackInTimePingTest) {
706 PrefsMock prefs;
707 int64_t future =
708 (Time::Now() + TimeDelta::FromHours(3 * 24 + 4)).ToInternalValue();
709 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
710 .WillOnce(DoAll(SetArgumentPointee<1>(future), Return(true)));
711 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
712 .WillOnce(DoAll(SetArgumentPointee<1>(future), Return(true)));
713 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _))
714 .WillOnce(Return(true));
715 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _))
716 .WillOnce(Return(true));
717 vector<char> post_data;
718 ASSERT_TRUE(
719 TestUpdateCheck(&prefs,
720 kDefaultTestParams,
721 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
722 "xmlns=\"http://www.google.com/update2/response\" "
723 "protocol=\"2.0\"><daystart elapsed_seconds=\"100\"/>"
724 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
725 "<updatecheck status=\"noupdate\"/></app></gupdate>",
726 kActionCodeSuccess,
727 NULL,
728 &post_data));
729 string post_str(&post_data[0], post_data.size());
730 EXPECT_EQ(post_str.find("o:ping"), string::npos);
731}
732
733TEST(OmahaRequestActionTest, LastPingDayUpdateTest) {
734 // This test checks that the action updates the last ping day to now
Darin Petkov84c763c2010-07-29 16:27:58 -0700735 // minus 200 seconds with a slack of 5 seconds. Therefore, the test
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700736 // may fail if it runs for longer than 5 seconds. It shouldn't run
737 // that long though.
738 int64_t midnight =
739 (Time::Now() - TimeDelta::FromSeconds(200)).ToInternalValue();
740 int64_t midnight_slack =
741 (Time::Now() - TimeDelta::FromSeconds(195)).ToInternalValue();
742 PrefsMock prefs;
743 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay,
744 AllOf(Ge(midnight), Le(midnight_slack))))
745 .WillOnce(Return(true));
746 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay,
747 AllOf(Ge(midnight), Le(midnight_slack))))
748 .WillOnce(Return(true));
749 ASSERT_TRUE(
750 TestUpdateCheck(&prefs,
751 kDefaultTestParams,
752 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
753 "xmlns=\"http://www.google.com/update2/response\" "
754 "protocol=\"2.0\"><daystart elapsed_seconds=\"200\"/>"
755 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
756 "<updatecheck status=\"noupdate\"/></app></gupdate>",
757 kActionCodeSuccess,
758 NULL,
759 NULL));
760}
761
762TEST(OmahaRequestActionTest, NoElapsedSecondsTest) {
763 PrefsMock prefs;
764 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
765 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
766 ASSERT_TRUE(
767 TestUpdateCheck(&prefs,
768 kDefaultTestParams,
769 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
770 "xmlns=\"http://www.google.com/update2/response\" "
771 "protocol=\"2.0\"><daystart blah=\"200\"/>"
772 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
773 "<updatecheck status=\"noupdate\"/></app></gupdate>",
774 kActionCodeSuccess,
775 NULL,
776 NULL));
777}
778
779TEST(OmahaRequestActionTest, BadElapsedSecondsTest) {
780 PrefsMock prefs;
781 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
782 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
783 ASSERT_TRUE(
784 TestUpdateCheck(&prefs,
785 kDefaultTestParams,
786 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
787 "xmlns=\"http://www.google.com/update2/response\" "
788 "protocol=\"2.0\"><daystart elapsed_seconds=\"x\"/>"
789 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
790 "<updatecheck status=\"noupdate\"/></app></gupdate>",
791 kActionCodeSuccess,
792 NULL,
793 NULL));
794}
795
Darin Petkov84c763c2010-07-29 16:27:58 -0700796TEST(OmahaRequestActionTest, NoUniqueIDTest) {
797 vector<char> post_data;
798 ASSERT_FALSE(TestUpdateCheck(NULL, // prefs
799 kDefaultTestParams,
800 "invalid xml>",
801 kActionCodeError,
802 NULL, // response
803 &post_data));
804 // convert post_data to string
805 string post_str(&post_data[0], post_data.size());
806 EXPECT_EQ(post_str.find("machineid="), string::npos);
807 EXPECT_EQ(post_str.find("userid="), string::npos);
808}
809
Darin Petkov6a5b3222010-07-13 14:55:28 -0700810} // namespace chromeos_update_engine