Skip to content

Commit 0705e52

Browse files
authored
Merge pull request #309 from Duke-GCB/305-python2-download-fix
Fixes downloading for python2
2 parents c93e169 + 8a5dc80 commit 0705e52

2 files changed

Lines changed: 18 additions & 10 deletions

File tree

ddsc/core/download.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,16 @@ def run(self):
218218
self._show_downloaded_files_status()
219219

220220
def _download_files(self):
221-
with multiprocessing.Pool(self.num_workers) as pool:
221+
pool = multiprocessing.Pool(self.num_workers)
222+
try:
222223
for project_file in self._get_project_files():
223224
self._download_file(pool, project_file)
224225
while self._work_queue_is_full():
225226
self._wait_for_and_retry_failed_downloads(pool)
226227
while self._work_queue_is_not_empty():
227228
self._wait_for_and_retry_failed_downloads(pool)
229+
finally:
230+
pool.close()
228231

229232
def _show_downloaded_files_status(self):
230233
print("\nVerifying contents of {} downloaded files using file hashes.".format(self.files_to_download))
@@ -275,7 +278,9 @@ def _print_path_filter_warnings(self):
275278

276279
def _download_file(self, pool, project_file):
277280
output_path = project_file.get_local_path(self.dest_directory)
278-
os.makedirs(os.path.dirname(output_path), exist_ok=True)
281+
output_path_parent = os.path.dirname(output_path)
282+
if not os.path.exists(output_path_parent):
283+
os.makedirs(output_path_parent)
279284
file_download_state = FileDownloadState(project_file, output_path, self.config)
280285
self._async_download_file(pool, file_download_state)
281286

@@ -318,6 +323,7 @@ def show_progress_bar(self):
318323
files_downloaded,
319324
self.files_to_download
320325
))
326+
sys.stdout.flush()
321327

322328
def make_spinner_char(self, current_time):
323329
half_seconds = int(current_time)

ddsc/core/tests/test_download.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from ddsc.core.pathfilter import PathFilter
66
import queue
77
import requests
8-
from mock.mock import patch, Mock, call, mock_open
8+
from mock.mock import patch, Mock, call, mock_open, ANY
99

1010

1111
class TestFileHash(TestCase):
@@ -206,7 +206,7 @@ def test_run(self, mock_time, mock_file_download_state, mock_print, mock_os, moc
206206
self.project.get_project_files_generator.return_value = [
207207
(mock_project_file, {DDS_TOTAL_HEADER: 1})
208208
]
209-
mock_pool = mock_multiprocessing.Pool.return_value.__enter__.return_value
209+
mock_pool = mock_multiprocessing.Pool.return_value
210210
mock_apply_async = mock_pool.apply_async
211211
mock_apply_async.return_value.get.return_value.status.get_status_line.return_value = 'Hash Status Line'
212212

@@ -229,7 +229,6 @@ def test_run(self, mock_time, mock_file_download_state, mock_print, mock_os, moc
229229

230230
@patch('ddsc.core.download.multiprocessing')
231231
def test_download_files(self, mock_multiprocessing):
232-
mock_pool = mock_multiprocessing.Pool.return_value.__enter__.return_value
233232
project_file_downloader = ProjectFileDownloader(self.config, self.dest_directory, self.project,
234233
path_filter=None)
235234
project_file_downloader.show_progress_bar = Mock()
@@ -262,14 +261,14 @@ def test_download_files(self, mock_multiprocessing):
262261

263262
# Expected behavior is to download file 1, wait for that to finish, download file 2, then wait for one more time
264263
manager.assert_has_calls([
265-
call.download_file(mock_pool, 'project_file1_obj'),
264+
call.download_file(ANY, 'project_file1_obj'),
266265
call.work_queue_is_full(),
267-
call.wait_for_and_retry_failed_downloads(mock_pool),
266+
call.wait_for_and_retry_failed_downloads(ANY),
268267
call.work_queue_is_full(),
269-
call.download_file(mock_pool, 'project_file2_obj'),
268+
call.download_file(ANY, 'project_file2_obj'),
270269
call.work_queue_is_full(),
271270
call.work_queue_is_not_empty(),
272-
call.wait_for_and_retry_failed_downloads(mock_pool),
271+
call.wait_for_and_retry_failed_downloads(ANY),
273272
call.work_queue_is_not_empty()
274273
])
275274

@@ -389,14 +388,16 @@ def test_get_project_files_with_filter_warnings(self, mock_print, mock_multiproc
389388
@patch('ddsc.core.download.os')
390389
@patch('ddsc.core.download.FileDownloadState')
391390
def test_download_file(self, mock_file_download_state, mock_os, mock_multiprocessing):
391+
mock_os.path.exists.return_value = False
392392
mock_pool = Mock()
393393
mock_project_file = Mock(file_url={'host': 'somehost', 'url': 'someurl'})
394394
mock_project_file.get_local_path.return_value = '/tmp/data.out'
395395
project_file_downloader = ProjectFileDownloader(self.config, self.dest_directory, self.project,
396396
path_filter=None)
397397
project_file_downloader._download_file(mock_pool, mock_project_file)
398398
mock_os.path.dirname.assert_called_with("/tmp/data.out")
399-
mock_os.makedirs.assert_called_with(mock_os.path.dirname.return_value, exist_ok=True)
399+
mock_os.path.exists.assert_called_with(mock_os.path.dirname.return_value)
400+
mock_os.makedirs.assert_called_with(mock_os.path.dirname.return_value)
400401
mock_file_download_state.assert_called_with(mock_project_file, '/tmp/data.out', self.config)
401402
mock_pool.apply_async.assert_called_with(download_file, (mock_file_download_state.return_value,
402403
project_file_downloader.message_queue))
@@ -474,6 +475,7 @@ def test_show_progress_bar(self, mock_time, mock_sys, mock_multiprocessing):
474475
downloader.get_download_progress.return_value = (10, 1000)
475476
downloader.show_progress_bar()
476477
mock_sys.stdout.write.assert_called_with('\r| downloaded 1 KB @ 10 B/s (10 of 20 files complete)')
478+
mock_sys.stdout.flush.assert_called_with()
477479

478480
@patch('ddsc.core.download.multiprocessing')
479481
def test_make_spinner_char(self, mock_multiprocessing):

0 commit comments

Comments
 (0)