From e4ddb090aede72b5a40cfaaa15bb2ff72d2a1e89 Mon Sep 17 00:00:00 2001 From: Rodrigo Barbieri Date: Tue, 16 Aug 2016 10:49:35 -0300 Subject: [PATCH] Fix fallback share migration with empty files Fallback share migration fails with empty files. This patch fixes it by performing additional checks to address this specific scenario. Change-Id: I36d59740b4e52005e6025e5df5989bf55d6bade4 Closes-bug: #1613713 --- manila/data/utils.py | 63 +++++++++++-------- manila/tests/data/test_utils.py | 29 ++++++++- ...igration-empty-files-01d1a3caa2e9705e.yaml | 4 ++ 3 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 releasenotes/notes/migration-empty-files-01d1a3caa2e9705e.yaml diff --git a/manila/data/utils.py b/manila/data/utils.py index e284251b9e..daccd96f59 100644 --- a/manila/data/utils.py +++ b/manila/data/utils.py @@ -34,37 +34,46 @@ class Copy(object): self.current_copy = None self.ignore_list = ignore_list self.cancelled = False + self.initialized = False + self.completed = False def get_progress(self): - if self.current_copy is not None: - - try: - size, err = utils.execute("stat", "-c", "%s", - self.current_copy['file_path'], - run_as_root=True) - size = int(size) - except utils.processutils.ProcessExecutionError: - size = 0 - - total_progress = 0 - if self.total_size > 0: - total_progress = self.current_size * 100 / self.total_size - current_file_progress = 0 - if self.current_copy['size'] > 0: - current_file_progress = size * 100 / self.current_copy['size'] - current_file_path = self.current_copy['file_path'] - - progress = { - 'total_progress': total_progress, - 'current_file_path': current_file_path, - 'current_file_progress': current_file_progress - } - - return progress - else: + # Empty share or empty contents + if self.completed and self.total_size == 0: return {'total_progress': 100} + if not self.initialized or self.current_copy is None: + return {'total_progress': 0} + + try: + size, err = utils.execute("stat", "-c", "%s", + self.current_copy['file_path'], + run_as_root=True) + size = int(size) + except utils.processutils.ProcessExecutionError: + size = 0 + + current_file_progress = 0 + if self.current_copy['size'] > 0: + current_file_progress = size * 100 / self.current_copy['size'] + current_file_path = self.current_copy['file_path'] + + total_progress = 0 + if self.total_size > 0: + if current_file_progress == 100: + size = 0 + total_progress = int((self.current_size + size) * + 100 / self.total_size) + + progress = { + 'total_progress': total_progress, + 'current_file_path': current_file_path, + 'current_file_progress': current_file_progress + } + + return progress + def cancel(self): self.cancelled = True @@ -72,8 +81,10 @@ class Copy(object): def run(self): self.get_total_size(self.src) + self.initialized = True self.copy_data(self.src) self.copy_stats(self.src) + self.completed = True LOG.info(six.text_type(self.get_progress())) diff --git a/manila/tests/data/test_utils.py b/manila/tests/data/test_utils.py index 02fab17bb0..3de1770b30 100644 --- a/manila/tests/data/test_utils.py +++ b/manila/tests/data/test_utils.py @@ -45,6 +45,7 @@ class CopyClassTestCase(test.TestCase): mock.Mock(return_value=("100", ""))) # run + self._copy.initialized = True out = self._copy.get_progress() # asserts @@ -53,11 +54,34 @@ class CopyClassTestCase(test.TestCase): utils.execute.assert_called_once_with("stat", "-c", "%s", "/fake/path", run_as_root=True) - def test_get_progress_current_copy_none(self): - self._copy.current_copy = None + def test_get_progress_not_initialized(self): + expected = {'total_progress': 0} + + # run + self._copy.initialized = False + out = self._copy.get_progress() + + # asserts + self.assertEqual(expected, out) + + def test_get_progress_completed_empty(self): expected = {'total_progress': 100} # run + self._copy.initialized = True + self._copy.completed = True + self._copy.total_size = 0 + out = self._copy.get_progress() + + # asserts + self.assertEqual(expected, out) + + def test_get_progress_current_copy_none(self): + self._copy.current_copy = None + expected = {'total_progress': 0} + + # run + self._copy.initialized = True out = self._copy.get_progress() # asserts @@ -74,6 +98,7 @@ class CopyClassTestCase(test.TestCase): mock.Mock(side_effect=utils.processutils.ProcessExecutionError())) # run + self._copy.initialized = True out = self._copy.get_progress() # asserts diff --git a/releasenotes/notes/migration-empty-files-01d1a3caa2e9705e.yaml b/releasenotes/notes/migration-empty-files-01d1a3caa2e9705e.yaml new file mode 100644 index 0000000000..3309360b29 --- /dev/null +++ b/releasenotes/notes/migration-empty-files-01d1a3caa2e9705e.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - Fixed share migration error using Data Service when there are + only empty files.