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.
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
):
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
,
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')
44 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
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
)
55 local_path
= 'local_path'
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
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
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')
90 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
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
)
101 local_path
= 'local_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.
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')
132 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
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'
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')
188 'catapult_base.dependency_manager.DependencyManager._GetDependencyInfo')
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
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')
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
,
227 dep_manager
= dependency_manager
.DependencyManager([])
228 self
.assertFalse(local_path_mock
.call_args
)
229 self
.assertFalse(sb_find_path_mock
.call_args
)
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
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
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.
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([])
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
)
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
)
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
,
328 expected_lookup_dict
= {dep
: {plat1
: dep_info1
,
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
)
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
,
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([])
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
,
383 dep1
: {plat1
: dep_info_c
}}
384 base_config_mock
= mock
.MagicMock(spec
=dependency_manager
.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
,
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
,
420 expected_lookup_dict
= {dep
: {plat1
: dep_info_a
,
422 dep1
: {plat1
: dep_info_c
},
423 dep2
: {plat1
: dep_info1
,
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()
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
,
451 dep1
: {plat1
: dep_info_c
},
452 dep2
: {plat1
: dep_info1
,
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
,
468 dep1
: {plat1
: dep_info_c
}})
470 def testFollowupUpdateDependenciesWithCollisions(self
):
471 dep_manager
= dependency_manager
.DependencyManager([])
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
,
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
,
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
,
522 expected_lookup_dict
= {dep
: {plat1
: dep_info_a
,
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()
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
,
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
)
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
,
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',
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
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
(
613 # Dependency and platform in the dependency manager. No default exists.
614 self
.assertEqual('dep_info12', dep_manager
._GetDependencyInfo
(
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
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
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')
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'
694 cs_bucket
= 'cs_bucket'
695 download_path
= 'download_path'
697 # No dependency info.
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
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
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
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
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
739 None, dependency_manager
.DependencyManager
._CloudStoragePath
(dep_info
))
741 @mock.patch('os.path.exists')
742 @mock.patch('os.chmod')
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'
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
760 os
.path
.abspath(download_path
),
761 dependency_manager
.DependencyManager
._CloudStoragePath
(dep_info
))
762 chmod_mock
.assert_called_once_with(
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
774 'catapult_base.dependency_manager.dependency_manager.os.makedirs'):
776 exceptions
.FileNotFoundError
,
777 dependency_manager
.DependencyManager
._CloudStoragePath
, dep_info
)
778 exists_mock
.assert_called_with(download_path
)
780 @mock.patch('os.path.exists')
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
789 cloud_storage
.CloudStorageError
,
790 dependency_manager
.DependencyManager
._CloudStoragePath
, dep_info
)
792 cs_get_mock
.side_effect
= cloud_storage
.ServerError
794 cloud_storage
.ServerError
,
795 dependency_manager
.DependencyManager
._CloudStoragePath
, dep_info
)
797 cs_get_mock
.side_effect
= cloud_storage
.NotFoundError
799 cloud_storage
.NotFoundError
,
800 dependency_manager
.DependencyManager
._CloudStoragePath
, dep_info
)
802 cs_get_mock
.side_effect
= cloud_storage
.PermissionError
804 cloud_storage
.PermissionError
,
805 dependency_manager
.DependencyManager
._CloudStoragePath
, dep_info
)
807 cs_get_mock
.side_effect
= cloud_storage
.CredentialsError
809 cloud_storage
.CredentialsError
,
810 dependency_manager
.DependencyManager
._CloudStoragePath
, dep_info
)