Coverage for manila/tests/share/drivers/windows/test_windows_utils.py: 100%

165 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-02-18 22:19 +0000

1# Copyright (c) 2015 Cloudbase Solutions SRL 

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 

16from unittest import mock 

17 

18import ddt 

19 

20from manila.share.drivers.windows import windows_utils 

21from manila import test 

22 

23 

24@ddt.ddt 

25class WindowsUtilsTestCase(test.TestCase): 

26 def setUp(self): 

27 self._remote_exec = mock.Mock() 

28 self._windows_utils = windows_utils.WindowsUtils(self._remote_exec) 

29 super(WindowsUtilsTestCase, self).setUp() 

30 

31 def test_initialize_disk(self): 

32 self._windows_utils.initialize_disk(mock.sentinel.server, 

33 mock.sentinel.disk_number) 

34 

35 cmd = ["Initialize-Disk", "-Number", mock.sentinel.disk_number] 

36 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

37 

38 def test_create_partition(self): 

39 self._windows_utils.create_partition(mock.sentinel.server, 

40 mock.sentinel.disk_number) 

41 

42 cmd = ["New-Partition", "-DiskNumber", 

43 mock.sentinel.disk_number, "-UseMaximumSize"] 

44 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

45 

46 def test_format_partition(self): 

47 self._windows_utils.format_partition(mock.sentinel.server, 

48 mock.sentinel.disk_number, 

49 mock.sentinel.partition_number) 

50 cmd = ("Get-Partition -DiskNumber %(disk_number)s " 

51 "-PartitionNumber %(partition_number)s | " 

52 "Format-Volume -FileSystem NTFS -Force -Confirm:$false" % { 

53 'disk_number': mock.sentinel.disk_number, 

54 'partition_number': mock.sentinel.partition_number, 

55 }) 

56 self._remote_exec.assert_called_once_with(mock.sentinel.server, 

57 cmd) 

58 

59 def test_add_access_path(self): 

60 self._windows_utils.add_access_path(mock.sentinel.server, 

61 mock.sentinel.mount_path, 

62 mock.sentinel.disk_number, 

63 mock.sentinel.partition_number) 

64 

65 cmd = ["Add-PartitionAccessPath", "-DiskNumber", 

66 mock.sentinel.disk_number, 

67 "-PartitionNumber", mock.sentinel.partition_number, 

68 "-AccessPath", self._windows_utils.quote_string( 

69 mock.sentinel.mount_path) 

70 ] 

71 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

72 

73 def test_resize_partition(self): 

74 self._windows_utils.resize_partition(mock.sentinel.server, 

75 mock.sentinel.size_bytes, 

76 mock.sentinel.disk_number, 

77 mock.sentinel.partition_number) 

78 

79 cmd = ['Resize-Partition', '-DiskNumber', mock.sentinel.disk_number, 

80 '-PartitionNumber', mock.sentinel.partition_number, 

81 '-Size', mock.sentinel.size_bytes] 

82 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

83 

84 @ddt.data("1", "") 

85 def test_get_disk_number_by_serial_number(self, disk_number): 

86 mock_serial_number = "serial_number" 

87 self._remote_exec.return_value = (disk_number, mock.sentinel.std_err) 

88 expected_disk_number = int(disk_number) if disk_number else None 

89 

90 result = self._windows_utils.get_disk_number_by_serial_number( 

91 mock.sentinel.server, 

92 mock_serial_number) 

93 

94 pattern = "%s*" % mock_serial_number 

95 cmd = ("Get-Disk | " 

96 "Where-Object {$_.SerialNumber -like '%s'} | " 

97 "Select-Object -ExpandProperty Number" % pattern) 

98 

99 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

100 self.assertEqual(expected_disk_number, result) 

101 

102 @ddt.data("1", "") 

103 def test_get_disk_number_by_mount_path(self, disk_number): 

104 fake_mount_path = "fake_mount_path" 

105 self._remote_exec.return_value = (disk_number, mock.sentinel.std_err) 

106 expected_disk_number = int(disk_number) if disk_number else None 

107 

108 result = self._windows_utils.get_disk_number_by_mount_path( 

109 mock.sentinel.server, 

110 fake_mount_path) 

111 

112 cmd = ('Get-Partition | ' 

113 'Where-Object {$_.AccessPaths -contains "%s"} | ' 

114 'Select-Object -ExpandProperty DiskNumber' % 

115 (fake_mount_path + "\\")) 

116 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

117 self.assertEqual(expected_disk_number, result) 

118 

119 def test_get_volume_path_by_mount_path(self): 

120 fake_mount_path = "fake_mount_path" 

121 fake_volume_path = "fake_volume_path" 

122 self._remote_exec.return_value = fake_volume_path + '\r\n', None 

123 

124 result = self._windows_utils.get_volume_path_by_mount_path( 

125 mock.sentinel.server, 

126 fake_mount_path) 

127 

128 cmd = ('Get-Partition | ' 

129 'Where-Object {$_.AccessPaths -contains "%s"} | ' 

130 'Get-Volume | ' 

131 'Select-Object -ExpandProperty Path' % 

132 (fake_mount_path + "\\")) 

133 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

134 self.assertEqual(fake_volume_path, result) 

135 

136 def test_get_disk_space_by_path(self): 

137 fake_disk_size = 1024 

138 fake_free_bytes = 1000 

139 fake_fsutil_output = ("Total # of bytes : %(total_bytes)s" 

140 "Total # of avail free bytes : %(free_bytes)s" 

141 % dict(total_bytes=fake_disk_size, 

142 free_bytes=fake_free_bytes)) 

143 self._remote_exec.return_value = fake_fsutil_output, None 

144 

145 result = self._windows_utils.get_disk_space_by_path( 

146 mock.sentinel.server, 

147 mock.sentinel.mount_path) 

148 

149 cmd = ["fsutil", "volume", "diskfree", 

150 self._windows_utils.quote_string(mock.sentinel.mount_path)] 

151 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

152 self.assertEqual((fake_disk_size, fake_free_bytes), result) 

153 

154 def test_get_partition_maximum_size(self): 

155 fake_max_size = 1024 

156 self._remote_exec.return_value = ("%s" % fake_max_size, 

157 mock.sentinel.std_err) 

158 

159 result = self._windows_utils.get_partition_maximum_size( 

160 mock.sentinel.server, 

161 mock.sentinel.disk_number, 

162 mock.sentinel.partition_number) 

163 

164 cmd = ('Get-PartitionSupportedSize -DiskNumber %(disk_number)s ' 

165 '-PartitionNumber %(partition_number)s | ' 

166 'Select-Object -ExpandProperty SizeMax' % 

167 dict(disk_number=mock.sentinel.disk_number, 

168 partition_number=mock.sentinel.partition_number)) 

169 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

170 self.assertEqual(fake_max_size, result) 

171 

172 def test_set_disk_online_status(self): 

173 self._windows_utils.set_disk_online_status(mock.sentinel.server, 

174 mock.sentinel.disk_number, 

175 online=True) 

176 

177 cmd = ["Set-Disk", "-Number", mock.sentinel.disk_number, 

178 "-IsOffline", 0] 

179 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

180 

181 def test_set_disk_readonly_status(self): 

182 self._windows_utils.set_disk_readonly_status(mock.sentinel.server, 

183 mock.sentinel.disk_number, 

184 readonly=False) 

185 

186 cmd = ["Set-Disk", "-Number", mock.sentinel.disk_number, 

187 "-IsReadOnly", 0] 

188 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

189 

190 def test_update_disk(self): 

191 self._windows_utils.update_disk(mock.sentinel.server, 

192 mock.sentinel.disk_number) 

193 

194 cmd = ["Update-Disk", mock.sentinel.disk_number] 

195 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

196 

197 def test_join_domain(self): 

198 mock_server = {'ip': mock.sentinel.server_ip} 

199 

200 self._windows_utils.join_domain(mock_server, 

201 mock.sentinel.domain, 

202 mock.sentinel.admin_username, 

203 mock.sentinel.admin_password) 

204 

205 cmds = [ 

206 ('$password = "%s" | ' 

207 'ConvertTo-SecureString -asPlainText -Force' % 

208 mock.sentinel.admin_password), 

209 ('$credential = ' 

210 'New-Object System.Management.Automation.PSCredential(' 

211 '"%s", $password)' % mock.sentinel.admin_username), 

212 ('Add-Computer -DomainName "%s" -Credential $credential' % 

213 mock.sentinel.domain)] 

214 cmd = ";".join(cmds) 

215 self._remote_exec.assert_called_once_with(mock_server, cmd) 

216 

217 def test_unjoin_domain(self): 

218 self._windows_utils.unjoin_domain(mock.sentinel.server, 

219 mock.sentinel.admin_username, 

220 mock.sentinel.admin_password) 

221 

222 cmds = [ 

223 ('$password = "%s" | ' 

224 'ConvertTo-SecureString -asPlainText -Force' % 

225 mock.sentinel.admin_password), 

226 ('$credential = ' 

227 'New-Object System.Management.Automation.PSCredential(' 

228 '"%s", $password)' % mock.sentinel.admin_username), 

229 ('Remove-Computer -UnjoinDomaincredential $credential ' 

230 '-Passthru -Verbose -Force')] 

231 cmd = ";".join(cmds) 

232 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

233 

234 def test_get_current_domain(self): 

235 fake_domain = " domain" 

236 self._remote_exec.return_value = (fake_domain, mock.sentinel.std_err) 

237 

238 result = self._windows_utils.get_current_domain(mock.sentinel.server) 

239 

240 cmd = "(Get-WmiObject Win32_ComputerSystem).Domain" 

241 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

242 self.assertEqual(fake_domain.strip(), result) 

243 

244 def test_ensure_directory_exists(self): 

245 self._windows_utils.ensure_directory_exists(mock.sentinel.server, 

246 mock.sentinel.path) 

247 

248 cmd = ["New-Item", "-ItemType", "Directory", "-Force", "-Path", 

249 self._windows_utils.quote_string(mock.sentinel.path)] 

250 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

251 

252 @ddt.data(False, True) 

253 @mock.patch.object(windows_utils.WindowsUtils, 'path_exists') 

254 def test_remove(self, is_junction, mock_path_exists): 

255 recurse = True 

256 self._windows_utils.remove(mock.sentinel.server, 

257 mock.sentinel.path, 

258 is_junction=is_junction, 

259 recurse=recurse) 

260 

261 if is_junction: 

262 cmd = ('[System.IO.Directory]::Delete(' 

263 '%(path)s, %(recurse)d)' 

264 % dict(path=self._windows_utils.quote_string( 

265 mock.sentinel.path), 

266 recurse=recurse)) 

267 else: 

268 cmd = ["Remove-Item", "-Confirm:$false", "-Path", 

269 self._windows_utils.quote_string(mock.sentinel.path), 

270 "-Force", '-Recurse'] 

271 

272 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

273 

274 @mock.patch.object(windows_utils.WindowsUtils, 'path_exists') 

275 def test_remove_unexisting_path(self, mock_path_exists): 

276 mock_path_exists.return_value = False 

277 self._windows_utils.remove(mock.sentinel.server, 

278 mock.sentinel.path) 

279 self.assertFalse(self._remote_exec.called) 

280 

281 @ddt.data("True", "False") 

282 def test_path_exists(self, path_exists): 

283 self._remote_exec.return_value = (path_exists, 

284 mock.sentinel.std_err) 

285 

286 result = self._windows_utils.path_exists(mock.sentinel.server, 

287 mock.sentinel.path) 

288 

289 cmd = ["Test-Path", mock.sentinel.path] 

290 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

291 self.assertEqual(path_exists == "True", result) 

292 

293 def test_normalize_path(self): 

294 fake_path = "C:/" 

295 result = self._windows_utils.normalize_path(fake_path) 

296 

297 self.assertEqual("C:\\", result) 

298 

299 def test_get_interface_index_by_ip(self): 

300 _FAKE_INDEX = "2" 

301 self._remote_exec.return_value = (_FAKE_INDEX, mock.sentinel.std_err) 

302 

303 result = self._windows_utils.get_interface_index_by_ip( 

304 mock.sentinel.server, 

305 mock.sentinel.ip) 

306 

307 cmd = ('Get-NetIPAddress | ' 

308 'Where-Object {$_.IPAddress -eq "%(ip)s"} | ' 

309 'Select-Object -ExpandProperty InterfaceIndex' % 

310 dict(ip=mock.sentinel.ip)) 

311 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

312 self.assertEqual(int(_FAKE_INDEX), result) 

313 

314 def test_set_dns_client_search_list(self): 

315 mock_search_list = ["A", "B", "C"] 

316 

317 self._windows_utils.set_dns_client_search_list(mock.sentinel.server, 

318 mock_search_list) 

319 

320 cmd = ["Set-DnsClientGlobalSetting", 

321 "-SuffixSearchList", "@('A','B','C')"] 

322 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

323 

324 def test_set_dns_client_server_addresses(self): 

325 mock_dns_servers = ["A", "B", "C"] 

326 

327 self._windows_utils.set_dns_client_server_addresses( 

328 mock.sentinel.server, 

329 mock.sentinel.if_index, 

330 mock_dns_servers) 

331 

332 cmd = ["Set-DnsClientServerAddress", 

333 "-InterfaceIndex", mock.sentinel.if_index, 

334 "-ServerAddresses", "('A','B','C')"] 

335 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

336 

337 def test_set_win_reg_value(self): 

338 self._windows_utils.set_win_reg_value(mock.sentinel.server, 

339 mock.sentinel.path, 

340 mock.sentinel.key, 

341 mock.sentinel.value) 

342 

343 cmd = ['Set-ItemProperty', '-Path', 

344 self._windows_utils.quote_string(mock.sentinel.path), 

345 '-Name', mock.sentinel.key, '-Value', mock.sentinel.value] 

346 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd) 

347 

348 @ddt.data(None, mock.sentinel.key_name) 

349 def test_get_win_reg_value(self, key_name): 

350 self._remote_exec.return_value = (mock.sentinel.value, 

351 mock.sentinel.std_err) 

352 

353 result = self._windows_utils.get_win_reg_value(mock.sentinel.server, 

354 mock.sentinel.path, 

355 name=key_name) 

356 

357 cmd = "Get-ItemProperty -Path %s" % ( 

358 self._windows_utils.quote_string(mock.sentinel.path)) 

359 if key_name: 

360 cmd += " | Select-Object -ExpandProperty %s" % key_name 

361 self._remote_exec.assert_called_once_with(mock.sentinel.server, 

362 cmd, 

363 retry=False) 

364 self.assertEqual(mock.sentinel.value, result) 

365 

366 def test_quote_string(self): 

367 result = self._windows_utils.quote_string(mock.sentinel.string) 

368 self.assertEqual('"%s"' % mock.sentinel.string, result)