blob: e937d71bd5d74f90e91c0d9b2697f46484781b76 [file] [log] [blame]
Darin Petkov7ed561b2011-10-04 02:59:03 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
rspangler@google.com49fdf182009-10-10 00:57:34 +00002// 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:
David Zeuthena99981f2013-04-29 13:42:47 -070039 explicit DownloadActionTestProcessorDelegate(ErrorCode expected_code)
Darin Petkovc97435c2010-07-20 12:37:43 -070040 : 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,
David Zeuthena99981f2013-04-29 13:42:47 -070047 ErrorCode 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));
David Zeuthena99981f2013-04-29 13:42:47 -070052 if (expected_code_ != kErrorCodeDownloadWriteError) {
Darin Petkov9ce452b2010-11-17 14:33:28 -080053 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,
David Zeuthena99981f2013-04-29 13:42:47 -070063 ErrorCode 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 {
David Zeuthena99981f2013-04-29 13:42:47 -070068 EXPECT_EQ(kErrorCodeSuccess, code);
Darin Petkovc97435c2010-07-20 12:37:43 -070069 }
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_;
David Zeuthena99981f2013-04-29 13:42:47 -070076 ErrorCode 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
Don Garrette410e0f2011-11-10 15:39:01 -080084 virtual bool Write(const void* bytes, size_t count) {
Darin Petkov9ce452b2010-11-17 14:33:28 -080085 if (++current_write_ == fail_write_) {
Don Garrette410e0f2011-11-10 15:39:01 -080086 return false;
Darin Petkov9ce452b2010-11-17 14:33:28 -080087 }
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,
Darin Petkov9ce452b2010-11-17 14:33:28 -0800119 int fail_write,
Darin Petkov9d911fa2010-08-19 09:36:08 -0700120 bool use_download_delegate) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000121 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
122
123 // TODO(adlr): see if we need a different file for build bots
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700124 ScopedTempFile output_temp_file;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800125 TestDirectFileWriter writer;
126 writer.set_fail_write(fail_write);
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700127
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700128 // We pull off the first byte from data and seek past it.
129
Darin Petkov7ed561b2011-10-04 02:59:03 -0700130 string hash =
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700131 OmahaHashCalculator::OmahaHashOfBytes(&data[1], data.size() - 1);
Darin Petkov7ed561b2011-10-04 02:59:03 -0700132 uint64_t size = data.size();
133 InstallPlan install_plan(false,
Gilad Arnold21504f02013-05-24 08:51:22 -0700134 false,
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700135 "",
Darin Petkov50332f12010-09-24 11:44:47 -0700136 size,
Darin Petkovc97435c2010-07-20 12:37:43 -0700137 hash,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700138 0,
139 "",
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700140 output_temp_file.GetPath(),
141 "");
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000142 ObjectFeederAction<InstallPlan> feeder_action;
143 feeder_action.set_obj(install_plan);
Darin Petkov73058b42010-10-06 16:32:19 -0700144 PrefsMock prefs;
Andrew de los Reyes45168102010-11-22 11:13:50 -0800145 MockHttpFetcher* http_fetcher = new MockHttpFetcher(&data[0],
146 data.size(),
147 NULL);
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700148 // takes ownership of passed in HttpFetcher
Jay Srinivasanf0572052012-10-23 18:12:56 -0700149 DownloadAction download_action(&prefs, NULL, http_fetcher);
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700150 download_action.SetTestFileWriter(&writer);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000151 BondActions(&feeder_action, &download_action);
Darin Petkov9d911fa2010-08-19 09:36:08 -0700152 DownloadActionDelegateMock download_delegate;
153 if (use_download_delegate) {
154 InSequence s;
155 download_action.set_delegate(&download_delegate);
156 EXPECT_CALL(download_delegate, SetDownloadStatus(true)).Times(1);
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700157 if (data.size() > kMockHttpFetcherChunkSize)
158 EXPECT_CALL(download_delegate,
159 BytesReceived(1 + kMockHttpFetcherChunkSize, _));
Darin Petkov9ce452b2010-11-17 14:33:28 -0800160 EXPECT_CALL(download_delegate, BytesReceived(_, _)).Times(AtLeast(1));
Darin Petkov9d911fa2010-08-19 09:36:08 -0700161 EXPECT_CALL(download_delegate, SetDownloadStatus(false)).Times(1);
162 }
David Zeuthena99981f2013-04-29 13:42:47 -0700163 ErrorCode expected_code = kErrorCodeSuccess;
Darin Petkov7ed561b2011-10-04 02:59:03 -0700164 if (fail_write > 0)
David Zeuthena99981f2013-04-29 13:42:47 -0700165 expected_code = kErrorCodeDownloadWriteError;
Darin Petkov50332f12010-09-24 11:44:47 -0700166 DownloadActionTestProcessorDelegate delegate(expected_code);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000167 delegate.loop_ = loop;
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700168 delegate.expected_data_ = vector<char>(data.begin() + 1, data.end());
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700169 delegate.path_ = output_temp_file.GetPath();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000170 ActionProcessor processor;
171 processor.set_delegate(&delegate);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000172 processor.EnqueueAction(&feeder_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000173 processor.EnqueueAction(&download_action);
174
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700175 StartProcessorInRunLoopArgs args;
176 args.processor = &processor;
177 args.http_fetcher = http_fetcher;
178 g_timeout_add(0, &StartProcessorInRunLoop, &args);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000179 g_main_loop_run(loop);
180 g_main_loop_unref(loop);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000181}
182} // namespace {}
183
184TEST(DownloadActionTest, SimpleTest) {
185 vector<char> small;
186 const char* foo = "foo";
187 small.insert(small.end(), foo, foo + strlen(foo));
Darin Petkov50332f12010-09-24 11:44:47 -0700188 TestWithData(small,
Darin Petkov9ce452b2010-11-17 14:33:28 -0800189 0, // fail_write
Darin Petkov50332f12010-09-24 11:44:47 -0700190 true); // use_download_delegate
rspangler@google.com49fdf182009-10-10 00:57:34 +0000191}
192
193TEST(DownloadActionTest, LargeTest) {
194 vector<char> big(5 * kMockHttpFetcherChunkSize);
195 char c = '0';
196 for (unsigned int i = 0; i < big.size(); i++) {
197 big[i] = c;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800198 c = ('9' == c) ? '0' : c + 1;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000199 }
Darin Petkov50332f12010-09-24 11:44:47 -0700200 TestWithData(big,
Darin Petkov9ce452b2010-11-17 14:33:28 -0800201 0, // fail_write
202 true); // use_download_delegate
203}
204
205TEST(DownloadActionTest, FailWriteTest) {
206 vector<char> big(5 * kMockHttpFetcherChunkSize);
207 char c = '0';
208 for (unsigned int i = 0; i < big.size(); i++) {
209 big[i] = c;
210 c = ('9' == c) ? '0' : c + 1;
211 }
212 TestWithData(big,
Darin Petkov9ce452b2010-11-17 14:33:28 -0800213 2, // fail_write
Darin Petkov50332f12010-09-24 11:44:47 -0700214 true); // use_download_delegate
Darin Petkovc97435c2010-07-20 12:37:43 -0700215}
216
Darin Petkov9d911fa2010-08-19 09:36:08 -0700217TEST(DownloadActionTest, NoDownloadDelegateTest) {
218 vector<char> small;
219 const char* foo = "foofoo";
220 small.insert(small.end(), foo, foo + strlen(foo));
Darin Petkov50332f12010-09-24 11:44:47 -0700221 TestWithData(small,
Darin Petkov9ce452b2010-11-17 14:33:28 -0800222 0, // fail_write
Darin Petkov50332f12010-09-24 11:44:47 -0700223 false); // use_download_delegate
rspangler@google.com49fdf182009-10-10 00:57:34 +0000224}
225
226namespace {
227class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
228 public:
229 void ProcessingStopped(const ActionProcessor* processor) {
230 ASSERT_TRUE(loop_);
231 g_main_loop_quit(loop_);
232 }
233 GMainLoop *loop_;
234};
235
236gboolean TerminateEarlyTestStarter(gpointer data) {
237 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
238 processor->StartProcessing();
239 CHECK(processor->IsRunning());
240 processor->StopProcessing();
241 return FALSE;
242}
243
Darin Petkov9d911fa2010-08-19 09:36:08 -0700244void TestTerminateEarly(bool use_download_delegate) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000245 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
246
247 vector<char> data(kMockHttpFetcherChunkSize + kMockHttpFetcherChunkSize / 2);
248 memset(&data[0], 0, data.size());
249
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700250 ScopedTempFile temp_file;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000251 {
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700252 DirectFileWriter writer;
253
rspangler@google.com49fdf182009-10-10 00:57:34 +0000254 // takes ownership of passed in HttpFetcher
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000255 ObjectFeederAction<InstallPlan> feeder_action;
Gilad Arnold21504f02013-05-24 08:51:22 -0700256 InstallPlan install_plan(false, false, "", 0, "", 0, "",
257 temp_file.GetPath(), "");
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000258 feeder_action.set_obj(install_plan);
Darin Petkov73058b42010-10-06 16:32:19 -0700259 PrefsMock prefs;
Jay Srinivasanf0572052012-10-23 18:12:56 -0700260 DownloadAction download_action(&prefs, NULL,
Andrew de los Reyes45168102010-11-22 11:13:50 -0800261 new MockHttpFetcher(&data[0],
262 data.size(),
263 NULL));
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700264 download_action.SetTestFileWriter(&writer);
Darin Petkov9d911fa2010-08-19 09:36:08 -0700265 DownloadActionDelegateMock download_delegate;
266 if (use_download_delegate) {
267 InSequence s;
268 download_action.set_delegate(&download_delegate);
269 EXPECT_CALL(download_delegate, SetDownloadStatus(true)).Times(1);
270 EXPECT_CALL(download_delegate, SetDownloadStatus(false)).Times(1);
271 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000272 TerminateEarlyTestProcessorDelegate delegate;
273 delegate.loop_ = loop;
274 ActionProcessor processor;
275 processor.set_delegate(&delegate);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000276 processor.EnqueueAction(&feeder_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000277 processor.EnqueueAction(&download_action);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000278 BondActions(&feeder_action, &download_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000279
280 g_timeout_add(0, &TerminateEarlyTestStarter, &processor);
281 g_main_loop_run(loop);
282 g_main_loop_unref(loop);
283 }
284
285 // 1 or 0 chunks should have come through
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700286 const off_t resulting_file_size(utils::FileSize(temp_file.GetPath()));
287 EXPECT_GE(resulting_file_size, 0);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000288 if (resulting_file_size != 0)
289 EXPECT_EQ(kMockHttpFetcherChunkSize, resulting_file_size);
290}
291
Darin Petkov9d911fa2010-08-19 09:36:08 -0700292} // namespace {}
293
294TEST(DownloadActionTest, TerminateEarlyTest) {
295 TestTerminateEarly(true);
296}
297
298TEST(DownloadActionTest, TerminateEarlyNoDownloadDelegateTest) {
299 TestTerminateEarly(false);
300}
301
rspangler@google.com49fdf182009-10-10 00:57:34 +0000302class DownloadActionTestAction;
303
304template<>
305class ActionTraits<DownloadActionTestAction> {
306 public:
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000307 typedef InstallPlan OutputObjectType;
308 typedef InstallPlan InputObjectType;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000309};
310
311// This is a simple Action class for testing.
Yunlian Jiang2dac5762013-04-12 09:53:09 -0700312class DownloadActionTestAction : public Action<DownloadActionTestAction> {
313 public:
rspangler@google.com49fdf182009-10-10 00:57:34 +0000314 DownloadActionTestAction() : did_run_(false) {}
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000315 typedef InstallPlan InputObjectType;
316 typedef InstallPlan OutputObjectType;
317 ActionPipe<InstallPlan>* in_pipe() { return in_pipe_.get(); }
318 ActionPipe<InstallPlan>* out_pipe() { return out_pipe_.get(); }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000319 ActionProcessor* processor() { return processor_; }
320 void PerformAction() {
321 did_run_ = true;
322 ASSERT_TRUE(HasInputObject());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000323 EXPECT_TRUE(expected_input_object_ == GetInputObject());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000324 ASSERT_TRUE(processor());
David Zeuthena99981f2013-04-29 13:42:47 -0700325 processor()->ActionComplete(this, kErrorCodeSuccess);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000326 }
327 string Type() const { return "DownloadActionTestAction"; }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000328 InstallPlan expected_input_object_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000329 bool did_run_;
330};
331
332namespace {
333// This class is an ActionProcessorDelegate that simply terminates the
334// run loop when the ActionProcessor has completed processing. It's used
335// only by the test PassObjectOutTest.
336class PassObjectOutTestProcessorDelegate : public ActionProcessorDelegate {
337 public:
David Zeuthena99981f2013-04-29 13:42:47 -0700338 void ProcessingDone(const ActionProcessor* processor, ErrorCode code) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000339 ASSERT_TRUE(loop_);
340 g_main_loop_quit(loop_);
341 }
342 GMainLoop *loop_;
343};
344
345gboolean PassObjectOutTestStarter(gpointer data) {
346 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
347 processor->StartProcessing();
348 return FALSE;
349}
350}
351
352TEST(DownloadActionTest, PassObjectOutTest) {
353 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
354
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700355 DirectFileWriter writer;
356
rspangler@google.com49fdf182009-10-10 00:57:34 +0000357 // takes ownership of passed in HttpFetcher
Darin Petkov7ed561b2011-10-04 02:59:03 -0700358 InstallPlan install_plan(false,
Gilad Arnold21504f02013-05-24 08:51:22 -0700359 false,
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700360 "",
Darin Petkov50332f12010-09-24 11:44:47 -0700361 1,
Andrew de los Reyes1e338b82010-01-22 14:57:27 -0800362 OmahaHashCalculator::OmahaHashOfString("x"),
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700363 0,
364 "",
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700365 "/dev/null",
Andrew de los Reyes1e338b82010-01-22 14:57:27 -0800366 "/dev/null");
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000367 ObjectFeederAction<InstallPlan> feeder_action;
368 feeder_action.set_obj(install_plan);
Darin Petkov73058b42010-10-06 16:32:19 -0700369 PrefsMock prefs;
Jay Srinivasanf0572052012-10-23 18:12:56 -0700370 DownloadAction download_action(&prefs, NULL,
371 new MockHttpFetcher("x", 1, NULL));
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700372 download_action.SetTestFileWriter(&writer);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000373
374 DownloadActionTestAction test_action;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000375 test_action.expected_input_object_ = install_plan;
376 BondActions(&feeder_action, &download_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000377 BondActions(&download_action, &test_action);
378
379 ActionProcessor processor;
380 PassObjectOutTestProcessorDelegate delegate;
381 delegate.loop_ = loop;
382 processor.set_delegate(&delegate);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000383 processor.EnqueueAction(&feeder_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000384 processor.EnqueueAction(&download_action);
385 processor.EnqueueAction(&test_action);
386
387 g_timeout_add(0, &PassObjectOutTestStarter, &processor);
388 g_main_loop_run(loop);
389 g_main_loop_unref(loop);
390
391 EXPECT_EQ(true, test_action.did_run_);
392}
393
394TEST(DownloadActionTest, BadOutFileTest) {
395 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
396
397 const string path("/fake/path/that/cant/be/created/because/of/missing/dirs");
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700398 DirectFileWriter writer;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000399
400 // takes ownership of passed in HttpFetcher
Gilad Arnold21504f02013-05-24 08:51:22 -0700401 InstallPlan install_plan(false, false, "", 0, "", 0, "", path, "");
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000402 ObjectFeederAction<InstallPlan> feeder_action;
403 feeder_action.set_obj(install_plan);
Darin Petkov73058b42010-10-06 16:32:19 -0700404 PrefsMock prefs;
Jay Srinivasanf0572052012-10-23 18:12:56 -0700405 DownloadAction download_action(&prefs, NULL,
406 new MockHttpFetcher("x", 1, NULL));
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700407 download_action.SetTestFileWriter(&writer);
Darin Petkovc1a8b422010-07-19 11:34:49 -0700408
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000409 BondActions(&feeder_action, &download_action);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000410
411 ActionProcessor processor;
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.StartProcessing();
415 ASSERT_FALSE(processor.IsRunning());
416
417 g_main_loop_unref(loop);
418}
419
420} // namespace chromeos_update_engine