| 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 #include "update_engine/utils.h" |
| 15 | 15 |
| 16 namespace chromeos_update_engine { | 16 namespace chromeos_update_engine { |
| 17 | 17 |
| 18 using std::string; | 18 using std::string; |
| 19 using std::vector; | 19 using std::vector; |
| 20 | 20 |
| 21 class DownloadActionTest : public ::testing::Test { }; | 21 class DownloadActionTest : public ::testing::Test { }; |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate { | 24 class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate { |
| 25 public: | 25 public: |
| 26 DownloadActionTestProcessorDelegate() | 26 explicit DownloadActionTestProcessorDelegate(ActionExitCode expected_code) |
| 27 : loop_(NULL), processing_done_called_(false) {} | 27 : loop_(NULL), |
| 28 processing_done_called_(false), |
| 29 expected_code_(expected_code) {} |
| 28 virtual ~DownloadActionTestProcessorDelegate() { | 30 virtual ~DownloadActionTestProcessorDelegate() { |
| 29 EXPECT_TRUE(processing_done_called_); | 31 EXPECT_TRUE(processing_done_called_); |
| 30 } | 32 } |
| 31 virtual void ProcessingDone(const ActionProcessor* processor, | 33 virtual void ProcessingDone(const ActionProcessor* processor, |
| 32 ActionExitCode code) { | 34 ActionExitCode code) { |
| 33 ASSERT_TRUE(loop_); | 35 ASSERT_TRUE(loop_); |
| 34 g_main_loop_quit(loop_); | 36 g_main_loop_quit(loop_); |
| 35 vector<char> found_data; | 37 vector<char> found_data; |
| 36 ASSERT_TRUE(utils::ReadFile(path_, &found_data)); | 38 ASSERT_TRUE(utils::ReadFile(path_, &found_data)); |
| 37 ASSERT_EQ(expected_data_.size(), found_data.size()); | 39 ASSERT_EQ(expected_data_.size(), found_data.size()); |
| 38 for (unsigned i = 0; i < expected_data_.size(); i++) { | 40 for (unsigned i = 0; i < expected_data_.size(); i++) { |
| 39 EXPECT_EQ(expected_data_[i], found_data[i]); | 41 EXPECT_EQ(expected_data_[i], found_data[i]); |
| 40 } | 42 } |
| 41 processing_done_called_ = true; | 43 processing_done_called_ = true; |
| 42 } | 44 } |
| 43 | 45 |
| 44 virtual void ActionCompleted(ActionProcessor* processor, | 46 virtual void ActionCompleted(ActionProcessor* processor, |
| 45 AbstractAction* action, | 47 AbstractAction* action, |
| 46 ActionExitCode code) { | 48 ActionExitCode code) { |
| 47 // make sure actions always succeed | 49 const string type = action->Type(); |
| 48 EXPECT_EQ(kActionCodeSuccess, code); | 50 if (type == DownloadAction::StaticType()) { |
| 51 EXPECT_EQ(expected_code_, code); |
| 52 } else { |
| 53 EXPECT_EQ(kActionCodeSuccess, code); |
| 54 } |
| 49 } | 55 } |
| 50 | 56 |
| 51 GMainLoop *loop_; | 57 GMainLoop *loop_; |
| 52 string path_; | 58 string path_; |
| 53 vector<char> expected_data_; | 59 vector<char> expected_data_; |
| 54 bool processing_done_called_; | 60 bool processing_done_called_; |
| 61 ActionExitCode expected_code_; |
| 55 }; | 62 }; |
| 56 | 63 |
| 57 struct EntryPointArgs { | 64 struct EntryPointArgs { |
| 58 const vector<char> *data; | 65 const vector<char> *data; |
| 59 GMainLoop *loop; | 66 GMainLoop *loop; |
| 60 ActionProcessor *processor; | 67 ActionProcessor *processor; |
| 61 }; | 68 }; |
| 62 | 69 |
| 63 gboolean StartProcessorInRunLoop(gpointer data) { | 70 gboolean StartProcessorInRunLoop(gpointer data) { |
| 64 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data); | 71 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data); |
| 65 processor->StartProcessing(); | 72 processor->StartProcessing(); |
| 66 return FALSE; | 73 return FALSE; |
| 67 } | 74 } |
| 68 | 75 |
| 69 void TestWithData(const vector<char>& data) { | 76 void TestWithData(const vector<char>& data, bool hash_test) { |
| 70 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); | 77 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); |
| 71 | 78 |
| 72 // TODO(adlr): see if we need a different file for build bots | 79 // TODO(adlr): see if we need a different file for build bots |
| 73 ScopedTempFile output_temp_file; | 80 ScopedTempFile output_temp_file; |
| 74 DirectFileWriter writer; | 81 DirectFileWriter writer; |
| 75 | 82 |
| 76 // takes ownership of passed in HttpFetcher | 83 // takes ownership of passed in HttpFetcher |
| 84 string hash = hash_test ? |
| 85 OmahaHashCalculator::OmahaHashOfString("random string") : |
| 86 OmahaHashCalculator::OmahaHashOfData(data); |
| 77 InstallPlan install_plan(true, | 87 InstallPlan install_plan(true, |
| 78 "", | 88 "", |
| 79 0, | 89 0, |
| 80 OmahaHashCalculator::OmahaHashOfData(data), | 90 hash, |
| 81 output_temp_file.GetPath(), | 91 output_temp_file.GetPath(), |
| 82 ""); | 92 ""); |
| 83 ObjectFeederAction<InstallPlan> feeder_action; | 93 ObjectFeederAction<InstallPlan> feeder_action; |
| 84 feeder_action.set_obj(install_plan); | 94 feeder_action.set_obj(install_plan); |
| 85 DownloadAction download_action(new MockHttpFetcher(&data[0], | 95 DownloadAction download_action(new MockHttpFetcher(&data[0], |
| 86 data.size())); | 96 data.size())); |
| 87 download_action.SetTestFileWriter(&writer); | 97 download_action.SetTestFileWriter(&writer); |
| 88 BondActions(&feeder_action, &download_action); | 98 BondActions(&feeder_action, &download_action); |
| 89 | 99 |
| 90 DownloadActionTestProcessorDelegate delegate; | 100 DownloadActionTestProcessorDelegate delegate( |
| 101 hash_test ? kActionCodeDownloadHashMismatchError : kActionCodeSuccess); |
| 91 delegate.loop_ = loop; | 102 delegate.loop_ = loop; |
| 92 delegate.expected_data_ = data; | 103 delegate.expected_data_ = data; |
| 93 delegate.path_ = output_temp_file.GetPath(); | 104 delegate.path_ = output_temp_file.GetPath(); |
| 94 ActionProcessor processor; | 105 ActionProcessor processor; |
| 95 processor.set_delegate(&delegate); | 106 processor.set_delegate(&delegate); |
| 96 processor.EnqueueAction(&feeder_action); | 107 processor.EnqueueAction(&feeder_action); |
| 97 processor.EnqueueAction(&download_action); | 108 processor.EnqueueAction(&download_action); |
| 98 | 109 |
| 99 g_timeout_add(0, &StartProcessorInRunLoop, &processor); | 110 g_timeout_add(0, &StartProcessorInRunLoop, &processor); |
| 100 g_main_loop_run(loop); | 111 g_main_loop_run(loop); |
| 101 g_main_loop_unref(loop); | 112 g_main_loop_unref(loop); |
| 102 } | 113 } |
| 103 } // namespace {} | 114 } // namespace {} |
| 104 | 115 |
| 105 TEST(DownloadActionTest, SimpleTest) { | 116 TEST(DownloadActionTest, SimpleTest) { |
| 106 vector<char> small; | 117 vector<char> small; |
| 107 const char* foo = "foo"; | 118 const char* foo = "foo"; |
| 108 small.insert(small.end(), foo, foo + strlen(foo)); | 119 small.insert(small.end(), foo, foo + strlen(foo)); |
| 109 TestWithData(small); | 120 TestWithData(small, false); |
| 110 } | 121 } |
| 111 | 122 |
| 112 TEST(DownloadActionTest, LargeTest) { | 123 TEST(DownloadActionTest, LargeTest) { |
| 113 vector<char> big(5 * kMockHttpFetcherChunkSize); | 124 vector<char> big(5 * kMockHttpFetcherChunkSize); |
| 114 char c = '0'; | 125 char c = '0'; |
| 115 for (unsigned int i = 0; i < big.size(); i++) { | 126 for (unsigned int i = 0; i < big.size(); i++) { |
| 116 big[i] = c; | 127 big[i] = c; |
| 117 if ('9' == c) | 128 if ('9' == c) |
| 118 c = '0'; | 129 c = '0'; |
| 119 else | 130 else |
| 120 c++; | 131 c++; |
| 121 } | 132 } |
| 122 TestWithData(big); | 133 TestWithData(big, false); |
| 134 } |
| 135 |
| 136 TEST(DownloadActionTest, BadHashTest) { |
| 137 vector<char> small; |
| 138 const char* foo = "foo"; |
| 139 small.insert(small.end(), foo, foo + strlen(foo)); |
| 140 TestWithData(small, true); |
| 123 } | 141 } |
| 124 | 142 |
| 125 namespace { | 143 namespace { |
| 126 class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate { | 144 class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate { |
| 127 public: | 145 public: |
| 128 void ProcessingStopped(const ActionProcessor* processor) { | 146 void ProcessingStopped(const ActionProcessor* processor) { |
| 129 ASSERT_TRUE(loop_); | 147 ASSERT_TRUE(loop_); |
| 130 g_main_loop_quit(loop_); | 148 g_main_loop_quit(loop_); |
| 131 } | 149 } |
| 132 GMainLoop *loop_; | 150 GMainLoop *loop_; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 ActionProcessor processor; | 300 ActionProcessor processor; |
| 283 processor.EnqueueAction(&feeder_action); | 301 processor.EnqueueAction(&feeder_action); |
| 284 processor.EnqueueAction(&download_action); | 302 processor.EnqueueAction(&download_action); |
| 285 processor.StartProcessing(); | 303 processor.StartProcessing(); |
| 286 ASSERT_FALSE(processor.IsRunning()); | 304 ASSERT_FALSE(processor.IsRunning()); |
| 287 | 305 |
| 288 g_main_loop_unref(loop); | 306 g_main_loop_unref(loop); |
| 289 } | 307 } |
| 290 | 308 |
| 291 } // namespace chromeos_update_engine | 309 } // namespace chromeos_update_engine |
| OLD | NEW |