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 |