Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: download_action_unittest.cc

Issue 3131022: AU: Update status to DOWNLOADING only after receiving some bytes from server. (Closed) Base URL: http://src.chromium.org/git/update_engine.git
Patch Set: review feedback Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « download_action.cc ('k') | update_attempter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <gmock/gmock.h>
8 #include <gtest/gtest.h> 9 #include <gtest/gtest.h>
9 #include "update_engine/action_pipe.h" 10 #include "update_engine/action_pipe.h"
10 #include "update_engine/download_action.h" 11 #include "update_engine/download_action.h"
11 #include "update_engine/mock_http_fetcher.h" 12 #include "update_engine/mock_http_fetcher.h"
12 #include "update_engine/omaha_hash_calculator.h" 13 #include "update_engine/omaha_hash_calculator.h"
13 #include "update_engine/test_utils.h" 14 #include "update_engine/test_utils.h"
14 #include "update_engine/utils.h" 15 #include "update_engine/utils.h"
15 16
16 namespace chromeos_update_engine { 17 namespace chromeos_update_engine {
17 18
18 using std::string; 19 using std::string;
19 using std::vector; 20 using std::vector;
21 using testing::_;
22 using testing::AtLeast;
23 using testing::InSequence;
20 24
21 class DownloadActionTest : public ::testing::Test { }; 25 class DownloadActionTest : public ::testing::Test { };
22 26
23 namespace { 27 namespace {
28 class DownloadActionDelegateMock : public DownloadActionDelegate {
29 public:
30 MOCK_METHOD1(SetDownloadStatus, void(bool active));
31 MOCK_METHOD2(BytesReceived, void(uint64_t bytes_received, uint64_t total));
32 };
33
24 class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate { 34 class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate {
25 public: 35 public:
26 explicit DownloadActionTestProcessorDelegate(ActionExitCode expected_code) 36 explicit DownloadActionTestProcessorDelegate(ActionExitCode expected_code)
27 : loop_(NULL), 37 : loop_(NULL),
28 processing_done_called_(false), 38 processing_done_called_(false),
29 expected_code_(expected_code) {} 39 expected_code_(expected_code) {}
30 virtual ~DownloadActionTestProcessorDelegate() { 40 virtual ~DownloadActionTestProcessorDelegate() {
31 EXPECT_TRUE(processing_done_called_); 41 EXPECT_TRUE(processing_done_called_);
32 } 42 }
33 virtual void ProcessingDone(const ActionProcessor* processor, 43 virtual void ProcessingDone(const ActionProcessor* processor,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 GMainLoop *loop; 76 GMainLoop *loop;
67 ActionProcessor *processor; 77 ActionProcessor *processor;
68 }; 78 };
69 79
70 gboolean StartProcessorInRunLoop(gpointer data) { 80 gboolean StartProcessorInRunLoop(gpointer data) {
71 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data); 81 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
72 processor->StartProcessing(); 82 processor->StartProcessing();
73 return FALSE; 83 return FALSE;
74 } 84 }
75 85
76 void TestWithData(const vector<char>& data, bool hash_test) { 86 void TestWithData(const vector<char>& data,
87 bool hash_test,
88 bool use_download_delegate) {
77 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); 89 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
78 90
79 // TODO(adlr): see if we need a different file for build bots 91 // TODO(adlr): see if we need a different file for build bots
80 ScopedTempFile output_temp_file; 92 ScopedTempFile output_temp_file;
81 DirectFileWriter writer; 93 DirectFileWriter writer;
82 94
83 // takes ownership of passed in HttpFetcher 95 // takes ownership of passed in HttpFetcher
84 string hash = hash_test ? 96 string hash = hash_test ?
85 OmahaHashCalculator::OmahaHashOfString("random string") : 97 OmahaHashCalculator::OmahaHashOfString("random string") :
86 OmahaHashCalculator::OmahaHashOfData(data); 98 OmahaHashCalculator::OmahaHashOfData(data);
87 InstallPlan install_plan(true, 99 InstallPlan install_plan(true,
88 "", 100 "",
89 0, 101 0,
90 hash, 102 hash,
91 output_temp_file.GetPath(), 103 output_temp_file.GetPath(),
92 ""); 104 "");
93 ObjectFeederAction<InstallPlan> feeder_action; 105 ObjectFeederAction<InstallPlan> feeder_action;
94 feeder_action.set_obj(install_plan); 106 feeder_action.set_obj(install_plan);
95 DownloadAction download_action(new MockHttpFetcher(&data[0], 107 DownloadAction download_action(new MockHttpFetcher(&data[0],
96 data.size())); 108 data.size()));
97 download_action.SetTestFileWriter(&writer); 109 download_action.SetTestFileWriter(&writer);
98 BondActions(&feeder_action, &download_action); 110 BondActions(&feeder_action, &download_action);
99 111 DownloadActionDelegateMock download_delegate;
112 if (use_download_delegate) {
113 InSequence s;
114 download_action.set_delegate(&download_delegate);
115 EXPECT_CALL(download_delegate, SetDownloadStatus(true)).Times(1);
116 EXPECT_CALL(download_delegate, BytesReceived(_, _)).Times(AtLeast(1));
117 EXPECT_CALL(download_delegate, SetDownloadStatus(false)).Times(1);
118 }
100 DownloadActionTestProcessorDelegate delegate( 119 DownloadActionTestProcessorDelegate delegate(
101 hash_test ? kActionCodeDownloadHashMismatchError : kActionCodeSuccess); 120 hash_test ? kActionCodeDownloadHashMismatchError : kActionCodeSuccess);
102 delegate.loop_ = loop; 121 delegate.loop_ = loop;
103 delegate.expected_data_ = data; 122 delegate.expected_data_ = data;
104 delegate.path_ = output_temp_file.GetPath(); 123 delegate.path_ = output_temp_file.GetPath();
105 ActionProcessor processor; 124 ActionProcessor processor;
106 processor.set_delegate(&delegate); 125 processor.set_delegate(&delegate);
107 processor.EnqueueAction(&feeder_action); 126 processor.EnqueueAction(&feeder_action);
108 processor.EnqueueAction(&download_action); 127 processor.EnqueueAction(&download_action);
109 128
110 g_timeout_add(0, &StartProcessorInRunLoop, &processor); 129 g_timeout_add(0, &StartProcessorInRunLoop, &processor);
111 g_main_loop_run(loop); 130 g_main_loop_run(loop);
112 g_main_loop_unref(loop); 131 g_main_loop_unref(loop);
113 } 132 }
114 } // namespace {} 133 } // namespace {}
115 134
116 TEST(DownloadActionTest, SimpleTest) { 135 TEST(DownloadActionTest, SimpleTest) {
117 vector<char> small; 136 vector<char> small;
118 const char* foo = "foo"; 137 const char* foo = "foo";
119 small.insert(small.end(), foo, foo + strlen(foo)); 138 small.insert(small.end(), foo, foo + strlen(foo));
120 TestWithData(small, false); 139 TestWithData(small, false, true);
121 } 140 }
122 141
123 TEST(DownloadActionTest, LargeTest) { 142 TEST(DownloadActionTest, LargeTest) {
124 vector<char> big(5 * kMockHttpFetcherChunkSize); 143 vector<char> big(5 * kMockHttpFetcherChunkSize);
125 char c = '0'; 144 char c = '0';
126 for (unsigned int i = 0; i < big.size(); i++) { 145 for (unsigned int i = 0; i < big.size(); i++) {
127 big[i] = c; 146 big[i] = c;
128 if ('9' == c) 147 if ('9' == c)
129 c = '0'; 148 c = '0';
130 else 149 else
131 c++; 150 c++;
132 } 151 }
133 TestWithData(big, false); 152 TestWithData(big, false, true);
134 } 153 }
135 154
136 TEST(DownloadActionTest, BadHashTest) { 155 TEST(DownloadActionTest, BadHashTest) {
137 vector<char> small; 156 vector<char> small;
138 const char* foo = "foo"; 157 const char* foo = "foo";
139 small.insert(small.end(), foo, foo + strlen(foo)); 158 small.insert(small.end(), foo, foo + strlen(foo));
140 TestWithData(small, true); 159 TestWithData(small, true, true);
160 }
161
162 TEST(DownloadActionTest, NoDownloadDelegateTest) {
163 vector<char> small;
164 const char* foo = "foofoo";
165 small.insert(small.end(), foo, foo + strlen(foo));
166 TestWithData(small, false, false);
141 } 167 }
142 168
143 namespace { 169 namespace {
144 class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate { 170 class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
145 public: 171 public:
146 void ProcessingStopped(const ActionProcessor* processor) { 172 void ProcessingStopped(const ActionProcessor* processor) {
147 ASSERT_TRUE(loop_); 173 ASSERT_TRUE(loop_);
148 g_main_loop_quit(loop_); 174 g_main_loop_quit(loop_);
149 } 175 }
150 GMainLoop *loop_; 176 GMainLoop *loop_;
151 }; 177 };
152 178
153 gboolean TerminateEarlyTestStarter(gpointer data) { 179 gboolean TerminateEarlyTestStarter(gpointer data) {
154 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data); 180 ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
155 processor->StartProcessing(); 181 processor->StartProcessing();
156 CHECK(processor->IsRunning()); 182 CHECK(processor->IsRunning());
157 processor->StopProcessing(); 183 processor->StopProcessing();
158 return FALSE; 184 return FALSE;
159 } 185 }
160 186
161 } // namespace {} 187 void TestTerminateEarly(bool use_download_delegate) {
162
163 TEST(DownloadActionTest, TerminateEarlyTest) {
164 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); 188 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
165 189
166 vector<char> data(kMockHttpFetcherChunkSize + kMockHttpFetcherChunkSize / 2); 190 vector<char> data(kMockHttpFetcherChunkSize + kMockHttpFetcherChunkSize / 2);
167 memset(&data[0], 0, data.size()); 191 memset(&data[0], 0, data.size());
168 192
169 ScopedTempFile temp_file; 193 ScopedTempFile temp_file;
170 { 194 {
171 DirectFileWriter writer; 195 DirectFileWriter writer;
172 196
173 // takes ownership of passed in HttpFetcher 197 // takes ownership of passed in HttpFetcher
174 ObjectFeederAction<InstallPlan> feeder_action; 198 ObjectFeederAction<InstallPlan> feeder_action;
175 InstallPlan install_plan(true, "", 0, "", temp_file.GetPath(), ""); 199 InstallPlan install_plan(true, "", 0, "", temp_file.GetPath(), "");
176 feeder_action.set_obj(install_plan); 200 feeder_action.set_obj(install_plan);
177 DownloadAction download_action(new MockHttpFetcher(&data[0], data.size())); 201 DownloadAction download_action(new MockHttpFetcher(&data[0], data.size()));
178 download_action.SetTestFileWriter(&writer); 202 download_action.SetTestFileWriter(&writer);
203 DownloadActionDelegateMock download_delegate;
204 if (use_download_delegate) {
205 InSequence s;
206 download_action.set_delegate(&download_delegate);
207 EXPECT_CALL(download_delegate, SetDownloadStatus(true)).Times(1);
208 EXPECT_CALL(download_delegate, SetDownloadStatus(false)).Times(1);
209 }
179 TerminateEarlyTestProcessorDelegate delegate; 210 TerminateEarlyTestProcessorDelegate delegate;
180 delegate.loop_ = loop; 211 delegate.loop_ = loop;
181 ActionProcessor processor; 212 ActionProcessor processor;
182 processor.set_delegate(&delegate); 213 processor.set_delegate(&delegate);
183 processor.EnqueueAction(&feeder_action); 214 processor.EnqueueAction(&feeder_action);
184 processor.EnqueueAction(&download_action); 215 processor.EnqueueAction(&download_action);
185 BondActions(&feeder_action, &download_action); 216 BondActions(&feeder_action, &download_action);
186 217
187 g_timeout_add(0, &TerminateEarlyTestStarter, &processor); 218 g_timeout_add(0, &TerminateEarlyTestStarter, &processor);
188 g_main_loop_run(loop); 219 g_main_loop_run(loop);
189 g_main_loop_unref(loop); 220 g_main_loop_unref(loop);
190 } 221 }
191 222
192 // 1 or 0 chunks should have come through 223 // 1 or 0 chunks should have come through
193 const off_t resulting_file_size(utils::FileSize(temp_file.GetPath())); 224 const off_t resulting_file_size(utils::FileSize(temp_file.GetPath()));
194 EXPECT_GE(resulting_file_size, 0); 225 EXPECT_GE(resulting_file_size, 0);
195 if (resulting_file_size != 0) 226 if (resulting_file_size != 0)
196 EXPECT_EQ(kMockHttpFetcherChunkSize, resulting_file_size); 227 EXPECT_EQ(kMockHttpFetcherChunkSize, resulting_file_size);
197 } 228 }
198 229
230 } // namespace {}
231
232 TEST(DownloadActionTest, TerminateEarlyTest) {
233 TestTerminateEarly(true);
234 }
235
236 TEST(DownloadActionTest, TerminateEarlyNoDownloadDelegateTest) {
237 TestTerminateEarly(false);
238 }
239
199 class DownloadActionTestAction; 240 class DownloadActionTestAction;
200 241
201 template<> 242 template<>
202 class ActionTraits<DownloadActionTestAction> { 243 class ActionTraits<DownloadActionTestAction> {
203 public: 244 public:
204 typedef InstallPlan OutputObjectType; 245 typedef InstallPlan OutputObjectType;
205 typedef InstallPlan InputObjectType; 246 typedef InstallPlan InputObjectType;
206 }; 247 };
207 248
208 // This is a simple Action class for testing. 249 // This is a simple Action class for testing.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 ActionProcessor processor; 341 ActionProcessor processor;
301 processor.EnqueueAction(&feeder_action); 342 processor.EnqueueAction(&feeder_action);
302 processor.EnqueueAction(&download_action); 343 processor.EnqueueAction(&download_action);
303 processor.StartProcessing(); 344 processor.StartProcessing();
304 ASSERT_FALSE(processor.IsRunning()); 345 ASSERT_FALSE(processor.IsRunning());
305 346
306 g_main_loop_unref(loop); 347 g_main_loop_unref(loop);
307 } 348 }
308 349
309 } // namespace chromeos_update_engine 350 } // namespace chromeos_update_engine
OLDNEW
« no previous file with comments | « download_action.cc ('k') | update_attempter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698