OLD | NEW |
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 #include <vector> | 6 #include <vector> |
7 #include <glib.h> | 7 #include <glib.h> |
8 #include <gtest/gtest.h> | 8 #include <gtest/gtest.h> |
9 #include "update_engine/action_pipe.h" | 9 #include "update_engine/action_pipe.h" |
10 #include "update_engine/download_action.h" | 10 #include "update_engine/download_action.h" |
11 #include "update_engine/mock_http_fetcher.h" | 11 #include "update_engine/mock_http_fetcher.h" |
12 #include "update_engine/omaha_hash_calculator.h" | 12 #include "update_engine/omaha_hash_calculator.h" |
13 #include "update_engine/test_utils.h" | 13 #include "update_engine/test_utils.h" |
| 14 #include "update_engine/utils.h" |
14 | 15 |
15 namespace chromeos_update_engine { | 16 namespace chromeos_update_engine { |
16 | 17 |
17 using std::string; | 18 using std::string; |
18 using std::vector; | 19 using std::vector; |
19 | 20 |
20 class DownloadActionTest : public ::testing::Test { }; | 21 class DownloadActionTest : public ::testing::Test { }; |
21 | 22 |
22 namespace { | 23 namespace { |
23 class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate { | 24 class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate { |
24 public: | 25 public: |
25 DownloadActionTestProcessorDelegate() | 26 DownloadActionTestProcessorDelegate() |
26 : loop_(NULL), processing_done_called_(false) {} | 27 : loop_(NULL), processing_done_called_(false) {} |
27 virtual ~DownloadActionTestProcessorDelegate() { | 28 virtual ~DownloadActionTestProcessorDelegate() { |
28 EXPECT_TRUE(processing_done_called_); | 29 EXPECT_TRUE(processing_done_called_); |
29 } | 30 } |
30 virtual void ProcessingDone(const ActionProcessor* processor) { | 31 virtual void ProcessingDone(const ActionProcessor* processor) { |
31 ASSERT_TRUE(loop_); | 32 ASSERT_TRUE(loop_); |
32 g_main_loop_quit(loop_); | 33 g_main_loop_quit(loop_); |
33 vector<char> found_data = ReadFile(path_); | 34 vector<char> found_data; |
| 35 ASSERT_TRUE(utils::ReadFile(path_, &found_data)); |
34 ASSERT_EQ(expected_data_.size(), found_data.size()); | 36 ASSERT_EQ(expected_data_.size(), found_data.size()); |
35 for (unsigned i = 0; i < expected_data_.size(); i++) { | 37 for (unsigned i = 0; i < expected_data_.size(); i++) { |
36 EXPECT_EQ(expected_data_[i], found_data[i]); | 38 EXPECT_EQ(expected_data_[i], found_data[i]); |
37 } | 39 } |
38 processing_done_called_ = true; | 40 processing_done_called_ = true; |
39 } | 41 } |
40 | 42 |
41 virtual void ActionCompleted(const ActionProcessor* processor, | 43 virtual void ActionCompleted(ActionProcessor* processor, |
42 const AbstractAction* action, | 44 AbstractAction* action, |
43 bool success) { | 45 bool success) { |
44 // make sure actions always succeed | 46 // make sure actions always succeed |
45 EXPECT_TRUE(success); | 47 EXPECT_TRUE(success); |
46 } | 48 } |
47 | 49 |
48 GMainLoop *loop_; | 50 GMainLoop *loop_; |
49 string path_; | 51 string path_; |
50 vector<char> expected_data_; | 52 vector<char> expected_data_; |
51 bool processing_done_called_; | 53 bool processing_done_called_; |
52 }; | 54 }; |
(...skipping 16 matching lines...) Expand all Loading... |
69 use_data = GzipCompressData(data); | 71 use_data = GzipCompressData(data); |
70 } else { | 72 } else { |
71 use_data = data; | 73 use_data = data; |
72 } | 74 } |
73 | 75 |
74 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); | 76 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); |
75 | 77 |
76 // TODO(adlr): see if we need a different file for build bots | 78 // TODO(adlr): see if we need a different file for build bots |
77 const string path("/tmp/DownloadActionTest"); | 79 const string path("/tmp/DownloadActionTest"); |
78 // takes ownership of passed in HttpFetcher | 80 // takes ownership of passed in HttpFetcher |
79 DownloadAction download_action("", path, 0, | 81 InstallPlan install_plan(compress, "", |
80 OmahaHashCalculator::OmahaHashOfData(use_data), | 82 OmahaHashCalculator::OmahaHashOfData(use_data), |
81 compress, new MockHttpFetcher(&use_data[0], | 83 compress ? "" : path, compress ? path : ""); |
82 use_data.size())); | 84 ObjectFeederAction<InstallPlan> feeder_action; |
| 85 feeder_action.set_obj(install_plan); |
| 86 DownloadAction download_action(new MockHttpFetcher(&use_data[0], |
| 87 use_data.size())); |
| 88 BondActions(&feeder_action, &download_action); |
| 89 |
83 DownloadActionTestProcessorDelegate delegate; | 90 DownloadActionTestProcessorDelegate delegate; |
84 delegate.loop_ = loop; | 91 delegate.loop_ = loop; |
85 delegate.expected_data_ = data; | 92 delegate.expected_data_ = data; |
86 delegate.path_ = path; | 93 delegate.path_ = path; |
87 ActionProcessor processor; | 94 ActionProcessor processor; |
88 processor.set_delegate(&delegate); | 95 processor.set_delegate(&delegate); |
| 96 processor.EnqueueAction(&feeder_action); |
89 processor.EnqueueAction(&download_action); | 97 processor.EnqueueAction(&download_action); |
90 | 98 |
91 g_timeout_add(0, &StartProcessorInRunLoop, &processor); | 99 g_timeout_add(0, &StartProcessorInRunLoop, &processor); |
92 g_main_loop_run(loop); | 100 g_main_loop_run(loop); |
93 g_main_loop_unref(loop); | 101 g_main_loop_unref(loop); |
94 | 102 |
95 // remove temp file; don't care if there are errors here | 103 // remove temp file; don't care if there are errors here |
96 unlink(path.c_str()); | 104 unlink(path.c_str()); |
97 } | 105 } |
98 } // namespace {} | 106 } // namespace {} |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 | 149 |
142 TEST(DownloadActionTest, TerminateEarlyTest) { | 150 TEST(DownloadActionTest, TerminateEarlyTest) { |
143 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); | 151 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); |
144 | 152 |
145 vector<char> data(kMockHttpFetcherChunkSize + kMockHttpFetcherChunkSize / 2); | 153 vector<char> data(kMockHttpFetcherChunkSize + kMockHttpFetcherChunkSize / 2); |
146 memset(&data[0], 0, data.size()); | 154 memset(&data[0], 0, data.size()); |
147 | 155 |
148 const string path("/tmp/DownloadActionTest"); | 156 const string path("/tmp/DownloadActionTest"); |
149 { | 157 { |
150 // takes ownership of passed in HttpFetcher | 158 // takes ownership of passed in HttpFetcher |
151 DownloadAction download_action("", path, 0, "", false, | 159 ObjectFeederAction<InstallPlan> feeder_action; |
152 new MockHttpFetcher(&data[0], data.size())); | 160 InstallPlan install_plan(false, "", "", path, ""); |
| 161 feeder_action.set_obj(install_plan); |
| 162 DownloadAction download_action(new MockHttpFetcher(&data[0], data.size())); |
153 TerminateEarlyTestProcessorDelegate delegate; | 163 TerminateEarlyTestProcessorDelegate delegate; |
154 delegate.loop_ = loop; | 164 delegate.loop_ = loop; |
155 ActionProcessor processor; | 165 ActionProcessor processor; |
156 processor.set_delegate(&delegate); | 166 processor.set_delegate(&delegate); |
| 167 processor.EnqueueAction(&feeder_action); |
157 processor.EnqueueAction(&download_action); | 168 processor.EnqueueAction(&download_action); |
| 169 BondActions(&feeder_action, &download_action); |
158 | 170 |
159 g_timeout_add(0, &TerminateEarlyTestStarter, &processor); | 171 g_timeout_add(0, &TerminateEarlyTestStarter, &processor); |
160 g_main_loop_run(loop); | 172 g_main_loop_run(loop); |
161 g_main_loop_unref(loop); | 173 g_main_loop_unref(loop); |
162 } | 174 } |
163 | 175 |
164 // 1 or 0 chunks should have come through | 176 // 1 or 0 chunks should have come through |
165 const off_t resulting_file_size(FileSize(path)); | 177 const off_t resulting_file_size(FileSize(path)); |
166 if (resulting_file_size != 0) | 178 if (resulting_file_size != 0) |
167 EXPECT_EQ(kMockHttpFetcherChunkSize, resulting_file_size); | 179 EXPECT_EQ(kMockHttpFetcherChunkSize, resulting_file_size); |
168 } | 180 } |
169 | 181 |
170 class DownloadActionTestAction; | 182 class DownloadActionTestAction; |
171 | 183 |
172 template<> | 184 template<> |
173 class ActionTraits<DownloadActionTestAction> { | 185 class ActionTraits<DownloadActionTestAction> { |
174 public: | 186 public: |
175 typedef string OutputObjectType; | 187 typedef InstallPlan OutputObjectType; |
176 typedef string InputObjectType; | 188 typedef InstallPlan InputObjectType; |
177 }; | 189 }; |
178 | 190 |
179 // This is a simple Action class for testing. | 191 // This is a simple Action class for testing. |
180 struct DownloadActionTestAction : public Action<DownloadActionTestAction> { | 192 struct DownloadActionTestAction : public Action<DownloadActionTestAction> { |
181 DownloadActionTestAction() : did_run_(false) {} | 193 DownloadActionTestAction() : did_run_(false) {} |
182 typedef string InputObjectType; | 194 typedef InstallPlan InputObjectType; |
183 typedef string OutputObjectType; | 195 typedef InstallPlan OutputObjectType; |
184 ActionPipe<string>* in_pipe() { return in_pipe_.get(); } | 196 ActionPipe<InstallPlan>* in_pipe() { return in_pipe_.get(); } |
185 ActionPipe<string>* out_pipe() { return out_pipe_.get(); } | 197 ActionPipe<InstallPlan>* out_pipe() { return out_pipe_.get(); } |
186 ActionProcessor* processor() { return processor_; } | 198 ActionProcessor* processor() { return processor_; } |
187 void PerformAction() { | 199 void PerformAction() { |
188 did_run_ = true; | 200 did_run_ = true; |
189 ASSERT_TRUE(HasInputObject()); | 201 ASSERT_TRUE(HasInputObject()); |
190 EXPECT_EQ(expected_input_object_, GetInputObject()); | 202 EXPECT_TRUE(expected_input_object_ == GetInputObject()); |
191 ASSERT_TRUE(processor()); | 203 ASSERT_TRUE(processor()); |
192 processor()->ActionComplete(this, true); | 204 processor()->ActionComplete(this, true); |
193 } | 205 } |
194 string Type() const { return "DownloadActionTestAction"; } | 206 string Type() const { return "DownloadActionTestAction"; } |
195 string expected_input_object_; | 207 InstallPlan expected_input_object_; |
196 bool did_run_; | 208 bool did_run_; |
197 }; | 209 }; |
198 | 210 |
199 namespace { | 211 namespace { |
200 // This class is an ActionProcessorDelegate that simply terminates the | 212 // This class is an ActionProcessorDelegate that simply terminates the |
201 // run loop when the ActionProcessor has completed processing. It's used | 213 // run loop when the ActionProcessor has completed processing. It's used |
202 // only by the test PassObjectOutTest. | 214 // only by the test PassObjectOutTest. |
203 class PassObjectOutTestProcessorDelegate : public ActionProcessorDelegate { | 215 class PassObjectOutTestProcessorDelegate : public ActionProcessorDelegate { |
204 public: | 216 public: |
205 void ProcessingDone(const ActionProcessor* processor) { | 217 void ProcessingDone(const ActionProcessor* processor) { |
206 ASSERT_TRUE(loop_); | 218 ASSERT_TRUE(loop_); |
207 g_main_loop_quit(loop_); | 219 g_main_loop_quit(loop_); |
208 } | 220 } |
209 GMainLoop *loop_; | 221 GMainLoop *loop_; |
210 }; | 222 }; |
211 | 223 |
212 gboolean PassObjectOutTestStarter(gpointer data) { | 224 gboolean PassObjectOutTestStarter(gpointer data) { |
213 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data); | 225 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data); |
214 processor->StartProcessing(); | 226 processor->StartProcessing(); |
215 return FALSE; | 227 return FALSE; |
216 } | 228 } |
217 } | 229 } |
218 | 230 |
219 TEST(DownloadActionTest, PassObjectOutTest) { | 231 TEST(DownloadActionTest, PassObjectOutTest) { |
220 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); | 232 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); |
221 | 233 |
222 const string path("/tmp/DownloadActionTest"); | 234 const string path("/tmp/DownloadActionTest"); |
223 | 235 |
224 // takes ownership of passed in HttpFetcher | 236 // takes ownership of passed in HttpFetcher |
225 DownloadAction download_action("", path, 0, | 237 InstallPlan install_plan(false, "", |
226 OmahaHashCalculator::OmahaHashOfString("x"), | 238 OmahaHashCalculator::OmahaHashOfString("x"), path, |
227 false, new MockHttpFetcher("x", 1)); | 239 ""); |
| 240 ObjectFeederAction<InstallPlan> feeder_action; |
| 241 feeder_action.set_obj(install_plan); |
| 242 DownloadAction download_action(new MockHttpFetcher("x", 1)); |
228 | 243 |
229 DownloadActionTestAction test_action; | 244 DownloadActionTestAction test_action; |
230 test_action.expected_input_object_ = path; | 245 test_action.expected_input_object_ = install_plan; |
| 246 BondActions(&feeder_action, &download_action); |
231 BondActions(&download_action, &test_action); | 247 BondActions(&download_action, &test_action); |
232 | 248 |
233 ActionProcessor processor; | 249 ActionProcessor processor; |
234 PassObjectOutTestProcessorDelegate delegate; | 250 PassObjectOutTestProcessorDelegate delegate; |
235 delegate.loop_ = loop; | 251 delegate.loop_ = loop; |
236 processor.set_delegate(&delegate); | 252 processor.set_delegate(&delegate); |
| 253 processor.EnqueueAction(&feeder_action); |
237 processor.EnqueueAction(&download_action); | 254 processor.EnqueueAction(&download_action); |
238 processor.EnqueueAction(&test_action); | 255 processor.EnqueueAction(&test_action); |
239 | 256 |
240 g_timeout_add(0, &PassObjectOutTestStarter, &processor); | 257 g_timeout_add(0, &PassObjectOutTestStarter, &processor); |
241 g_main_loop_run(loop); | 258 g_main_loop_run(loop); |
242 g_main_loop_unref(loop); | 259 g_main_loop_unref(loop); |
243 | 260 |
244 EXPECT_EQ(true, test_action.did_run_); | 261 EXPECT_EQ(true, test_action.did_run_); |
245 } | 262 } |
246 | 263 |
247 TEST(DownloadActionTest, BadOutFileTest) { | 264 TEST(DownloadActionTest, BadOutFileTest) { |
248 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); | 265 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); |
249 | 266 |
250 const string path("/fake/path/that/cant/be/created/because/of/missing/dirs"); | 267 const string path("/fake/path/that/cant/be/created/because/of/missing/dirs"); |
251 | 268 |
252 // takes ownership of passed in HttpFetcher | 269 // takes ownership of passed in HttpFetcher |
253 DownloadAction download_action("", path, 0, "", false, | 270 InstallPlan install_plan(false, "", "", path, ""); |
254 new MockHttpFetcher("x", 1)); | 271 ObjectFeederAction<InstallPlan> feeder_action; |
| 272 feeder_action.set_obj(install_plan); |
| 273 DownloadAction download_action(new MockHttpFetcher("x", 1)); |
| 274 BondActions(&feeder_action, &download_action); |
255 | 275 |
256 ActionProcessor processor; | 276 ActionProcessor processor; |
| 277 processor.EnqueueAction(&feeder_action); |
257 processor.EnqueueAction(&download_action); | 278 processor.EnqueueAction(&download_action); |
258 processor.StartProcessing(); | 279 processor.StartProcessing(); |
259 ASSERT_FALSE(processor.IsRunning()); | 280 ASSERT_FALSE(processor.IsRunning()); |
260 | 281 |
261 g_main_loop_unref(loop); | 282 g_main_loop_unref(loop); |
262 } | 283 } |
263 | 284 |
264 } // namespace chromeos_update_engine | 285 } // namespace chromeos_update_engine |
OLD | NEW |