Merge pull request #36 from trobert2/all_tested_with_mock

Added unit tests using mock
This commit is contained in:
Alessandro Pilotti 2014-01-19 15:01:38 -08:00
commit 4dcd0f1d4a
33 changed files with 4025 additions and 0 deletions

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,57 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.
def get_fake_metadata_json(version):
if version == '2013-04-04':
return {"random_seed":
"Wn51FGjZa3vlZtTxJuPr96oCf+X8jqbA9U2XR5wNdnApy1fz"
"/2NNssUwPoNzG6etw9RBn+XiZ0zKWnFzMsTopaN7WwYjWTnIsVw3cpIk"
"Td579wQgoEr1ANqhfO3qTvkOVNMhzTAw1ps+wqRmkLxH+1qYJnX06Gcd"
"KRRGkWTaOSlTkieA0LO2oTGFlbFDWcOW2vT5BvSBmqP7vNLzbLDMTc7M"
"IWRBzwmtcVPC17QL6EhZJTUcZ0mTz7l0R0DocLmFwHEXFEEr+q4WaJjt"
"1ejOOxVM3tiT7D8YpRZnnGNPfvEhq1yVMUoi8yv9pFmMmXicNBhm6zDK"
"VjcWk0gfbvaQcMnnOLrrE1VxAAzyNyPIXBI/H7AAHz2ECz7dgd2/4ocv"
"3bmTRY3hhcUKtNuat2IOvSGgMBUGdWnLorQGFz8t0/bcYhE0Dve35U6H"
"mtj78ydV/wmQWG0iq49NX6hk+VUmZtSZztlkbsaa7ajNjZ+Md9oZtlhX"
"Z5vJuhRXnHiCm7dRNO8Xo6HffEBH5A4smQ1T2Kda+1c18DZrY7+iQJRi"
"fa6witPCw0tXkQ6nlCLqL2weJD1XMiTZLSM/XsZFGGSkKCKvKLEqQrI/"
"XFUq/TA6B4aLGFlmmhOO/vMJcht06O8qVU/xtd5Mv/MRFzYaSG568Z/m"
"hk4vYLYdQYAA+pXRW9A=",
"uuid": "4b32ddf7-7941-4c36-a854-a1f5ac45b318",
"availability_zone": "nova",
"hostname": "windows.novalocal",
"launch_index": 0,
"public_keys": {"key": "ssh-rsa "
"AAAAB3NzaC1yc2EAAAADAQABAAABA"
"QDf7kQHq7zvBod3yIZs0tB/AOOZz5pab7qt/h"
"78VF7yi6qTsFdUnQxRue43R/75wa9EEyokgYR"
"LKIN+Jq2A5tXNMcK+rNOCzLJFtioAwEl+S6VL"
"G9jfkbUv++7zoSMOsanNmEDvG0B79MpyECFCl"
"th2DsdE4MQypify35U5ri5Qi7E6PEYAsU65LF"
"MG2boeCIB29BEooE6AgPr2DuJeJ+2uw+YScF9"
"FV3og4Wyz5zipPVh8YpVev6dlg0tRWUrCtZF9"
"IODpCTrT3vsPRG3xz7CppR+vGi/1gLXHtJCRj"
"frHwkY6cXyhypNmkU99K/wMqSv30vsDwdnsQ1"
"q3YhLarMHB Generated by Nova\n",
"name": "windows"},
"network_config": {"content_path": "network",
'debian_config': 'iface eth0 inet static'
'address 10.11.12.13'
'broadcast 0.0.0.0'
'netmask 255.255.255.255'
'gateway 1.2.3.4'
'dns-nameserver 8.8.8.8'}}

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,84 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 importlib
import mock
import os
import sys
import unittest
import uuid
from cloudbaseinit.openstack.common import cfg
CONF = cfg.CONF
_win32com_mock = mock.MagicMock()
_ctypes_mock = mock.MagicMock()
_ctypes_util_mock = mock.MagicMock()
_win32com_client_mock = mock.MagicMock()
_pywintypes_mock = mock.MagicMock()
_mock_dict = {'win32com': _win32com_mock,
'ctypes': _ctypes_mock,
'ctypes.util': _ctypes_util_mock,
'win32com.client': _win32com_client_mock,
'pywintypes': _pywintypes_mock}
class ConfigDriveServiceTest(unittest.TestCase):
@mock.patch.dict(sys.modules, _mock_dict)
def setUp(self):
configdrive = importlib.import_module('cloudbaseinit.metadata.services'
'.configdrive.configdrive')
self._config_drive = configdrive.ConfigDriveService()
def tearDown(self):
reload(sys)
@mock.patch('cloudbaseinit.metadata.services.configdrive.manager.'
'ConfigDriveManager.get_config_drive_files')
@mock.patch('tempfile.gettempdir')
@mock.patch('os.path.join')
def test_load(self, mock_join, mock_gettempdir,
mock_get_config_drive_files):
uuid.uuid4 = mock.MagicMock()
fake_path = os.path.join('fake', 'path')
fake_path_found = os.path.join(fake_path, 'found')
uuid.uuid4.return_value = 'random'
mock_get_config_drive_files.return_value = fake_path_found
mock_join.return_value = fake_path
response = self._config_drive.load()
mock_join.assert_called_with(mock_gettempdir(), 'random')
mock_get_config_drive_files.assert_called_once_with(
fake_path, CONF.config_drive_raw_hhd, CONF.config_drive_cdrom)
self.assertEqual(self._config_drive._metadata_path, fake_path)
self.assertEqual(response, fake_path_found)
@mock.patch('os.path.normpath')
@mock.patch('os.path.join')
def test_get_data(self, mock_join, mock_normpath):
fake_path = os.path.join('fake', 'path')
with mock.patch('__builtin__.open',
mock.mock_open(read_data='fake data'), create=True):
response = self._config_drive._get_data(fake_path)
self.assertEqual(response, 'fake data')
mock_join.assert_called_with(
self._config_drive._metadata_path, fake_path)
@mock.patch('shutil.rmtree')
def test_cleanup(self, mock_rmtree):
fake_path = os.path.join('fake', 'path')
self._config_drive._metadata_path = fake_path
self._config_drive.cleanup()
self.assertEqual(self._config_drive._metadata_path, None)

View File

@ -0,0 +1,144 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import os
import unittest
from cloudbaseinit.metadata.services import ec2service
from cloudbaseinit.openstack.common import cfg
CONF = cfg.CONF
class Ec2ServiceTest(unittest.TestCase):
def setUp(self):
self._ec2service = ec2service.EC2Service()
@mock.patch('cloudbaseinit.metadata.services.ec2service.EC2Service'
'.get_meta_data')
def _test_load(self, mock_get_meta_data, side_effect):
mock_get_meta_data.side_effect = [side_effect]
response = self._ec2service.load()
mock_get_meta_data.assert_called_once_with('openstack')
if side_effect is Exception:
self.assertFalse(response)
else:
self.assertTrue(response)
def test_load_exception(self):
self._test_load(side_effect=Exception)
def test_load(self):
self._test_load(side_effect='fake data')
@mock.patch('posixpath.join')
@mock.patch('urllib2.Request')
@mock.patch('urllib2.urlopen')
@mock.patch('cloudbaseinit.metadata.services.ec2service.EC2Service'
'._load_public_keys')
@mock.patch('cloudbaseinit.metadata.services.ec2service.EC2Service'
'._check_EC2')
@mock.patch('cloudbaseinit.metadata.services.ec2service.EC2Service'
'._get_EC2_value')
def _test_get_data(self, mock_get_EC2_value, mock_check_EC2,
mock_load_public_keys, mock_urlopen,
mock_Request, mock_join, check_ec2, data_type):
mock_path = mock.MagicMock()
mock_req = mock.MagicMock()
mock_response = mock.MagicMock()
fake_path = os.path.join('fake', 'path')
mock_join.return_value = fake_path
mock_check_EC2.return_value = check_ec2
mock_Request.return_value = mock_req
mock_urlopen.return_value = mock_response
mock_response.read.return_value = 'fake data'
mock_path.endswith.return_value = data_type
if check_ec2 is None:
self.assertRaises(Exception, self._ec2service._get_data,
mock_path)
elif data_type is 'meta_data.json':
response = self._ec2service._get_data(mock_path)
print response
for key in ec2service.ec2nodes:
mock_get_EC2_value.assert_called_with(key)
mock_load_public_keys.assert_called_with()
elif data_type is 'user_data':
response = self._ec2service._get_data(mock_path)
mock_join.assert_called_with(CONF.ec2_metadata_base_url,
'user-data')
mock_Request.assert_called_once_with(fake_path)
mock_urlopen.assert_called_once_with(mock_req)
mock_response.read.assert_called_once_with()
self.assertEqual(response, 'fake data')
def test_get_data_metadata_json(self):
self._test_get_data(check_ec2=True, data_type='meta_data.json')
def test_get_data_user_data(self):
self._test_get_data(check_ec2=True, data_type='user_data')
def test_get_data_no_EC2(self):
self._test_get_data(check_ec2=None, data_type=None)
@mock.patch('cloudbaseinit.metadata.services.ec2service.EC2Service'
'._get_EC2_value')
def _test_check_EC2(self, mock_get_EC2_value, side_effect):
mock_get_EC2_value.side_effect = [side_effect]
response = self._ec2service._check_EC2()
if side_effect is Exception:
self.assertFalse(response)
else:
self.assertTrue(response)
def test_check_EC2_Exception(self):
self._test_check_EC2(side_effect=Exception)
def test_check_EC2(self):
self._test_check_EC2(side_effect='fake value')
@mock.patch('posixpath.join')
@mock.patch('urllib2.Request')
@mock.patch('urllib2.urlopen')
def test_get_EC2_value(self, mock_urlopen, mock_Request, mock_join):
mock_key = mock.MagicMock()
mock_response = mock.MagicMock()
fake_path = os.path.join('fake', 'path')
mock_join.return_value = fake_path
mock_Request.return_value = 'fake req'
mock_urlopen.return_value = mock_response
mock_response.read.return_value = 'fake data'
response = self._ec2service._get_EC2_value(mock_key)
mock_join.assert_called_with(CONF.ec2_metadata_base_url,
'meta-data', mock_key)
mock_Request.assert_called_once_with(fake_path)
mock_urlopen.assert_called_once_with('fake req')
mock_response.read.assert_called_once_with()
self.assertEqual(response, 'fake data')
@mock.patch('cloudbaseinit.metadata.services.ec2service.EC2Service'
'._get_EC2_value')
def test_load_public_keys(self, mock_get_EC2_value):
data = {}
key_list = mock.MagicMock()
mock_get_EC2_value.return_value = key_list
self._ec2service._load_public_keys(data)
mock_get_EC2_value.assert_called_with('public-keys/')
self.assertEqual(data['public_keys'], {})

View File

@ -0,0 +1,156 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import os
import unittest
import urllib2
from cloudbaseinit.metadata.services import base
from cloudbaseinit.metadata.services import httpservice
from cloudbaseinit.openstack.common import cfg
CONF = cfg.CONF
class HttpServiceTest(unittest.TestCase):
def setUp(self):
CONF.set_override('retry_count_interval', 0)
self._httpservice = httpservice.HttpService()
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
@mock.patch('urlparse.urlparse')
def _test_check_metadata_ip_route(self, mock_urlparse, mock_get_os_utils,
side_effect):
mock_utils = mock.MagicMock()
mock_split = mock.MagicMock()
mock_get_os_utils.return_value = mock_utils
mock_utils.check_os_version.return_value = True
mock_urlparse().netloc.split.return_value = mock_split
mock_split[0].startswith.return_value = True
mock_utils.check_static_route_exists.return_value = False
mock_utils.get_default_gateway.return_value = (1, '0.0.0.0')
mock_utils.add_static_route.side_effect = [side_effect]
self._httpservice._check_metadata_ip_route()
mock_utils.check_os_version.assert_called_once_with(6, 0)
mock_urlparse.assert_called_with(CONF.metadata_base_url)
mock_split[0].startswith.assert_called_once_with("169.254.")
mock_utils.check_static_route_exists.assert_called_once_with(
mock_split[0])
mock_utils.get_default_gateway.assert_called_once_with()
mock_utils.add_static_route.assert_called_once_with(
mock_split[0], "255.255.255.255", '0.0.0.0', 1, 10)
def test_test_check_metadata_ip_route(self):
self._test_check_metadata_ip_route(side_effect=None)
def test_test_check_metadata_ip_route_fail(self):
self._test_check_metadata_ip_route(side_effect=Exception)
@mock.patch('cloudbaseinit.metadata.services.httpservice.HttpService'
'._check_metadata_ip_route')
@mock.patch('cloudbaseinit.metadata.services.httpservice.HttpService'
'.get_meta_data')
def _test_load(self, mock_get_meta_data, mock_check_metadata_ip_route,
side_effect):
mock_get_meta_data.side_effect = [side_effect]
response = self._httpservice.load()
mock_check_metadata_ip_route.assert_called_once_with()
mock_get_meta_data.assert_called_once_with('openstack')
if side_effect:
self.assertEqual(response, False)
else:
self.assertEqual(response, True)
def test_load(self):
self._test_load(side_effect=None)
def test_load_exception(self):
self._test_load(side_effect=Exception)
@mock.patch('urllib2.urlopen')
def _test_get_response(self, mock_urlopen, side_effect):
mock_req = mock.MagicMock
if side_effect and side_effect.code is 404:
mock_urlopen.side_effect = [side_effect]
self.assertRaises(base.NotExistingMetadataException,
self._httpservice._get_response,
mock_req)
elif side_effect and side_effect.code:
mock_urlopen.side_effect = [side_effect]
self.assertRaises(Exception, self._httpservice._get_response,
mock_req)
else:
mock_urlopen.return_value = 'fake url'
response = self._httpservice._get_response(mock_req)
self.assertEqual(response, 'fake url')
def test_get_response_fail_HTTPError(self):
error = urllib2.HTTPError("http://169.254.169.254/", 404,
'test error 404', {}, None)
self._test_get_response(side_effect=error)
def test_get_response_fail_other_exception(self):
error = urllib2.HTTPError("http://169.254.169.254/", 409,
'test error 409', {}, None)
self._test_get_response(side_effect=error)
def test_get_response(self):
self._test_get_response(side_effect=None)
@mock.patch('cloudbaseinit.metadata.services.httpservice.HttpService'
'._get_response')
@mock.patch('posixpath.join')
@mock.patch('urllib2.Request')
def test_get_data(self, mock_Request, mock_posix_join,
mock_get_response):
fake_path = os.path.join('fake', 'path')
mock_data = mock.MagicMock()
mock_norm_path = mock.MagicMock()
mock_req = mock.MagicMock()
mock_get_response.return_value = mock_data
mock_posix_join.return_value = mock_norm_path
mock_Request.return_value = mock_req
response = self._httpservice._get_data(fake_path)
mock_posix_join.assert_called_with(CONF.metadata_base_url, fake_path)
mock_Request.assert_called_once_with(mock_norm_path)
mock_get_response.assert_called_once_with(mock_req)
self.assertEqual(response, mock_data.read())
@mock.patch('cloudbaseinit.metadata.services.httpservice.HttpService'
'._get_response')
@mock.patch('posixpath.join')
@mock.patch('urllib2.Request')
def test_post_data(self, mock_Request, mock_posix_join,
mock_get_response):
fake_path = os.path.join('fake', 'path')
fake_data = 'fake data'
mock_data = mock.MagicMock()
mock_norm_path = mock.MagicMock()
mock_req = mock.MagicMock()
mock_get_response.return_value = mock_data
mock_posix_join.return_value = mock_norm_path
mock_Request.return_value = mock_req
response = self._httpservice._post_data(fake_path, fake_data)
mock_posix_join.assert_called_with(CONF.metadata_base_url,
fake_path)
mock_Request.assert_called_once_with(mock_norm_path, data=fake_data)
mock_get_response.assert_called_once_with(mock_req)
self.assertEqual(response, True)

View File

@ -0,0 +1,41 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import unittest
from cloudbaseinit.metadata import factory
class MetadataServiceFactoryTests(unittest.TestCase):
def setUp(self):
self._factory = factory.MetadataServiceFactory()
@mock.patch('cloudbaseinit.utils.classloader.ClassLoader.load_class')
def _test_get_metadata_service(self, mock_load_class, ret_value):
mock_load_class.side_effect = ret_value
if ret_value is Exception:
self.assertRaises(Exception, self._factory.get_metadata_service)
else:
response = self._factory.get_metadata_service()
self.assertEqual(response, mock_load_class()())
def test_get_metadata_service(self):
m = mock.MagicMock()
self._test_get_metadata_service(ret_value=m)
def test_get_metadata_service_exception(self):
self._test_get_metadata_service(ret_value=Exception)

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,43 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import os
import unittest
from cloudbaseinit.osutils import factory
class OSUtilsFactory(unittest.TestCase):
def setUp(self):
self._factory = factory.OSUtilsFactory()
@mock.patch('cloudbaseinit.utils.classloader.ClassLoader.load_class')
def _test_get_os_utils(self, mock_load_class, fake_name):
os.name = fake_name
self._factory.get_os_utils()
if fake_name == 'nt':
mock_load_class.assert_called_with(
'cloudbaseinit.osutils.windows.WindowsUtils')
elif fake_name == 'posix':
mock_load_class.assert_called_with(
'cloudbaseinit.osutils.posix.PosixUtils')
def test_get_os_utils_windows(self):
self._test_get_os_utils(fake_name='nt')
def test_get_os_utils_posix(self):
self._test_get_os_utils(fake_name='posix')

View File

@ -0,0 +1,975 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 ctypes
import mock
import time
import sys
import unittest
if sys.platform == 'win32':
import _winreg
import win32process
import win32security
import wmi
from ctypes import windll
from ctypes import wintypes
from cloudbaseinit.osutils import windows as windows_utils
from cloudbaseinit.openstack.common import cfg
CONF = cfg.CONF
@unittest.skipUnless(sys.platform == "win32", "requires Windows")
class WindowsUtilsTest(unittest.TestCase):
'''Tests for the windows utils class'''
_CONFIG_NAME = 'FakeConfig'
_DESTINATION = '192.168.192.168'
_GATEWAY = '10.7.1.1'
_NETMASK = '255.255.255.0'
_PASSWORD = 'Passw0rd'
_SECTION = 'fake_section'
_USERNAME = 'Admin'
def setUp(self):
self._winutils = windows_utils.WindowsUtils()
self._conn = mock.MagicMock()
def test_enable_shutdown_privilege(self):
fake_process = mock.MagicMock()
fake_token = True
private_LUID = 'fakeid'
win32process.GetCurrentProcess = mock.MagicMock(
return_value=fake_process)
win32security.OpenProcessToken = mock.MagicMock(
return_value=fake_token)
win32security.LookupPrivilegeValue = mock.MagicMock(
return_value=private_LUID)
win32security.AdjustTokenPrivileges = mock.MagicMock()
self._winutils._enable_shutdown_privilege()
privilege = [(private_LUID, win32security.SE_PRIVILEGE_ENABLED)]
win32security.AdjustTokenPrivileges.assert_called_with(
fake_token,
False,
privilege)
win32security.OpenProcessToken.assert_called_with(
fake_process,
win32security.TOKEN_ADJUST_PRIVILEGES |
win32security.TOKEN_QUERY)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._enable_shutdown_privilege')
def _test_reboot(self, mock_enable_shutdown_privilege, ret_value):
windll.advapi32.InitiateSystemShutdownW = mock.MagicMock(
return_value=ret_value)
if not ret_value:
self.assertRaises(Exception, self._winutils.reboot)
else:
self._winutils.reboot()
windll.advapi32.InitiateSystemShutdownW.assert_called_with(
0,
"Cloudbase-Init reboot",
0, True, True)
def test_reboot(self):
self._test_reboot(ret_value=True)
def test_reboot_failed(self):
self._test_reboot(ret_value=None)
@mock.patch('wmi.WMI')
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._sanitize_wmi_input')
def _test_get_user_wmi_object(self, mock_sanitize_wmi_input, mock_WMI,
returnvalue):
mock_WMI.return_value = self._conn
mock_sanitize_wmi_input.return_value = self._USERNAME
self._conn.query.return_value = returnvalue
response = self._winutils._get_user_wmi_object(self._USERNAME)
self._conn.query.assert_called_with("SELECT * FROM Win32_Account "
"where name = \'%s\'" %
self._USERNAME)
mock_sanitize_wmi_input.assert_called_with(self._USERNAME)
mock_WMI.assert_called_with(moniker='//./root/cimv2')
if returnvalue:
self.assertTrue(response is not None)
else:
self.assertTrue(response is None)
def test_get_user_wmi_object(self):
caption = 'fake'
self._test_get_user_wmi_object(returnvalue=caption)
def test_no_user_wmi_object(self):
empty_caption = ''
self._test_get_user_wmi_object(returnvalue=empty_caption)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_user_wmi_object')
def _test_user_exists(self, mock_get_user_wmi_object, returnvalue):
mock_get_user_wmi_object.return_value = returnvalue
response = self._winutils.user_exists(returnvalue)
mock_get_user_wmi_object.assert_called_with(returnvalue)
if returnvalue:
self.assertTrue(response)
else:
self.assertFalse(response)
def test_user_exists(self):
self._test_user_exists(returnvalue=self._USERNAME)
def test_username_does_not_exist(self):
self._test_user_exists(returnvalue=None)
def test_sanitize_wmi_input(self):
unsanitised = ' \' '
response = self._winutils._sanitize_wmi_input(unsanitised)
sanitised = ' \'\' '
self.assertEqual(response, sanitised)
def test_sanitize_shell_input(self):
unsanitised = ' " '
response = self._winutils.sanitize_shell_input(unsanitised)
sanitised = ' \\" '
self.assertEqual(response, sanitised)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._set_user_password_expiration')
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'.execute_process')
def _test_create_or_change_user(self, mock_execute_process,
mock_set_user_password_expiration,
create, password_expires, ret_value=0):
args = ['NET', 'USER', self._USERNAME, self._PASSWORD]
if create:
args.append('/ADD')
mock_execute_process.return_value = (None, None, ret_value)
if not ret_value:
self._winutils._create_or_change_user(self._USERNAME,
self._PASSWORD, create,
password_expires)
mock_set_user_password_expiration.assert_called_with(
self._USERNAME, password_expires)
else:
self.assertRaises(
Exception, self._winutils._create_or_change_user,
self._USERNAME, self._PASSWORD, create, password_expires)
mock_execute_process.assert_called_with(args)
def test_create_user_and_add_password_expire_true(self):
self._test_create_or_change_user(create=True, password_expires=True)
def test_create_user_and_add_password_expire_false(self):
self._test_create_or_change_user(create=True, password_expires=False)
def test_add_password_expire_true(self):
self._test_create_or_change_user(create=False, password_expires=True)
def test_add_password_expire_false(self):
self._test_create_or_change_user(create=False, password_expires=False)
def test_create_user_and_add_password_expire_true_with_ret_value(self):
self._test_create_or_change_user(create=True, password_expires=True,
ret_value=1)
def test_create_user_and_add_password_expire_false_with_ret_value(self):
self._test_create_or_change_user(create=True,
password_expires=False, ret_value=1)
def test_add_password_expire_true_with_ret_value(self):
self._test_create_or_change_user(create=False,
password_expires=True, ret_value=1)
def test_add_password_expire_false_with_ret_value(self):
self._test_create_or_change_user(create=False,
password_expires=False, ret_value=1)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_user_wmi_object')
def _test_set_user_password_expiration(self, mock_get_user_wmi_object,
fake_obj):
mock_get_user_wmi_object.return_value = fake_obj
response = self._winutils._set_user_password_expiration(
self._USERNAME, True)
if fake_obj:
self.assertTrue(fake_obj.PasswordExpires)
self.assertTrue(response)
else:
self.assertFalse(response)
def test_set_password_expiration(self):
fake = mock.Mock()
self._test_set_user_password_expiration(fake_obj=fake)
def test_set_password_expiration_no_object(self):
self._test_set_user_password_expiration(fake_obj=None)
def _test_get_user_sid_and_domain(self, ret_val):
cbSid = mock.Mock()
sid = mock.Mock()
size = 1024
cchReferencedDomainName = mock.Mock()
domainName = mock.Mock()
sidNameUse = mock.Mock()
ctypes.create_string_buffer = mock.MagicMock(return_value=sid)
ctypes.sizeof = mock.MagicMock(return_value=size)
wintypes.DWORD = mock.MagicMock(return_value=cchReferencedDomainName)
ctypes.create_unicode_buffer = mock.MagicMock(return_value=domainName)
ctypes.byref = mock.MagicMock()
windll.advapi32.LookupAccountNameW = mock.MagicMock(
return_value=ret_val)
if ret_val is None:
self.assertRaises(
Exception, self._winutils._get_user_sid_and_domain,
self._USERNAME)
else:
response = self._winutils._get_user_sid_and_domain(self._USERNAME)
windll.advapi32.LookupAccountNameW.assert_called_with(
0, unicode(self._USERNAME), sid, ctypes.byref(cbSid),
domainName, ctypes.byref(cchReferencedDomainName),
ctypes.byref(sidNameUse))
self.assertEqual(response, (sid, domainName.value))
def test_get_user_sid_and_domain(self):
fake_obj = mock.Mock()
self._test_get_user_sid_and_domain(ret_val=fake_obj)
def test_get_user_sid_and_domain_no_return_value(self):
self._test_get_user_sid_and_domain(ret_val=None)
def _test_add_user_to_local_group(self, ret_value):
windows_utils.Win32_LOCALGROUP_MEMBERS_INFO_3 = mock.MagicMock()
lmi = windows_utils.Win32_LOCALGROUP_MEMBERS_INFO_3()
group_name = 'Admins'
windll.netapi32.NetLocalGroupAddMembers = mock.MagicMock(
return_value=ret_value)
if ret_value is not 0:
self.assertRaises(
Exception, self._winutils.add_user_to_local_group,
self._USERNAME, group_name)
else:
ctypes.addressof = mock.MagicMock()
self._winutils.add_user_to_local_group(self._USERNAME,
group_name)
windll.netapi32.NetLocalGroupAddMembers.assert_called_with(
0, unicode(group_name), 3, ctypes.addressof(lmi), 1)
self.assertEqual(lmi.lgrmi3_domainandname, unicode(self._USERNAME))
def test_add_user_to_local_group_no_error(self):
self._test_add_user_to_local_group(ret_value=0)
def test_add_user_to_local_group_not_found(self):
self._test_add_user_to_local_group(
ret_value=self._winutils.NERR_GroupNotFound)
def test_add_user_to_local_group_access_denied(self):
self._test_add_user_to_local_group(
ret_value=self._winutils.ERROR_ACCESS_DENIED)
def test_add_user_to_local_group_no_member(self):
self._test_add_user_to_local_group(
ret_value=self._winutils.ERROR_NO_SUCH_MEMBER)
def test_add_user_to_local_group_member_in_alias(self):
self._test_add_user_to_local_group(
ret_value=self._winutils.ERROR_MEMBER_IN_ALIAS)
def test_add_user_to_local_group_invalid_member(self):
self._test_add_user_to_local_group(
ret_value=self._winutils.ERROR_INVALID_MEMBER)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_user_wmi_object')
def _test_get_user_sid(self, mock_get_user_wmi_object, fail):
r = mock.Mock()
if not fail:
mock_get_user_wmi_object.return_value = None
response = self._winutils.get_user_sid(self._USERNAME)
self.assertTrue(response is None)
else:
mock_get_user_wmi_object.return_value = r
response = self._winutils.get_user_sid(self._USERNAME)
self.assertTrue(response is not None)
mock_get_user_wmi_object.assert_called_with(self._USERNAME)
def test_get_user_sid(self):
self._test_get_user_sid(fail=False)
def test_get_user_sid_fail(self):
self._test_get_user_sid(fail=True)
def _test_create_user_logon_session(self, logon, loaduser,
load_profile=True):
wintypes.HANDLE = mock.MagicMock()
pi = windows_utils.Win32_PROFILEINFO()
windll.advapi32.LogonUserW = mock.MagicMock(return_value=logon)
ctypes.byref = mock.MagicMock()
if not logon:
self.assertRaises(
Exception, self._winutils.create_user_logon_session,
self._USERNAME, self._PASSWORD, domain='.',
load_profile=load_profile)
elif load_profile and not loaduser:
windll.userenv.LoadUserProfileW = mock.MagicMock(
return_value=None)
windll.kernel32.CloseHandle = mock.MagicMock(return_value=None)
self.assertRaises(Exception,
self._winutils.create_user_logon_session,
self._USERNAME, self._PASSWORD, domain='.',
load_profile=load_profile)
windll.userenv.LoadUserProfileW.assert_called_with(
wintypes.HANDLE(), ctypes.byref(pi))
windll.kernel32.CloseHandle.assert_called_with(wintypes.HANDLE())
elif not load_profile:
response = self._winutils.create_user_logon_session(
self._USERNAME, self._PASSWORD, domain='.',
load_profile=load_profile)
self.assertTrue(response is not None)
else:
size = 1024
windll.userenv.LoadUserProfileW = mock.MagicMock()
ctypes.sizeof = mock.MagicMock(return_value=size)
windows_utils.Win32_PROFILEINFO = mock.MagicMock(
return_value=loaduser)
response = self._winutils.create_user_logon_session(
self._USERNAME, self._PASSWORD, domain='.',
load_profile=load_profile)
windll.userenv.LoadUserProfileW.assert_called_with(
wintypes.HANDLE(), ctypes.byref(pi))
self.assertTrue(response is not None)
def test_create_user_logon_session_fail_load_false(self):
self._test_create_user_logon_session(0, 0, True)
def test_create_user_logon_session_fail_load_true(self):
self._test_create_user_logon_session(0, 0, False)
def test_create_user_logon_session_load_true(self):
m = mock.Mock()
n = mock.Mock()
self._test_create_user_logon_session(m, n, True)
def test_create_user_logon_session_load_false(self):
m = mock.Mock()
n = mock.Mock()
self._test_create_user_logon_session(m, n, False)
def test_create_user_logon_session_no_load_true(self):
m = mock.Mock()
self._test_create_user_logon_session(m, None, True)
def test_create_user_logon_session_no_load_false(self):
m = mock.Mock()
self._test_create_user_logon_session(m, None, False)
def test_close_user_logon_session(self):
token = mock.Mock()
windll.kernel32.CloseHandle = mock.MagicMock()
self._winutils.close_user_logon_session(token)
windll.kernel32.CloseHandle.assert_called_with(token)
@mock.patch('ctypes.windll.kernel32.SetComputerNameExW')
def _test_set_host_name(self, mock_SetComputerNameExW, ret_value):
wmi.WMI = mock.MagicMock(return_value=self._conn)
mock_SetComputerNameExW.return_value = ret_value
if not ret_value:
self.assertRaises(Exception, self._winutils.set_host_name,
'fake name')
else:
self._winutils.set_host_name('fake name')
mock_SetComputerNameExW.assert_called_with(
self._winutils.ComputerNamePhysicalDnsHostname,
unicode('fake name'))
def test_set_host_name(self):
self._test_set_host_name(ret_value='fake response')
def test_set_host_exception(self):
self._test_set_host_name(ret_value=None)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'.get_user_sid')
def _test_get_user_home(self, mock_get_user_sid, user_sid):
key = mock.MagicMock()
mock_get_user_sid.return_value = user_sid
_winreg.OpenKey = mock.MagicMock(return_value=key)
_winreg.QueryValueEx = mock.MagicMock()
response = self._winutils.get_user_home(self._USERNAME)
if user_sid:
mock_get_user_sid.assert_called_with(self._USERNAME)
_winreg.OpenKey.assert_called_with(
_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows '
'NT\\CurrentVersion\\ProfileList\\'
'%s' % mock_get_user_sid())
self.assertTrue(response is not None)
_winreg.QueryValueEx.assert_called_with(
_winreg.OpenKey().__enter__(), 'ProfileImagePath')
else:
self.assertTrue(response is None)
def test_get_user_home(self):
user = mock.MagicMock()
self._test_get_user_home(user_sid=user)
def test_get_user_home_fail(self):
self._test_get_user_home(user_sid=None)
@mock.patch('wmi.WMI')
def test_get_network_adapters(self, mock_WMI):
mock_WMI.return_value = self._conn
mock_response = mock.MagicMock()
self._conn.query.return_value = [mock_response]
response = self._winutils.get_network_adapters()
self._conn.query.assert_called_with(
'SELECT * FROM Win32_NetworkAdapter WHERE AdapterTypeId = 0 AND '
'PhysicalAdapter = True AND MACAddress IS NOT NULL')
self.assertEqual(response, [mock_response.Name])
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._sanitize_wmi_input')
def _test_set_static_network_config(self, mock_sanitize_wmi_input,
adapter, ret_val1=None,
ret_val2=None, ret_val3=None):
wmi.WMI = mock.MagicMock(return_value=self._conn)
address = '10.10.10.10'
adapter_name = 'adapter_name'
broadcast = '0.0.0.0'
dns_list = ['8.8.8.8']
if not adapter:
self.assertRaises(
Exception, self._winutils.set_static_network_config,
adapter_name, address, self._NETMASK,
broadcast, self._GATEWAY, dns_list)
else:
mock_sanitize_wmi_input.return_value = adapter_name
self._conn.query.return_value = adapter
adapter_config = adapter[0].associators()[0]
adapter_config.EnableStatic = mock.MagicMock(return_value=ret_val1)
adapter_config.SetGateways = mock.MagicMock(return_value=ret_val2)
adapter_config.SetDNSServerSearchOrder = mock.MagicMock(
return_value=ret_val3)
adapter.__len__ = mock.MagicMock(return_value=1)
if ret_val1[0] > 1:
self.assertRaises(
Exception, self._winutils.set_static_network_config,
adapter_name, address, self._NETMASK,
broadcast, self._GATEWAY, dns_list)
elif ret_val2[0] > 1:
self.assertRaises(
Exception, self._winutils.set_static_network_config,
adapter_name, address, self._NETMASK,
broadcast, self._GATEWAY, dns_list)
elif ret_val3[0] > 1:
self.assertRaises(
Exception, self._winutils.set_static_network_config,
adapter_name, address, self._NETMASK,
broadcast, self._GATEWAY, dns_list)
else:
response = self._winutils.set_static_network_config(
adapter_name, address, self._NETMASK,
broadcast, self._GATEWAY, dns_list)
if ret_val1[0] or ret_val2[0] or ret_val3[0] == 1:
self.assertTrue(response)
else:
self.assertFalse(response)
adapter_config.EnableStatic.assert_called_with(
[address], [self._NETMASK])
adapter_config.SetGateways.assert_called_with(
[self._GATEWAY], [1])
adapter_config.SetDNSServerSearchOrder.assert_called_with(
dns_list)
self._winutils._sanitize_wmi_input.assert_called_with(
adapter_name)
adapter[0].associators.assert_called_with(
wmi_result_class='Win32_NetworkAdapterConfiguration')
self._conn.query.assert_called_with(
'SELECT * FROM Win32_NetworkAdapter WHERE MACAddress IS '
'NOT NULL AND Name = \'%(adapter_name_san)s\'' %
{'adapter_name_san': adapter_name})
def test_set_static_network_config(self):
adapter = mock.MagicMock()
ret_val1 = (1,)
ret_val2 = (1,)
ret_val3 = (0,)
self._test_set_static_network_config(adapter=adapter,
ret_val1=ret_val1,
ret_val2=ret_val2,
ret_val3=ret_val3)
def test_set_static_network_config_query_fail(self):
self._test_set_static_network_config(adapter=None)
def test_set_static_network_config_cannot_set_ip(self):
adapter = mock.MagicMock()
ret_val1 = (2,)
self._test_set_static_network_config(adapter=adapter,
ret_val1=ret_val1)
def test_set_static_network_config_cannot_set_gateway(self):
adapter = mock.MagicMock()
ret_val1 = (1,)
ret_val2 = (2,)
self._test_set_static_network_config(adapter=adapter,
ret_val1=ret_val1,
ret_val2=ret_val2)
def test_set_static_network_config_cannot_set_DNS(self):
adapter = mock.MagicMock()
ret_val1 = (1,)
ret_val2 = (1,)
ret_val3 = (2,)
self._test_set_static_network_config(adapter=adapter,
ret_val1=ret_val1,
ret_val2=ret_val2,
ret_val3=ret_val3)
def test_set_static_network_config_no_reboot(self):
adapter = mock.MagicMock()
ret_val1 = (0,)
ret_val2 = (0,)
ret_val3 = (0,)
self._test_set_static_network_config(adapter=adapter,
ret_val1=ret_val1,
ret_val2=ret_val2,
ret_val3=ret_val3)
def _test_get_config_key_name(self, section):
response = self._winutils._get_config_key_name(section)
if section:
self.assertEqual(
response, self._winutils._config_key + section + '\\')
else:
self.assertEqual(response, self._winutils._config_key)
def test_get_config_key_name_with_section(self):
self._test_get_config_key_name(self._SECTION)
def test_get_config_key_name_no_section(self):
self._test_get_config_key_name(None)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_config_key_name')
def _test_set_config_value(self, mock_get_config_key_name, value):
key = mock.MagicMock()
key_name = self._winutils._config_key + self._SECTION + '\\' + self\
._CONFIG_NAME
mock_get_config_key_name.return_value = key_name
_winreg.CreateKey = mock.MagicMock()
_winreg.REG_DWORD = mock.Mock()
_winreg.REG_SZ = mock.Mock()
_winreg.SetValueEx = mock.MagicMock()
self._winutils.set_config_value(self._CONFIG_NAME, value,
self._SECTION)
_winreg.CreateKey.__enter__.return_value = key
with _winreg.CreateKey as m:
assert m == key
_winreg.CreateKey.__enter__.assert_called_with()
_winreg.CreateKey.__exit__.assert_called_with(None, None, None)
_winreg.CreateKey.assert_called_with(_winreg.HKEY_LOCAL_MACHINE,
key_name)
mock_get_config_key_name.assert_called_with(self._SECTION)
if type(value) == int:
_winreg.SetValueEx.assert_called_with(
_winreg.CreateKey().__enter__(), self._CONFIG_NAME, 0,
_winreg.REG_DWORD, value)
else:
_winreg.SetValueEx.assert_called_with(
_winreg.CreateKey().__enter__(), self._CONFIG_NAME, 0,
_winreg.REG_SZ, value)
def test_set_config_value_int(self):
self._test_set_config_value(value=1)
def test_set_config_value_not_int(self):
self._test_set_config_value(value='1')
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_config_key_name')
def _test_get_config_value(self, mock_get_config_key_name, value):
key_name = self._winutils._config_key + self._SECTION + '\\'
key_name += self._CONFIG_NAME
_winreg.OpenKey = mock.MagicMock()
_winreg.REG_DWORD = mock.Mock()
_winreg.REG_SZ = mock.Mock()
if type(value) == int:
regtype = _winreg.REG_DWORD
else:
regtype = _winreg.REG_SZ
_winreg.QueryValueEx = mock.MagicMock(return_value=(value, regtype))
if value is None:
mock_get_config_key_name.side_effect = [WindowsError]
self.assertRaises(WindowsError, self._winutils.get_config_value,
self._CONFIG_NAME, None)
else:
mock_get_config_key_name.return_value = key_name
response = self._winutils.get_config_value(self._CONFIG_NAME,
self._SECTION)
_winreg.OpenKey.assert_called_with(_winreg.HKEY_LOCAL_MACHINE,
key_name)
mock_get_config_key_name.assert_called_with(self._SECTION)
_winreg.QueryValueEx.assert_called_with(
_winreg.OpenKey().__enter__(), self._CONFIG_NAME)
self.assertEqual(response, value)
def test_get_config_value_type_int(self):
self._test_get_config_value(value=1)
def test_get_config_value_type_str(self):
self._test_get_config_value(value='fake')
def test_get_config_value_type_error(self):
self._test_get_config_value(value=None)
def _test_wait_for_boot_completion(self, ret_val):
key = mock.MagicMock()
time.sleep = mock.MagicMock()
_winreg.OpenKey = mock.MagicMock()
_winreg.QueryValueEx = mock.MagicMock()
_winreg.QueryValueEx.side_effect = ret_val
self._winutils.wait_for_boot_completion()
_winreg.OpenKey.__enter__.return_value = key
_winreg.OpenKey.assert_called_with(
_winreg.HKEY_LOCAL_MACHINE,
"SYSTEM\\Setup\\Status\\SysprepStatus", 0, _winreg.KEY_READ)
_winreg.QueryValueEx.assert_called_with(
_winreg.OpenKey().__enter__(), "GeneralizationState")
def test_wait_for_boot_completion(self):
ret_val = [[7]]
self._test_wait_for_boot_completion(ret_val)
@mock.patch('wmi.WMI')
def test_get_service(self, mock_WMI):
mock_WMI.return_value = self._conn
self._conn.Win32_Service.return_value = ['fake name']
response = self._winutils._get_service('fake name')
mock_WMI.assert_called_with(moniker='//./root/cimv2')
self._conn.Win32_Service.assert_called_with(Name='fake name')
self.assertEqual(response, 'fake name')
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_service')
def test_check_service_exists(self, mock_get_service):
mock_get_service.return_value = 'not None'
response = self._winutils.check_service_exists('fake name')
self.assertEqual(response, True)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_service')
def test_get_service_status(self, mock_get_service):
mock_service = mock.MagicMock()
mock_get_service.return_value = mock_service
response = self._winutils.get_service_status('fake name')
self.assertEqual(response, mock_service.State)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_service')
def test_get_service_start_mode(self, mock_get_service):
mock_service = mock.MagicMock()
mock_get_service.return_value = mock_service
response = self._winutils.get_service_start_mode('fake name')
self.assertEqual(response, mock_service.StartMode)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_service')
def _test_set_service_start_mode(self, mock_get_service, ret_val):
mock_service = mock.MagicMock()
mock_get_service.return_value = mock_service
mock_service.ChangeStartMode.return_value = (ret_val,)
if ret_val != 0:
self.assertRaises(Exception,
self._winutils.set_service_start_mode,
'fake name', 'fake mode')
else:
self._winutils.set_service_start_mode('fake name', 'fake mode')
mock_service.ChangeStartMode.assert_called_once_with('fake mode')
def test_set_service_start_mode(self):
self._test_set_service_start_mode(ret_val=0)
def test_set_service_start_mode_exception(self):
self._test_set_service_start_mode(ret_val=1)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_service')
def _test_start_service(self, mock_get_service, ret_val):
mock_service = mock.MagicMock()
mock_get_service.return_value = mock_service
mock_service.StartService.return_value = (ret_val,)
if ret_val != 0:
self.assertRaises(Exception,
self._winutils.start_service,
'fake name')
else:
self._winutils.start_service('fake name')
mock_service.StartService.assert_called_once_with()
def test_start_service(self):
self._test_set_service_start_mode(ret_val=0)
def test_start_service_exception(self):
self._test_set_service_start_mode(ret_val=1)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_service')
def _test_stop_service(self, mock_get_service, ret_val):
mock_service = mock.MagicMock()
mock_get_service.return_value = mock_service
mock_service.StopService.return_value = (ret_val,)
if ret_val != 0:
self.assertRaises(Exception,
self._winutils.stop_service,
'fake name')
else:
self._winutils.stop_service('fake name')
mock_service.StopService.assert_called_once_with()
def test_stop_service(self):
self._test_stop_service(ret_val=0)
def test_stop_service_exception(self):
self._test_stop_service(ret_val=1)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'.stop_service')
def test_terminate(self, mock_stop_service):
time.sleep = mock.MagicMock()
self._winutils.terminate()
mock_stop_service.assert_called_with(self._winutils._service_name)
time.sleep.assert_called_with(3)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_ipv4_routing_table')
def _test_get_default_gateway(self, mock_get_ipv4_routing_table,
routing_table):
mock_get_ipv4_routing_table.return_value = [routing_table]
response = self._winutils.get_default_gateway()
mock_get_ipv4_routing_table.assert_called_once_with()
if routing_table[0] == '0.0.0.0':
self.assertEqual(response, (routing_table[3], routing_table[2]))
else:
self.assertEqual(response, (None, None))
def test_get_default_gateway(self):
routing_table = ['0.0.0.0', '1.1.1.1', self._GATEWAY, '8.8.8.8']
self._test_get_default_gateway(routing_table=routing_table)
def test_get_default_gateway_error(self):
routing_table = ['1.1.1.1', '1.1.1.1', self._GATEWAY, '8.8.8.8']
self._test_get_default_gateway(routing_table=routing_table)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'._get_ipv4_routing_table')
def _test_check_static_route_exists(self, mock_get_ipv4_routing_table,
routing_table):
mock_get_ipv4_routing_table.return_value = [routing_table]
response = self._winutils.check_static_route_exists(self._DESTINATION)
mock_get_ipv4_routing_table.assert_called_once_with()
if routing_table[0] == self._DESTINATION:
self.assertTrue(response)
else:
self.assertFalse(response)
def test_check_static_route_exists_true(self):
routing_table = [self._DESTINATION, '1.1.1.1', self._GATEWAY,
'8.8.8.8']
self._test_check_static_route_exists(routing_table=routing_table)
def test_check_static_route_exists_false(self):
routing_table = ['0.0.0.0', '1.1.1.1', self._GATEWAY, '8.8.8.8']
self._test_check_static_route_exists(routing_table=routing_table)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
'.execute_process')
def _test_add_static_route(self, mock_execute_process, err):
next_hop = '10.10.10.10'
interface_index = 1
metric = 9
args = ['ROUTE', 'ADD', self._DESTINATION, 'MASK', self._NETMASK,
next_hop]
mock_execute_process.return_value = (None, err, None)
if err:
self.assertRaises(Exception, self._winutils.add_static_route,
self._DESTINATION, self._NETMASK, next_hop,
interface_index, metric)
else:
self._winutils.add_static_route(self._DESTINATION, self._NETMASK,
next_hop, interface_index, metric)
mock_execute_process.assert_called_with(args)
def test_add_static_route(self):
self._test_add_static_route(err=404)
def test_add_static_route_fail(self):
self._test_add_static_route(err=None)
@mock.patch('ctypes.sizeof')
@mock.patch('ctypes.byref')
@mock.patch('ctypes.windll.kernel32.VerSetConditionMask')
@mock.patch('ctypes.windll.kernel32.VerifyVersionInfoW')
@mock.patch('ctypes.windll.kernel32.GetLastError')
def _test_check_os_version(self, mock_GetLastError,
mock_VerifyVersionInfoW,
mock_VerSetConditionMask, mock_byref,
mock_sizeof, ret_value, error_value=None):
mock_VerSetConditionMask.return_value = 2
mock_VerifyVersionInfoW.return_value = ret_value
mock_GetLastError.return_value = error_value
old_version = self._winutils.ERROR_OLD_WIN_VERSION
if error_value and error_value is not old_version:
self.assertRaises(Exception, self._winutils.check_os_version, 3,
1, 2)
mock_GetLastError.assert_called_once_with()
else:
response = self._winutils.check_os_version(3, 1, 2)
mock_sizeof.assert_called_once_with(
windows_utils.Win32_OSVERSIONINFOEX_W)
self.assertEqual(mock_VerSetConditionMask.call_count, 3)
mock_VerifyVersionInfoW.assert_called_with(mock_byref(),
1 | 2 | 3 | 7,
2)
if error_value is old_version:
mock_GetLastError.assert_called_with()
self.assertEqual(response, False)
else:
self.assertEqual(response, True)
def test_check_os_version(self):
m = mock.MagicMock()
self._test_check_os_version(ret_value=m)
def test_check_os_version_expect_False(self):
self._test_check_os_version(
ret_value=None, error_value=self._winutils.ERROR_OLD_WIN_VERSION)
def test_check_os_version_exception(self):
self._test_check_os_version(ret_value=None, error_value=9999)
def _test_get_volume_label(self, ret_val):
label = mock.MagicMock()
max_label_size = 261
drive = 'Fake_drive'
ctypes.create_unicode_buffer = mock.MagicMock(return_value=label)
ctypes.windll.kernel32.GetVolumeInformationW = mock.MagicMock(
return_value=ret_val)
response = self._winutils.get_volume_label(drive)
if ret_val:
self.assertTrue(response is not None)
else:
self.assertTrue(response is None)
ctypes.create_unicode_buffer.assert_called_with(max_label_size)
ctypes.windll.kernel32.GetVolumeInformationW.assert_called_with(
drive, label, max_label_size, 0, 0, 0, 0, 0)
def test_get_volume_label(self):
self._test_get_volume_label('ret')
def test_get_volume_label_no_return_value(self):
self._test_get_volume_label(None)
@mock.patch('re.search')
@mock.patch('cloudbaseinit.osutils.base.BaseOSUtils.'
'generate_random_password')
def test_generate_random_password(self, mock_generate_random_password,
mock_search):
length = 14
mock_search.return_value = True
mock_generate_random_password.return_value = 'Passw0rd'
response = self._winutils.generate_random_password(length)
mock_generate_random_password.assert_called_once_with(length)
self.assertEqual(response, 'Passw0rd')
@mock.patch('ctypes.create_unicode_buffer')
@mock.patch('ctypes.windll.kernel32.GetLogicalDriveStringsW')
def _test_get_logical_drives(self, mock_GetLogicalDriveStringsW,
mock_create_unicode_buffer, buf_length):
mock_buf = mock.MagicMock()
mock_buf.__getitem__.side_effect = ['1', '\x00']
mock_create_unicode_buffer.return_value = mock_buf
mock_GetLogicalDriveStringsW.return_value = buf_length
if buf_length is None:
self.assertRaises(Exception, self._winutils._get_logical_drives)
else:
response = self._winutils._get_logical_drives()
print mock_buf.mock_calls
mock_create_unicode_buffer.assert_called_with(261)
mock_GetLogicalDriveStringsW.assert_called_with(260, mock_buf)
self.assertEqual(response, ['1'])
def test_get_logical_drives_exception(self):
self._test_get_logical_drives(buf_length=None)
def test_get_logical_drives(self):
self._test_get_logical_drives(buf_length=2)
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils.'
'_get_logical_drives')
@mock.patch('cloudbaseinit.osutils.windows.kernel32')
def test_get_cdrom_drives(self, mock_kernel32, mock_get_logical_drives):
mock_get_logical_drives.return_value = ['drive']
mock_kernel32.GetDriveTypeW.return_value = self._winutils.DRIVE_CDROM
response = self._winutils.get_cdrom_drives()
mock_get_logical_drives.assert_called_with()
self.assertEqual(response, ['drive'])
@mock.patch('win32com.client.Dispatch')
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils._get_fw_protocol')
def _test_firewall_create_rule(self, mock_get_fw_protocol, mock_Dispatch):
self._winutils.firewall_create_rule(
name='fake name', port=9999, protocol=self._winutils.PROTOCOL_TCP)
expected = [mock.call("HNetCfg.FWOpenPort"),
mock.call("HNetCfg.FwMgr")]
self.assertEqual(mock_Dispatch.call_args_list, expected)
mock_get_fw_protocol.assert_called_once_with(
self._winutils.PROTOCOL_TCP)
@mock.patch('win32com.client.Dispatch')
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils._get_fw_protocol')
def test_firewall_remove_rule(self, mock_get_fw_protocol, mock_Dispatch):
self._winutils.firewall_remove_rule(
name='fake name', port=9999, protocol=self._winutils.PROTOCOL_TCP)
mock_Dispatch.assert_called_once_with("HNetCfg.FwMgr")
mock_get_fw_protocol.assert_called_once_with(
self._winutils.PROTOCOL_TCP)

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,37 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import unittest
from cloudbaseinit.plugins import factory
from cloudbaseinit.openstack.common import cfg
CONF = cfg.CONF
class PluginFactoryTests(unittest.TestCase):
def setUp(self):
self._factory = factory.PluginFactory()
@mock.patch('cloudbaseinit.utils.classloader.ClassLoader.load_class')
def test_load_plugins(self, mock_load_class):
expected = []
for path in CONF.plugins:
expected.append(mock.call(path))
response = self._factory.load_plugins()
self.assertEqual(mock_load_class.call_args_list, expected)
self.assertTrue(response is not None)

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,77 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import unittest
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins import base
from cloudbaseinit.plugins.windows import createuser
CONF = cfg.CONF
class CreateUserPluginTests(unittest.TestCase):
def setUp(self):
self._create_user = createuser.CreateUserPlugin()
def test_get_password(self):
mock_osutils = mock.MagicMock()
mock_osutils.generate_random_password.return_value = 'fake password'
response = self._create_user._get_password(mock_osutils)
mock_osutils.generate_random_password.assert_called_once_with(14)
self.assertEqual(response, 'fake password')
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
@mock.patch('cloudbaseinit.plugins.windows.createuser.CreateUserPlugin'
'._get_password')
def _test_execute(self, mock_get_password, mock_get_os_utils,
user_exists=True):
CONF.set_override('groups', ['Admins'])
shared_data = {}
mock_token = mock.MagicMock()
mock_osutils = mock.MagicMock()
mock_service = mock.MagicMock()
mock_get_password.return_value = 'password'
mock_get_os_utils.return_value = mock_osutils
mock_osutils.user_exists.return_value = user_exists
mock_osutils.create_user_logon_session.return_value = mock_token
response = self._create_user.execute(mock_service, shared_data)
mock_get_os_utils.assert_called_once_with()
mock_get_password.assert_called_once_with(mock_osutils)
mock_osutils.user_exists.assert_called_once_with(CONF.username)
if user_exists:
mock_osutils.set_user_password.assert_called_once_with(
CONF.username, 'password')
else:
mock_osutils.create_user.assert_called_once_with(CONF.username,
'password')
mock_osutils.create_user_logon_session.assert_called_once_with(
CONF.username, 'password', True)
mock_osutils.close_user_logon_session.assert_called_once_with(
mock_token)
mock_osutils.add_user_to_local_group.assert_called_once_with(
CONF.username, CONF.groups[0])
self.assertEqual(response, (base.PLUGIN_EXECUTION_DONE, False))
def test_execute_user_exists(self):
self._test_execute(user_exists=True)
def test_execute_no_user(self):
self._test_execute(user_exists=False)

View File

@ -0,0 +1,210 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2013 Cloudbase Solutions Srl
#
# 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 importlib
import mock
import re
import sys
import unittest
from cloudbaseinit.openstack.common import cfg
CONF = cfg.CONF
_ctypes_mock = mock.MagicMock()
_comtypes_mock = mock.MagicMock()
class ExtendVolumesPluginTests(unittest.TestCase):
@mock.patch.dict(sys.modules, {'comtypes': _comtypes_mock,
'ctypes': _ctypes_mock})
def setUp(self):
extendvolumes = importlib.import_module('cloudbaseinit.plugins.'
'windows.extendvolumes')
self._extend_volumes = extendvolumes.ExtendVolumesPlugin()
def tearDown(self):
reload(sys)
@mock.patch('cloudbaseinit.plugins.windows.extendvolumes'
'.ExtendVolumesPlugin._get_volume_index')
@mock.patch('cloudbaseinit.plugins.windows.extendvolumes'
'.ExtendVolumesPlugin._extend_volume')
@mock.patch('cloudbaseinit.plugins.windows.vds.IVdsVolume')
def test_extend_volumes(self, _vds_mock, mock_extend_volume,
mock_get_volume_index):
mock_pack = mock.MagicMock()
mock_volume_idxs = mock.MagicMock()
mock_enum = mock.MagicMock()
mock_unk = mock.MagicMock()
mock_c = mock.MagicMock()
mock_volume = mock.MagicMock()
mock_properties = mock.MagicMock()
mock_pack.QueryVolumes.return_value = mock_enum
mock_enum.Next.side_effect = [(mock_unk, mock_c), (None, None)]
mock_unk.QueryInterface.return_value = mock_volume
mock_volume.GetProperties.return_value = mock_properties
_ctypes_mock.wstring_at.return_value = 'fake name'
mock_get_volume_index.return_value = mock_volume_idxs
self._extend_volumes._extend_volumes(mock_pack, [mock_volume_idxs])
mock_pack.QueryVolumes.assert_called_once_with()
mock_enum.Next.assert_called_with(1)
mock_unk.QueryInterface.assert_called_once_with(_vds_mock)
mock_volume.GetProperties.assert_called_once_with()
_ctypes_mock.wstring_at.assert_called_with(mock_properties.pwszName)
mock_get_volume_index.assert_called_once_with('fake name')
mock_extend_volume.assert_called_once_with(mock_pack, mock_volume,
mock_properties)
_ctypes_mock.windll.ole32.CoTaskMemFree.assert_called_once_with(
mock_properties.pwszName)
def test_get_volume_index(self):
mock_value = mock.MagicMock()
re.match = mock.MagicMock(return_value=mock_value)
mock_value.group.return_value = '9999'
response = self._extend_volumes._get_volume_index('$2')
mock_value.group.assert_called_once_with(1)
self.assertTrue(response == 9999)
@mock.patch('cloudbaseinit.plugins.windows.extendvolumes'
'.ExtendVolumesPlugin._get_volume_extents_to_resize')
@mock.patch('cloudbaseinit.plugins.windows.vds.VDS_INPUT_DISK')
def test_extend_volume(self, mock_VDS_INPUT_DISK,
mock_get_volume_extents_to_resize):
mock_disk = mock.MagicMock()
mock_pack = mock.MagicMock()
mock_volume = mock.MagicMock()
mock_properties = mock.MagicMock()
mock_volume_extent = mock.MagicMock()
mock_async = mock.MagicMock()
mock_get_volume_extents_to_resize.return_value = [(mock_volume_extent,
9999)]
mock_VDS_INPUT_DISK.return_value = mock_disk
mock_volume.Extend.return_value = mock_async
self._extend_volumes._extend_volume(mock_pack, mock_volume,
mock_properties)
mock_get_volume_extents_to_resize.assert_called_once_with(
mock_pack, mock_properties.id)
_ctypes_mock.wstring_at.assert_called_with(mock_properties.pwszName)
mock_volume.Extend.assert_called_once_with(
mock_VDS_INPUT_DISK.__mul__()(), 1)
mock_async.Wait.assert_called_once_with()
@mock.patch('cloudbaseinit.plugins.windows.vds.IVdsDisk')
@mock.patch('cloudbaseinit.plugins.windows.vds.VDS_DISK_EXTENT')
def test_get_volume_extents_to_resize(self, mock_VDS_DISK_EXTENT,
mock_IVdsDisk):
mock_pack = mock.MagicMock()
mock_extents_p = mock.MagicMock()
mock_unk = mock.MagicMock()
mock_c = mock.MagicMock()
mock_disk = mock.MagicMock()
mock_enum = mock.MagicMock()
fake_volume_id = '$1'
mock_array = mock.MagicMock()
mock_array.volumeId = fake_volume_id
mock_pack.QueryDisks.return_value = mock_enum
mock_enum.Next.side_effect = [(mock_unk, mock_c), (None, None)]
mock_unk.QueryInterface.return_value = mock_disk
mock_disk.QueryExtents.return_value = (mock_extents_p,
1)
mock_VDS_DISK_EXTENT.__mul__().from_address.return_value = [mock_array]
response = self._extend_volumes._get_volume_extents_to_resize(
mock_pack, fake_volume_id)
mock_pack.QueryDisks.assert_called_once_with()
mock_enum.Next.assert_called_with(1)
mock_unk.QueryInterface.assert_called_once_with(mock_IVdsDisk)
_ctypes_mock.addressof.assert_called_with(mock_extents_p.contents)
mock_VDS_DISK_EXTENT.__mul__().from_address.assert_called_with(
_ctypes_mock.addressof(mock_extents_p.contents))
_ctypes_mock.pointer.assert_called_once_with(
mock_VDS_DISK_EXTENT())
self.assertEqual(response, [])
_ctypes_mock.windll.ole32.CoTaskMemFree.assert_called_with(
mock_extents_p)
@mock.patch('cloudbaseinit.plugins.windows.vds.'
'VDS_QUERY_SOFTWARE_PROVIDERS')
@mock.patch('cloudbaseinit.plugins.windows.vds.IVdsSwProvider')
def test_query_providers(self, mock_IVdsSwProvider,
mock_VDS_QUERY_SOFTWARE_PROVIDERS):
mock_svc = mock.MagicMock()
mock_enum = mock.MagicMock()
mock_unk = mock.MagicMock()
mock_c = mock.MagicMock()
mock_svc.QueryProviders.return_value = mock_enum
mock_enum.Next.side_effect = [(mock_unk, mock_c), (None, None)]
mock_unk.QueryInterface.return_value = 'fake providers'
response = self._extend_volumes._query_providers(mock_svc)
mock_svc.QueryProviders.assert_called_once_with(
mock_VDS_QUERY_SOFTWARE_PROVIDERS)
mock_enum.Next.assert_called_with(1)
mock_unk.QueryInterface.assert_called_once_with(mock_IVdsSwProvider)
self.assertEqual(response, ['fake providers'])
@mock.patch('cloudbaseinit.plugins.windows.vds.IVdsPack')
def test_query_packs(self, mock_IVdsPack):
mock_provider = mock.MagicMock()
mock_enum = mock.MagicMock()
mock_unk = mock.MagicMock()
mock_c = mock.MagicMock()
mock_provider.QueryPacks.return_value = mock_enum
mock_enum.Next.side_effect = [(mock_unk, mock_c), (None, None)]
mock_unk.QueryInterface.return_value = 'fake packs'
response = self._extend_volumes._query_packs(mock_provider)
mock_provider.QueryPacks.assert_called_once_with()
mock_enum.Next.assert_called_with(1)
mock_unk.QueryInterface.assert_called_once_with(mock_IVdsPack)
self.assertEqual(response, ['fake packs'])
def test_get_volumes_to_extend(self):
CONF.set_override('volumes_to_extend', '1')
response = self._extend_volumes._get_volumes_to_extend()
self.assertEqual(response, [1])
@mock.patch('cloudbaseinit.plugins.windows.vds.load_vds_service')
@mock.patch('cloudbaseinit.plugins.windows.extendvolumes.'
'ExtendVolumesPlugin._query_providers')
@mock.patch('cloudbaseinit.plugins.windows.extendvolumes.'
'ExtendVolumesPlugin._query_packs')
@mock.patch('cloudbaseinit.plugins.windows.extendvolumes.'
'ExtendVolumesPlugin._extend_volumes')
def test_execute(self, mock_extend_volumes, mock_query_packs,
mock_query_providers, mock_load_vds_service):
CONF.set_override('volumes_to_extend', '1')
mock_svc = mock.MagicMock()
fake_providers = ['fake providers']
fake_packs = ['fake packs']
mock_service = mock.MagicMock()
fake_data = 'fake data'
mock_load_vds_service.return_value = mock_svc
mock_query_providers.return_value = fake_providers
mock_query_packs.return_value = fake_packs
self._extend_volumes.execute(mock_service, fake_data)
mock_query_providers.assert_called_once_with(mock_svc)
mock_query_packs.assert_called_once_with('fake providers')
mock_extend_volumes.assert_called_with('fake packs', [1])

View File

@ -0,0 +1,79 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import re
import unittest
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins.windows import networkconfig
from cloudbaseinit.tests.metadata import fake_json_response
CONF = cfg.CONF
class NetworkConfigPluginPluginTests(unittest.TestCase):
def setUp(self):
self._network_plugin = networkconfig.NetworkConfigPlugin()
self.fake_data = fake_json_response.get_fake_metadata_json(
'2013-04-04')
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
def _test_execute(self, mock_get_os_utils, search_result, no_adapters):
CONF.set_override('network_adapter', 'fake adapter')
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
re.search = mock.MagicMock(return_value=search_result)
fake_shared_data = 'fake shared data'
mock_service.get_meta_data.return_value = self.fake_data
mock_service.get_content.return_value = search_result
mock_get_os_utils.return_value = mock_osutils
mock_osutils.set_static_network_config.return_value = False
if search_result is None:
self.assertRaises(Exception, self._network_plugin.execute,
mock_service, fake_shared_data)
elif no_adapters:
CONF.set_override('network_adapter', None)
mock_osutils.get_network_adapters.return_value = None
self.assertRaises(Exception, self._network_plugin.execute,
mock_service, fake_shared_data)
else:
response = self._network_plugin.execute(mock_service,
fake_shared_data)
mock_service.get_meta_data.assert_called_once_with('openstack')
mock_service.get_content.assert_called_once_with(
'openstack', self.fake_data['network_config']['content_path'])
mock_osutils.set_static_network_config.assert_called_once_with(
'fake adapter', search_result.group('address'),
search_result.group('netmask'),
search_result.group('broadcast'),
search_result.group('gateway'),
search_result.group('dnsnameservers').strip().split(' '))
self.assertEqual(response, (1, False))
def test_execute(self):
m = mock.MagicMock()
self._test_execute(search_result=m, no_adapters=False)
def test_execute_no_debian(self):
self._test_execute(search_result=None, no_adapters=False)
def test_execute_no_adapters(self):
m = mock.MagicMock()
self._test_execute(search_result=m, no_adapters=True)

View File

@ -0,0 +1,57 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import unittest
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins.windows import sethostname
from cloudbaseinit.tests.metadata import fake_json_response
CONF = cfg.CONF
class SetHostNamePluginPluginTests(unittest.TestCase):
def setUp(self):
self._sethostname_plugin = sethostname.SetHostNamePlugin()
self.fake_data = fake_json_response.get_fake_metadata_json(
'2013-04-04')
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
def _test_execute(self, mock_get_os_utils, hostname_exists):
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
fake_shared_data = 'fake data'
mock_service.get_meta_data.return_value = self.fake_data
if hostname_exists is False:
del self.fake_data['hostname']
mock_get_os_utils.return_value = mock_osutils
mock_osutils.set_host_name.return_value = False
response = self._sethostname_plugin.execute(mock_service,
fake_shared_data)
mock_service.get_meta_data.assert_called_once_with('openstack')
if hostname_exists is True:
mock_get_os_utils.assert_called_once_with()
mock_osutils.set_host_name.assert_called_once_with(
self.fake_data['hostname'].split('.', 1)[0])
self.assertEqual(response, (1, False))
def test_execute(self):
self._test_execute(hostname_exists=True)
def test_execute_no_hostname(self):
self._test_execute(hostname_exists=False)

View File

@ -0,0 +1,166 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import unittest
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins import constants
from cloudbaseinit.plugins.windows import setuserpassword
from cloudbaseinit.tests.metadata import fake_json_response
CONF = cfg.CONF
class SetUserPasswordPluginTests(unittest.TestCase):
def setUp(self):
self._setpassword_plugin = setuserpassword.SetUserPasswordPlugin()
self.fake_data = fake_json_response.get_fake_metadata_json(
'2013-04-04')
@mock.patch('base64.b64encode')
@mock.patch('cloudbaseinit.utils.crypt.CryptManager'
'.load_ssh_rsa_public_key')
def test_encrypt_password(self, mock_load_ssh_key, mock_b64encode):
mock_rsa = mock.MagicMock()
fake_ssh_pub_key = 'fake key'
fake_password = 'fake password'
mock_load_ssh_key.return_value = mock_rsa
mock_rsa.__enter__().public_encrypt.return_value = 'public encrypted'
mock_b64encode.return_value = 'encrypted password'
response = self._setpassword_plugin._encrypt_password(
fake_ssh_pub_key, fake_password)
print mock_rsa.mock_calls
mock_load_ssh_key.assert_called_with(fake_ssh_pub_key)
mock_rsa.__enter__().public_encrypt.assert_called_with('fake password')
mock_b64encode.assert_called_with('public encrypted')
self.assertEqual(response, 'encrypted password')
def _test_get_ssh_public_key(self, data_exists):
mock_service = mock.MagicMock()
mock_service.get_meta_data.return_value = self.fake_data
if data_exists is False:
del self.fake_data['public_keys']
response = self._setpassword_plugin._get_ssh_public_key(
mock_service)
self.assertEqual(response, False)
else:
response = self._setpassword_plugin._get_ssh_public_key(
mock_service)
mock_service.get_meta_data.assert_called_with(
'openstack', self._setpassword_plugin._post_password_md_ver)
self.assertEqual(response, self.fake_data['public_keys']['name'])
def test_get_ssh_plublic_key(self):
self._test_get_ssh_public_key(data_exists=True)
def test_get_ssh_plublic_key_no_pub_keys(self):
self._test_get_ssh_public_key(data_exists=False)
def test_get_password(self):
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
mock_service.get_meta_data.return_value = self.fake_data
CONF.set_override('inject_user_password', False)
mock_osutils.generate_random_password.return_value = 'Passw0rd'
response = self._setpassword_plugin._get_password(mock_service,
mock_osutils)
mock_service.get_meta_data.assert_called_with('openstack')
mock_osutils.generate_random_password.assert_called_once_with(14)
self.assertEqual(response, 'Passw0rd')
@mock.patch('cloudbaseinit.plugins.windows.setuserpassword.'
'SetUserPasswordPlugin._get_ssh_public_key')
@mock.patch('cloudbaseinit.plugins.windows.setuserpassword.'
'SetUserPasswordPlugin._encrypt_password')
def _test_set_metadata_password(self, mock_encrypt_password,
mock_get_key, ssh_pub_key):
fake_passw0rd = 'fake Passw0rd'
mock_service = mock.MagicMock()
mock_get_key.return_value = ssh_pub_key
mock_encrypt_password.return_value = 'encrypted password'
mock_service.post_password.return_value = 'value'
response = self._setpassword_plugin._set_metadata_password(
fake_passw0rd, mock_service)
if ssh_pub_key is None:
self.assertEqual(response, True)
else:
mock_get_key.assert_called_once_with(mock_service)
mock_encrypt_password.assert_called_once_with(ssh_pub_key,
fake_passw0rd)
mock_service.post_password.assert_called_with(
'encrypted password',
self._setpassword_plugin._post_password_md_ver)
self.assertEqual(response, 'value')
def test_set_metadata_password_with_ssh_key(self):
fake_key = 'fake key'
self._test_set_metadata_password(ssh_pub_key=fake_key)
def test_set_metadata_password_no_ssh_key(self):
self._test_set_metadata_password(ssh_pub_key=None)
@mock.patch('cloudbaseinit.plugins.windows.setuserpassword.'
'SetUserPasswordPlugin._get_password')
def test_set_password(self, mock_get_password):
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
mock_get_password.return_value = 'fake password'
response = self._setpassword_plugin._set_password(mock_service,
mock_osutils,
'fake user')
mock_get_password.assert_called_once_with(mock_service, mock_osutils)
mock_osutils.set_user_password.assert_called_once_with('fake user',
'fake password')
self.assertEqual(response, 'fake password')
@mock.patch('cloudbaseinit.plugins.windows.setuserpassword.'
'SetUserPasswordPlugin._set_password')
@mock.patch('cloudbaseinit.plugins.windows.setuserpassword.'
'SetUserPasswordPlugin._set_metadata_password')
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
def test_execute(self, mock_get_os_utils, mock_set_metadata_password,
mock_set_password):
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
fake_shared_data = mock.MagicMock()
fake_shared_data.get.return_value = 'fake username'
mock_service.is_password_set.return_value = False
mock_get_os_utils.return_value = mock_osutils
mock_osutils.user_exists.return_value = True
mock_set_password.return_value = 'fake password'
response = self._setpassword_plugin.execute(mock_service,
fake_shared_data)
fake_shared_data.get.assert_called_with(
constants.SHARED_DATA_USERNAME, CONF.username)
mock_service.is_password_set.assert_called_once_with(
self._setpassword_plugin._post_password_md_ver)
mock_get_os_utils.assert_called_once_with()
mock_osutils.user_exists.assert_called_once_with('fake username')
mock_set_password.assert_called_once_with(mock_service, mock_osutils,
'fake username')
mock_set_metadata_password.assert_called_once_with('fake password',
mock_service)
self.assertEqual(response, (2, False))

View File

@ -0,0 +1,70 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import os
import unittest
from cloudbaseinit.plugins.windows import sshpublickeys
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.tests.metadata import fake_json_response
CONF = cfg.CONF
class SetUserSSHPublicKeysPluginTests(unittest.TestCase):
def setUp(self):
self._set_ssh_keys_plugin = sshpublickeys.SetUserSSHPublicKeysPlugin()
self.fake_data = fake_json_response.get_fake_metadata_json(
'2013-04-04')
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
@mock.patch('os.path')
@mock.patch('os.makedirs')
def _test_execute(self, mock_os_makedirs, mock_os_path,
mock_get_os_utils, user_home):
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
fake_shared_data = 'fake data'
mock_service.get_meta_data.return_value = self.fake_data
CONF.set_override('username', 'fake user')
mock_get_os_utils.return_value = mock_osutils
mock_osutils.get_user_home.return_value = user_home
mock_os_path.exists.return_value = False
if user_home is None:
self.assertRaises(Exception, self._set_ssh_keys_plugin,
mock_service, fake_shared_data)
else:
with mock.patch('cloudbaseinit.plugins.windows.sshpublickeys'
'.open',
mock.mock_open(), create=True):
response = self._set_ssh_keys_plugin.execute(mock_service,
fake_shared_data)
mock_service.get_meta_data.assert_called_with('openstack')
mock_osutils.get_user_home.assert_called_with('fake user')
self.assertEqual(mock_os_path.join.call_count, 2)
mock_os_makedirs.assert_called_once_with(mock_os_path.join())
self.assertEqual(response, (1, False))
def test_execute_with_user_home(self):
fake_user_home = os.path.join('fake', 'home')
self._test_execute(user_home=fake_user_home)
def test_execute_with_no_user_home(self):
self._test_execute(user_home=None)

View File

@ -0,0 +1,263 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import tempfile
import uuid
import unittest
from cloudbaseinit.metadata.services import base as base_metadata
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins.windows import userdata
from cloudbaseinit.tests.metadata import fake_json_response
CONF = cfg.CONF
class UserDataPluginTest(unittest.TestCase):
def setUp(self):
self._userdata = userdata.UserDataPlugin()
self.fake_data = fake_json_response.get_fake_metadata_json(
'2013-04-04')
@mock.patch('os.path')
def test_get_plugin_path(self, mock_ospath):
mock_ospath.join.return_value = 'fake path'
response = self._userdata._get_plugin_path()
mock_ospath.join.assert_called_with(
mock_ospath.dirname(mock_ospath.dirname(mock_ospath.realpath())),
"windows/userdata-plugins")
self.assertEqual(response, 'fake path')
@mock.patch('cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
'._process_userdata')
def _test_execute(self, mock_process_userdata, user_data, exception):
mock_service = mock.MagicMock()
fake_shared_data = 'fake data'
if exception:
e = base_metadata.NotExistingMetadataException()
mock_service.side_effect = e
else:
mock_service.get_user_data.return_value = user_data
response = self._userdata.execute(mock_service, fake_shared_data)
mock_service.get_user_data.assert_called_with('openstack')
if user_data:
mock_process_userdata.assert_called_with(user_data)
self.assertEqual(response, (1, False))
def test_execute(self):
self._test_execute(user_data=self.fake_data, exception=False)
def test_execute_no_data(self):
self._test_execute(user_data=None, exception=False)
def test_execute_exception(self):
self._test_execute(user_data=None, exception=True)
@mock.patch('cloudbaseinit.plugins.windows.userdata.handle')
@mock.patch('cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
'._parse_mime')
@mock.patch('cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
'._process_part')
def _test_process_userdata(self, mock_process_part, mock_parse_mime,
mock_handle, user_data):
mock_process_part().__iter__.side_effect = ['fake']
self._userdata._process_userdata(user_data)
print mock_parse_mime.mock_calls
print mock_process_part.mock_calls
if user_data.startswith('Content-Type: multipart'):
mock_parse_mime.assert_called_once_with(user_data)
self.assertEqual(mock_process_part.call_count, 1)
else:
mock_handle.assert_called_once_with(user_data)
def test_process_userdata_multipart(self):
user_data = 'Content-Type: multipart fake data'
self._test_process_userdata(user_data=user_data)
def test_process_userdata(self):
user_data = 'fake data'
self._test_process_userdata(user_data=user_data)
@mock.patch('cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
'._get_part_handler')
@mock.patch('cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
'._begin_part_process_event')
@mock.patch('cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
'._end_part_process_event')
def test_process_part(self, mock_end_part_process_event,
mock_begin_part_process_event,
mock_get_part_handler):
mock_part = mock.MagicMock()
mock_part_handler = mock.MagicMock()
mock_get_part_handler.return_value = mock_part_handler
self._userdata._process_part(mock_part)
mock_get_part_handler.assert_called_once_with(mock_part)
mock_begin_part_process_event.assert_called_once_with(mock_part)
mock_part.get_content_type.assert_called_once_with()
mock_part.get_filename.assert_called_once_with()
mock_part_handler.process.assert_called_with(mock_part)
mock_end_part_process_event.assert_called_with(mock_part)
@mock.patch('cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
'._get_custom_handler')
def test_begin_part_process_event(self, mock_get_custom_handler):
mock_part = mock.MagicMock()
mock_handler = mock.MagicMock()
mock_get_custom_handler.return_value = mock_handler
self._userdata._begin_part_process_event(mock_part)
mock_part.get_filename.assert_called_with()
mock_part.get_payload.assert_called_with()
mock_handler.assert_called_with("", "__begin__",
mock_part.get_filename(),
mock_part.get_payload())
@mock.patch('cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
'._get_custom_handler')
def test_end_part_process_event(self, mock_get_custom_handler):
mock_part = mock.MagicMock()
mock_handler = mock.MagicMock()
mock_get_custom_handler.return_value = mock_handler
self._userdata._end_part_process_event(mock_part)
mock_part.get_payload.assert_called_with()
mock_handler.assert_called_with("", "__end__",
mock_part.get_filename(),
mock_part.get_payload())
def test_get_custom_handler(self):
mock_part = mock.MagicMock()
mock_part.get_content_type.return_value = 0
self._userdata.plugin_set.has_custom_handlers = True
self._userdata.plugin_set.custom_handlers = [0]
response = self._userdata._get_custom_handler(mock_part)
mock_part.get_content_type.assert_called_with()
self.assertEqual(response, 0)
def test_get_part_handler(self):
mock_part = mock.MagicMock()
mock_part.get_content_type.return_value = 0
self._userdata.plugin_set.set = {0: 'fake value'}
response = self._userdata._get_part_handler(mock_part)
mock_part.get_content_type.assert_called_with()
self.assertEqual(response, 'fake value')
@mock.patch('email.message_from_string')
def test_parse_mime(self, mock_message_from_string):
mock_msg = mock.MagicMock()
mock_message_from_string.return_value = mock_msg
response = self._userdata._parse_mime(self.fake_data)
mock_message_from_string.assert_called_once_with(self.fake_data)
mock_msg.walk.assert_called_once_with()
self.assertEqual(response, mock_msg.walk())
@mock.patch('re.search')
@mock.patch('tempfile.gettempdir')
@mock.patch('os.remove')
@mock.patch('os.path.isdir')
@mock.patch('os.path.join')
@mock.patch('os.path.exists')
@mock.patch('os.path.expandvars')
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
def _test_handle(self, mock_get_os_utils, mock_path_expandvars,
mock_path_exists, mock_path_join, mock_path_isdir,
mock_os_remove, mock_gettempdir, mock_re_search,
fake_user_data, directory_exists):
#TODO: recheck, these are old!
mock_osutils = mock.MagicMock()
uuid.uuid4 = mock.MagicMock(return_value='randomID')
mock_path_join.return_value = 'fake_temp\\randomID'
match_instance = mock.MagicMock()
path = 'fake_temp\\randomID'
args = None
mock_get_os_utils.return_value = mock_osutils
if fake_user_data == '^rem cmd\s':
side_effect = [match_instance]
number_of_calls = 1
extension = '.cmd'
args = [path+extension]
shell = True
elif fake_user_data == '#!':
side_effect = [None, match_instance]
number_of_calls = 2
extension = '.sh'
args = ['bash.exe', path+extension]
shell = False
elif fake_user_data == '#ps1\s':
side_effect = [None, None, match_instance]
number_of_calls = 3
extension = '.ps1'
args = ['powershell.exe', '-ExecutionPolicy', 'RemoteSigned',
'-NonInteractive', path+extension]
shell = False
else:
side_effect = [None, None, None, match_instance]
number_of_calls = 4
extension = '.ps1'
shell = False
if directory_exists:
args = [mock_path_expandvars('%windir%\\sysnative\\'
'WindowsPowerShell\\v1.0\\'
'powershell.exe'),
'-ExecutionPolicy',
'RemoteSigned', '-NonInteractive', path+extension]
mock_path_isdir.return_value = True
else:
mock_path_isdir.return_value = False
mock_re_search.side_effect = side_effect
with mock.patch('cloudbaseinit.plugins.windows.userdata.open',
mock.mock_open(), create=True):
response = userdata.handle(fake_user_data)
tempfile.gettempdir.assert_called_once_with()
mock_path_join.assert_called_once_with(mock_gettempdir(),
str(uuid.uuid4()))
assert mock_re_search.call_count == number_of_calls
if args:
mock_osutils.execute_process.assert_called_with(args, shell)
self.assertEqual(response, (1, False))
def test_handle_batch(self):
fake_user_data = '^rem cmd\s'
self._test_handle(fake_user_data=fake_user_data,
directory_exists=True)
def test_handle_shell(self):
fake_user_data = '^#!'
self._test_handle(fake_user_data=fake_user_data,
directory_exists=True)
def test_handle_powershell(self):
fake_user_data = '^#ps1\s'
self._test_handle(fake_user_data=fake_user_data,
directory_exists=True)
def test_handle_powershell_sysnative(self):
fake_user_data = '#ps1_sysnative\s'
self._test_handle(fake_user_data=fake_user_data,
directory_exists=True)
def test_handle_powershell_sysnative_no_sysnative(self):
fake_user_data = '#ps1_sysnative\s'
self._test_handle(fake_user_data=fake_user_data,
directory_exists=False)

View File

@ -0,0 +1,43 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Mirantis Inc.
# 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 mock
import unittest
from cloudbaseinit.plugins.windows import userdata_plugins
class MultipartUserDataPluginTest(unittest.TestCase):
def setUp(self):
fake_path = 'fake path'
self._userdata = userdata_plugins.PluginSet(fake_path)
@mock.patch('glob.glob')
@mock.patch('cloudbaseinit.plugins.windows.userdata_plugins.'
'load_from_file')
def test_load(self, mock_load_from_file, mock_glob):
fake_files = ['fake_file.py']
mock_plugin = mock.MagicMock()
mock_glob.return_value = fake_files
mock_load_from_file.return_value = mock_plugin
self._userdata.load()
mock_glob.assert_called_once_with(self._userdata.path + '/*.py')
mock_load_from_file.assert_called_once_with('fake_file.py',
self._userdata)
self.assertEqual(self._userdata.set[mock_plugin.type], mock_plugin)

View File

@ -0,0 +1,156 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 importlib
import mock
import sys
import unittest
_ctypes_mock = mock.MagicMock()
_win32com_mock = mock.MagicMock()
_pywintypes_mock = mock.MagicMock()
mock_dict = {'ctypes': _ctypes_mock,
'win32com': _win32com_mock,
'pywintypes': _pywintypes_mock}
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins import constants
CONF = cfg.CONF
class ConfigWinRMCertificateAuthPluginTests(unittest.TestCase):
@mock.patch.dict(sys.modules, mock_dict)
def setUp(self):
winrmcert = importlib.import_module('cloudbaseinit.plugins.windows.'
'winrmcertificateauth')
self.x509 = importlib.import_module('cloudbaseinit.plugins.windows'
'.x509')
self._certif_auth = winrmcert.ConfigWinRMCertificateAuthPlugin()
def tearDown(self):
reload(sys)
def _test_get_client_auth_cert(self, chunk):
mock_service = mock.MagicMock()
mock_meta_data = mock.MagicMock()
mock_meta = mock.MagicMock()
mock_service.get_meta_data.return_value = mock_meta_data
mock_meta_data.get.return_value = mock_meta
mock_meta.get.side_effect = chunk
mock_service.get_user_data.return_value = self.x509.PEM_HEADER
response = self._certif_auth._get_client_auth_cert(mock_service)
mock_service.get_meta_data.assert_called_once_with('openstack')
mock_meta_data.get.assert_called_once_with('meta')
if chunk == [None]:
mock_service.get_user_data.assert_called_once_with('openstack')
mock_meta.get.assert_called_once_with('admin_cert0')
self.assertEqual(response, self.x509.PEM_HEADER)
else:
expected = [mock.call('admin_cert0'), mock.call('admin_cert1')]
self.assertEqual(mock_meta.get.call_args_list, expected)
self.assertEqual(response, 'fake data')
def test_get_client_auth_cert(self):
chunk = ['fake data', None]
self._test_get_client_auth_cert(chunk=chunk)
def test_get_client_auth_cert_no_cert_data(self):
self._test_get_client_auth_cert(chunk=[None])
def _test_get_credentials(self, fake_user, fake_password):
mock_shared_data = mock.MagicMock()
mock_shared_data.get.side_effect = [fake_user, fake_password]
if fake_user is None or fake_password is None:
self.assertRaises(Exception,
self._certif_auth._get_credentials,
mock_shared_data)
else:
response = self._certif_auth._get_credentials(mock_shared_data)
expected = [mock.call(constants.SHARED_DATA_USERNAME),
mock.call(constants.SHARED_DATA_PASSWORD)]
self.assertEqual(mock_shared_data.get.call_args_list, expected)
mock_shared_data.__setitem__.assert_called_once_with(
'admin_password', None)
self.assertEqual(response, (fake_user, fake_password))
def test_test_get_credentials(self):
self._test_get_credentials(fake_user='fake user',
fake_password='fake password')
def test_test_get_credentials_no_user(self):
self._test_get_credentials(fake_user=None,
fake_password='fake password')
def test_test_get_credentials_no_password(self):
self._test_get_credentials(fake_user='fake user',
fake_password=None)
@mock.patch('cloudbaseinit.plugins.windows.winrmcertificateauth'
'.ConfigWinRMCertificateAuthPlugin._get_credentials')
@mock.patch('cloudbaseinit.plugins.windows.winrmcertificateauth'
'.ConfigWinRMCertificateAuthPlugin._get_client_auth_cert')
@mock.patch('cloudbaseinit.plugins.windows.x509.CryptoAPICertManager'
'.import_cert')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig')
def _test_execute(self, mock_WinRMConfig, mock_import_cert,
mock_get_client_auth_cert, mock_get_credentials,
cert_data, cert_upn):
mock_service = mock.MagicMock()
mock_cert_thumprint = mock.MagicMock()
fake_credentials = ('fake user', 'fake password')
mock_shared_data = mock.MagicMock()
mock_get_client_auth_cert.return_value = cert_data
mock_get_credentials.return_value = fake_credentials
mock_import_cert.return_value = (mock_cert_thumprint, cert_upn)
mock_WinRMConfig.get_cert_mapping.return_value = True
response = self._certif_auth.execute(mock_service,
mock_shared_data)
if not cert_data or not cert_upn:
self.assertEqual(response, (1, False))
else:
mock_get_client_auth_cert.assert_called_once_with(mock_service)
mock_get_credentials.assert_called_once_with(mock_shared_data)
mock_import_cert.assert_called_once_with(
cert_data, store_name=self.x509.STORE_NAME_ROOT)
mock_WinRMConfig().set_auth_config.assert_called_once_with(
certificate=True)
mock_WinRMConfig().get_cert_mapping.assert_called_once_with(
mock_cert_thumprint, cert_upn)
mock_WinRMConfig().delete_cert_mapping.assert_called_once_with(
mock_cert_thumprint, cert_upn)
mock_WinRMConfig().create_cert_mapping.assert_called_once_with(
mock_cert_thumprint, cert_upn, 'fake user',
'fake password')
self.assertEqual(response, (1, False))
def test_execute(self):
cert_data = 'fake cert data'
cert_upn = mock.MagicMock()
self._test_execute(cert_data=cert_data, cert_upn=cert_upn)
def test_execute_no_cert_data(self):
cert_upn = mock.MagicMock()
self._test_execute(cert_data=None, cert_upn=cert_upn)
def test_execute_no_cert_upn(self):
cert_data = 'fake cert data'
self._test_execute(cert_data=cert_data, cert_upn=None)

View File

@ -0,0 +1,378 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import sys
import unittest
from cloudbaseinit.openstack.common import cfg
if sys.platform == 'win32':
from cloudbaseinit.plugins.windows import winrmconfig
CONF = cfg.CONF
@unittest.skipUnless(sys.platform == "win32", "requires Windows")
class WinRMConfigTests(unittest.TestCase):
def setUp(self):
self._winrmconfig = winrmconfig.WinRMConfig()
@mock.patch('win32com.client.Dispatch')
def test_get_wsman_session(self, mock_Dispatch):
mock_wsman = mock.MagicMock()
mock_Dispatch.return_value = mock_wsman
response = self._winrmconfig._get_wsman_session()
mock_Dispatch.assert_called_once_with('WSMan.Automation')
mock_wsman.CreateSession.assert_called_once_with()
self.assertEqual(response, mock_wsman.CreateSession())
@mock.patch('re.match')
def test_get_node_tag(self, mock_match):
mock_tag = mock.MagicMock()
response = self._winrmconfig._get_node_tag(mock_tag)
mock_match.assert_called_once_with("^{.*}(.*)$", mock_tag)
self.assertEqual(response, mock_match().groups().__getitem__())
@mock.patch('xml.etree.ElementTree.fromstring')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_node_tag')
def _test_parse_listener_xml(self, mock_get_node_tag, mock_fromstring,
data_xml, tag=None, text='Fake'):
mock_node = mock.MagicMock()
mock_node.tag = tag
mock_node.text = text
fake_tree = [mock_node]
mock_get_node_tag.return_value = tag
mock_fromstring.return_value = fake_tree
response = self._winrmconfig._parse_listener_xml(data_xml=data_xml)
if data_xml is None:
self.assertEqual(response, None)
else:
mock_fromstring.assert_called_once_with(data_xml)
mock_get_node_tag.assert_called_once_with(tag)
if tag is "ListeningOn":
self.assertEqual(response, {'ListeningOn': ['Fake']})
elif tag is "Enabled":
if text is 'true':
self.assertEqual(response, {'ListeningOn': [],
'Enabled': True})
else:
self.assertEqual(response, {'ListeningOn': [],
'Enabled': False})
elif tag is 'Port':
self.assertEqual(response, {'ListeningOn': [],
'Port': int(text)})
else:
self.assertEqual(response, {'ListeningOn': [],
tag: text})
def test_parse_listener_xml_no_data(self):
self._test_parse_listener_xml(data_xml=None)
def test_parse_listener_xml_listening_on(self):
self._test_parse_listener_xml(data_xml='fake data', tag="ListeningOn")
def test_parse_listener_xml_enabled_true(self):
self._test_parse_listener_xml(data_xml='fake data',
tag="Enabled", text='true')
def test_parse_listener_xml_enabled_false(self):
self._test_parse_listener_xml(data_xml='fake data', tag='Enabled',
text='false')
def test_parse_listener_xml_port(self):
self._test_parse_listener_xml(data_xml='fake data', tag='Port',
text='9999')
def test_parse_listener_xml_other_tag(self):
self._test_parse_listener_xml(data_xml='fake data', tag='fake tag',
text='fake text')
@mock.patch('xml.etree.ElementTree.fromstring')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_node_tag')
def _test_parse_cert_mapping_xml(self, mock_get_node_tag,
mock_fromstring, data_xml, tag=None,
text='Fake'):
mock_node = mock.MagicMock()
mock_node.tag = tag
mock_node.text = text
fake_tree = [mock_node]
mock_get_node_tag.return_value = tag
mock_fromstring.return_value = fake_tree
response = self._winrmconfig._parse_cert_mapping_xml(data_xml=data_xml)
if data_xml is None:
self.assertEqual(response, None)
else:
mock_fromstring.assert_called_once_with(data_xml)
mock_get_node_tag.assert_called_once_with(tag)
if tag is "Enabled":
if text is 'true':
self.assertEqual(response, {'Enabled': True})
else:
self.assertEqual(response, {'Enabled': False})
else:
self.assertEqual(response, {tag: text})
def test_parse_cert_mapping_xml_no_data(self):
self._test_parse_cert_mapping_xml(data_xml=None)
def test_parse_cert_mapping_xml_enabled_true(self):
self._test_parse_listener_xml(data_xml='fake data',
tag="Enabled", text='true')
def test_parse_cert_mapping_xml_enabled_false(self):
self._test_parse_listener_xml(data_xml='fake data', tag='Enabled',
text='false')
def test_parse_cert_mapping_xml_other_tag(self):
self._test_parse_listener_xml(data_xml='fake data', tag='fake tag',
text='fake text')
def _test_get_xml_bool(self, value):
response = self._winrmconfig._get_xml_bool(value)
if value:
self.assertEqual(response, 'true')
else:
self.assertEqual(response, 'false')
def test_get_xml_bool_true(self):
self._test_get_xml_bool(value='fake value')
def test_get_xml_bool_false(self):
self._test_get_xml_bool(value=None)
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_wsman_session')
def _test_get_resource(self, mock_get_wsman_session, resource):
fake_session = mock.MagicMock()
fake_uri = 'fake:\\uri'
fake_session.Get.side_effect = [resource]
mock_get_wsman_session.return_value = fake_session
if resource is Exception:
self.assertRaises(Exception, self._winrmconfig._get_resource,
fake_uri)
else:
response = self._winrmconfig._get_resource(fake_uri)
mock_get_wsman_session.assert_called_once_with()
fake_session.Get.assert_called_once_with(fake_uri)
self.assertEqual(response, resource)
def test_get_resource(self):
self._test_get_resource(resource='fake resource')
def test_get_resource_exception(self):
self._test_get_resource(resource=Exception)
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_wsman_session')
def test_delete_resource(self, mock_get_wsman_session):
fake_session = mock.MagicMock()
fake_uri = 'fake:\\uri'
mock_get_wsman_session.return_value = fake_session
self._winrmconfig._delete_resource(fake_uri)
fake_session.Delete.assert_called_once_with(fake_uri)
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_wsman_session')
def test_create_resource(self, mock_get_wsman_session):
fake_session = mock.MagicMock()
fake_uri = 'fake:\\uri'
mock_get_wsman_session.return_value = fake_session
self._winrmconfig._create_resource(fake_uri, 'fake data')
fake_session.Create.assert_called_once_with(fake_uri, 'fake data')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_parse_cert_mapping_xml')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_resource')
def test_get_cert_mapping(self, mock_get_resource,
mock_parse_cert_mapping_xml):
fake_dict = {'issuer': 'issuer',
'subject': 'subject',
'uri': 'fake:\\uri'}
mock_parse_cert_mapping_xml.return_value = 'fake response'
mock_get_resource.return_value = 'fake resource'
response = self._winrmconfig.get_cert_mapping('issuer', 'subject',
uri='fake:\\uri')
mock_parse_cert_mapping_xml.assert_called_with('fake resource')
mock_get_resource.assert_called_with(
self._winrmconfig._SERVICE_CERTMAPPING_URI % fake_dict)
self.assertEqual(response, 'fake response')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_delete_resource')
def test_delete_cert_mapping(self, mock_delete_resource):
fake_dict = {'issuer': 'issuer',
'subject': 'subject',
'uri': 'fake:\\uri'}
self._winrmconfig.delete_cert_mapping('issuer', 'subject',
uri='fake:\\uri')
mock_delete_resource.assert_called_with(
self._winrmconfig._SERVICE_CERTMAPPING_URI % fake_dict)
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_xml_bool')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_create_resource')
def test_create_cert_mapping(self, mock_create_resource,
mock_get_xml_bool):
fake_dict = {'issuer': 'issuer',
'subject': 'subject',
'uri': 'fake:\\uri'}
mock_get_xml_bool.return_value = True
self._winrmconfig.create_cert_mapping(
issuer='issuer', subject='subject', username='fake user',
password='fake password', uri='fake:\\uri', enabled=True)
mock_get_xml_bool.assert_called_once_with(True)
mock_create_resource.assert_called_once_with(
self._winrmconfig._SERVICE_CERTMAPPING_URI % fake_dict,
'<p:certmapping xmlns:p="http://schemas.microsoft.com/wbem/wsman/'
'1/config/service/certmapping.xsd">'
'<p:Enabled>%(enabled)s</p:Enabled>'
'<p:Password>%(password)s</p:Password>'
'<p:UserName>%(username)s</p:UserName>'
'</p:certmapping>' % {'enabled': True,
'username': 'fake user',
'password': 'fake password'})
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_resource')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_parse_listener_xml')
def test_get_listener(self, mock_parse_listener_xml, mock_get_resource):
dict = {'protocol': 'HTTPS',
'address': 'fake:\\address'}
mock_get_resource.return_value = 'fake resource'
mock_parse_listener_xml.return_value = 'fake response'
response = self._winrmconfig.get_listener(protocol='HTTPS',
address="fake:\\address")
mock_get_resource.assert_called_with(
self._winrmconfig._SERVICE_LISTENER_URI % dict)
mock_parse_listener_xml.assert_called_once_with('fake resource')
self.assertEqual(response, 'fake response')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_delete_resource')
def test_delete_listener(self, mock_delete_resource):
dict = {'protocol': 'HTTPS',
'address': 'fake:\\address'}
self._winrmconfig.delete_listener(protocol='HTTPS',
address="fake:\\address")
mock_delete_resource.assert_called_with(
self._winrmconfig._SERVICE_LISTENER_URI % dict)
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_create_resource')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_xml_bool')
def test_create_listener(self, mock_get_xml_bool, mock_create_resource):
dict = {'protocol': 'HTTPS',
'address': 'fake:\\address'}
mock_get_xml_bool.return_value = True
self._winrmconfig.create_listener(protocol='HTTPS',
cert_thumbprint=None,
address="fake:\\address",
enabled=True)
mock_create_resource.assert_called_once_with(
self._winrmconfig._SERVICE_LISTENER_URI % dict,
'<p:Listener xmlns:p="http://schemas.microsoft.com/'
'wbem/wsman/1/config/listener.xsd">'
'<p:Enabled>%(enabled)s</p:Enabled>'
'<p:CertificateThumbPrint>%(cert_thumbprint)s'
'</p:CertificateThumbPrint>'
'<p:URLPrefix>wsman</p:URLPrefix>'
'</p:Listener>' % {"enabled": True,
"cert_thumbprint": None})
@mock.patch('xml.etree.ElementTree.fromstring')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_node_tag')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_resource')
def test_get_auth_config(self, mock_get_resource, mock_get_node_tag,
mock_fromstring):
mock_node = mock.MagicMock()
mock_node.tag = 'tag'
mock_node.text = 'value'
fake_tree = [mock_node]
mock_get_resource.return_value = 'fake data xml'
mock_fromstring.return_value = fake_tree
mock_get_node_tag.return_value = 'tag'
response = self._winrmconfig.get_auth_config()
mock_get_resource.assert_called_with(
self._winrmconfig._SERVICE_AUTH_URI)
mock_fromstring.assert_called_once_with('fake data xml')
mock_get_node_tag.assert_called_once_with(mock_node.tag)
self.assertEqual(response, {'tag': 'value'})
@mock.patch('xml.etree.ElementTree.fromstring')
@mock.patch('xml.etree.ElementTree.tostring')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_wsman_session')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig.'
'_get_xml_bool')
def test_set_auth_config(self, mock_get_xml_bool, mock_get_wsman_session,
mock_tostring, mock_fromstring):
mock_session = mock.MagicMock()
mock_tree = mock.MagicMock()
mock_node = mock.MagicMock()
base_url = 'http://schemas.microsoft.com/wbem/wsman/1/config/service/'
expected_find = [
mock.call('.//cfg:Certificate', namespaces={
'cfg': base_url + 'auth'}),
mock.call('.//cfg:Kerberos',
namespaces={'cfg': base_url + 'auth'}),
mock.call('.//cfg:CbtHardeningLevel',
namespaces={'cfg': base_url + 'auth'}),
mock.call('.//cfg:Negotiate',
namespaces={'cfg': base_url + 'auth'}),
mock.call('.//cfg:CredSSP',
namespaces={'cfg': base_url + 'auth'}),
mock.call('.//cfg:Basic',
namespaces={'cfg': base_url + 'auth'})]
expected_get_xml_bool = [mock.call('certificate'),
mock.call('kerberos'),
mock.call('cbt_hardening_level'),
mock.call('negotiate'),
mock.call('credSSP'),
mock.call('basic')]
mock_get_wsman_session.return_value = mock_session
mock_session.Get.return_value = 'fake xml'
mock_fromstring.return_value = mock_tree
mock_get_xml_bool.return_value = 'true'
mock_tostring.return_value = 'fake xml'
mock_tree.find.return_value = mock_node
mock_node.text.lower.return_value = 'old value'
self._winrmconfig.set_auth_config(
basic='basic', kerberos='kerberos', negotiate='negotiate',
certificate='certificate', credSSP='credSSP',
cbt_hardening_level='cbt_hardening_level')
self.assertEqual(mock_tree.find.call_args_list, expected_find)
self.assertEqual(mock_get_xml_bool.call_args_list,
expected_get_xml_bool)
mock_get_wsman_session.assert_called_once_with()
mock_session.Get.assert_called_with(
self._winrmconfig._SERVICE_AUTH_URI)
mock_fromstring.assert_called_once_with('fake xml')
mock_session.Put.assert_called_with(
self._winrmconfig._SERVICE_AUTH_URI, 'fake xml')

View File

@ -0,0 +1,117 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 importlib
import mock
import sys
import unittest
from cloudbaseinit.openstack.common import cfg
CONF = cfg.CONF
_mock_wintypes = mock.MagicMock()
mock_dict = {'ctypes.wintypes': _mock_wintypes}
class ConfigWinRMListenerPluginTests(unittest.TestCase):
@mock.patch.dict(sys.modules, mock_dict)
def setUp(self):
winrmlistener = importlib.import_module('cloudbaseinit.plugins.'
'windows.winrmlistener')
self._winrmlistener = winrmlistener.ConfigWinRMListenerPlugin()
def _test_check_winrm_service(self, service_exists):
mock_osutils = mock.MagicMock()
mock_osutils.check_service_exists.return_value = service_exists
mock_osutils.SERVICE_START_MODE_MANUAL = 'fake start'
mock_osutils.SERVICE_START_MODE_DISABLED = 'fake start'
mock_osutils.SERVICE_STATUS_STOPPED = 'fake status'
mock_osutils.get_service_start_mode.return_value = 'fake start'
mock_osutils.get_service_status.return_value = 'fake status'
response = self._winrmlistener._check_winrm_service(mock_osutils)
if not service_exists:
self.assertEqual(response, False)
else:
mock_osutils.get_service_start_mode.assert_called_once_with(
self._winrmlistener._winrm_service_name)
mock_osutils.get_service_start_mode.assert_called_once_with(
self._winrmlistener._winrm_service_name)
mock_osutils.set_service_start_mode.assert_called_once_with(
self._winrmlistener._winrm_service_name,
mock_osutils .SERVICE_START_MODE_AUTOMATIC)
mock_osutils.get_service_status.assert_called_once_with(
self._winrmlistener._winrm_service_name)
mock_osutils.start_service.assert_called_once_with(
self._winrmlistener._winrm_service_name)
self.assertEqual(response, True)
def test_check_winrm_service(self):
self._test_check_winrm_service(service_exists=True)
def test_check_winrm_service_no_service(self):
self._test_check_winrm_service(service_exists=False)
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
@mock.patch('cloudbaseinit.plugins.windows.winrmlistener.'
'ConfigWinRMListenerPlugin._check_winrm_service')
@mock.patch('cloudbaseinit.plugins.windows.winrmconfig.WinRMConfig')
@mock.patch('cloudbaseinit.plugins.windows.x509.CryptoAPICertManager'
'.create_self_signed_cert')
def _test_execute(self, mock_create_cert, mock_WinRMConfig,
mock_check_winrm_service, mock_get_os_utils,
service_status):
mock_service = mock.MagicMock()
mock_listener_config = mock.MagicMock()
mock_cert_thumbprint = mock.MagicMock()
shared_data = 'fake data'
mock_osutils = mock.MagicMock()
mock_get_os_utils.return_value = mock_osutils
mock_check_winrm_service.return_value = service_status
mock_create_cert.return_value = mock_cert_thumbprint
mock_WinRMConfig().get_listener.return_value = mock_listener_config
mock_listener_config.get.return_value = 9999
response = self._winrmlistener.execute(mock_service, shared_data)
mock_get_os_utils.assert_called_once_with()
mock_check_winrm_service.assert_called_once_with(mock_osutils)
if not service_status:
self.assertEqual(response, (2, False))
else:
mock_WinRMConfig().set_auth_config.assert_called_once_with(
basic=CONF.winrm_enable_basic_auth)
mock_create_cert.assert_called_once_with(
self._winrmlistener._cert_subject)
mock_WinRMConfig().get_listener.assert_called_with(
protocol="HTTPS")
mock_WinRMConfig().delete_listener.assert_called_once_with(
protocol="HTTPS")
mock_WinRMConfig().create_listener.assert_called_once_with(
protocol="HTTPS", cert_thumbprint=mock_cert_thumbprint)
mock_listener_config.get.assert_called_once_with("Port")
mock_osutils.firewall_create_rule.assert_called_once_with(
"WinRM HTTPS", 9999, mock_osutils.PROTOCOL_TCP)
self.assertEqual(response, (1, False))
def test_execute(self):
self._test_execute(service_status=True)
def test_execute_service_status_is_false(self):
self._test_execute(service_status=False)

View File

@ -0,0 +1,383 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import sys
import unittest
from cloudbaseinit.openstack.common import cfg
if sys.platform == 'win32':
from cloudbaseinit.plugins.windows import cryptoapi
from cloudbaseinit.plugins.windows import x509
CONF = cfg.CONF
@unittest.skipUnless(sys.platform == "win32", "requires Windows")
class CryptoAPICertManagerTests(unittest.TestCase):
def setUp(self):
self._x509 = x509.CryptoAPICertManager()
@mock.patch('cloudbaseinit.plugins.windows.x509.free')
@mock.patch('ctypes.c_ubyte')
@mock.patch('ctypes.POINTER')
@mock.patch('ctypes.cast')
@mock.patch('cloudbaseinit.plugins.windows.x509.malloc')
@mock.patch('ctypes.byref')
@mock.patch('ctypes.wintypes.DWORD')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertGetCertificateContextProperty')
def _test_get_cert_thumprint(self,
mock_CertGetCertificateContextProperty,
mock_DWORD, mock_byref, mock_malloc,
mock_cast, mock_POINTER, mock_c_ubyte,
mock_free, ret_val):
mock_pointer = mock.MagicMock()
fake_cert_context_p = 'fake context'
mock_DWORD().value = 10
mock_CertGetCertificateContextProperty.return_value = ret_val
mock_POINTER.return_value = mock_pointer
mock_cast().contents = [16]
if not ret_val:
self.assertRaises(cryptoapi.CryptoAPIException,
self._x509._get_cert_thumprint,
fake_cert_context_p)
else:
expected = [mock.call(fake_cert_context_p,
cryptoapi.CERT_SHA1_HASH_PROP_ID,
None, mock_byref()),
mock.call(fake_cert_context_p,
cryptoapi.CERT_SHA1_HASH_PROP_ID,
mock_malloc(), mock_byref())]
response = self._x509._get_cert_thumprint(fake_cert_context_p)
self.assertEqual(
mock_CertGetCertificateContextProperty.call_args_list,
expected)
mock_malloc.assert_called_with(mock_DWORD())
mock_cast.assert_called_with(mock_malloc(), mock_pointer)
mock_free.assert_called_with(mock_malloc())
self.assertEqual(response, '10')
def test_get_cert_thumprint(self):
self._test_get_cert_thumprint(ret_val=True)
def test_get_cert_thumprint_GetCertificateContextProperty_exception(self):
self._test_get_cert_thumprint(ret_val=False)
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CryptDestroyKey')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CryptReleaseContext')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CryptGenKey')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CryptAcquireContext')
@mock.patch('ctypes.byref')
@mock.patch('ctypes.wintypes.HANDLE')
def _test_generate_key(self, mock_HANDLE, mock_byref,
mock_CryptAcquireContext, mock_CryptGenKey,
mock_CryptReleaseContext, mock_CryptDestroyKey,
acquired_context, generate_key_ret_val):
mock_CryptAcquireContext.return_value = acquired_context
mock_CryptGenKey.return_value = generate_key_ret_val
if not acquired_context:
self.assertRaises(cryptoapi.CryptoAPIException,
self._x509._generate_key,
'fake container', True)
else:
if generate_key_ret_val is None:
self.assertRaises(cryptoapi.CryptoAPIException,
self._x509._generate_key, 'fake container',
True)
mock_byref.assert_called_with(mock_HANDLE())
else:
self._x509._generate_key('fake container', True)
mock_CryptAcquireContext.assert_called_with(
mock_byref(), 'fake container', None,
cryptoapi.PROV_RSA_FULL, cryptoapi.CRYPT_MACHINE_KEYSET)
mock_CryptGenKey.assert_called_with(mock_HANDLE(),
cryptoapi.AT_SIGNATURE,
0x08000000, mock_HANDLE())
mock_CryptDestroyKey.assert_called_once_with(
mock_HANDLE())
mock_CryptReleaseContext.assert_called_once_with(
mock_HANDLE(), 0)
def test_generate_key(self):
self._test_generate_key(acquired_context=True,
generate_key_ret_val='fake key')
def test_generate_key_GetCertificateContextProperty_exception(self):
self._test_generate_key(acquired_context=False,
generate_key_ret_val='fake key')
def test_generate_key_CryptGenKey_exception(self):
self._test_generate_key(acquired_context=True,
generate_key_ret_val=None)
@mock.patch('cloudbaseinit.plugins.windows.x509.free')
@mock.patch('copy.copy')
@mock.patch('ctypes.byref')
@mock.patch('cloudbaseinit.plugins.windows.x509.malloc')
@mock.patch('ctypes.POINTER')
@mock.patch('ctypes.cast')
@mock.patch('cloudbaseinit.plugins.windows.x509.CryptoAPICertManager'
'._generate_key')
@mock.patch('cloudbaseinit.plugins.windows.x509.CryptoAPICertManager'
'._get_cert_thumprint')
@mock.patch('uuid.uuid4')
@mock.patch('ctypes.wintypes.DWORD')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertStrToName')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CRYPTOAPI_BLOB')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CRYPT_KEY_PROV_INFO')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CRYPT_ALGORITHM_IDENTIFIER')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'SYSTEMTIME')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'GetSystemTime')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertCreateSelfSignCertificate')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertAddEnhancedKeyUsageIdentifier')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertOpenStore')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertAddCertificateContextToStore')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertCloseStore')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertFreeCertificateContext')
def _test_create_self_signed_cert(self, mock_CertFreeCertificateContext,
mock_CertCloseStore,
mock_CertAddCertificateContextToStore,
mock_CertOpenStore,
mock_CertAddEnhancedKeyUsageIdentifier,
mock_CertCreateSelfSignCertificate,
mock_GetSystemTime, mock_SYSTEMTIME,
mock_CRYPT_ALGORITHM_IDENTIFIER,
mock_CRYPT_KEY_PROV_INFO,
mock_CRYPTOAPI_BLOB,
mock_CertStrToName, mock_DWORD,
mock_uuid4, mock_get_cert_thumprint,
mock_generate_key, mock_cast,
mock_POINTER, mock_malloc, mock_byref,
mock_copy, mock_free, certstr,
certificate, enhanced_key,
store_handle, context_to_store):
mock_uuid4.return_value = 'fake_name'
mock_CertCreateSelfSignCertificate.return_value = certificate
mock_CertAddEnhancedKeyUsageIdentifier.return_value = enhanced_key
mock_CertStrToName.return_value = certstr
mock_CertOpenStore.return_value = store_handle
mock_CertAddCertificateContextToStore.return_value = context_to_store
if (certstr is None or certificate is None or enhanced_key is None
or store_handle is None or context_to_store is None):
self.assertRaises(cryptoapi.CryptoAPIException,
self._x509.create_self_signed_cert,
'fake subject', 10, True, x509.STORE_NAME_MY)
else:
response = self._x509.create_self_signed_cert(
subject='fake subject')
mock_cast.assert_called_with(mock_malloc(), mock_POINTER())
mock_CRYPTOAPI_BLOB.assert_called_once_with()
mock_CRYPT_KEY_PROV_INFO.assert_called_once_with()
mock_CRYPT_ALGORITHM_IDENTIFIER.assert_called_once_with()
mock_SYSTEMTIME.assert_called_once_with()
mock_GetSystemTime.assert_called_once_with(mock_byref())
mock_copy.assert_called_once_with(mock_SYSTEMTIME())
mock_CertCreateSelfSignCertificate.assert_called_once_with(
None, mock_byref(), 0, mock_byref(),
mock_byref(), mock_byref(), mock_byref(), None)
mock_CertAddEnhancedKeyUsageIdentifier.assert_called_with(
mock_CertCreateSelfSignCertificate(),
cryptoapi.szOID_PKIX_KP_SERVER_AUTH)
mock_CertOpenStore.assert_called_with(
cryptoapi.CERT_STORE_PROV_SYSTEM, 0, 0,
cryptoapi.CERT_SYSTEM_STORE_LOCAL_MACHINE,
unicode(x509.STORE_NAME_MY))
mock_get_cert_thumprint.assert_called_once_with(
mock_CertCreateSelfSignCertificate())
mock_CertCloseStore.assert_called_once_with(store_handle, 0)
mock_CertFreeCertificateContext.assert_called_once_with(
mock_CertCreateSelfSignCertificate())
mock_free.assert_called_once_with(mock_cast())
self.assertEqual(response, mock_get_cert_thumprint())
mock_generate_key.assert_called_once_with('fake_name', True)
def test_create_self_signed_cert(self):
self._test_create_self_signed_cert(certstr='fake cert name',
certificate='fake certificate',
enhanced_key='fake key',
store_handle='fake handle',
context_to_store='fake context')
def test_create_self_signed_cert_CertStrToName_fail(self):
self._test_create_self_signed_cert(certstr=None,
certificate='fake certificate',
enhanced_key='fake key',
store_handle='fake handle',
context_to_store='fake context')
def test_create_self_signed_cert_CertCreateSelfSignCertificate_fail(self):
self._test_create_self_signed_cert(certstr='fake cert name',
certificate=None,
enhanced_key='fake key',
store_handle='fake handle',
context_to_store='fake context')
def test_create_self_signed_cert_AddEnhancedKeyUsageIdentifier_fail(self):
self._test_create_self_signed_cert(certstr='fake cert name',
certificate='fake certificate',
enhanced_key=None,
store_handle='fake handle',
context_to_store='fake context')
def test_create_self_signed_cert_CertOpenStore_fail(self):
self._test_create_self_signed_cert(certstr='fake cert name',
certificate='fake certificate',
enhanced_key='fake key',
store_handle=None,
context_to_store='fake context')
def test_create_self_signed_cert_AddCertificateContextToStore_fail(self):
self._test_create_self_signed_cert(certstr='fake cert name',
certificate='fake certificate',
enhanced_key='fake key',
store_handle='fake handle',
context_to_store=None)
def test_get_cert_base64(self):
fake_cert_data = ''
fake_cert_data += x509.PEM_HEADER + '\n'
fake_cert_data += 'fake cert' + '\n'
fake_cert_data += x509.PEM_FOOTER
response = self._x509._get_cert_base64(fake_cert_data)
self.assertEqual(response, 'fake cert')
@mock.patch('cloudbaseinit.plugins.windows.x509.free')
@mock.patch('cloudbaseinit.plugins.windows.x509.CryptoAPICertManager'
'._get_cert_thumprint')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertCloseStore')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertFreeCertificateContext')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertGetNameString')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertAddEncodedCertificateToStore')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CertOpenStore')
@mock.patch('cloudbaseinit.plugins.windows.cryptoapi.'
'CryptStringToBinaryA')
@mock.patch('cloudbaseinit.plugins.windows.x509.CryptoAPICertManager'
'._get_cert_base64')
@mock.patch('ctypes.POINTER')
@mock.patch('cloudbaseinit.plugins.windows.x509.malloc')
@mock.patch('ctypes.cast')
@mock.patch('ctypes.byref')
@mock.patch('ctypes.wintypes.DWORD')
@mock.patch('ctypes.create_unicode_buffer')
def _test_import_cert(self, mock_create_unicode_buffer, mock_DWORD,
mock_byref, mock_cast,
mock_malloc, mock_POINTER, mock_get_cert_base64,
mock_CryptStringToBinaryA, mock_CertOpenStore,
mock_CertAddEncodedCertificateToStore,
mock_CertGetNameString,
mock_CertFreeCertificateContext,
mock_CertCloseStore, mock_get_cert_thumprint,
mock_free, crypttstr, store_handle, add_enc_cert,
upn_len):
fake_cert_data = ''
fake_cert_data += x509.PEM_HEADER + '\n'
fake_cert_data += 'fake cert' + '\n'
fake_cert_data += x509.PEM_FOOTER
mock_get_cert_base64.return_value = 'fake cert'
mock_CryptStringToBinaryA.return_value = crypttstr
mock_CertOpenStore.return_value = store_handle
mock_CertAddEncodedCertificateToStore.return_value = add_enc_cert
mock_CertGetNameString.side_effect = [2, upn_len]
expected = [mock.call('fake cert', len('fake cert'),
cryptoapi.CRYPT_STRING_BASE64, None,
mock_byref(), None, None),
mock.call('fake cert', len('fake cert'),
cryptoapi.CRYPT_STRING_BASE64, mock_cast(),
mock_byref(), None, None)]
expected2 = [mock.call(mock_POINTER()(), cryptoapi.CERT_NAME_UPN_TYPE,
0, None, None, 0),
mock.call(mock_POINTER()(), cryptoapi.CERT_NAME_UPN_TYPE,
0, None, mock_create_unicode_buffer(), 2)]
if (not crypttstr or store_handle is None or add_enc_cert is None or
upn_len != 2):
self.assertRaises(cryptoapi.CryptoAPIException,
self._x509.import_cert, fake_cert_data, True,
x509.STORE_NAME_MY)
else:
response = self._x509.import_cert(fake_cert_data)
mock_cast.assert_called_with(mock_malloc(), mock_POINTER())
self.assertEqual(mock_CryptStringToBinaryA.call_args_list,
expected)
mock_CertOpenStore.assert_called_with(
cryptoapi.CERT_STORE_PROV_SYSTEM, 0, 0,
cryptoapi.CERT_SYSTEM_STORE_LOCAL_MACHINE,
unicode(x509.STORE_NAME_MY))
mock_CertAddEncodedCertificateToStore.assert_called_with(
mock_CertOpenStore(),
cryptoapi.X509_ASN_ENCODING | cryptoapi.PKCS_7_ASN_ENCODING,
mock_cast(), mock_DWORD(),
cryptoapi.CERT_STORE_ADD_REPLACE_EXISTING, mock_byref())
mock_create_unicode_buffer.assert_called_with(2)
self.assertEqual(mock_CertGetNameString.call_args_list, expected2)
mock_get_cert_thumprint.assert_called_once_with(mock_POINTER()())
mock_CertFreeCertificateContext.assert_called_once_with(
mock_POINTER()())
mock_CertCloseStore.assert_called_once_with(
mock_CertOpenStore(), 0)
mock_free.assert_called_once_with(mock_cast())
self.assertEqual(response, (mock_get_cert_thumprint(),
mock_create_unicode_buffer().value))
mock_get_cert_base64.assert_called_with(fake_cert_data)
def test_import_cert(self):
self._test_import_cert(crypttstr=True, store_handle='fake handle',
add_enc_cert='fake encoded cert', upn_len=2)
def test_import_cert_CryptStringToBinaryA_fail(self):
self._test_import_cert(crypttstr=False, store_handle='fake handle',
add_enc_cert='fake encoded cert', upn_len=2)
def test_import_cert_CertOpenStore_fail(self):
self._test_import_cert(crypttstr=False, store_handle=None,
add_enc_cert='fake encoded cert', upn_len=2)
def test_import_cert_CertAddEncodedCertificateToStore_fail(self):
self._test_import_cert(crypttstr=True, store_handle='fake handle',
add_enc_cert=None, upn_len=2)
def test_import_cert_CertGetNameString_fail(self):
self._test_import_cert(crypttstr=True, store_handle='fake handle',
add_enc_cert='fake encoded cert', upn_len=3)

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.

View File

@ -0,0 +1,42 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 importlib
import mock
import unittest
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins.windows import userdata_plugins
#the name of the module includes "-", importlib.import_module is needed:
heathandler = importlib.import_module("cloudbaseinit.plugins.windows"
".userdata-plugins.heathandler")
CONF = cfg.CONF
class HeatUserDataHandlerTests(unittest.TestCase):
def setUp(self):
parent_set = userdata_plugins.PluginSet
self._heathandler = heathandler.HeatUserDataHandler(parent_set)
@mock.patch('cloudbaseinit.plugins.windows.userdata.handle')
def test_process(self, mock_handle):
mock_part = mock.MagicMock()
mock_part.get_filename.return_value = "cfn-userdata"
self._heathandler.process(mock_part)
mock_part.get_filename.assert_called_once_with()
mock_handle.assert_called_once_with(mock_part.get_payload())

View File

@ -0,0 +1,87 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 importlib
import mock
import os
import unittest
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins.windows import userdata_plugins
#the name of the module includes "-", importlib.import_module is needed:
parthandler = importlib.import_module("cloudbaseinit.plugins.windows"
".userdata-plugins.parthandler")
CONF = cfg.CONF
class PartHandlerScriptHandlerTests(unittest.TestCase):
def setUp(self):
parent_set = userdata_plugins.PluginSet('fake_path')
self._parthandler = parthandler.PartHandlerScriptHandler(parent_set)
@mock.patch('imp.load_source')
@mock.patch('imp.load_compiled')
@mock.patch('cloudbaseinit.plugins.windows.userdata-plugins.parthandler'
'.__import__', create=True)
def _test_load_from_file(self, mock__import__, mock_load_compiled,
mock_load_source, filepath):
mock_module = mock.MagicMock()
mock__import__.return_value = mock_module
mod_name, file_ext = os.path.splitext(os.path.split(filepath)[-1])
response = parthandler.load_from_file(filepath, 'fake_function')
print response
if file_ext.lower() == '.py':
mock_load_source.assert_called_with('path', filepath)
elif file_ext.lower() == '.pyc':
mock_load_compiled.assert_called_with('path', filepath)
mock__import__.assert_called_once_with('path')
self.assertEqual(response, mock_module.fake_function)
def test_load_from_file_py(self):
fake_file_path = os.path.join(os.path.join('fake', 'file'), 'path')
self._test_load_from_file(filepath=fake_file_path + '.py')
def test_load_from_file_pyc(self):
fake_file_path = os.path.join(os.path.join('fake', 'file'), 'path')
self._test_load_from_file(filepath=fake_file_path + '.pyc')
@mock.patch('cloudbaseinit.plugins.windows.userdata-plugins.parthandler.'
'load_from_file')
def test_process(self, mock_load_from_file):
mock_part = mock.MagicMock()
mock_part.get_filename.return_value = 'fake_name'
handler_path = self._parthandler.parent_set.path + "/part-handler/"
handler_path += 'fake_name'
expected = [mock.call(),
mock.call(handler_path, "list_types"),
mock.call(handler_path, "handle_part")]
mock_load_from_file().return_value = ['fake part']
with mock.patch("cloudbaseinit.plugins.windows.userdata-plugins."
"parthandler.open", mock.mock_open(), create=True):
self._parthandler.process(mock_part)
print mock_load_from_file.mock_calls
print self._parthandler.parent_set.custom_handlers
mock_part.get_filename.assert_called_once_with()
mock_part.get_payload.assert_called_once_with()
self.assertEqual(mock_load_from_file.call_args_list, expected)
self.assertEqual(self._parthandler.parent_set.has_custom_handlers,
True)
self.assertEqual(self._parthandler.parent_set.custom_handlers,
{'fake part': mock_load_from_file()})

View File

@ -0,0 +1,84 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 importlib
import mock
import os
import unittest
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.plugins.windows import userdata_plugins
#the name of the module includes "-", importlib.import_module is needed:
shellscript = importlib.import_module("cloudbaseinit.plugins.windows"
".userdata-plugins.shellscript")
CONF = cfg.CONF
class ShellScriptHandlerTests(unittest.TestCase):
def setUp(self):
parent_set = userdata_plugins.PluginSet('fake_path')
self._shellscript = shellscript.ShellScriptHandler(parent_set)
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
@mock.patch('tempfile.gettempdir')
def _test_process(self, mock_gettempdir, mock_get_os_utils, filename,
exception=False):
fake_dir_path = os.path.join("fake", "dir")
mock_osutils = mock.MagicMock()
mock_part = mock.MagicMock()
mock_part.get_filename.return_value = filename
mock_gettempdir.return_value = fake_dir_path
mock_get_os_utils.return_value = mock_osutils
if exception:
mock_osutils.execute_process.side_effect = [Exception]
with mock.patch("cloudbaseinit.plugins.windows.userdata-plugins."
"shellscript.open", mock.mock_open(), create=True):
response = self._shellscript.process(mock_part)
mock_part.get_filename.assert_called_once_with()
mock_gettempdir.assert_called_once_with()
if filename.endswith(".cmd"):
mock_osutils.execute_process.assert_called_with(
[os.path.join(fake_dir_path, filename)], True)
elif filename.endswith(".sh"):
mock_osutils.execute_process.assert_called_with(
['bash.exe', os.path.join(fake_dir_path, filename)], False)
elif filename.endswith(".ps1"):
mock_osutils.execute_process.assert_called_with(
['powershell.exe', '-ExecutionPolicy', 'RemoteSigned',
'-NonInteractive', os.path.join(fake_dir_path, filename)],
False)
self.assertFalse(response)
def test_process_cmd(self):
self._test_process(filename='fake.cmd')
def test_process_sh(self):
self._test_process(filename='fake.cmd')
def test_process_ps1(self):
self._test_process(filename='fake.cmd')
def test_process_other(self):
self._test_process(filename='fake.other')
def test_process_exception(self):
self._test_process(filename='fake.cmd', exception=True)

View File

@ -0,0 +1,141 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Cloudbase Solutions Srl
#
# 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 mock
import unittest
import sys
from cloudbaseinit import init
from cloudbaseinit.plugins import base
from cloudbaseinit.openstack.common import cfg
CONF = cfg.CONF
_win32com_mock = mock.MagicMock()
_comtypes_mock = mock.MagicMock()
_pywintypes_mock = mock.MagicMock()
_ctypes_mock = mock.MagicMock()
_ctypes_util_mock = mock.MagicMock()
mock_dict = {'ctypes.util': _ctypes_util_mock,
'win32com': _win32com_mock,
'comtypes': _comtypes_mock,
'pywintypes': _pywintypes_mock,
'ctypes': _ctypes_mock}
class InitManagerTest(unittest.TestCase):
@mock.patch.dict(sys.modules, mock_dict)
def setUp(self):
self.osutils = mock.MagicMock()
self.plugin = mock.MagicMock()
self._init = init.InitManager()
def tearDown(self):
reload(sys)
reload(init)
def test_get_plugin_status(self):
self.osutils.get_config_value.return_value = 1
response = self._init._get_plugin_status(self.osutils, 'fake plugin')
self.osutils.get_config_value.assert_called_once_with(
'fake plugin', self._init._PLUGINS_CONFIG_SECTION)
self.assertTrue(response == 1)
def test_set_plugin_status(self):
self._init._set_plugin_status(self.osutils, 'fake plugin', 'status')
self.osutils.set_config_value.assert_called_once_with(
'fake plugin', 'status', self._init._PLUGINS_CONFIG_SECTION)
@mock.patch('cloudbaseinit.init.InitManager._get_plugin_status')
@mock.patch('cloudbaseinit.init.InitManager._set_plugin_status')
def _test_exec_plugin(self, status, mock_set_plugin_status,
mock_get_plugin_status):
fake_name = 'fake name'
self.plugin.get_name.return_value = fake_name
self.plugin.execute.return_value = (status, True)
mock_get_plugin_status.return_value = status
response = self._init._exec_plugin(osutils=self.osutils,
service='fake service',
plugin=self.plugin,
shared_data='shared data')
mock_get_plugin_status.assert_called_once_with(self.osutils,
fake_name)
if status is base.PLUGIN_EXECUTE_ON_NEXT_BOOT:
self.plugin.execute.assert_called_once_with('fake service',
'shared data')
mock_set_plugin_status.assert_called_once_with(self.osutils,
fake_name, status)
self.assertTrue(response)
def test_test_exec_plugin_execution_done(self):
self._test_exec_plugin(base.PLUGIN_EXECUTION_DONE)
def test_test_exec_plugin(self):
self._test_exec_plugin(base.PLUGIN_EXECUTE_ON_NEXT_BOOT)
def _test_check_plugin_os_requirements(self, requirements):
sys.platform = 'win32'
fake_name = 'fake name'
self.plugin.get_name.return_value = fake_name
self.plugin.get_os_requirements.return_value = requirements
response = self._init._check_plugin_os_requirements(self.osutils,
self.plugin)
self.plugin.get_name.assert_called_once_with()
self.plugin.get_os_requirements.assert_called_once_with()
if requirements[0] == 'win32':
self.assertTrue(response)
else:
self.assertFalse(response)
def test_check_plugin_os_requirements(self):
self._test_check_plugin_os_requirements(('win32', (5, 2)))
def test_check_plugin_os_requirements_other_requirenments(self):
self._test_check_plugin_os_requirements(('linux', (5, 2)))
@mock.patch('cloudbaseinit.init.InitManager'
'._check_plugin_os_requirements')
@mock.patch('cloudbaseinit.init.InitManager._exec_plugin')
@mock.patch('cloudbaseinit.plugins.factory.PluginFactory.load_plugins')
@mock.patch('cloudbaseinit.osutils.factory.OSUtilsFactory.get_os_utils')
@mock.patch('cloudbaseinit.metadata.factory.MetadataServiceFactory.'
'get_metadata_service')
def test_configure_host(self, mock_get_metadata_service,
mock_get_os_utils, mock_load_plugins,
mock_exec_plugin,
mock_check_os_requirements):
fake_service = mock.MagicMock()
fake_plugin = mock.MagicMock()
mock_load_plugins.return_value = [fake_plugin]
mock_get_os_utils.return_value = self.osutils
mock_get_metadata_service.return_value = fake_service
fake_service.get_name.return_value = 'fake name'
self._init.configure_host()
self.osutils.wait_for_boot_completion.assert_called_once()
mock_get_metadata_service.assert_called_once_with()
fake_service.get_name.assert_called_once_with()
mock_check_os_requirements.assert_called_once_with(self.osutils,
fake_plugin)
mock_exec_plugin.assert_called_once_with(self.osutils, fake_service,
fake_plugin, {})
fake_service.cleanup.assert_called_once_with()
self.osutils.reboot.assert_called_once_with()