Coverage for manila/tests/share/drivers/windows/test_windows_smb_driver.py: 100%
138 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.
16import os
17from unittest import mock
19import ddt
21from manila.share import configuration
22from manila.share.drivers import generic
23from manila.share.drivers.windows import service_instance
24from manila.share.drivers.windows import windows_smb_driver as windows_drv
25from manila.share.drivers.windows import windows_smb_helper
26from manila.share.drivers.windows import windows_utils
27from manila.share.drivers.windows import winrm_helper
28from manila import test
29from manila.tests import fake_share
32@ddt.ddt
33class WindowsSMBDriverTestCase(test.TestCase):
34 @mock.patch.object(winrm_helper, 'WinRMHelper')
35 @mock.patch.object(windows_utils, 'WindowsUtils')
36 @mock.patch.object(windows_smb_helper, 'WindowsSMBHelper')
37 @mock.patch.object(service_instance,
38 'WindowsServiceInstanceManager')
39 def setUp(self, mock_sv_instance_mgr, mock_smb_helper_cls,
40 mock_utils_cls, mock_winrm_helper_cls):
41 self.flags(driver_handles_share_servers=True)
42 self._fake_conf = configuration.Configuration(None)
44 self._share = fake_share.fake_share(share_proto='SMB')
45 self._share_server = dict(
46 backend_details=mock.sentinel.backend_details)
48 self._drv = windows_drv.WindowsSMBDriver(
49 configuration=self._fake_conf)
50 self._drv._setup_helpers()
52 self._remote_execute = mock_winrm_helper_cls.return_value
53 self._windows_utils = mock_utils_cls.return_value
54 self._smb_helper = mock_smb_helper_cls.return_value
55 super(WindowsSMBDriverTestCase, self).setUp()
57 @mock.patch('manila.share.driver.ShareDriver')
58 def test_update_share_stats(self, mock_base_driver):
59 self._drv._update_share_stats()
60 mock_base_driver._update_share_stats.assert_called_once_with(
61 self._drv,
62 data=dict(storage_protocol="CIFS"))
64 @mock.patch.object(service_instance, 'WindowsServiceInstanceManager')
65 def test_setup_service_instance_manager(self, mock_sv_instance_mgr):
66 self._drv._setup_service_instance_manager()
67 mock_sv_instance_mgr.assert_called_once_with(
68 driver_config=self._fake_conf)
70 def test_setup_helpers(self):
71 expected_helpers = {"SMB": self._smb_helper,
72 "CIFS": self._smb_helper}
73 self._drv._setup_helpers()
74 self.assertEqual(expected_helpers, self._drv._helpers)
76 @mock.patch.object(generic.GenericShareDriver, '_teardown_server')
77 def test_teardown_server(self, mock_super_teardown):
78 mock_server = {'joined_domain': True,
79 'instance_id': mock.sentinel.instance_id}
80 mock_sec_service = {'user': mock.sentinel.user,
81 'password': mock.sentinel.password,
82 'domain': mock.sentinel.domain}
84 sv_mgr = self._drv.service_instance_manager
85 sv_mgr.get_valid_security_service.return_value = mock_sec_service
86 # We ensure that domain unjoin exceptions do not prevent the
87 # service instance from being teared down.
88 self._windows_utils.unjoin_domain.side_effect = Exception
90 self._drv._teardown_server(mock_server,
91 mock_sec_service)
93 sv_mgr.get_valid_security_service.assert_called_once_with(
94 mock_sec_service)
95 self._windows_utils.unjoin_domain.assert_called_once_with(
96 mock_server,
97 mock_sec_service['user'],
98 mock_sec_service['password'])
99 mock_super_teardown.assert_called_once_with(mock_server,
100 mock_sec_service)
102 @mock.patch.object(windows_drv.WindowsSMBDriver, '_get_disk_number')
103 def test_format_device(self, mock_get_disk_number):
104 mock_get_disk_number.return_value = mock.sentinel.disk_number
106 self._drv._format_device(mock.sentinel.server, mock.sentinel.vol)
108 self._drv._get_disk_number.assert_called_once_with(
109 mock.sentinel.server, mock.sentinel.vol)
110 self._windows_utils.initialize_disk.assert_called_once_with(
111 mock.sentinel.server, mock.sentinel.disk_number)
112 self._windows_utils.create_partition.assert_called_once_with(
113 mock.sentinel.server, mock.sentinel.disk_number)
114 self._windows_utils.format_partition.assert_called_once_with(
115 mock.sentinel.server, mock.sentinel.disk_number,
116 self._drv._DEFAULT_SHARE_PARTITION)
118 @mock.patch.object(windows_drv.WindowsSMBDriver,
119 '_ensure_disk_online_and_writable')
120 @mock.patch.object(windows_drv.WindowsSMBDriver, '_get_disk_number')
121 @mock.patch.object(windows_drv.WindowsSMBDriver, '_get_mount_path')
122 @mock.patch.object(windows_drv.WindowsSMBDriver, '_is_device_mounted')
123 def test_mount_device(self, mock_device_mounted, mock_get_mount_path,
124 mock_get_disk_number, mock_ensure_disk):
125 mock_get_mount_path.return_value = mock.sentinel.mount_path
126 mock_get_disk_number.return_value = mock.sentinel.disk_number
127 mock_device_mounted.return_value = False
129 self._drv._mount_device(share=mock.sentinel.share,
130 server_details=mock.sentinel.server,
131 volume=mock.sentinel.vol)
133 mock_device_mounted.assert_called_once_with(
134 mock.sentinel.mount_path, mock.sentinel.server, mock.sentinel.vol)
135 mock_get_disk_number.assert_called_once_with(
136 mock.sentinel.server, mock.sentinel.vol)
137 self._windows_utils.ensure_directory_exists.assert_called_once_with(
138 mock.sentinel.server, mock.sentinel.mount_path)
139 self._windows_utils.add_access_path(
140 mock.sentinel.server,
141 mock.sentinel.mount_path,
142 mock.sentinel.disk_number,
143 self._drv._DEFAULT_SHARE_PARTITION)
144 mock_ensure_disk.assert_called_once_with(
145 mock.sentinel.server, mock.sentinel.disk_number)
147 @mock.patch.object(windows_drv.WindowsSMBDriver, '_get_mount_path')
148 def test_unmount_device(self, mock_get_mount_path):
149 mock_get_mount_path.return_value = mock.sentinel.mount_path
150 mock_get_disk_number_by_path = (
151 self._windows_utils.get_disk_number_by_mount_path)
153 self._drv._unmount_device(mock.sentinel.share,
154 mock.sentinel.server)
156 mock_get_mount_path.assert_called_once_with(mock.sentinel.share)
158 mock_get_disk_number_by_path.assert_called_once_with(
159 mock.sentinel.server, mock.sentinel.mount_path)
160 self._windows_utils.set_disk_online_status.assert_called_once_with(
161 mock.sentinel.server,
162 mock_get_disk_number_by_path.return_value,
163 online=False)
165 @ddt.data(None, 1)
166 @mock.patch.object(windows_drv.WindowsSMBDriver, '_get_disk_number')
167 @mock.patch.object(windows_drv.WindowsSMBDriver,
168 '_ensure_disk_online_and_writable')
169 def test_resize_filesystem(self, new_size, mock_ensure_disk,
170 mock_get_disk_number):
171 mock_get_disk_number.return_value = mock.sentinel.disk_number
172 mock_get_max_size = self._windows_utils.get_partition_maximum_size
173 mock_get_max_size.return_value = mock.sentinel.max_size
175 self._drv._resize_filesystem(mock.sentinel.server,
176 mock.sentinel.vol,
177 new_size=new_size)
179 mock_get_disk_number.assert_called_once_with(mock.sentinel.server,
180 mock.sentinel.vol)
181 self._drv._ensure_disk_online_and_writable.assert_called_once_with(
182 mock.sentinel.server, mock.sentinel.disk_number)
184 if not new_size:
185 mock_get_max_size.assert_called_once_with(
186 mock.sentinel.server,
187 mock.sentinel.disk_number,
188 self._drv._DEFAULT_SHARE_PARTITION)
189 expected_new_size = mock.sentinel.max_size
190 else:
191 expected_new_size = new_size << 30
193 self._windows_utils.resize_partition.assert_called_once_with(
194 mock.sentinel.server,
195 expected_new_size,
196 mock.sentinel.disk_number,
197 self._drv._DEFAULT_SHARE_PARTITION)
199 def test_ensure_disk_online_and_writable(self):
200 self._drv._ensure_disk_online_and_writable(
201 mock.sentinel.server, mock.sentinel.disk_number)
203 self._windows_utils.update_disk.assert_called_once_with(
204 mock.sentinel.server, mock.sentinel.disk_number)
205 self._windows_utils.set_disk_online_status.assert_called_once_with(
206 mock.sentinel.server, mock.sentinel.disk_number, online=True)
207 self._windows_utils.set_disk_readonly_status.assert_called_once_with(
208 mock.sentinel.server, mock.sentinel.disk_number, readonly=False)
210 def test_get_mounted_share_size(self):
211 fake_size_gb = 10
212 self._windows_utils.get_disk_space_by_path.return_value = (
213 fake_size_gb << 30, mock.sentinel.free_bytes)
215 share_size = self._drv._get_mounted_share_size(
216 mock.sentinel.mount_path,
217 mock.sentinel.server)
219 self.assertEqual(fake_size_gb, share_size)
221 def test_get_consumed_space(self):
222 fake_size_gb = 2
223 fake_free_space_gb = 1
224 self._windows_utils.get_disk_space_by_path.return_value = (
225 fake_size_gb << 30, fake_free_space_gb << 30)
227 consumed_space = self._drv._get_consumed_space(
228 mock.sentinel.mount_path,
229 mock.sentinel.server)
231 self.assertEqual(fake_size_gb - fake_free_space_gb, consumed_space)
233 def test_get_mount_path(self):
234 fake_mount_path = 'fake_mount_path'
235 fake_share_name = 'fake_share_name'
236 mock_share = {'name': fake_share_name}
237 self.flags(share_mount_path=fake_mount_path)
239 mount_path = self._drv._get_mount_path(mock_share)
241 self._windows_utils.normalize_path.assert_called_once_with(
242 os.path.join(fake_mount_path, fake_share_name))
243 self.assertEqual(self._windows_utils.normalize_path.return_value,
244 mount_path)
246 @ddt.data(None, 2)
247 def test_get_disk_number(self, disk_number_by_serial=None):
248 mock_get_disk_number_by_serial = (
249 self._windows_utils.get_disk_number_by_serial_number)
251 mock_get_disk_number_by_serial.return_value = disk_number_by_serial
252 mock_volume = {'id': mock.sentinel.vol_id,
253 'mountpoint': "/dev/sdb"}
254 # If the disk number cannot be identified using the disk serial
255 # number, we expect it to be retrieved based on the volume mountpoint,
256 # having disk number 1 in this case.
257 expected_disk_number = (disk_number_by_serial
258 if disk_number_by_serial else 1)
260 disk_number = self._drv._get_disk_number(mock.sentinel.server,
261 mock_volume)
263 mock_get_disk_number_by_serial.assert_called_once_with(
264 mock.sentinel.server, mock.sentinel.vol_id)
265 self.assertEqual(expected_disk_number, disk_number)
267 @ddt.data(None, 2)
268 def test_is_device_mounted(self, disk_number_by_path):
269 mock_get_disk_number_by_path = (
270 self._windows_utils.get_disk_number_by_mount_path)
271 mock_get_disk_number_by_path.return_value = disk_number_by_path
273 expected_result = disk_number_by_path is not None
274 is_mounted = self._drv._is_device_mounted(
275 mount_path=mock.sentinel.mount_path,
276 server_details=mock.sentinel.server)
278 mock_get_disk_number_by_path.assert_called_once_with(
279 mock.sentinel.server,
280 mock.sentinel.mount_path)
281 self.assertEqual(expected_result, is_mounted)