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
« 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.
16from unittest import mock
18import ddt
20from manila.share.drivers.windows import windows_utils
21from manila import test
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()
31 def test_initialize_disk(self):
32 self._windows_utils.initialize_disk(mock.sentinel.server,
33 mock.sentinel.disk_number)
35 cmd = ["Initialize-Disk", "-Number", mock.sentinel.disk_number]
36 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
38 def test_create_partition(self):
39 self._windows_utils.create_partition(mock.sentinel.server,
40 mock.sentinel.disk_number)
42 cmd = ["New-Partition", "-DiskNumber",
43 mock.sentinel.disk_number, "-UseMaximumSize"]
44 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
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)
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)
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)
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)
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)
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
90 result = self._windows_utils.get_disk_number_by_serial_number(
91 mock.sentinel.server,
92 mock_serial_number)
94 pattern = "%s*" % mock_serial_number
95 cmd = ("Get-Disk | "
96 "Where-Object {$_.SerialNumber -like '%s'} | "
97 "Select-Object -ExpandProperty Number" % pattern)
99 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
100 self.assertEqual(expected_disk_number, result)
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
108 result = self._windows_utils.get_disk_number_by_mount_path(
109 mock.sentinel.server,
110 fake_mount_path)
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)
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
124 result = self._windows_utils.get_volume_path_by_mount_path(
125 mock.sentinel.server,
126 fake_mount_path)
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)
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
145 result = self._windows_utils.get_disk_space_by_path(
146 mock.sentinel.server,
147 mock.sentinel.mount_path)
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)
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)
159 result = self._windows_utils.get_partition_maximum_size(
160 mock.sentinel.server,
161 mock.sentinel.disk_number,
162 mock.sentinel.partition_number)
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)
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)
177 cmd = ["Set-Disk", "-Number", mock.sentinel.disk_number,
178 "-IsOffline", 0]
179 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
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)
186 cmd = ["Set-Disk", "-Number", mock.sentinel.disk_number,
187 "-IsReadOnly", 0]
188 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
190 def test_update_disk(self):
191 self._windows_utils.update_disk(mock.sentinel.server,
192 mock.sentinel.disk_number)
194 cmd = ["Update-Disk", mock.sentinel.disk_number]
195 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
197 def test_join_domain(self):
198 mock_server = {'ip': mock.sentinel.server_ip}
200 self._windows_utils.join_domain(mock_server,
201 mock.sentinel.domain,
202 mock.sentinel.admin_username,
203 mock.sentinel.admin_password)
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)
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)
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)
234 def test_get_current_domain(self):
235 fake_domain = " domain"
236 self._remote_exec.return_value = (fake_domain, mock.sentinel.std_err)
238 result = self._windows_utils.get_current_domain(mock.sentinel.server)
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)
244 def test_ensure_directory_exists(self):
245 self._windows_utils.ensure_directory_exists(mock.sentinel.server,
246 mock.sentinel.path)
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)
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)
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']
272 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
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)
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)
286 result = self._windows_utils.path_exists(mock.sentinel.server,
287 mock.sentinel.path)
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)
293 def test_normalize_path(self):
294 fake_path = "C:/"
295 result = self._windows_utils.normalize_path(fake_path)
297 self.assertEqual("C:\\", result)
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)
303 result = self._windows_utils.get_interface_index_by_ip(
304 mock.sentinel.server,
305 mock.sentinel.ip)
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)
314 def test_set_dns_client_search_list(self):
315 mock_search_list = ["A", "B", "C"]
317 self._windows_utils.set_dns_client_search_list(mock.sentinel.server,
318 mock_search_list)
320 cmd = ["Set-DnsClientGlobalSetting",
321 "-SuffixSearchList", "@('A','B','C')"]
322 self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
324 def test_set_dns_client_server_addresses(self):
325 mock_dns_servers = ["A", "B", "C"]
327 self._windows_utils.set_dns_client_server_addresses(
328 mock.sentinel.server,
329 mock.sentinel.if_index,
330 mock_dns_servers)
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)
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)
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)
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)
353 result = self._windows_utils.get_win_reg_value(mock.sentinel.server,
354 mock.sentinel.path,
355 name=key_name)
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)
366 def test_quote_string(self):
367 result = self._windows_utils.quote_string(mock.sentinel.string)
368 self.assertEqual('"%s"' % mock.sentinel.string, result)