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

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. 

15 

16import os 

17import time 

18from unittest import mock 

19 

20from manila.data import utils as data_utils 

21from manila import exception 

22from manila import test 

23from manila import utils 

24 

25 

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 

37 

38 self.mock_log = self.mock_object(data_utils, 'LOG') 

39 

40 def test_get_progress(self): 

41 expected = {'total_progress': 1, 

42 'current_file_path': '/fake/path', 

43 'current_file_progress': 100} 

44 

45 # mocks 

46 self.mock_object(utils, 'execute', 

47 mock.Mock(return_value=("100", ""))) 

48 

49 # run 

50 self._copy.initialized = True 

51 out = self._copy.get_progress() 

52 

53 # asserts 

54 self.assertEqual(expected, out) 

55 

56 utils.execute.assert_called_once_with("stat", "-c", "%s", "/fake/path", 

57 run_as_root=True) 

58 

59 def test_get_progress_not_initialized(self): 

60 expected = {'total_progress': 0} 

61 

62 # run 

63 self._copy.initialized = False 

64 out = self._copy.get_progress() 

65 

66 # asserts 

67 self.assertEqual(expected, out) 

68 

69 def test_get_progress_completed_empty(self): 

70 expected = {'total_progress': 100} 

71 

72 # run 

73 self._copy.initialized = True 

74 self._copy.completed = True 

75 self._copy.total_size = 0 

76 out = self._copy.get_progress() 

77 

78 # asserts 

79 self.assertEqual(expected, out) 

80 

81 def test_get_progress_current_copy_none(self): 

82 self._copy.current_copy = None 

83 expected = {'total_progress': 0} 

84 

85 # run 

86 self._copy.initialized = True 

87 out = self._copy.get_progress() 

88 

89 # asserts 

90 self.assertEqual(expected, out) 

91 

92 def test_get_progress_exception(self): 

93 expected = {'total_progress': 1, 

94 'current_file_path': '/fake/path', 

95 'current_file_progress': 0} 

96 

97 # mocks 

98 self.mock_object( 

99 utils, 'execute', 

100 mock.Mock(side_effect=utils.processutils.ProcessExecutionError())) 

101 

102 # run 

103 self._copy.initialized = True 

104 out = self._copy.get_progress() 

105 

106 # asserts 

107 self.assertEqual(expected, out) 

108 

109 utils.execute.assert_called_once_with("stat", "-c", "%s", "/fake/path", 

110 run_as_root=True) 

111 

112 def test_cancel(self): 

113 self._copy.cancelled = False 

114 

115 # run 

116 self._copy.cancel() 

117 

118 # asserts 

119 self.assertTrue(self._copy.cancelled) 

120 

121 # reset 

122 self._copy.cancelled = False 

123 

124 def test_get_total_size(self): 

125 self._copy.total_size = 0 

126 

127 values = [("folder1/\nitem/\nfile1\nitem", ""), 

128 ("", ""), 

129 ("10000", "")] 

130 

131 def get_output(*args, **kwargs): 

132 return values.pop(0) 

133 

134 # mocks 

135 self.mock_object(utils, 'execute', mock.Mock( 

136 side_effect=get_output)) 

137 

138 # run 

139 self._copy.get_total_size(self._copy.src) 

140 

141 # asserts 

142 self.assertEqual(10000, self._copy.total_size) 

143 

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 ]) 

153 

154 def test_get_total_size_cancelled_1(self): 

155 self._copy.total_size = 0 

156 self._copy.cancelled = True 

157 

158 # run 

159 self._copy.get_total_size(self._copy.src) 

160 

161 # asserts 

162 self.assertEqual(0, self._copy.total_size) 

163 

164 # reset 

165 self._copy.total_size = 10000 

166 self._copy.cancelled = False 

167 

168 def test_get_total_size_cancelled_2(self): 

169 self._copy.total_size = 0 

170 

171 def ls_output(*args, **kwargs): 

172 self._copy.cancelled = True 

173 return "folder1/", "" 

174 

175 # mocks 

176 self.mock_object(utils, 'execute', mock.Mock( 

177 side_effect=ls_output)) 

178 

179 # run 

180 self._copy.get_total_size(self._copy.src) 

181 

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) 

187 

188 # reset 

189 self._copy.total_size = 10000 

190 self._copy.cancelled = False 

191 

192 def test_copy_data(self): 

193 

194 values = [("folder1/\nitem/\nfile1\nitem", ""), 

195 "", 

196 ("", ""), 

197 ("10000", ""), 

198 "", 

199 ""] 

200 

201 def get_output(*args, **kwargs): 

202 return values.pop(0) 

203 

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') 

212 

213 # run 

214 self._copy.copy_data(self._copy.src) 

215 

216 # asserts 

217 self._copy.get_progress.assert_called_once_with() 

218 

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 ]) 

237 

238 def test__validate_item(self): 

239 

240 self.mock_object(utils, 'execute', mock.Mock( 

241 side_effect=[("abcxyz", ""), ("defrst", "")])) 

242 

243 self.assertRaises(exception.ShareDataCopyFailed, 

244 data_utils._validate_item, 'src', 'dest') 

245 

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 ]) 

250 

251 def test_copy_data_cancelled_1(self): 

252 

253 self._copy.cancelled = True 

254 

255 # run 

256 self._copy.copy_data(self._copy.src) 

257 

258 # reset 

259 self._copy.cancelled = False 

260 

261 def test_copy_data_cancelled_2(self): 

262 

263 def ls_output(*args, **kwargs): 

264 self._copy.cancelled = True 

265 return "folder1/", "" 

266 

267 # mocks 

268 self.mock_object(utils, 'execute', mock.Mock( 

269 side_effect=ls_output)) 

270 

271 # run 

272 self._copy.copy_data(self._copy.src) 

273 

274 # asserts 

275 utils.execute.assert_called_once_with( 

276 "ls", "-pA1", "--group-directories-first", self._copy.src, 

277 run_as_root=True) 

278 

279 # reset 

280 self._copy.cancelled = False 

281 

282 def test_copy_stats(self): 

283 

284 values = [("folder1/\nitem/\nfile1\nitem", ""), 

285 ("", ""), 

286 "", 

287 "", 

288 "", 

289 "", 

290 "", 

291 ""] 

292 

293 def get_output(*args, **kwargs): 

294 return values.pop(0) 

295 

296 # mocks 

297 self.mock_object(utils, 'execute', mock.Mock( 

298 side_effect=get_output)) 

299 

300 # run 

301 self._copy.copy_stats(self._copy.src) 

302 

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 ]) 

326 

327 def test_copy_stats_cancelled_1(self): 

328 

329 self._copy.cancelled = True 

330 

331 # run 

332 self._copy.copy_stats(self._copy.src) 

333 

334 # reset 

335 self._copy.cancelled = False 

336 

337 def test_copy_stats_cancelled_2(self): 

338 

339 def ls_output(*args, **kwargs): 

340 self._copy.cancelled = True 

341 return "folder1/", "" 

342 

343 # mocks 

344 self.mock_object(utils, 'execute', mock.Mock( 

345 side_effect=ls_output)) 

346 

347 # run 

348 self._copy.copy_stats(self._copy.src) 

349 

350 # asserts 

351 utils.execute.assert_called_once_with( 

352 "ls", "-pA1", "--group-directories-first", self._copy.src, 

353 run_as_root=True) 

354 

355 # reset 

356 self._copy.cancelled = False 

357 

358 def test_run(self): 

359 

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') 

365 

366 # run 

367 self._copy.run() 

368 

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()