Coverage for manila/tests/data/test_utils.py: 100%
140 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright 2015 Hitachi Data Systems inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16import os
17import time
18from unittest import mock
20from manila.data import utils as data_utils
21from manila import exception
22from manila import test
23from manila import utils
26class CopyClassTestCase(test.TestCase):
27 def setUp(self):
28 super(CopyClassTestCase, self).setUp()
29 src = '/path/fake/src'
30 dest = '/path/fake/dst'
31 ignore_list = ['item']
32 self._copy = data_utils.Copy(src, dest, ignore_list)
33 self._copy.total_size = 10000
34 self._copy.current_size = 100
35 self._copy.current_copy = {'file_path': '/fake/path', 'size': 100}
36 self._copy.check_hash = True
38 self.mock_log = self.mock_object(data_utils, 'LOG')
40 def test_get_progress(self):
41 expected = {'total_progress': 1,
42 'current_file_path': '/fake/path',
43 'current_file_progress': 100}
45 # mocks
46 self.mock_object(utils, 'execute',
47 mock.Mock(return_value=("100", "")))
49 # run
50 self._copy.initialized = True
51 out = self._copy.get_progress()
53 # asserts
54 self.assertEqual(expected, out)
56 utils.execute.assert_called_once_with("stat", "-c", "%s", "/fake/path",
57 run_as_root=True)
59 def test_get_progress_not_initialized(self):
60 expected = {'total_progress': 0}
62 # run
63 self._copy.initialized = False
64 out = self._copy.get_progress()
66 # asserts
67 self.assertEqual(expected, out)
69 def test_get_progress_completed_empty(self):
70 expected = {'total_progress': 100}
72 # run
73 self._copy.initialized = True
74 self._copy.completed = True
75 self._copy.total_size = 0
76 out = self._copy.get_progress()
78 # asserts
79 self.assertEqual(expected, out)
81 def test_get_progress_current_copy_none(self):
82 self._copy.current_copy = None
83 expected = {'total_progress': 0}
85 # run
86 self._copy.initialized = True
87 out = self._copy.get_progress()
89 # asserts
90 self.assertEqual(expected, out)
92 def test_get_progress_exception(self):
93 expected = {'total_progress': 1,
94 'current_file_path': '/fake/path',
95 'current_file_progress': 0}
97 # mocks
98 self.mock_object(
99 utils, 'execute',
100 mock.Mock(side_effect=utils.processutils.ProcessExecutionError()))
102 # run
103 self._copy.initialized = True
104 out = self._copy.get_progress()
106 # asserts
107 self.assertEqual(expected, out)
109 utils.execute.assert_called_once_with("stat", "-c", "%s", "/fake/path",
110 run_as_root=True)
112 def test_cancel(self):
113 self._copy.cancelled = False
115 # run
116 self._copy.cancel()
118 # asserts
119 self.assertTrue(self._copy.cancelled)
121 # reset
122 self._copy.cancelled = False
124 def test_get_total_size(self):
125 self._copy.total_size = 0
127 values = [("folder1/\nitem/\nfile1\nitem", ""),
128 ("", ""),
129 ("10000", "")]
131 def get_output(*args, **kwargs):
132 return values.pop(0)
134 # mocks
135 self.mock_object(utils, 'execute', mock.Mock(
136 side_effect=get_output))
138 # run
139 self._copy.get_total_size(self._copy.src)
141 # asserts
142 self.assertEqual(10000, self._copy.total_size)
144 utils.execute.assert_has_calls([
145 mock.call("ls", "-pA1", "--group-directories-first",
146 self._copy.src, run_as_root=True),
147 mock.call("ls", "-pA1", "--group-directories-first",
148 os.path.join(self._copy.src, "folder1/"),
149 run_as_root=True),
150 mock.call("stat", "-c", "%s",
151 os.path.join(self._copy.src, "file1"), run_as_root=True)
152 ])
154 def test_get_total_size_cancelled_1(self):
155 self._copy.total_size = 0
156 self._copy.cancelled = True
158 # run
159 self._copy.get_total_size(self._copy.src)
161 # asserts
162 self.assertEqual(0, self._copy.total_size)
164 # reset
165 self._copy.total_size = 10000
166 self._copy.cancelled = False
168 def test_get_total_size_cancelled_2(self):
169 self._copy.total_size = 0
171 def ls_output(*args, **kwargs):
172 self._copy.cancelled = True
173 return "folder1/", ""
175 # mocks
176 self.mock_object(utils, 'execute', mock.Mock(
177 side_effect=ls_output))
179 # run
180 self._copy.get_total_size(self._copy.src)
182 # asserts
183 self.assertEqual(0, self._copy.total_size)
184 utils.execute.assert_called_once_with(
185 "ls", "-pA1", "--group-directories-first", self._copy.src,
186 run_as_root=True)
188 # reset
189 self._copy.total_size = 10000
190 self._copy.cancelled = False
192 def test_copy_data(self):
194 values = [("folder1/\nitem/\nfile1\nitem", ""),
195 "",
196 ("", ""),
197 ("10000", ""),
198 "",
199 ""]
201 def get_output(*args, **kwargs):
202 return values.pop(0)
204 # mocks
205 self.mock_object(data_utils, '_validate_item',
206 mock.Mock(side_effect=[exception.ShareDataCopyFailed(
207 reason='fake'), None]))
208 self.mock_object(utils, 'execute', mock.Mock(
209 side_effect=get_output))
210 self.mock_object(self._copy, 'get_progress')
211 self.mock_object(time, 'sleep')
213 # run
214 self._copy.copy_data(self._copy.src)
216 # asserts
217 self._copy.get_progress.assert_called_once_with()
219 utils.execute.assert_has_calls([
220 mock.call("ls", "-pA1", "--group-directories-first",
221 self._copy.src, run_as_root=True),
222 mock.call("mkdir", "-p", os.path.join(self._copy.dest, "folder1/"),
223 run_as_root=True),
224 mock.call("ls", "-pA1", "--group-directories-first",
225 os.path.join(self._copy.src, "folder1/"),
226 run_as_root=True),
227 mock.call("stat", "-c", "%s",
228 os.path.join(self._copy.src, "file1"), run_as_root=True),
229 mock.call("cp", "-P", "--preserve=all",
230 os.path.join(self._copy.src, "file1"),
231 os.path.join(self._copy.dest, "file1"),
232 run_as_root=True),
233 mock.call("cp", "-P", "--preserve=all",
234 os.path.join(self._copy.src, "file1"),
235 os.path.join(self._copy.dest, "file1"), run_as_root=True)
236 ])
238 def test__validate_item(self):
240 self.mock_object(utils, 'execute', mock.Mock(
241 side_effect=[("abcxyz", ""), ("defrst", "")]))
243 self.assertRaises(exception.ShareDataCopyFailed,
244 data_utils._validate_item, 'src', 'dest')
246 utils.execute.assert_has_calls([
247 mock.call("sha256sum", "src", run_as_root=True),
248 mock.call("sha256sum", "dest", run_as_root=True),
249 ])
251 def test_copy_data_cancelled_1(self):
253 self._copy.cancelled = True
255 # run
256 self._copy.copy_data(self._copy.src)
258 # reset
259 self._copy.cancelled = False
261 def test_copy_data_cancelled_2(self):
263 def ls_output(*args, **kwargs):
264 self._copy.cancelled = True
265 return "folder1/", ""
267 # mocks
268 self.mock_object(utils, 'execute', mock.Mock(
269 side_effect=ls_output))
271 # run
272 self._copy.copy_data(self._copy.src)
274 # asserts
275 utils.execute.assert_called_once_with(
276 "ls", "-pA1", "--group-directories-first", self._copy.src,
277 run_as_root=True)
279 # reset
280 self._copy.cancelled = False
282 def test_copy_stats(self):
284 values = [("folder1/\nitem/\nfile1\nitem", ""),
285 ("", ""),
286 "",
287 "",
288 "",
289 "",
290 "",
291 ""]
293 def get_output(*args, **kwargs):
294 return values.pop(0)
296 # mocks
297 self.mock_object(utils, 'execute', mock.Mock(
298 side_effect=get_output))
300 # run
301 self._copy.copy_stats(self._copy.src)
303 # asserts
304 utils.execute.assert_has_calls([
305 mock.call("ls", "-pA1", "--group-directories-first",
306 self._copy.src, run_as_root=True),
307 mock.call("ls", "-pA1", "--group-directories-first",
308 os.path.join(self._copy.src, "folder1/"),
309 run_as_root=True),
310 mock.call(
311 "chmod",
312 "--reference=%s" % os.path.join(self._copy.src, "folder1/"),
313 os.path.join(self._copy.dest, "folder1/"),
314 run_as_root=True),
315 mock.call(
316 "touch",
317 "--reference=%s" % os.path.join(self._copy.src, "folder1/"),
318 os.path.join(self._copy.dest, "folder1/"),
319 run_as_root=True),
320 mock.call(
321 "chown",
322 "--reference=%s" % os.path.join(self._copy.src, "folder1/"),
323 os.path.join(self._copy.dest, "folder1/"),
324 run_as_root=True),
325 ])
327 def test_copy_stats_cancelled_1(self):
329 self._copy.cancelled = True
331 # run
332 self._copy.copy_stats(self._copy.src)
334 # reset
335 self._copy.cancelled = False
337 def test_copy_stats_cancelled_2(self):
339 def ls_output(*args, **kwargs):
340 self._copy.cancelled = True
341 return "folder1/", ""
343 # mocks
344 self.mock_object(utils, 'execute', mock.Mock(
345 side_effect=ls_output))
347 # run
348 self._copy.copy_stats(self._copy.src)
350 # asserts
351 utils.execute.assert_called_once_with(
352 "ls", "-pA1", "--group-directories-first", self._copy.src,
353 run_as_root=True)
355 # reset
356 self._copy.cancelled = False
358 def test_run(self):
360 # mocks
361 self.mock_object(self._copy, 'get_total_size')
362 self.mock_object(self._copy, 'copy_data')
363 self.mock_object(self._copy, 'copy_stats')
364 self.mock_object(self._copy, 'get_progress')
366 # run
367 self._copy.run()
369 # asserts
370 self.assertTrue(data_utils.LOG.info.called)
371 self._copy.get_total_size.assert_called_once_with(self._copy.src)
372 self._copy.copy_data.assert_called_once_with(self._copy.src)
373 self._copy.copy_stats.assert_called_once_with(self._copy.src)
374 self._copy.get_progress.assert_called_once_with()