blob: 16c2507da6ffe27ec4664f4511bbbe18e1a3eaae [file] [log] [blame]
rspangler@google.com49fdf182009-10-10 00:57:34 +00001// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
6#include <vector>
Darin Petkov73058b42010-10-06 16:32:19 -07007
rspangler@google.com49fdf182009-10-10 00:57:34 +00008#include <glib.h>
Darin Petkov9d911fa2010-08-19 09:36:08 -07009#include <gmock/gmock.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000010#include <gtest/gtest.h>
Darin Petkov73058b42010-10-06 16:32:19 -070011
rspangler@google.com49fdf182009-10-10 00:57:34 +000012#include "update_engine/action_pipe.h"
13#include "update_engine/download_action.h"
14#include "update_engine/mock_http_fetcher.h"
15#include "update_engine/omaha_hash_calculator.h"
Darin Petkov73058b42010-10-06 16:32:19 -070016#include "update_engine/prefs_mock.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000017#include "update_engine/test_utils.h"
adlr@google.comc98a7ed2009-12-04 18:54:03 +000018#include "update_engine/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000019
20namespace chromeos_update_engine {
21
22using std::string;
23using std::vector;
Darin Petkov9d911fa2010-08-19 09:36:08 -070024using testing::_;
25using testing::AtLeast;
26using testing::InSequence;
rspangler@google.com49fdf182009-10-10 00:57:34 +000027
28class DownloadActionTest : public ::testing::Test { };
29
30namespace {
Darin Petkov9d911fa2010-08-19 09:36:08 -070031class DownloadActionDelegateMock : public DownloadActionDelegate {
32 public:
33 MOCK_METHOD1(SetDownloadStatus, void(bool active));
34 MOCK_METHOD2(BytesReceived, void(uint64_t bytes_received, uint64_t total));
35};
36
rspangler@google.com49fdf182009-10-10 00:57:34 +000037class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate {
38 public:
Darin Petkovc97435c2010-07-20 12:37:43 -070039 explicit DownloadActionTestProcessorDelegate(ActionExitCode expected_code)
40 : loop_(NULL),
41 processing_done_called_(false),
42 expected_code_(expected_code) {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000043 virtual ~DownloadActionTestProcessorDelegate() {
44 EXPECT_TRUE(processing_done_called_);
45 }
Darin Petkovc1a8b422010-07-19 11:34:49 -070046 virtual void ProcessingDone(const ActionProcessor* processor,
47 ActionExitCode code) {
rspangler@google.com49fdf182009-10-10 00:57:34 +000048 ASSERT_TRUE(loop_);
49 g_main_loop_quit(loop_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +000050 vector<char> found_data;
51 ASSERT_TRUE(utils::ReadFile(path_, &found_data));
Darin Petkov9ce452b2010-11-17 14:33:28 -080052 if (expected_code_ != kActionCodeDownloadWriteError) {
53 ASSERT_EQ(expected_data_.size(), found_data.size());
54 for (unsigned i = 0; i < expected_data_.size(); i++) {
55 EXPECT_EQ(expected_data_[i], found_data[i]);
56 }
rspangler@google.com49fdf182009-10-10 00:57:34 +000057 }
58 processing_done_called_ = true;
59 }
60
adlr@google.comc98a7ed2009-12-04 18:54:03 +000061 virtual void ActionCompleted(ActionProcessor* processor,
62 AbstractAction* action,
Darin Petkovc1a8b422010-07-19 11:34:49 -070063 ActionExitCode code) {
Darin Petkovc97435c2010-07-20 12:37:43 -070064 const string type = action->Type();
65 if (type == DownloadAction::StaticType()) {
66 EXPECT_EQ(expected_code_, code);
67 } else {
68 EXPECT_EQ(kActionCodeSuccess, code);
69 }
rspangler@google.com49fdf182009-10-10 00:57:34 +000070 }
71
72 GMainLoop *loop_;
73 string path_;
74 vector<char> expected_data_;
75 bool processing_done_called_;
Darin Petkovc97435c2010-07-20 12:37:43 -070076 ActionExitCode expected_code_;
rspangler@google.com49fdf182009-10-10 00:57:34 +000077};
78
Darin Petkov9ce452b2010-11-17 14:33:28 -080079class TestDirectFileWriter : public DirectFileWriter {
80 public:
81 TestDirectFileWriter() : fail_write_(0), current_write_(0) {}
82 void set_fail_write(int fail_write) { fail_write_ = fail_write; }
83
84 virtual ssize_t Write(const void* bytes, size_t count) {
85 if (++current_write_ == fail_write_) {
86 return -EINVAL;
87 }
88 return DirectFileWriter::Write(bytes, count);
89 }
90
91 private:
92 // If positive, fail on the |fail_write_| call to Write.
93 int fail_write_;
94 int current_write_;
95};
96
rspangler@google.com49fdf182009-10-10 00:57:34 +000097struct EntryPointArgs {
98 const vector<char> *data;
99 GMainLoop *loop;
100 ActionProcessor *processor;
101};
102
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700103struct StartProcessorInRunLoopArgs {
104 ActionProcessor* processor;
105 MockHttpFetcher* http_fetcher;
106};
107
rspangler@google.com49fdf182009-10-10 00:57:34 +0000108gboolean StartProcessorInRunLoop(gpointer data) {
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700109 ActionProcessor* processor =
110 reinterpret_cast<StartProcessorInRunLoopArgs*>(data)->processor;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000111 processor->StartProcessing();
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700112 MockHttpFetcher* http_fetcher =
113 reinterpret_cast<StartProcessorInRunLoopArgs*>(data)->http_fetcher;
114 http_fetcher->SetOffset(1);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000115 return FALSE;
116}
117
Darin Petkov9d911fa2010-08-19 09:36:08 -0700118void TestWithData(const vector<char>& data,
119 bool hash_test,
Darin Petkov50332f12010-09-24 11:44:47 -0700120 bool size_test,
Darin Petkov9ce452b2010-11-17 14:33:28 -0800121 int fail_write,
Darin Petkov9d911fa2010-08-19 09:36:08 -0700122 bool use_download_delegate) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000123 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
124
125 // TODO(adlr): see if we need a different file for build bots
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700126 ScopedTempFile output_temp_file;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800127 TestDirectFileWriter writer;
128 writer.set_fail_write(fail_write);
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700129
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700130 // We pull off the first byte from data and seek past it.
131
Darin Petkovc97435c2010-07-20 12:37:43 -0700132 string hash = hash_test ?
133 OmahaHashCalculator::OmahaHashOfString("random string") :
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700134 OmahaHashCalculator::OmahaHashOfBytes(&data[1], data.size() - 1);
Darin Petkov50332f12010-09-24 11:44:47 -0700135 uint64_t size = data.size() + (size_test ? 1 : 0);
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700136 InstallPlan install_plan(true,
Darin Petkov0406e402010-10-06 21:33:11 -0700137 false,
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700138 "",
Darin Petkov50332f12010-09-24 11:44:47 -0700139 size,
Darin Petkovc97435c2010-07-20 12:37:43 -0700140 hash,
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700141 output_temp_file.GetPath(),
142 "");
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000143 ObjectFeederAction<InstallPlan> feeder_action;
144 feeder_action.set_obj(install_plan);
Darin Petkov73058b42010-10-06 16:32:19 -0700145 PrefsMock prefs;
Andrew de los Reyes45168102010-11-22 11:13:50 -0800146 MockHttpFetcher* http_fetcher = new MockHttpFetcher(&data[0],
147 data.size(),
148 NULL);
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700149 // takes ownership of passed in HttpFetcher
150 DownloadAction download_action(&prefs, http_fetcher);
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700151 download_action.SetTestFileWriter(&writer);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000152 BondActions(&feeder_action, &download_action);
Darin Petkov9d911fa2010-08-19 09:36:08 -0700153 DownloadActionDelegateMock download_delegate;
154 if (use_download_delegate) {
155 InSequence s;
156 download_action.set_delegate(&download_delegate);
157 EXPECT_CALL(download_delegate, SetDownloadStatus(true)).Times(1);
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700158 if (data.size() > kMockHttpFetcherChunkSize)
159 EXPECT_CALL(download_delegate,
160 BytesReceived(1 + kMockHttpFetcherChunkSize, _));
Darin Petkov9ce452b2010-11-17 14:33:28 -0800161 EXPECT_CALL(download_delegate, BytesReceived(_, _)).Times(AtLeast(1));
Darin Petkov9d911fa2010-08-19 09:36:08 -0700162 EXPECT_CALL(download_delegate, SetDownloadStatus(false)).Times(1);
163 }
Darin Petkov50332f12010-09-24 11:44:47 -0700164 ActionExitCode expected_code = kActionCodeSuccess;
165 if (hash_test)
166 expected_code = kActionCodeDownloadHashMismatchError;
167 else if (size_test)
168 expected_code = kActionCodeDownloadSizeMismatchError;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800169 else if (fail_write > 0)
170 expected_code = kActionCodeDownloadWriteError;
Darin Petkov50332f12010-09-24 11:44:47 -0700171 DownloadActionTestProcessorDelegate delegate(expected_code);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000172 delegate.loop_ = loop;
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700173 delegate.expected_data_ = vector<char>(data.begin() + 1, data.end());
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700174 delegate.path_ = output_temp_file.GetPath();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000175 ActionProcessor processor;
176 processor.set_delegate(&delegate);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000177 processor.EnqueueAction(&feeder_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000178 processor.EnqueueAction(&download_action);
179
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700180 StartProcessorInRunLoopArgs args;
181 args.processor = &processor;
182 args.http_fetcher = http_fetcher;
183 g_timeout_add(0, &StartProcessorInRunLoop, &args);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000184 g_main_loop_run(loop);
185 g_main_loop_unref(loop);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000186}
187} // namespace {}
188
189TEST(DownloadActionTest, SimpleTest) {
190 vector<char> small;
191 const char* foo = "foo";
192 small.insert(small.end(), foo, foo + strlen(foo));
Darin Petkov50332f12010-09-24 11:44:47 -0700193 TestWithData(small,
194 false, // hash_test
195 false, // size_test
Darin Petkov9ce452b2010-11-17 14:33:28 -0800196 0, // fail_write
Darin Petkov50332f12010-09-24 11:44:47 -0700197 true); // use_download_delegate
rspangler@google.com49fdf182009-10-10 00:57:34 +0000198}
199
200TEST(DownloadActionTest, LargeTest) {
201 vector<char> big(5 * kMockHttpFetcherChunkSize);
202 char c = '0';
203 for (unsigned int i = 0; i < big.size(); i++) {
204 big[i] = c;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800205 c = ('9' == c) ? '0' : c + 1;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000206 }
Darin Petkov50332f12010-09-24 11:44:47 -0700207 TestWithData(big,
208 false, // hash_test
209 false, // size_test
Darin Petkov9ce452b2010-11-17 14:33:28 -0800210 0, // fail_write
211 true); // use_download_delegate
212}
213
214TEST(DownloadActionTest, FailWriteTest) {
215 vector<char> big(5 * kMockHttpFetcherChunkSize);
216 char c = '0';
217 for (unsigned int i = 0; i < big.size(); i++) {
218 big[i] = c;
219 c = ('9' == c) ? '0' : c + 1;
220 }
221 TestWithData(big,
222 false, // hash_test
223 false, // size_test
224 2, // fail_write
Darin Petkov50332f12010-09-24 11:44:47 -0700225 true); // use_download_delegate
Darin Petkovc97435c2010-07-20 12:37:43 -0700226}
227
228TEST(DownloadActionTest, BadHashTest) {
229 vector<char> small;
230 const char* foo = "foo";
231 small.insert(small.end(), foo, foo + strlen(foo));
Darin Petkov50332f12010-09-24 11:44:47 -0700232 TestWithData(small,
233 true, // hash_test
234 false, // size_test
Darin Petkov9ce452b2010-11-17 14:33:28 -0800235 0, // fail_write
Darin Petkov50332f12010-09-24 11:44:47 -0700236 true); // use_download_delegate
237}
238
239TEST(DownloadActionTest, BadSizeTest) {
240 const char* something = "something";
241 vector<char> small(something, something + strlen(something));
242 TestWithData(small,
243 false, // hash_test
244 true, // size_test
Darin Petkov9ce452b2010-11-17 14:33:28 -0800245 0, // fail_write
Darin Petkov50332f12010-09-24 11:44:47 -0700246 true); // use_download_delegate
Darin Petkov9d911fa2010-08-19 09:36:08 -0700247}
248
249TEST(DownloadActionTest, NoDownloadDelegateTest) {
250 vector<char> small;
251 const char* foo = "foofoo";
252 small.insert(small.end(), foo, foo + strlen(foo));
Darin Petkov50332f12010-09-24 11:44:47 -0700253 TestWithData(small,
254 false, // hash_test
255 false, // size_test
Darin Petkov9ce452b2010-11-17 14:33:28 -0800256 0, // fail_write
Darin Petkov50332f12010-09-24 11:44:47 -0700257 false); // use_download_delegate
rspangler@google.com49fdf182009-10-10 00:57:34 +0000258}
259
260namespace {
261class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
262 public:
263 void ProcessingStopped(const ActionProcessor* processor) {
264 ASSERT_TRUE(loop_);
265 g_main_loop_quit(loop_);
266 }
267 GMainLoop *loop_;
268};
269
270gboolean TerminateEarlyTestStarter(gpointer data) {
271 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
272 processor->StartProcessing();
273 CHECK(processor->IsRunning());
274 processor->StopProcessing();
275 return FALSE;
276}
277
Darin Petkov9d911fa2010-08-19 09:36:08 -0700278void TestTerminateEarly(bool use_download_delegate) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000279 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
280
281 vector<char> data(kMockHttpFetcherChunkSize + kMockHttpFetcherChunkSize / 2);
282 memset(&data[0], 0, data.size());
283
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700284 ScopedTempFile temp_file;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000285 {
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700286 DirectFileWriter writer;
287
rspangler@google.com49fdf182009-10-10 00:57:34 +0000288 // takes ownership of passed in HttpFetcher
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000289 ObjectFeederAction<InstallPlan> feeder_action;
Darin Petkov0406e402010-10-06 21:33:11 -0700290 InstallPlan install_plan(true, false, "", 0, "", temp_file.GetPath(), "");
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000291 feeder_action.set_obj(install_plan);
Darin Petkov73058b42010-10-06 16:32:19 -0700292 PrefsMock prefs;
293 DownloadAction download_action(&prefs,
Andrew de los Reyes45168102010-11-22 11:13:50 -0800294 new MockHttpFetcher(&data[0],
295 data.size(),
296 NULL));
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700297 download_action.SetTestFileWriter(&writer);
Darin Petkov9d911fa2010-08-19 09:36:08 -0700298 DownloadActionDelegateMock download_delegate;
299 if (use_download_delegate) {
300 InSequence s;
301 download_action.set_delegate(&download_delegate);
302 EXPECT_CALL(download_delegate, SetDownloadStatus(true)).Times(1);
303 EXPECT_CALL(download_delegate, SetDownloadStatus(false)).Times(1);
304 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000305 TerminateEarlyTestProcessorDelegate delegate;
306 delegate.loop_ = loop;
307 ActionProcessor processor;
308 processor.set_delegate(&delegate);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000309 processor.EnqueueAction(&feeder_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000310 processor.EnqueueAction(&download_action);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000311 BondActions(&feeder_action, &download_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000312
313 g_timeout_add(0, &TerminateEarlyTestStarter, &processor);
314 g_main_loop_run(loop);
315 g_main_loop_unref(loop);
316 }
317
318 // 1 or 0 chunks should have come through
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700319 const off_t resulting_file_size(utils::FileSize(temp_file.GetPath()));
320 EXPECT_GE(resulting_file_size, 0);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000321 if (resulting_file_size != 0)
322 EXPECT_EQ(kMockHttpFetcherChunkSize, resulting_file_size);
323}
324
Darin Petkov9d911fa2010-08-19 09:36:08 -0700325} // namespace {}
326
327TEST(DownloadActionTest, TerminateEarlyTest) {
328 TestTerminateEarly(true);
329}
330
331TEST(DownloadActionTest, TerminateEarlyNoDownloadDelegateTest) {
332 TestTerminateEarly(false);
333}
334
rspangler@google.com49fdf182009-10-10 00:57:34 +0000335class DownloadActionTestAction;
336
337template<>
338class ActionTraits<DownloadActionTestAction> {
339 public:
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000340 typedef InstallPlan OutputObjectType;
341 typedef InstallPlan InputObjectType;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000342};
343
344// This is a simple Action class for testing.
345struct DownloadActionTestAction : public Action<DownloadActionTestAction> {
346 DownloadActionTestAction() : did_run_(false) {}
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000347 typedef InstallPlan InputObjectType;
348 typedef InstallPlan OutputObjectType;
349 ActionPipe<InstallPlan>* in_pipe() { return in_pipe_.get(); }
350 ActionPipe<InstallPlan>* out_pipe() { return out_pipe_.get(); }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000351 ActionProcessor* processor() { return processor_; }
352 void PerformAction() {
353 did_run_ = true;
354 ASSERT_TRUE(HasInputObject());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000355 EXPECT_TRUE(expected_input_object_ == GetInputObject());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000356 ASSERT_TRUE(processor());
Darin Petkovc1a8b422010-07-19 11:34:49 -0700357 processor()->ActionComplete(this, kActionCodeSuccess);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000358 }
359 string Type() const { return "DownloadActionTestAction"; }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000360 InstallPlan expected_input_object_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000361 bool did_run_;
362};
363
364namespace {
365// This class is an ActionProcessorDelegate that simply terminates the
366// run loop when the ActionProcessor has completed processing. It's used
367// only by the test PassObjectOutTest.
368class PassObjectOutTestProcessorDelegate : public ActionProcessorDelegate {
369 public:
Darin Petkovc1a8b422010-07-19 11:34:49 -0700370 void ProcessingDone(const ActionProcessor* processor, ActionExitCode code) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000371 ASSERT_TRUE(loop_);
372 g_main_loop_quit(loop_);
373 }
374 GMainLoop *loop_;
375};
376
377gboolean PassObjectOutTestStarter(gpointer data) {
378 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
379 processor->StartProcessing();
380 return FALSE;
381}
382}
383
384TEST(DownloadActionTest, PassObjectOutTest) {
385 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
386
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700387 DirectFileWriter writer;
388
rspangler@google.com49fdf182009-10-10 00:57:34 +0000389 // takes ownership of passed in HttpFetcher
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700390 InstallPlan install_plan(true,
Darin Petkov0406e402010-10-06 21:33:11 -0700391 false,
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700392 "",
Darin Petkov50332f12010-09-24 11:44:47 -0700393 1,
Andrew de los Reyes1e338b82010-01-22 14:57:27 -0800394 OmahaHashCalculator::OmahaHashOfString("x"),
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700395 "/dev/null",
Andrew de los Reyes1e338b82010-01-22 14:57:27 -0800396 "/dev/null");
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000397 ObjectFeederAction<InstallPlan> feeder_action;
398 feeder_action.set_obj(install_plan);
Darin Petkov73058b42010-10-06 16:32:19 -0700399 PrefsMock prefs;
Andrew de los Reyes45168102010-11-22 11:13:50 -0800400 DownloadAction download_action(&prefs, new MockHttpFetcher("x", 1, NULL));
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700401 download_action.SetTestFileWriter(&writer);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000402
403 DownloadActionTestAction test_action;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000404 test_action.expected_input_object_ = install_plan;
405 BondActions(&feeder_action, &download_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000406 BondActions(&download_action, &test_action);
407
408 ActionProcessor processor;
409 PassObjectOutTestProcessorDelegate delegate;
410 delegate.loop_ = loop;
411 processor.set_delegate(&delegate);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000412 processor.EnqueueAction(&feeder_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000413 processor.EnqueueAction(&download_action);
414 processor.EnqueueAction(&test_action);
415
416 g_timeout_add(0, &PassObjectOutTestStarter, &processor);
417 g_main_loop_run(loop);
418 g_main_loop_unref(loop);
419
420 EXPECT_EQ(true, test_action.did_run_);
421}
422
423TEST(DownloadActionTest, BadOutFileTest) {
424 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
425
426 const string path("/fake/path/that/cant/be/created/because/of/missing/dirs");
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700427 DirectFileWriter writer;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000428
429 // takes ownership of passed in HttpFetcher
Darin Petkov0406e402010-10-06 21:33:11 -0700430 InstallPlan install_plan(true, false, "", 0, "", path, "");
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000431 ObjectFeederAction<InstallPlan> feeder_action;
432 feeder_action.set_obj(install_plan);
Darin Petkov73058b42010-10-06 16:32:19 -0700433 PrefsMock prefs;
Andrew de los Reyes45168102010-11-22 11:13:50 -0800434 DownloadAction download_action(&prefs, new MockHttpFetcher("x", 1, NULL));
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700435 download_action.SetTestFileWriter(&writer);
Darin Petkovc1a8b422010-07-19 11:34:49 -0700436
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000437 BondActions(&feeder_action, &download_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000438
439 ActionProcessor processor;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000440 processor.EnqueueAction(&feeder_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000441 processor.EnqueueAction(&download_action);
442 processor.StartProcessing();
443 ASSERT_FALSE(processor.IsRunning());
444
445 g_main_loop_unref(loop);
446}
447
448} // namespace chromeos_update_engine