368 lines
16 KiB
Python
368 lines
16 KiB
Python
# Copyright (c) 2015 Cloudbase Solutions SRL
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import ddt
|
|
import mock
|
|
|
|
from manila.share.drivers.windows import windows_utils
|
|
from manila import test
|
|
|
|
|
|
@ddt.ddt
|
|
class WindowsUtilsTestCase(test.TestCase):
|
|
def setUp(self):
|
|
self._remote_exec = mock.Mock()
|
|
self._windows_utils = windows_utils.WindowsUtils(self._remote_exec)
|
|
super(WindowsUtilsTestCase, self).setUp()
|
|
|
|
def test_initialize_disk(self):
|
|
self._windows_utils.initialize_disk(mock.sentinel.server,
|
|
mock.sentinel.disk_number)
|
|
|
|
cmd = ["Initialize-Disk", "-Number", mock.sentinel.disk_number]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_create_partition(self):
|
|
self._windows_utils.create_partition(mock.sentinel.server,
|
|
mock.sentinel.disk_number)
|
|
|
|
cmd = ["New-Partition", "-DiskNumber",
|
|
mock.sentinel.disk_number, "-UseMaximumSize"]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_format_partition(self):
|
|
self._windows_utils.format_partition(mock.sentinel.server,
|
|
mock.sentinel.disk_number,
|
|
mock.sentinel.partition_number)
|
|
cmd = ("Get-Partition -DiskNumber %(disk_number)s "
|
|
"-PartitionNumber %(partition_number)s | "
|
|
"Format-Volume -FileSystem NTFS -Force -Confirm:$false" % {
|
|
'disk_number': mock.sentinel.disk_number,
|
|
'partition_number': mock.sentinel.partition_number,
|
|
})
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server,
|
|
cmd)
|
|
|
|
def test_add_access_path(self):
|
|
self._windows_utils.add_access_path(mock.sentinel.server,
|
|
mock.sentinel.mount_path,
|
|
mock.sentinel.disk_number,
|
|
mock.sentinel.partition_number)
|
|
|
|
cmd = ["Add-PartitionAccessPath", "-DiskNumber",
|
|
mock.sentinel.disk_number,
|
|
"-PartitionNumber", mock.sentinel.partition_number,
|
|
"-AccessPath", self._windows_utils.quote_string(
|
|
mock.sentinel.mount_path)
|
|
]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_resize_partition(self):
|
|
self._windows_utils.resize_partition(mock.sentinel.server,
|
|
mock.sentinel.size_bytes,
|
|
mock.sentinel.disk_number,
|
|
mock.sentinel.partition_number)
|
|
|
|
cmd = ['Resize-Partition', '-DiskNumber', mock.sentinel.disk_number,
|
|
'-PartitionNumber', mock.sentinel.partition_number,
|
|
'-Size', mock.sentinel.size_bytes]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
@ddt.data("1", "")
|
|
def test_get_disk_number_by_serial_number(self, disk_number):
|
|
mock_serial_number = "serial_number"
|
|
self._remote_exec.return_value = (disk_number, mock.sentinel.std_err)
|
|
expected_disk_number = int(disk_number) if disk_number else None
|
|
|
|
result = self._windows_utils.get_disk_number_by_serial_number(
|
|
mock.sentinel.server,
|
|
mock_serial_number)
|
|
|
|
pattern = "%s*" % mock_serial_number
|
|
cmd = ("Get-Disk | "
|
|
"Where-Object {$_.SerialNumber -like '%s'} | "
|
|
"Select-Object -ExpandProperty Number" % pattern)
|
|
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
self.assertEqual(expected_disk_number, result)
|
|
|
|
@ddt.data("1", "")
|
|
def test_get_disk_number_by_mount_path(self, disk_number):
|
|
fake_mount_path = "fake_mount_path"
|
|
self._remote_exec.return_value = (disk_number, mock.sentinel.std_err)
|
|
expected_disk_number = int(disk_number) if disk_number else None
|
|
|
|
result = self._windows_utils.get_disk_number_by_mount_path(
|
|
mock.sentinel.server,
|
|
fake_mount_path)
|
|
|
|
cmd = ('Get-Partition | '
|
|
'Where-Object {$_.AccessPaths -contains "%s"} | '
|
|
'Select-Object -ExpandProperty DiskNumber' %
|
|
(fake_mount_path + "\\"))
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
self.assertEqual(expected_disk_number, result)
|
|
|
|
def test_get_volume_path_by_mount_path(self):
|
|
fake_mount_path = "fake_mount_path"
|
|
fake_volume_path = "fake_volume_path"
|
|
self._remote_exec.return_value = fake_volume_path + '\r\n', None
|
|
|
|
result = self._windows_utils.get_volume_path_by_mount_path(
|
|
mock.sentinel.server,
|
|
fake_mount_path)
|
|
|
|
cmd = ('Get-Partition | '
|
|
'Where-Object {$_.AccessPaths -contains "%s"} | '
|
|
'Get-Volume | '
|
|
'Select-Object -ExpandProperty Path' %
|
|
(fake_mount_path + "\\"))
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
self.assertEqual(fake_volume_path, result)
|
|
|
|
def test_get_disk_space_by_path(self):
|
|
fake_disk_size = 1024
|
|
fake_free_bytes = 1000
|
|
fake_fsutil_output = ("Total # of bytes : %(total_bytes)s"
|
|
"Total # of avail free bytes : %(free_bytes)s"
|
|
% dict(total_bytes=fake_disk_size,
|
|
free_bytes=fake_free_bytes))
|
|
self._remote_exec.return_value = fake_fsutil_output, None
|
|
|
|
result = self._windows_utils.get_disk_space_by_path(
|
|
mock.sentinel.server,
|
|
mock.sentinel.mount_path)
|
|
|
|
cmd = ["fsutil", "volume", "diskfree",
|
|
self._windows_utils.quote_string(mock.sentinel.mount_path)]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
self.assertEqual((fake_disk_size, fake_free_bytes), result)
|
|
|
|
def test_get_partition_maximum_size(self):
|
|
fake_max_size = 1024
|
|
self._remote_exec.return_value = ("%s" % fake_max_size,
|
|
mock.sentinel.std_err)
|
|
|
|
result = self._windows_utils.get_partition_maximum_size(
|
|
mock.sentinel.server,
|
|
mock.sentinel.disk_number,
|
|
mock.sentinel.partition_number)
|
|
|
|
cmd = ('Get-PartitionSupportedSize -DiskNumber %(disk_number)s '
|
|
'-PartitionNumber %(partition_number)s | '
|
|
'Select-Object -ExpandProperty SizeMax' %
|
|
dict(disk_number=mock.sentinel.disk_number,
|
|
partition_number=mock.sentinel.partition_number))
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
self.assertEqual(fake_max_size, result)
|
|
|
|
def test_set_disk_online_status(self):
|
|
self._windows_utils.set_disk_online_status(mock.sentinel.server,
|
|
mock.sentinel.disk_number,
|
|
online=True)
|
|
|
|
cmd = ["Set-Disk", "-Number", mock.sentinel.disk_number,
|
|
"-IsOffline", 0]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_set_disk_readonly_status(self):
|
|
self._windows_utils.set_disk_readonly_status(mock.sentinel.server,
|
|
mock.sentinel.disk_number,
|
|
readonly=False)
|
|
|
|
cmd = ["Set-Disk", "-Number", mock.sentinel.disk_number,
|
|
"-IsReadOnly", 0]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_update_disk(self):
|
|
self._windows_utils.update_disk(mock.sentinel.server,
|
|
mock.sentinel.disk_number)
|
|
|
|
cmd = ["Update-Disk", mock.sentinel.disk_number]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_join_domain(self):
|
|
mock_server = {'ip': mock.sentinel.server_ip}
|
|
|
|
self._windows_utils.join_domain(mock_server,
|
|
mock.sentinel.domain,
|
|
mock.sentinel.admin_username,
|
|
mock.sentinel.admin_password)
|
|
|
|
cmds = [
|
|
('$password = "%s" | '
|
|
'ConvertTo-SecureString -asPlainText -Force' %
|
|
mock.sentinel.admin_password),
|
|
('$credential = '
|
|
'New-Object System.Management.Automation.PSCredential('
|
|
'"%s", $password)' % mock.sentinel.admin_username),
|
|
('Add-Computer -DomainName "%s" -Credential $credential' %
|
|
mock.sentinel.domain)]
|
|
cmd = ";".join(cmds)
|
|
self._remote_exec.assert_called_once_with(mock_server, cmd)
|
|
|
|
def test_unjoin_domain(self):
|
|
self._windows_utils.unjoin_domain(mock.sentinel.server,
|
|
mock.sentinel.admin_username,
|
|
mock.sentinel.admin_password)
|
|
|
|
cmds = [
|
|
('$password = "%s" | '
|
|
'ConvertTo-SecureString -asPlainText -Force' %
|
|
mock.sentinel.admin_password),
|
|
('$credential = '
|
|
'New-Object System.Management.Automation.PSCredential('
|
|
'"%s", $password)' % mock.sentinel.admin_username),
|
|
('Remove-Computer -UnjoinDomaincredential $credential '
|
|
'-Passthru -Verbose -Force')]
|
|
cmd = ";".join(cmds)
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_get_current_domain(self):
|
|
fake_domain = " domain"
|
|
self._remote_exec.return_value = (fake_domain, mock.sentinel.std_err)
|
|
|
|
result = self._windows_utils.get_current_domain(mock.sentinel.server)
|
|
|
|
cmd = "(Get-WmiObject Win32_ComputerSystem).Domain"
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
self.assertEqual(fake_domain.strip(), result)
|
|
|
|
def test_ensure_directory_exists(self):
|
|
self._windows_utils.ensure_directory_exists(mock.sentinel.server,
|
|
mock.sentinel.path)
|
|
|
|
cmd = ["New-Item", "-ItemType", "Directory", "-Force", "-Path",
|
|
self._windows_utils.quote_string(mock.sentinel.path)]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
@ddt.data(False, True)
|
|
@mock.patch.object(windows_utils.WindowsUtils, 'path_exists')
|
|
def test_remove(self, is_junction, mock_path_exists):
|
|
recurse = True
|
|
self._windows_utils.remove(mock.sentinel.server,
|
|
mock.sentinel.path,
|
|
is_junction=is_junction,
|
|
recurse=recurse)
|
|
|
|
if is_junction:
|
|
cmd = ('[System.IO.Directory]::Delete('
|
|
'%(path)s, %(recurse)d)'
|
|
% dict(path=self._windows_utils.quote_string(
|
|
mock.sentinel.path),
|
|
recurse=recurse))
|
|
else:
|
|
cmd = ["Remove-Item", "-Confirm:$false", "-Path",
|
|
self._windows_utils.quote_string(mock.sentinel.path),
|
|
"-Force", '-Recurse']
|
|
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
@mock.patch.object(windows_utils.WindowsUtils, 'path_exists')
|
|
def test_remove_unexisting_path(self, mock_path_exists):
|
|
mock_path_exists.return_value = False
|
|
self._windows_utils.remove(mock.sentinel.server,
|
|
mock.sentinel.path)
|
|
self.assertFalse(self._remote_exec.called)
|
|
|
|
@ddt.data("True", "False")
|
|
def test_path_exists(self, path_exists):
|
|
self._remote_exec.return_value = (path_exists,
|
|
mock.sentinel.std_err)
|
|
|
|
result = self._windows_utils.path_exists(mock.sentinel.server,
|
|
mock.sentinel.path)
|
|
|
|
cmd = ["Test-Path", mock.sentinel.path]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
self.assertEqual(path_exists == "True", result)
|
|
|
|
def test_normalize_path(self):
|
|
fake_path = "C:/"
|
|
result = self._windows_utils.normalize_path(fake_path)
|
|
|
|
self.assertEqual("C:\\", result)
|
|
|
|
def test_get_interface_index_by_ip(self):
|
|
_FAKE_INDEX = "2"
|
|
self._remote_exec.return_value = (_FAKE_INDEX, mock.sentinel.std_err)
|
|
|
|
result = self._windows_utils.get_interface_index_by_ip(
|
|
mock.sentinel.server,
|
|
mock.sentinel.ip)
|
|
|
|
cmd = ('Get-NetIPAddress | '
|
|
'Where-Object {$_.IPAddress -eq "%(ip)s"} | '
|
|
'Select-Object -ExpandProperty InterfaceIndex' %
|
|
dict(ip=mock.sentinel.ip))
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
self.assertEqual(int(_FAKE_INDEX), result)
|
|
|
|
def test_set_dns_client_search_list(self):
|
|
mock_search_list = ["A", "B", "C"]
|
|
|
|
self._windows_utils.set_dns_client_search_list(mock.sentinel.server,
|
|
mock_search_list)
|
|
|
|
cmd = ["Set-DnsClientGlobalSetting",
|
|
"-SuffixSearchList", "@('A','B','C')"]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_set_dns_client_server_addresses(self):
|
|
mock_dns_servers = ["A", "B", "C"]
|
|
|
|
self._windows_utils.set_dns_client_server_addresses(
|
|
mock.sentinel.server,
|
|
mock.sentinel.if_index,
|
|
mock_dns_servers)
|
|
|
|
cmd = ["Set-DnsClientServerAddress",
|
|
"-InterfaceIndex", mock.sentinel.if_index,
|
|
"-ServerAddresses", "('A','B','C')"]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
def test_set_win_reg_value(self):
|
|
self._windows_utils.set_win_reg_value(mock.sentinel.server,
|
|
mock.sentinel.path,
|
|
mock.sentinel.key,
|
|
mock.sentinel.value)
|
|
|
|
cmd = ['Set-ItemProperty', '-Path',
|
|
self._windows_utils.quote_string(mock.sentinel.path),
|
|
'-Name', mock.sentinel.key, '-Value', mock.sentinel.value]
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server, cmd)
|
|
|
|
@ddt.data(None, mock.sentinel.key_name)
|
|
def test_get_win_reg_value(self, key_name):
|
|
self._remote_exec.return_value = (mock.sentinel.value,
|
|
mock.sentinel.std_err)
|
|
|
|
result = self._windows_utils.get_win_reg_value(mock.sentinel.server,
|
|
mock.sentinel.path,
|
|
name=key_name)
|
|
|
|
cmd = "Get-ItemProperty -Path %s" % (
|
|
self._windows_utils.quote_string(mock.sentinel.path))
|
|
if key_name:
|
|
cmd += " | Select-Object -ExpandProperty %s" % key_name
|
|
self._remote_exec.assert_called_once_with(mock.sentinel.server,
|
|
cmd,
|
|
retry=False)
|
|
self.assertEqual(mock.sentinel.value, result)
|
|
|
|
def test_quote_string(self):
|
|
result = self._windows_utils.quote_string(mock.sentinel.string)
|
|
self.assertEqual('"%s"' % mock.sentinel.string, result)
|