Roll PDFium 0d0935d..89d8b46
[chromium-blink-merge.git] / tools / telemetry / catapult_base / dependency_manager / dependency_manager_unittest.py
blobc9da86cdf15f5765e3c3f6646feeb90d3f483ccf
1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 import os
6 import stat
7 import unittest
9 import mock
11 from catapult_base import dependency_manager
12 from catapult_base import cloud_storage
13 from catapult_base.dependency_manager import exceptions
16 class DependencyManagerTest(unittest.TestCase):
17 @mock.patch(
18 'catapult_base.dependency_manager.DependencyManager._UpdateDependencies')
19 def testInit(self, update_mock):
20 self.assertRaises(ValueError, dependency_manager.DependencyManager, None)
21 self.assertFalse(update_mock.call_args)
22 self.assertRaises(ValueError, dependency_manager.DependencyManager,
23 'config_file?')
24 self.assertFalse(update_mock.call_args)
26 dependency_manager.DependencyManager([])
27 self.assertFalse(update_mock.call_args)
29 dependency_manager.DependencyManager(['config_file'])
30 update_mock.called_once_with_args('config_file')
31 update_mock.reset_mock()
33 dependency_manager.DependencyManager(
34 ['config_file1', 'config_file2', 'config_file3', 'config_file4'])
35 expected_calls = [mock.call('config_file1'), mock.call('config_file2'),
36 mock.call('config_file3'), mock.call('config_file4')]
37 update_mock.assert_has_calls(expected_calls, any_order=True)
38 update_mock.reset_mock()
41 @mock.patch('os.path')
42 @mock.patch('catapult_base.support_binaries.FindPath')
43 @mock.patch(
44 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
45 @mock.patch(
46 'catapult_base.dependency_manager.DependencyManager._CloudStoragePath')
47 @mock.patch('catapult_base.dependency_manager.DependencyManager._LocalPath')
48 def testFetchPathSupportBinaries(self, local_path_mock, cs_path_mock,
49 dep_info_mock, sb_find_path_mock, path_mock):
50 dep_manager = dependency_manager.DependencyManager([])
51 self.assertFalse(local_path_mock.call_args)
52 self.assertFalse(cs_path_mock.call_args)
53 self.assertFalse(sb_find_path_mock.call_args)
54 sb_path = 'sb_path'
55 local_path = 'local_path'
56 cs_path = 'cs_path'
57 dep_info = 'dep_info'
58 local_path_mock.return_value = local_path
59 cs_path_mock.return_value = cs_path
60 sb_find_path_mock.return_value = sb_path
61 dep_info_mock.return_value = dep_info
63 # Empty lookup_dict
64 found_path = dep_manager.FetchPath('dep', 'plat_arch_x86')
65 self.assertEqual(sb_path, found_path)
66 self.assertFalse(local_path_mock.call_args)
67 self.assertFalse(cs_path_mock.call_args)
68 sb_find_path_mock.assert_called_once_with('dep', 'arch_x86', 'plat')
69 local_path_mock.reset_mock()
70 cs_path_mock.reset_mock()
71 sb_find_path_mock.reset_mock()
73 # Non-empty lookup dict that doesn't contain the dependency we're looking
74 # for.
75 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
76 'dep2': mock.MagicMock()}
77 found_path = dep_manager.FetchPath('dep', 'plat_arch_x86')
79 self.assertEqual(sb_path, found_path)
80 self.assertFalse(local_path_mock.call_args)
81 self.assertFalse(cs_path_mock.call_args)
82 sb_find_path_mock.assert_called_once_with('dep', 'arch_x86', 'plat')
83 local_path_mock.reset_mock()
84 cs_path_mock.reset_mock()
85 sb_find_path_mock.reset_mock()
87 @mock.patch('os.path')
88 @mock.patch('catapult_base.support_binaries.FindPath')
89 @mock.patch(
90 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
91 @mock.patch(
92 'catapult_base.dependency_manager.DependencyManager._CloudStoragePath')
93 @mock.patch('catapult_base.dependency_manager.DependencyManager._LocalPath')
94 def testFetchPathLocalFile(self, local_path_mock, cs_path_mock, dep_info_mock,
95 sb_find_path_mock, path_mock):
96 dep_manager = dependency_manager.DependencyManager([])
97 self.assertFalse(local_path_mock.call_args)
98 self.assertFalse(cs_path_mock.call_args)
99 self.assertFalse(sb_find_path_mock.call_args)
100 sb_path = 'sb_path'
101 local_path = 'local_path'
102 cs_path = 'cs_path'
103 dep_info = 'dep_info'
104 local_path_mock.return_value = local_path
105 cs_path_mock.return_value = cs_path
106 sb_find_path_mock.return_value = sb_path
107 dep_info_mock.return_value = dep_info
110 # Non-empty lookup dict that contains the dependency we're looking for.
111 # Local path exists.
112 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
113 'dep2': mock.MagicMock()}
114 path_mock.exists.return_value = True
115 found_path = dep_manager.FetchPath('dep1', 'plat')
117 self.assertEqual(local_path, found_path)
118 local_path_mock.assert_called_with('dep_info')
119 self.assertFalse(cs_path_mock.call_args)
120 self.assertFalse(sb_find_path_mock.call_args)
121 # If the below assert fails, the ordering assumption that determined the
122 # path_mock return values is incorrect, and should be updated.
123 path_mock.exists.assert_called_once_with('local_path')
124 local_path_mock.reset_mock()
125 cs_path_mock.reset_mock()
126 sb_find_path_mock.reset_mock()
129 @mock.patch('os.path')
130 @mock.patch('catapult_base.support_binaries.FindPath')
131 @mock.patch(
132 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
133 @mock.patch(
134 'catapult_base.dependency_manager.DependencyManager._CloudStoragePath')
135 @mock.patch('catapult_base.dependency_manager.DependencyManager._LocalPath')
136 def testFetchPathRemoteFile(self, local_path_mock, cs_path_mock,
137 dep_info_mock, sb_find_path_mock, path_mock):
138 dep_manager = dependency_manager.DependencyManager([])
139 self.assertFalse(local_path_mock.call_args)
140 self.assertFalse(cs_path_mock.call_args)
141 self.assertFalse(sb_find_path_mock.call_args)
142 local_path = 'local_path'
143 cs_path = 'cs_path'
144 dep_info = 'dep_info'
145 cs_path_mock.return_value = cs_path
146 dep_info_mock.return_value = dep_info
148 # Non-empty lookup dict that contains the dependency we're looking for.
149 # Local path doesn't exist, but cloud_storage_path is downloaded.
150 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
151 'dep2': mock.MagicMock()}
152 path_mock.exists.side_effect = [False, True]
153 local_path_mock.return_value = local_path
154 found_path = dep_manager.FetchPath('dep1', 'plat')
156 self.assertEqual(cs_path, found_path)
157 local_path_mock.assert_called_with(dep_info)
158 cs_path_mock.assert_called_once_with(dep_info)
159 self.assertFalse(sb_find_path_mock.call_args)
160 # If the below assert fails, the ordering assumption that determined the
161 # path_mock return values is incorrect, and should be updated.
162 path_mock.exists.assert_has_calls([mock.call(local_path),
163 mock.call(cs_path)], any_order=False)
164 local_path_mock.reset_mock()
165 cs_path_mock.reset_mock()
166 sb_find_path_mock.reset_mock()
168 # Non-empty lookup dict that contains the dependency we're looking for.
169 # Local path isn't found, but cloud_storage_path is downloaded.
170 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
171 'dep2': mock.MagicMock()}
172 path_mock.exists.side_effect = [True]
173 local_path_mock.return_value = None
174 found_path = dep_manager.FetchPath('dep1', 'plat')
176 self.assertEqual(cs_path, found_path)
177 local_path_mock.assert_called_with(dep_info)
178 cs_path_mock.assert_called_once_with(dep_info)
179 self.assertFalse(sb_find_path_mock.call_args)
180 # If the below assert fails, the ordering assumption that determined the
181 # path_mock return values is incorrect, and should be updated.
182 path_mock.exists.assert_has_calls([mock.call(local_path),
183 mock.call(cs_path)], any_order=False)
185 @mock.patch('os.path')
186 @mock.patch('catapult_base.support_binaries.FindPath')
187 @mock.patch(
188 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
189 @mock.patch(
190 'catapult_base.dependency_manager.DependencyManager._CloudStoragePath')
191 @mock.patch('catapult_base.dependency_manager.DependencyManager._LocalPath')
192 def testFetchPathError(self, local_path_mock, cs_path_mock, dep_info_mock,
193 sb_find_path_mock, path_mock):
194 dep_manager = dependency_manager.DependencyManager([])
195 self.assertFalse(local_path_mock.call_args)
196 self.assertFalse(cs_path_mock.call_args)
197 self.assertFalse(sb_find_path_mock.call_args)
198 local_path_mock.return_value = None
199 cs_path_mock.return_value = None
200 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
201 'dep2': mock.MagicMock()}
202 # Non-empty lookup dict that contains the dependency we're looking for.
203 # Local path doesn't exist, and cloud_storage path wasn't successfully
204 # found.
205 self.assertRaises(exceptions.NoPathFoundError,
206 dep_manager.FetchPath, 'dep1', 'plat')
208 cs_path_mock.side_effect = cloud_storage.CredentialsError
209 self.assertRaises(cloud_storage.CredentialsError,
210 dep_manager.FetchPath, 'dep1', 'plat')
212 cs_path_mock.side_effect = cloud_storage.CloudStorageError
213 self.assertRaises(cloud_storage.CloudStorageError,
214 dep_manager.FetchPath, 'dep1', 'plat')
216 cs_path_mock.side_effect = cloud_storage.PermissionError
217 self.assertRaises(cloud_storage.PermissionError,
218 dep_manager.FetchPath, 'dep1', 'plat')
220 @mock.patch('os.path')
221 @mock.patch('catapult_base.support_binaries.FindLocallyBuiltPath')
222 @mock.patch(
223 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
224 @mock.patch('catapult_base.dependency_manager.DependencyManager._LocalPath')
225 def testLocalPath(self, local_path_mock, dep_info_mock, sb_find_path_mock,
226 path_mock):
227 dep_manager = dependency_manager.DependencyManager([])
228 self.assertFalse(local_path_mock.call_args)
229 self.assertFalse(sb_find_path_mock.call_args)
230 sb_path = 'sb_path'
231 local_path = 'local_path'
232 dep_info = 'dep_info'
233 local_path_mock.return_value = local_path
234 sb_find_path_mock.return_value = sb_path
235 dep_info_mock.return_value = dep_info
237 # Empty lookup_dict
238 found_path = dep_manager.LocalPath('dep', 'plat')
239 self.assertEqual(sb_path, found_path)
240 self.assertFalse(local_path_mock.call_args)
241 sb_find_path_mock.assert_called_once_with('dep')
242 local_path_mock.reset_mock()
243 sb_find_path_mock.reset_mock()
245 # Non-empty lookup dict that doesn't contain the dependency we're looking
246 # for.
247 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
248 'dep2': mock.MagicMock()}
249 found_path = dep_manager.LocalPath('dep', 'plat')
251 self.assertEqual(sb_path, found_path)
252 self.assertFalse(local_path_mock.call_args)
253 sb_find_path_mock.assert_called_once_with('dep')
254 local_path_mock.reset_mock()
255 sb_find_path_mock.reset_mock()
257 # Non-empty lookup dict that contains the dependency we're looking for.
258 # Local path exists.
259 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
260 'dep2': mock.MagicMock()}
261 path_mock.exists.return_value = True
262 found_path = dep_manager.LocalPath('dep1', 'plat')
264 self.assertEqual(local_path, found_path)
265 local_path_mock.assert_called_with('dep_info')
266 self.assertFalse(sb_find_path_mock.call_args)
267 # If the below assert fails, the ordering assumption that determined the
268 # path_mock return values is incorrect, and should be updated.
269 path_mock.exists.assert_called_once_with('local_path')
270 local_path_mock.reset_mock()
271 sb_find_path_mock.reset_mock()
273 # Non-empty lookup dict that contains the dependency we're looking for.
274 # Local path is found but doesn't exist.
275 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
276 'dep2': mock.MagicMock()}
277 path_mock.exists.return_value = False
278 local_path_mock.return_value = local_path
279 self.assertRaises(exceptions.NoPathFoundError,
280 dep_manager.LocalPath, 'dep1', 'plat')
282 # Non-empty lookup dict that contains the dependency we're looking for.
283 # Local path isn't found.
284 dep_manager._lookup_dict = {'dep1': mock.MagicMock(),
285 'dep2': mock.MagicMock()}
286 local_path_mock.return_value = None
287 self.assertRaises(exceptions.NoPathFoundError,
288 dep_manager.LocalPath, 'dep1', 'plat')
290 def testInitialUpdateDependencies(self):
291 dep_manager = dependency_manager.DependencyManager([])
293 # Empty BaseConfig.
294 dep_manager._lookup_dict = {}
295 base_config_mock = mock.MagicMock(spec=dependency_manager.BaseConfig)
296 base_config_mock.IterDependencyInfo.return_value = iter([])
297 dep_manager._UpdateDependencies(base_config_mock)
298 self.assertFalse(dep_manager._lookup_dict)
300 # One dependency/platform in a BaseConfig.
301 dep_manager._lookup_dict = {}
302 base_config_mock = mock.MagicMock(spec=dependency_manager.BaseConfig)
303 dep_info = mock.MagicMock(spec=dependency_manager.DependencyInfo)
304 dep = 'dependency'
305 plat = 'platform'
306 dep_info.dependency = dep
307 dep_info.platform = plat
308 base_config_mock.IterDependencyInfo.return_value = iter([dep_info])
309 expected_lookup_dict = {dep: {plat: dep_info}}
310 dep_manager._UpdateDependencies(base_config_mock)
311 self.assertEqual(expected_lookup_dict, dep_manager._lookup_dict)
312 self.assertFalse(dep_info.Update.called)
314 # One dependency multiple platforms in a BaseConfig.
315 dep_manager._lookup_dict = {}
316 base_config_mock = mock.MagicMock(spec=dependency_manager.BaseConfig)
317 dep = 'dependency'
318 plat1 = 'platform1'
319 plat2 = 'platform2'
320 dep_info1 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
321 dep_info1.dependency = dep
322 dep_info1.platform = plat1
323 dep_info2 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
324 dep_info2.dependency = dep
325 dep_info2.platform = plat2
326 base_config_mock.IterDependencyInfo.return_value = iter([dep_info1,
327 dep_info2])
328 expected_lookup_dict = {dep: {plat1: dep_info1,
329 plat2: dep_info2}}
330 dep_manager._UpdateDependencies(base_config_mock)
331 self.assertEqual(expected_lookup_dict, dep_manager._lookup_dict)
332 self.assertFalse(dep_info1.Update.called)
333 self.assertFalse(dep_info2.Update.called)
335 # Multiple dependencies, multiple platforms in a BaseConfig.
336 dep_manager._lookup_dict = {}
337 base_config_mock = mock.MagicMock(spec=dependency_manager.BaseConfig)
338 dep1 = 'dependency1'
339 dep2 = 'dependency2'
340 plat1 = 'platform1'
341 plat2 = 'platform2'
342 dep_info1 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
343 dep_info1.dependency = dep1
344 dep_info1.platform = plat1
345 dep_info2 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
346 dep_info2.dependency = dep1
347 dep_info2.platform = plat2
348 dep_info3 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
349 dep_info3.dependency = dep2
350 dep_info3.platform = plat2
351 base_config_mock.IterDependencyInfo.return_value = iter(
352 [dep_info1, dep_info2, dep_info3])
353 expected_lookup_dict = {dep1: {plat1: dep_info1,
354 plat2: dep_info2},
355 dep2: {plat2: dep_info3}}
356 dep_manager._UpdateDependencies(base_config_mock)
357 self.assertEqual(expected_lookup_dict, dep_manager._lookup_dict)
358 self.assertFalse(dep_info1.Update.called)
359 self.assertFalse(dep_info2.Update.called)
360 self.assertFalse(dep_info3.Update.called)
362 def testFollowupUpdateDependenciesNoOverlap(self):
363 dep_manager = dependency_manager.DependencyManager([])
364 dep = 'dependency'
365 dep1 = 'dependency1'
366 dep2 = 'dependency2'
367 dep3 = 'dependency3'
368 plat1 = 'platform1'
369 plat2 = 'platform2'
370 plat3 = 'platform3'
371 dep_info_a = mock.MagicMock(spec=dependency_manager.DependencyInfo)
372 dep_info_a.dependency = dep1
373 dep_info_a.platform = plat1
374 dep_info_b = mock.MagicMock(spec=dependency_manager.DependencyInfo)
375 dep_info_b.dependency = dep1
376 dep_info_b.platform = plat2
377 dep_info_c = mock.MagicMock(spec=dependency_manager.DependencyInfo)
378 dep_info_c.dependency = dep
379 dep_info_c.platform = plat1
381 start_lookup_dict = {dep: {plat1: dep_info_a,
382 plat2: dep_info_b},
383 dep1: {plat1: dep_info_c}}
384 base_config_mock = mock.MagicMock(spec=dependency_manager.BaseConfig)
386 # Empty BaseConfig.
387 dep_manager._lookup_dict = start_lookup_dict.copy()
388 base_config_mock.IterDependencyInfo.return_value = iter([])
389 dep_manager._UpdateDependencies(base_config_mock)
390 self.assertEqual(start_lookup_dict, dep_manager._lookup_dict)
392 # One dependency/platform in a BaseConfig.
393 dep_manager._lookup_dict = start_lookup_dict.copy()
394 dep_info = mock.MagicMock(spec=dependency_manager.DependencyInfo)
395 dep_info.dependency = dep3
396 dep_info.platform = plat1
397 base_config_mock.IterDependencyInfo.return_value = iter([dep_info])
398 expected_lookup_dict = {dep: {plat1: dep_info_a,
399 plat2: dep_info_b},
400 dep1: {plat1: dep_info_c},
401 dep3: {plat3: dep_info}}
403 dep_manager._UpdateDependencies(base_config_mock)
404 self.assertItemsEqual(expected_lookup_dict, dep_manager._lookup_dict)
405 self.assertFalse(dep_info.Update.called)
406 self.assertFalse(dep_info_a.Update.called)
407 self.assertFalse(dep_info_b.Update.called)
408 self.assertFalse(dep_info_c.Update.called)
410 # One dependency multiple platforms in a BaseConfig.
411 dep_manager._lookup_dict = start_lookup_dict.copy()
412 dep_info1 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
413 dep_info1.dependency = dep2
414 dep_info1.platform = plat1
415 dep_info2 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
416 dep_info2.dependency = dep2
417 dep_info2.platform = plat2
418 base_config_mock.IterDependencyInfo.return_value = iter([dep_info1,
419 dep_info2])
420 expected_lookup_dict = {dep: {plat1: dep_info_a,
421 plat2: dep_info_b},
422 dep1: {plat1: dep_info_c},
423 dep2: {plat1: dep_info1,
424 plat2: dep_info2}}
425 dep_manager._UpdateDependencies(base_config_mock)
426 self.assertEqual(expected_lookup_dict, dep_manager._lookup_dict)
427 self.assertFalse(dep_info1.Update.called)
428 self.assertFalse(dep_info2.Update.called)
429 self.assertFalse(dep_info_a.Update.called)
430 self.assertFalse(dep_info_b.Update.called)
431 self.assertFalse(dep_info_c.Update.called)
433 # Multiple dependencies, multiple platforms in a BaseConfig.
434 dep_manager._lookup_dict = start_lookup_dict.copy()
435 dep1 = 'dependency1'
436 plat1 = 'platform1'
437 plat2 = 'platform2'
438 dep_info1 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
439 dep_info1.dependency = dep2
440 dep_info1.platform = plat1
441 dep_info2 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
442 dep_info2.dependency = dep2
443 dep_info2.platform = plat2
444 dep_info3 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
445 dep_info3.dependency = dep3
446 dep_info3.platform = plat2
447 base_config_mock.IterDependencyInfo.return_value = iter(
448 [dep_info1, dep_info2, dep_info3])
449 expected_lookup_dict = {dep: {plat1: dep_info_a,
450 plat2: dep_info_b},
451 dep1: {plat1: dep_info_c},
452 dep2: {plat1: dep_info1,
453 plat2: dep_info2},
454 dep3: {plat2: dep_info3}}
455 dep_manager._UpdateDependencies(base_config_mock)
456 self.assertEqual(expected_lookup_dict, dep_manager._lookup_dict)
457 self.assertFalse(dep_info1.Update.called)
458 self.assertFalse(dep_info2.Update.called)
459 self.assertFalse(dep_info3.Update.called)
460 self.assertFalse(dep_info_a.Update.called)
461 self.assertFalse(dep_info_b.Update.called)
462 self.assertFalse(dep_info_c.Update.called)
464 # Ensure the testing data wasn't corrupted.
465 self.assertEqual(start_lookup_dict,
466 {dep: {plat1: dep_info_a,
467 plat2: dep_info_b},
468 dep1: {plat1: dep_info_c}})
470 def testFollowupUpdateDependenciesWithCollisions(self):
471 dep_manager = dependency_manager.DependencyManager([])
472 dep = 'dependency'
473 dep1 = 'dependency1'
474 dep2 = 'dependency2'
475 plat1 = 'platform1'
476 plat2 = 'platform2'
477 dep_info_a = mock.MagicMock(spec=dependency_manager.DependencyInfo)
478 dep_info_a.dependency = dep1
479 dep_info_a.platform = plat1
480 dep_info_b = mock.MagicMock(spec=dependency_manager.DependencyInfo)
481 dep_info_b.dependency = dep1
482 dep_info_b.platform = plat2
483 dep_info_c = mock.MagicMock(spec=dependency_manager.DependencyInfo)
484 dep_info_c.dependency = dep
485 dep_info_c.platform = plat1
487 start_lookup_dict = {dep: {plat1: dep_info_a,
488 plat2: dep_info_b},
489 dep1: {plat1: dep_info_c}}
490 base_config_mock = mock.MagicMock(spec=dependency_manager.BaseConfig)
492 # One dependency/platform.
493 dep_manager._lookup_dict = start_lookup_dict.copy()
494 dep_info = mock.MagicMock(spec=dependency_manager.DependencyInfo)
495 dep_info.dependency = dep
496 dep_info.platform = plat1
497 base_config_mock.IterDependencyInfo.return_value = iter([dep_info])
498 expected_lookup_dict = {dep: {plat1: dep_info_a,
499 plat2: dep_info_b},
500 dep1: {plat1: dep_info_c}}
502 dep_manager._UpdateDependencies(base_config_mock)
503 self.assertItemsEqual(expected_lookup_dict, dep_manager._lookup_dict)
504 dep_info_a.Update.assert_called_once_with(dep_info)
505 self.assertFalse(dep_info.Update.called)
506 self.assertFalse(dep_info_b.Update.called)
507 self.assertFalse(dep_info_c.Update.called)
508 dep_info_a.reset_mock()
509 dep_info_b.reset_mock()
510 dep_info_c.reset_mock()
512 # One dependency multiple platforms in a BaseConfig.
513 dep_manager._lookup_dict = start_lookup_dict.copy()
514 dep_info1 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
515 dep_info1.dependency = dep1
516 dep_info1.platform = plat1
517 dep_info2 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
518 dep_info2.dependency = dep2
519 dep_info2.platform = plat2
520 base_config_mock.IterDependencyInfo.return_value = iter([dep_info1,
521 dep_info2])
522 expected_lookup_dict = {dep: {plat1: dep_info_a,
523 plat2: dep_info_b},
524 dep1: {plat1: dep_info_c},
525 dep2: {plat2: dep_info2}}
526 dep_manager._UpdateDependencies(base_config_mock)
527 self.assertEqual(expected_lookup_dict, dep_manager._lookup_dict)
528 self.assertFalse(dep_info1.Update.called)
529 self.assertFalse(dep_info2.Update.called)
530 self.assertFalse(dep_info_a.Update.called)
531 self.assertFalse(dep_info_b.Update.called)
532 dep_info_c.Update.assert_called_once_with(dep_info1)
533 dep_info_a.reset_mock()
534 dep_info_b.reset_mock()
535 dep_info_c.reset_mock()
537 # Multiple dependencies, multiple platforms in a BaseConfig.
538 dep_manager._lookup_dict = start_lookup_dict.copy()
539 dep1 = 'dependency1'
540 plat1 = 'platform1'
541 plat2 = 'platform2'
542 dep_info1 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
543 dep_info1.dependency = dep
544 dep_info1.platform = plat1
545 dep_info2 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
546 dep_info2.dependency = dep1
547 dep_info2.platform = plat1
548 dep_info3 = mock.MagicMock(spec=dependency_manager.DependencyInfo)
549 dep_info3.dependency = dep2
550 dep_info3.platform = plat2
551 base_config_mock.IterDependencyInfo.return_value = iter(
552 [dep_info1, dep_info2, dep_info3])
553 expected_lookup_dict = {dep: {plat1: dep_info_a,
554 plat2: dep_info_b},
555 dep1: {plat1: dep_info_c},
556 dep2: {plat2: dep_info3}}
557 dep_manager._UpdateDependencies(base_config_mock)
558 self.assertEqual(expected_lookup_dict, dep_manager._lookup_dict)
559 self.assertFalse(dep_info1.Update.called)
560 self.assertFalse(dep_info2.Update.called)
561 self.assertFalse(dep_info3.Update.called)
562 self.assertFalse(dep_info_b.Update.called)
563 dep_info_a.Update.assert_called_once_with(dep_info1)
564 dep_info_c.Update.assert_called_once_with(dep_info2)
566 # Collision error.
567 dep_manager._lookup_dict = start_lookup_dict.copy()
568 dep_info = mock.MagicMock(spec=dependency_manager.DependencyInfo)
569 dep_info.dependency = dep
570 dep_info.platform = plat1
571 base_config_mock.IterDependencyInfo.return_value = iter([dep_info])
572 dep_info_a.Update.side_effect = ValueError
573 self.assertRaises(ValueError,
574 dep_manager._UpdateDependencies, base_config_mock)
576 # Ensure the testing data wasn't corrupted.
577 self.assertEqual(start_lookup_dict,
578 {dep: {plat1: dep_info_a,
579 plat2: dep_info_b},
580 dep1: {plat1: dep_info_c}})
582 def testGetDependencyInfo(self):
583 dep_manager = dependency_manager.DependencyManager([])
584 self.assertFalse(dep_manager._lookup_dict)
586 # No dependencies in the dependency manager.
587 self.assertEqual(None, dep_manager._GetDependencyInfo('missing_dep',
588 'missing_plat'))
590 dep_manager._lookup_dict = {'dep1': {'plat1': 'dep_info11',
591 'plat2': 'dep_info12',
592 'plat3': 'dep_info13'},
593 'dep2': {'plat1': 'dep_info11',
594 'plat2': 'dep_info21',
595 'plat3': 'dep_info23',
596 'default': 'dep_info2d'},
597 'dep3': {'plat1': 'dep_info31',
598 'plat2': 'dep_info32',
599 'default': 'dep_info3d'}}
600 # Dependency not in the dependency manager.
601 self.assertEqual(None, dep_manager._GetDependencyInfo(
602 'missing_dep', 'missing_plat'))
603 # Dependency in the dependency manager, but not the platform. No default.
604 self.assertEqual(None, dep_manager._GetDependencyInfo(
605 'dep1', 'missing_plat'))
606 # Dependency in the dependency manager, but not the platform, but a default
607 # exists.
608 self.assertEqual('dep_info2d', dep_manager._GetDependencyInfo(
609 'dep2', 'missing_plat'))
610 # Dependency and platform in the dependency manager. A default exists.
611 self.assertEqual('dep_info23', dep_manager._GetDependencyInfo(
612 'dep2', 'plat3'))
613 # Dependency and platform in the dependency manager. No default exists.
614 self.assertEqual('dep_info12', dep_manager._GetDependencyInfo(
615 'dep1', 'plat2'))
618 @mock.patch('os.path.exists')
619 def testLocalPathHelper(self, exists_mock):
620 dep_info = mock.MagicMock(spec=dependency_manager.DependencyInfo)
622 # There is no local path for the given dependency.
623 dep_info.local_paths = {}
624 self.assertEqual(None,
625 dependency_manager.DependencyManager._LocalPath(dep_info))
627 # There is a local path for the given dependency, but it doesn't exist.
628 exists_mock.side_effect = [False]
629 dep_info.local_paths = {'local_path0'}
630 self.assertEqual(None,
631 dependency_manager.DependencyManager._LocalPath(dep_info))
632 exists_mock.assert_called_once_with('local_path0')
633 exists_mock.reset_mock()
635 # There is a local path for the given dependency, and it does exist.
636 exists_mock.side_effect = [True]
637 dep_info.local_paths = {'local_path0'}
638 self.assertEqual('local_path0',
639 dependency_manager.DependencyManager._LocalPath(dep_info))
640 exists_mock.assert_called_once_with('local_path0')
641 exists_mock.reset_mock()
643 # There are multiple local paths for the given dependency, and the first one
644 # exists.
645 exists_mock.side_effect = [True]
646 dep_info.local_paths = {'local_path0', 'local_path1', 'local_path2'}
647 self.assertEqual('local_path0',
648 dependency_manager.DependencyManager._LocalPath(dep_info))
649 exists_mock.assert_called_once_with('local_path0')
650 exists_mock.reset_mock()
652 # There are multiple local paths for the given dependency, and the first one
653 # doesn't exist but the second one does.
654 exists_mock.side_effect = [False, True]
655 dep_info.local_paths = {'local_path0', 'local_path1', 'local_path2'}
656 self.assertEqual('local_path1',
657 dependency_manager.DependencyManager._LocalPath(dep_info))
658 expected_calls = [mock.call('local_path0'), mock.call('local_path1')]
659 exists_mock.assert_has_calls(expected_calls, any_order=False)
660 exists_mock.reset_mock()
662 # There are multiple local paths for the given dependency, and the first and
663 # second ones don't exist but the third one does.
664 exists_mock.side_effect = [False, False, True]
665 dep_info.local_paths = {'local_path0', 'local_path1', 'local_path2'}
666 self.assertEqual('local_path2',
667 dependency_manager.DependencyManager._LocalPath(dep_info))
668 expected_calls = [mock.call('local_path0'), mock.call('local_path1'),
669 mock.call('local_path2')]
670 exists_mock.assert_has_calls(expected_calls, any_order=False)
671 exists_mock.reset_mock()
673 # There are multiple local paths for the given dependency, but none of them
674 # exist.
675 exists_mock.side_effect = [False, False, False]
676 dep_info.local_paths = {'local_path0', 'local_path1', 'local_path2'}
677 self.assertEqual(None,
678 dependency_manager.DependencyManager._LocalPath(dep_info))
679 expected_calls = [mock.call('local_path0'), mock.call('local_path1'),
680 mock.call('local_path2')]
681 exists_mock.assert_has_calls(expected_calls, any_order=False)
682 exists_mock.reset_mock()
685 @mock.patch('os.path.exists')
686 @mock.patch('os.chmod')
687 @mock.patch(
688 'catapult_base.cloud_storage.GetIfHashChanged')
689 def testCloudStoragePathMissingData(
690 self, cs_get_mock, chmod_mock, exists_mock):
691 dep_info = mock.MagicMock(spec=dependency_manager.DependencyInfo)
692 cs_remote_path = 'cs_remote_path'
693 cs_hash = 'cs_hash'
694 cs_bucket = 'cs_bucket'
695 download_path = 'download_path'
697 # No dependency info.
698 self.assertEqual(
699 None, dependency_manager.DependencyManager._CloudStoragePath(None))
701 # There is no cloud_storage information for the dependency.
702 dep_info.cs_remote_path = None
703 dep_info.cs_hash = None
704 dep_info.cs_bucket = None
705 dep_info.download_path = None
706 self.assertEqual(
707 None, dependency_manager.DependencyManager._CloudStoragePath(dep_info))
709 # There is no cloud_storage remote_path the dependency.
710 dep_info.cs_remote_path = None
711 dep_info.cs_hash = cs_hash
712 dep_info.cs_bucket = cs_bucket
713 dep_info.download_path = download_path
714 self.assertEqual(
715 None, dependency_manager.DependencyManager._CloudStoragePath(dep_info))
717 # There is no cloud_storage hash for the dependency.
718 dep_info.cs_remote_path = cs_remote_path
719 dep_info.cs_hash = None
720 dep_info.cs_bucket = cs_bucket
721 dep_info.download_path = download_path
722 self.assertEqual(
723 None, dependency_manager.DependencyManager._CloudStoragePath(dep_info))
725 # There is no cloud_storage bucket for the dependency.
726 dep_info.cs_remote_path = cs_remote_path
727 dep_info.cs_hash = cs_hash
728 dep_info.cs_bucket = None
729 dep_info.download_path = download_path
730 self.assertEqual(
731 None, dependency_manager.DependencyManager._CloudStoragePath(dep_info))
733 # There is no download_path for the dependency.
734 dep_info.cs_remote_path = cs_remote_path
735 dep_info.cs_hash = cs_hash
736 dep_info.cs_bucket = cs_bucket
737 dep_info.download_path = None
738 self.assertEqual(
739 None, dependency_manager.DependencyManager._CloudStoragePath(dep_info))
741 @mock.patch('os.path.exists')
742 @mock.patch('os.chmod')
743 @mock.patch(
744 'catapult_base.cloud_storage.GetIfHashChanged')
745 def testCloudStoragePath(self, cs_get_mock, chmod_mock, exists_mock):
746 dep_info = mock.MagicMock(spec=dependency_manager.DependencyInfo)
747 cs_remote_path = 'cs_remote_path'
748 cs_hash = 'cs_hash'
749 cs_bucket = 'cs_bucket'
750 download_path = 'download_path'
752 # All of the needed information is given, and the downloaded path exists
753 # after calling cloud storage.
754 dep_info.cs_remote_path = cs_remote_path
755 dep_info.cs_hash = cs_hash
756 dep_info.cs_bucket = cs_bucket
757 dep_info.download_path = download_path
758 exists_mock.return_value = True
759 self.assertEqual(
760 os.path.abspath(download_path),
761 dependency_manager.DependencyManager._CloudStoragePath(dep_info))
762 chmod_mock.assert_called_once_with(
763 download_path,
764 stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP)
766 # All of the needed information is given, but the downloaded path doesn't
767 # exists after calling cloud storage.
768 dep_info.cs_remote_path = cs_remote_path
769 dep_info.cs_hash = cs_hash
770 dep_info.cs_bucket = cs_bucket
771 dep_info.download_path = download_path
772 exists_mock.return_value = False
773 with mock.patch(
774 'catapult_base.dependency_manager.dependency_manager.os.makedirs'):
775 self.assertRaises(
776 exceptions.FileNotFoundError,
777 dependency_manager.DependencyManager._CloudStoragePath, dep_info)
778 exists_mock.assert_called_with(download_path)
780 @mock.patch('os.path.exists')
781 @mock.patch(
782 'catapult_base.cloud_storage.GetIfHashChanged')
783 def testCloudStoragePathCloudStorageErrors(self, cs_get_mock, exists_mock):
784 dep_info = mock.MagicMock(spec=dependency_manager.DependencyInfo)
785 dep_info.download_path = 'download_path'
787 cs_get_mock.side_effect = cloud_storage.CloudStorageError
788 self.assertRaises(
789 cloud_storage.CloudStorageError,
790 dependency_manager.DependencyManager._CloudStoragePath, dep_info)
792 cs_get_mock.side_effect = cloud_storage.ServerError
793 self.assertRaises(
794 cloud_storage.ServerError,
795 dependency_manager.DependencyManager._CloudStoragePath, dep_info)
797 cs_get_mock.side_effect = cloud_storage.NotFoundError
798 self.assertRaises(
799 cloud_storage.NotFoundError,
800 dependency_manager.DependencyManager._CloudStoragePath, dep_info)
802 cs_get_mock.side_effect = cloud_storage.PermissionError
803 self.assertRaises(
804 cloud_storage.PermissionError,
805 dependency_manager.DependencyManager._CloudStoragePath, dep_info)
807 cs_get_mock.side_effect = cloud_storage.CredentialsError
808 self.assertRaises(
809 cloud_storage.CredentialsError,
810 dependency_manager.DependencyManager._CloudStoragePath, dep_info)