blob: 5ac0811b9f5e12c563cda594eefae00097799c1a [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(
38 "machine_id",
39 "user_id",
40 OmahaRequestParams::kOsPlatform,
41 OmahaRequestParams::kOsVersion,
42 "service_pack",
43 "x86-generic",
44 OmahaRequestParams::kAppId,
45 "0.1.0.0",
46 "en-US",
47 "unittest",
48 false, // delta okay
49 "http://url");
50
Darin Petkov6a5b3222010-07-13 14:55:28 -070051string GetNoUpdateResponse(const string& app_id) {
52 return string(
53 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
54 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
55 "appid=\"") + app_id + "\" status=\"ok\"><ping "
56 "status=\"ok\"/><updatecheck status=\"noupdate\"/></app></gupdate>";
57}
58
59string GetUpdateResponse(const string& app_id,
60 const string& display_version,
61 const string& more_info_url,
62 const string& prompt,
63 const string& codebase,
64 const string& hash,
65 const string& needsadmin,
66 const string& size) {
67 return string("<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
68 "xmlns=\"http://www.google.com/update2/response\" "
69 "protocol=\"2.0\"><app "
70 "appid=\"") + app_id + "\" status=\"ok\"><ping "
71 "status=\"ok\"/><updatecheck DisplayVersion=\"" + display_version + "\" "
72 "MoreInfo=\"" + more_info_url + "\" Prompt=\"" + prompt + "\" "
Andrew de los Reyes3270f742010-07-15 22:28:14 -070073 "IsDelta=\"true\" "
Darin Petkov6a5b3222010-07-13 14:55:28 -070074 "codebase=\"" + codebase + "\" "
75 "hash=\"" + hash + "\" needsadmin=\"" + needsadmin + "\" "
76 "size=\"" + size + "\" status=\"ok\"/></app></gupdate>";
77}
78
79class OmahaRequestActionTestProcessorDelegate : public ActionProcessorDelegate {
80 public:
81 OmahaRequestActionTestProcessorDelegate()
82 : loop_(NULL),
Darin Petkovc1a8b422010-07-19 11:34:49 -070083 expected_code_(kActionCodeSuccess) {}
Darin Petkov6a5b3222010-07-13 14:55:28 -070084 virtual ~OmahaRequestActionTestProcessorDelegate() {
85 }
Darin Petkovc1a8b422010-07-19 11:34:49 -070086 virtual void ProcessingDone(const ActionProcessor* processor,
87 ActionExitCode code) {
Darin Petkov6a5b3222010-07-13 14:55:28 -070088 ASSERT_TRUE(loop_);
89 g_main_loop_quit(loop_);
90 }
91
92 virtual void ActionCompleted(ActionProcessor* processor,
93 AbstractAction* action,
Darin Petkovc1a8b422010-07-19 11:34:49 -070094 ActionExitCode code) {
Darin Petkov6a5b3222010-07-13 14:55:28 -070095 // make sure actions always succeed
96 if (action->Type() == OmahaRequestAction::StaticType())
Darin Petkovc1a8b422010-07-19 11:34:49 -070097 EXPECT_EQ(expected_code_, code);
Darin Petkov6a5b3222010-07-13 14:55:28 -070098 else
Darin Petkovc1a8b422010-07-19 11:34:49 -070099 EXPECT_EQ(kActionCodeSuccess, code);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700100 }
101 GMainLoop *loop_;
Darin Petkovc1a8b422010-07-19 11:34:49 -0700102 ActionExitCode expected_code_;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700103};
104
105gboolean StartProcessorInRunLoop(gpointer data) {
106 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
107 processor->StartProcessing();
108 return FALSE;
109}
Darin Petkov6a5b3222010-07-13 14:55:28 -0700110} // namespace {}
111
112class OutputObjectCollectorAction;
113
114template<>
115class ActionTraits<OutputObjectCollectorAction> {
116 public:
117 // Does not take an object for input
118 typedef OmahaResponse InputObjectType;
119 // On success, puts the output path on output
120 typedef NoneType OutputObjectType;
121};
122
123class OutputObjectCollectorAction : public Action<OutputObjectCollectorAction> {
124 public:
125 OutputObjectCollectorAction() : has_input_object_(false) {}
126 void PerformAction() {
127 // copy input object
128 has_input_object_ = HasInputObject();
129 if (has_input_object_)
130 omaha_response_ = GetInputObject();
Darin Petkovc1a8b422010-07-19 11:34:49 -0700131 processor_->ActionComplete(this, kActionCodeSuccess);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700132 }
133 // Should never be called
134 void TerminateProcessing() {
135 CHECK(false);
136 }
137 // Debugging/logging
138 static std::string StaticType() {
139 return "OutputObjectCollectorAction";
140 }
141 std::string Type() const { return StaticType(); }
142 bool has_input_object_;
143 OmahaResponse omaha_response_;
144};
145
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700146// Returns true iff an output response was obtained from the
147// OmahaRequestAction. |prefs| may be NULL, in which case a local
148// PrefsMock is used. out_response may be NULL. out_post_data may be
149// null; if non-null, the post-data received by the mock HttpFetcher
150// is returned.
151bool TestUpdateCheck(PrefsInterface* prefs,
152 const OmahaRequestParams& params,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700153 const string& http_response,
Darin Petkovc1a8b422010-07-19 11:34:49 -0700154 ActionExitCode expected_code,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700155 OmahaResponse* out_response,
156 vector<char>* out_post_data) {
157 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
158 MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700159 http_response.size());
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700160 PrefsMock local_prefs;
161 OmahaRequestAction action(prefs ? prefs : &local_prefs,
162 params,
163 NULL,
164 fetcher);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700165 OmahaRequestActionTestProcessorDelegate delegate;
166 delegate.loop_ = loop;
Darin Petkovc1a8b422010-07-19 11:34:49 -0700167 delegate.expected_code_ = expected_code;
Darin Petkova4a8a8c2010-07-15 22:21:12 -0700168
Darin Petkov6a5b3222010-07-13 14:55:28 -0700169 ActionProcessor processor;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700170 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700171 processor.EnqueueAction(&action);
172
173 OutputObjectCollectorAction collector_action;
Darin Petkov6a5b3222010-07-13 14:55:28 -0700174 BondActions(&action, &collector_action);
175 processor.EnqueueAction(&collector_action);
176
177 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
178 g_main_loop_run(loop);
179 g_main_loop_unref(loop);
180 if (collector_action.has_input_object_ && out_response)
181 *out_response = collector_action.omaha_response_;
182 if (out_post_data)
183 *out_post_data = fetcher->post_data();
184 return collector_action.has_input_object_;
185}
186
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700187// Tests Event requests -- they should always succeed. |out_post_data|
188// may be null; if non-null, the post-data received by the mock
189// HttpFetcher is returned.
190void TestEvent(const OmahaRequestParams& params,
191 OmahaEvent* event,
192 const string& http_response,
193 vector<char>* out_post_data) {
194 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
195 MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
196 http_response.size());
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700197 PrefsMock prefs;
198 OmahaRequestAction action(&prefs, params, event, fetcher);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700199 OmahaRequestActionTestProcessorDelegate delegate;
200 delegate.loop_ = loop;
201 ActionProcessor processor;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700202 processor.set_delegate(&delegate);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700203 processor.EnqueueAction(&action);
204
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700205 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
206 g_main_loop_run(loop);
207 g_main_loop_unref(loop);
208 if (out_post_data)
209 *out_post_data = fetcher->post_data();
210}
211
Darin Petkov6a5b3222010-07-13 14:55:28 -0700212TEST(OmahaRequestActionTest, NoUpdateTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700213 OmahaResponse response;
214 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700215 TestUpdateCheck(NULL, // prefs
216 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700217 GetNoUpdateResponse(OmahaRequestParams::kAppId),
Darin Petkovc1a8b422010-07-19 11:34:49 -0700218 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700219 &response,
220 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700221 EXPECT_FALSE(response.update_exists);
222}
223
224TEST(OmahaRequestActionTest, ValidUpdateTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700225 OmahaResponse response;
226 ASSERT_TRUE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700227 TestUpdateCheck(NULL, // prefs
228 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700229 GetUpdateResponse(OmahaRequestParams::kAppId,
230 "1.2.3.4", // version
231 "http://more/info",
232 "true", // prompt
233 "http://code/base", // dl url
234 "HASH1234=", // checksum
235 "false", // needs admin
236 "123"), // size
Darin Petkovc1a8b422010-07-19 11:34:49 -0700237 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700238 &response,
239 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700240 EXPECT_TRUE(response.update_exists);
241 EXPECT_EQ("1.2.3.4", response.display_version);
242 EXPECT_EQ("http://code/base", response.codebase);
243 EXPECT_EQ("http://more/info", response.more_info_url);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700244 EXPECT_TRUE(response.is_delta);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700245 EXPECT_EQ("HASH1234=", response.hash);
246 EXPECT_EQ(123, response.size);
247 EXPECT_FALSE(response.needs_admin);
248 EXPECT_TRUE(response.prompt);
249}
250
251TEST(OmahaRequestActionTest, NoOutputPipeTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700252 const string http_response(GetNoUpdateResponse(OmahaRequestParams::kAppId));
253
254 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
255
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700256 PrefsMock prefs;
257 OmahaRequestAction action(&prefs, kDefaultTestParams, NULL,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700258 new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700259 http_response.size()));
260 OmahaRequestActionTestProcessorDelegate delegate;
261 delegate.loop_ = loop;
262 ActionProcessor processor;
263 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700264 processor.EnqueueAction(&action);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700265
266 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
267 g_main_loop_run(loop);
268 g_main_loop_unref(loop);
269 EXPECT_FALSE(processor.IsRunning());
270}
271
272TEST(OmahaRequestActionTest, InvalidXmlTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700273 OmahaResponse response;
274 ASSERT_FALSE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700275 TestUpdateCheck(NULL, // prefs
276 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700277 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700278 kActionCodeError,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700279 &response,
280 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700281 EXPECT_FALSE(response.update_exists);
282}
283
284TEST(OmahaRequestActionTest, MissingStatusTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700285 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700286 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700287 NULL, // prefs
288 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700289 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
290 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
291 "appid=\"foo\" status=\"ok\"><ping "
292 "status=\"ok\"/><updatecheck/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700293 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700294 &response,
295 NULL));
296 EXPECT_FALSE(response.update_exists);
297}
298
299TEST(OmahaRequestActionTest, InvalidStatusTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700300 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700301 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700302 NULL, // prefs
303 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700304 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
305 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
306 "appid=\"foo\" status=\"ok\"><ping "
307 "status=\"ok\"/><updatecheck status=\"foo\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700308 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700309 &response,
310 NULL));
311 EXPECT_FALSE(response.update_exists);
312}
313
314TEST(OmahaRequestActionTest, MissingNodesetTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700315 OmahaResponse response;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700316 ASSERT_FALSE(TestUpdateCheck(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700317 NULL, // prefs
318 kDefaultTestParams,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700319 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
320 "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
321 "appid=\"foo\" status=\"ok\"><ping "
322 "status=\"ok\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700323 kActionCodeError,
Darin Petkov6a5b3222010-07-13 14:55:28 -0700324 &response,
325 NULL));
326 EXPECT_FALSE(response.update_exists);
327}
328
329TEST(OmahaRequestActionTest, MissingFieldTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700330 OmahaResponse response;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700331 ASSERT_TRUE(TestUpdateCheck(NULL, // prefs
332 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700333 string("<?xml version=\"1.0\" "
334 "encoding=\"UTF-8\"?><gupdate "
335 "xmlns=\"http://www.google.com/"
336 "update2/response\" "
337 "protocol=\"2.0\"><app appid=\"") +
338 OmahaRequestParams::kAppId
339 + "\" status=\"ok\"><ping "
340 "status=\"ok\"/><updatecheck "
341 "DisplayVersion=\"1.2.3.4\" "
342 "Prompt=\"false\" "
343 "codebase=\"http://code/base\" "
344 "hash=\"HASH1234=\" needsadmin=\"true\" "
345 "size=\"123\" "
346 "status=\"ok\"/></app></gupdate>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700347 kActionCodeSuccess,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700348 &response,
349 NULL));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700350 EXPECT_TRUE(response.update_exists);
351 EXPECT_EQ("1.2.3.4", response.display_version);
352 EXPECT_EQ("http://code/base", response.codebase);
353 EXPECT_EQ("", response.more_info_url);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700354 EXPECT_FALSE(response.is_delta);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700355 EXPECT_EQ("HASH1234=", response.hash);
356 EXPECT_EQ(123, response.size);
357 EXPECT_TRUE(response.needs_admin);
358 EXPECT_FALSE(response.prompt);
359}
360
361namespace {
362class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
363 public:
364 void ProcessingStopped(const ActionProcessor* processor) {
365 ASSERT_TRUE(loop_);
366 g_main_loop_quit(loop_);
367 }
368 GMainLoop *loop_;
369};
370
371gboolean TerminateTransferTestStarter(gpointer data) {
372 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
373 processor->StartProcessing();
374 CHECK(processor->IsRunning());
375 processor->StopProcessing();
376 return FALSE;
377}
378} // namespace {}
379
380TEST(OmahaRequestActionTest, TerminateTransferTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700381 string http_response("doesn't matter");
382 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
383
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700384 PrefsMock prefs;
385 OmahaRequestAction action(&prefs, kDefaultTestParams, NULL,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700386 new MockHttpFetcher(http_response.data(),
Darin Petkov6a5b3222010-07-13 14:55:28 -0700387 http_response.size()));
388 TerminateEarlyTestProcessorDelegate delegate;
389 delegate.loop_ = loop;
390 ActionProcessor processor;
391 processor.set_delegate(&delegate);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700392 processor.EnqueueAction(&action);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700393
394 g_timeout_add(0, &TerminateTransferTestStarter, &processor);
395 g_main_loop_run(loop);
396 g_main_loop_unref(loop);
397}
398
399TEST(OmahaRequestActionTest, XmlEncodeTest) {
400 EXPECT_EQ("ab", XmlEncode("ab"));
401 EXPECT_EQ("a&lt;b", XmlEncode("a<b"));
402 EXPECT_EQ("foo-&#x3A9;", XmlEncode("foo-\xce\xa9"));
403 EXPECT_EQ("&lt;&amp;&gt;", XmlEncode("<&>"));
404 EXPECT_EQ("&amp;lt;&amp;amp;&amp;gt;", XmlEncode("&lt;&amp;&gt;"));
405
406 vector<char> post_data;
407
408 // Make sure XML Encode is being called on the params
409 OmahaRequestParams params("testthemachine<id",
410 "testtheuser_id&lt;",
411 OmahaRequestParams::kOsPlatform,
412 OmahaRequestParams::kOsVersion,
413 "testtheservice_pack>",
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700414 "x86 generic<id",
Darin Petkov6a5b3222010-07-13 14:55:28 -0700415 OmahaRequestParams::kAppId,
416 "0.1.0.0",
417 "en-US",
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700418 "unittest_track&lt;",
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700419 false, // delta okay
Darin Petkov6a5b3222010-07-13 14:55:28 -0700420 "http://url");
421 OmahaResponse response;
422 ASSERT_FALSE(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700423 TestUpdateCheck(NULL, // prefs
424 params,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700425 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700426 kActionCodeError,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700427 &response,
428 &post_data));
Darin Petkov6a5b3222010-07-13 14:55:28 -0700429 // convert post_data to string
430 string post_str(&post_data[0], post_data.size());
Darin Petkov6a5b3222010-07-13 14:55:28 -0700431 EXPECT_NE(post_str.find("testtheservice_pack&gt;"), string::npos);
432 EXPECT_EQ(post_str.find("testtheservice_pack>"), string::npos);
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700433 EXPECT_NE(post_str.find("x86 generic&lt;id"), string::npos);
434 EXPECT_EQ(post_str.find("x86 generic<id"), string::npos);
435 EXPECT_NE(post_str.find("unittest_track&amp;lt;"), string::npos);
436 EXPECT_EQ(post_str.find("unittest_track&lt;"), 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);
494 EXPECT_EQ(post_str.find("o:event"), string::npos);
495}
496
Darin Petkove17f86b2010-07-20 09:12:01 -0700497TEST(OmahaRequestActionTest, FormatSuccessEventOutputTest) {
498 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700499 TestEvent(kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700500 new OmahaEvent(OmahaEvent::kTypeUpdateDownloadStarted),
501 "invalid xml>",
502 &post_data);
503 // convert post_data to string
504 string post_str(&post_data[0], post_data.size());
505 string expected_event = StringPrintf(
506 " <o:event eventtype=\"%d\" eventresult=\"%d\"></o:event>\n",
507 OmahaEvent::kTypeUpdateDownloadStarted,
508 OmahaEvent::kResultSuccess);
509 EXPECT_NE(post_str.find(expected_event), string::npos);
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700510 EXPECT_EQ(post_str.find("o:ping"), string::npos);
Darin Petkove17f86b2010-07-20 09:12:01 -0700511 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
512}
513
514TEST(OmahaRequestActionTest, FormatErrorEventOutputTest) {
515 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700516 TestEvent(kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700517 new OmahaEvent(OmahaEvent::kTypeDownloadComplete,
518 OmahaEvent::kResultError,
519 kActionCodeError),
520 "invalid xml>",
521 &post_data);
522 // convert post_data to string
523 string post_str(&post_data[0], post_data.size());
524 string expected_event = StringPrintf(
525 " <o:event eventtype=\"%d\" eventresult=\"%d\" "
526 "errorcode=\"%d\"></o:event>\n",
527 OmahaEvent::kTypeDownloadComplete,
528 OmahaEvent::kResultError,
529 kActionCodeError);
530 EXPECT_NE(post_str.find(expected_event), string::npos);
531 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
532}
533
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700534TEST(OmahaRequestActionTest, FormatEventOutputTest) {
535 vector<char> post_data;
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700536 TestEvent(kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700537 new OmahaEvent(OmahaEvent::kTypeDownloadComplete,
538 OmahaEvent::kResultError,
Darin Petkove17f86b2010-07-20 09:12:01 -0700539 kActionCodeError),
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700540 "invalid xml>",
541 &post_data);
542 // convert post_data to string
543 string post_str(&post_data[0], post_data.size());
544 string expected_event = StringPrintf(
545 " <o:event eventtype=\"%d\" eventresult=\"%d\" "
546 "errorcode=\"%d\"></o:event>\n",
547 OmahaEvent::kTypeDownloadComplete,
548 OmahaEvent::kResultError,
Darin Petkove17f86b2010-07-20 09:12:01 -0700549 kActionCodeError);
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700550 EXPECT_NE(post_str.find(expected_event), string::npos);
551 EXPECT_EQ(post_str.find("o:updatecheck"), string::npos);
552}
553
554TEST(OmahaRequestActionTest, IsEventTest) {
555 string http_response("doesn't matter");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700556 PrefsMock prefs;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700557 OmahaRequestAction update_check_action(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700558 &prefs,
559 kDefaultTestParams,
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700560 NULL,
561 new MockHttpFetcher(http_response.data(),
562 http_response.size()));
563 EXPECT_FALSE(update_check_action.IsEvent());
564
565 OmahaRequestAction event_action(
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700566 &prefs,
567 kDefaultTestParams,
Darin Petkove17f86b2010-07-20 09:12:01 -0700568 new OmahaEvent(OmahaEvent::kTypeUpdateComplete),
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700569 new MockHttpFetcher(http_response.data(),
570 http_response.size()));
571 EXPECT_TRUE(event_action.IsEvent());
572}
573
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700574TEST(OmahaRequestActionTest, FormatDeltaOkayOutputTest) {
575 for (int i = 0; i < 2; i++) {
576 bool delta_okay = i == 1;
577 const char* delta_okay_str = delta_okay ? "true" : "false";
578 vector<char> post_data;
579 OmahaRequestParams params("machine_id",
580 "user_id",
581 OmahaRequestParams::kOsPlatform,
582 OmahaRequestParams::kOsVersion,
583 "service_pack",
584 "x86-generic",
585 OmahaRequestParams::kAppId,
586 "0.1.0.0",
587 "en-US",
588 "unittest_track",
589 delta_okay,
590 "http://url");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700591 ASSERT_FALSE(TestUpdateCheck(NULL, // prefs
592 params,
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700593 "invalid xml>",
Darin Petkovc1a8b422010-07-19 11:34:49 -0700594 kActionCodeError,
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -0700595 NULL,
596 &post_data));
597 // convert post_data to string
598 string post_str(&post_data[0], post_data.size());
599 EXPECT_NE(post_str.find(StringPrintf(" delta_okay=\"%s\"", delta_okay_str)),
600 string::npos)
601 << "i = " << i;
602 }
603}
604
Darin Petkove17f86b2010-07-20 09:12:01 -0700605TEST(OmahaRequestActionTest, OmahaEventTest) {
606 OmahaEvent default_event;
607 EXPECT_EQ(OmahaEvent::kTypeUnknown, default_event.type);
608 EXPECT_EQ(OmahaEvent::kResultError, default_event.result);
609 EXPECT_EQ(kActionCodeError, default_event.error_code);
610
611 OmahaEvent success_event(OmahaEvent::kTypeUpdateDownloadStarted);
612 EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadStarted, success_event.type);
613 EXPECT_EQ(OmahaEvent::kResultSuccess, success_event.result);
614 EXPECT_EQ(kActionCodeSuccess, success_event.error_code);
615
616 OmahaEvent error_event(OmahaEvent::kTypeUpdateDownloadFinished,
617 OmahaEvent::kResultError,
618 kActionCodeError);
619 EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadFinished, error_event.type);
620 EXPECT_EQ(OmahaEvent::kResultError, error_event.result);
621 EXPECT_EQ(kActionCodeError, error_event.error_code);
622}
623
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700624TEST(OmahaRequestActionTest, PingTest) {
625 PrefsMock prefs;
626 // Add a few hours to the day difference to test no rounding, etc.
627 int64_t five_days_ago =
628 (Time::Now() - TimeDelta::FromHours(5 * 24 + 13)).ToInternalValue();
629 int64_t six_days_ago =
630 (Time::Now() - TimeDelta::FromHours(6 * 24 + 11)).ToInternalValue();
631 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
632 .WillOnce(DoAll(SetArgumentPointee<1>(six_days_ago), Return(true)));
633 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
634 .WillOnce(DoAll(SetArgumentPointee<1>(five_days_ago), Return(true)));
635 vector<char> post_data;
636 ASSERT_TRUE(
637 TestUpdateCheck(&prefs,
638 kDefaultTestParams,
639 GetNoUpdateResponse(OmahaRequestParams::kAppId),
640 kActionCodeSuccess,
641 NULL,
642 &post_data));
643 string post_str(&post_data[0], post_data.size());
644 EXPECT_NE(post_str.find("<o:ping a=\"6\" r=\"5\"></o:ping>"), string::npos);
645}
646
647TEST(OmahaRequestActionTest, ActivePingTest) {
648 PrefsMock prefs;
649 int64_t three_days_ago =
650 (Time::Now() - TimeDelta::FromHours(3 * 24 + 12)).ToInternalValue();
651 int64_t now = Time::Now().ToInternalValue();
652 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
653 .WillOnce(DoAll(SetArgumentPointee<1>(three_days_ago), Return(true)));
654 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
655 .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
656 vector<char> post_data;
657 ASSERT_TRUE(
658 TestUpdateCheck(&prefs,
659 kDefaultTestParams,
660 GetNoUpdateResponse(OmahaRequestParams::kAppId),
661 kActionCodeSuccess,
662 NULL,
663 &post_data));
664 string post_str(&post_data[0], post_data.size());
665 EXPECT_NE(post_str.find("<o:ping a=\"3\"></o:ping>"), string::npos);
666}
667
668TEST(OmahaRequestActionTest, RollCallPingTest) {
669 PrefsMock prefs;
670 int64_t four_days_ago =
671 (Time::Now() - TimeDelta::FromHours(4 * 24)).ToInternalValue();
672 int64_t now = Time::Now().ToInternalValue();
673 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
674 .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
675 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
676 .WillOnce(DoAll(SetArgumentPointee<1>(four_days_ago), Return(true)));
677 vector<char> post_data;
678 ASSERT_TRUE(
679 TestUpdateCheck(&prefs,
680 kDefaultTestParams,
681 GetNoUpdateResponse(OmahaRequestParams::kAppId),
682 kActionCodeSuccess,
683 NULL,
684 &post_data));
685 string post_str(&post_data[0], post_data.size());
686 EXPECT_NE(post_str.find("<o:ping r=\"4\"></o:ping>\n"), string::npos);
687}
688
689TEST(OmahaRequestActionTest, NoPingTest) {
690 PrefsMock prefs;
691 int64_t one_hour_ago =
692 (Time::Now() - TimeDelta::FromHours(1)).ToInternalValue();
693 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
694 .WillOnce(DoAll(SetArgumentPointee<1>(one_hour_ago), Return(true)));
695 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
696 .WillOnce(DoAll(SetArgumentPointee<1>(one_hour_ago), Return(true)));
697 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
698 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
699 vector<char> post_data;
700 ASSERT_TRUE(
701 TestUpdateCheck(&prefs,
702 kDefaultTestParams,
703 GetNoUpdateResponse(OmahaRequestParams::kAppId),
704 kActionCodeSuccess,
705 NULL,
706 &post_data));
707 string post_str(&post_data[0], post_data.size());
708 EXPECT_EQ(post_str.find("o:ping"), string::npos);
709}
710
711TEST(OmahaRequestActionTest, BackInTimePingTest) {
712 PrefsMock prefs;
713 int64_t future =
714 (Time::Now() + TimeDelta::FromHours(3 * 24 + 4)).ToInternalValue();
715 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
716 .WillOnce(DoAll(SetArgumentPointee<1>(future), Return(true)));
717 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
718 .WillOnce(DoAll(SetArgumentPointee<1>(future), Return(true)));
719 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _))
720 .WillOnce(Return(true));
721 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _))
722 .WillOnce(Return(true));
723 vector<char> post_data;
724 ASSERT_TRUE(
725 TestUpdateCheck(&prefs,
726 kDefaultTestParams,
727 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
728 "xmlns=\"http://www.google.com/update2/response\" "
729 "protocol=\"2.0\"><daystart elapsed_seconds=\"100\"/>"
730 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
731 "<updatecheck status=\"noupdate\"/></app></gupdate>",
732 kActionCodeSuccess,
733 NULL,
734 &post_data));
735 string post_str(&post_data[0], post_data.size());
736 EXPECT_EQ(post_str.find("o:ping"), string::npos);
737}
738
739TEST(OmahaRequestActionTest, LastPingDayUpdateTest) {
740 // This test checks that the action updates the last ping day to now
741 // minus 200 seconds with a slack for 5 seconds. Therefore, the test
742 // may fail if it runs for longer than 5 seconds. It shouldn't run
743 // that long though.
744 int64_t midnight =
745 (Time::Now() - TimeDelta::FromSeconds(200)).ToInternalValue();
746 int64_t midnight_slack =
747 (Time::Now() - TimeDelta::FromSeconds(195)).ToInternalValue();
748 PrefsMock prefs;
749 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay,
750 AllOf(Ge(midnight), Le(midnight_slack))))
751 .WillOnce(Return(true));
752 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay,
753 AllOf(Ge(midnight), Le(midnight_slack))))
754 .WillOnce(Return(true));
755 ASSERT_TRUE(
756 TestUpdateCheck(&prefs,
757 kDefaultTestParams,
758 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
759 "xmlns=\"http://www.google.com/update2/response\" "
760 "protocol=\"2.0\"><daystart elapsed_seconds=\"200\"/>"
761 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
762 "<updatecheck status=\"noupdate\"/></app></gupdate>",
763 kActionCodeSuccess,
764 NULL,
765 NULL));
766}
767
768TEST(OmahaRequestActionTest, NoElapsedSecondsTest) {
769 PrefsMock prefs;
770 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
771 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
772 ASSERT_TRUE(
773 TestUpdateCheck(&prefs,
774 kDefaultTestParams,
775 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
776 "xmlns=\"http://www.google.com/update2/response\" "
777 "protocol=\"2.0\"><daystart blah=\"200\"/>"
778 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
779 "<updatecheck status=\"noupdate\"/></app></gupdate>",
780 kActionCodeSuccess,
781 NULL,
782 NULL));
783}
784
785TEST(OmahaRequestActionTest, BadElapsedSecondsTest) {
786 PrefsMock prefs;
787 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
788 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
789 ASSERT_TRUE(
790 TestUpdateCheck(&prefs,
791 kDefaultTestParams,
792 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
793 "xmlns=\"http://www.google.com/update2/response\" "
794 "protocol=\"2.0\"><daystart elapsed_seconds=\"x\"/>"
795 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
796 "<updatecheck status=\"noupdate\"/></app></gupdate>",
797 kActionCodeSuccess,
798 NULL,
799 NULL));
800}
801
Darin Petkov6a5b3222010-07-13 14:55:28 -0700802} // namespace chromeos_update_engine