# Copyright 2014: 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 os import mock from oslo.config import cfg from rally import exceptions from rally.verification.verifiers.tempest import config from tests import fakes from tests import test CONF = cfg.CONF class ConfigTestCase(test.TestCase): @mock.patch("rally.objects.deploy.db.deployment_get") @mock.patch("rally.osclients.Clients.verified_keystone") @mock.patch("rally.verification.verifiers.tempest.config.os.path.isfile") def setUp(self, mock_isfile, mock_verified_keystone, mock_get): super(ConfigTestCase, self).setUp() self.endpoint = {"username": "test", "tenant_name": "test", "password": "test", "auth_url": "http://test/v2.0", "permission": "admin"} mock_get.return_value = {"endpoints": [self.endpoint]} mock_isfile.return_value = True self.deploy_id = "fake_deploy_id" self.conf_generator = config.TempestConf(self.deploy_id) def _remove_default_section(self, items): # getting items from configparser by specified section name # retruns also values from DEFAULT section defaults = (("log_file", "tempest.log"), ("debug", "True"), ("use_stderr", "False")) return [item for item in items if item not in defaults] @mock.patch("rally.verification.verifiers.tempest.config.requests") @mock.patch("rally.verification.verifiers.tempest.config.os.rename") @mock.patch("six.moves.builtins.open") def test__load_img_success(self, mock_open, mock_rename, mock_requests): mock_result = mock.MagicMock() mock_result.status_code = 200 mock_requests.get.return_value = mock_result mock_file = mock.MagicMock() mock_open.return_value = mock_file self.conf_generator._load_img() cirros_url = ("http://download.cirros-cloud.net/%s/%s" % (CONF.image.cirros_version, CONF.image.cirros_image)) mock_requests.get.assert_called_once_with(cirros_url, stream=True) @mock.patch("rally.verification.verifiers.tempest.config.requests") def test__load_img_notfound(self, mock_requests): mock_result = mock.MagicMock() mock_result.status_code = 404 mock_requests.get.return_value = mock_result self.assertRaises(exceptions.TempestConfigCreationFailure, self.conf_generator._load_img) def test__get_url(self): service = "test_service" url = "test_url" # mocked at setUp self.conf_generator.keystoneclient.auth_ref = { "serviceCatalog": [{ "name": service, "endpoints": [{"publicURL": url}] }]} self.assertEqual(self.conf_generator._get_url(service), url) @mock.patch("rally.verification.verifiers.tempest.config.TempestConf" "._get_url") def test__set_boto(self, mock_get_url): url = "test_url" mock_get_url.return_value = url self.conf_generator._set_boto() expected = (("ec2_url", url), ("s3_url", url), ("build_interval", "1"), ("build_timeout", "196"), ("http_socket_timeout", "30"), ("instance_type", "m1.nano"), ("ssh_user", "cirros"), ("s3_materials_path", os.path.join(self.conf_generator.data_path, "s3matherials"))) results = self._remove_default_section( self.conf_generator.conf.items("boto")) self.assertEqual(sorted(expected), sorted(results)) def test__set_compute_admin(self): self.conf_generator._set_compute_admin() expected = [("username", self.endpoint["username"]), ("password", self.endpoint["password"]), ("tenant_name", self.endpoint["tenant_name"])] results = self._remove_default_section( self.conf_generator.conf.items("compute-admin")) self.assertEqual(sorted(expected), sorted(results)) @mock.patch("rally.osclients.nova") def test__set_compute_flavors(self, mock_nova): mock_novaclient = mock.MagicMock() mock_novaclient.flavors.list.return_value = [ fakes.FakeFlavor(id="id1"), fakes.FakeFlavor(id="id2")] mock_nova.Client.return_value = mock_novaclient self.conf_generator._set_compute_flavors() expected = ("id1", "id2") results = (self.conf_generator.conf.get("compute", "flavor_ref"), self.conf_generator.conf.get("compute", "flavor_ref_alt")) self.assertEqual(sorted(expected), sorted(results)) @mock.patch("rally.osclients.nova") def test__set_compute_flavors_create(self, mock_nova): mock_novaclient = mock.MagicMock() mock_novaclient.flavors.list.return_value = [] mock_novaclient.flavors.create.side_effect = [ fakes.FakeFlavor(id="id1"), fakes.FakeFlavor(id="id2")] mock_nova.Client.return_value = mock_novaclient self.conf_generator._set_compute_flavors() self.assertEqual(mock_novaclient.flavors.create.call_count, 2) expected = ("id1", "id2") results = (self.conf_generator.conf.get("compute", "flavor_ref"), self.conf_generator.conf.get("compute", "flavor_ref_alt")) self.assertEqual(sorted(expected), sorted(results)) @mock.patch("rally.osclients.nova") def test__set_compute_flavors_create_fails(self, mock_nova): mock_novaclient = mock.MagicMock() mock_novaclient.flavors.list.return_value = [] mock_novaclient.flavors.create.side_effect = Exception() mock_nova.Client.return_value = mock_novaclient self.assertRaises(exceptions.TempestConfigCreationFailure, self.conf_generator._set_compute_flavors) @mock.patch("rally.osclients.glance") @mock.patch("rally.osclients.keystone") def test__set_compute_images(self, mock_keystone, mock_glance): mock_glanceclient = mock.MagicMock() mock_glanceclient.images.list.return_value = [ fakes.FakeImage(id="id1", name="cirros1"), fakes.FakeImage(id="id2", name="cirros2")] mock_glance.Client.return_value = mock_glanceclient self.conf_generator._set_compute_images() expected = ("id1", "id2") results = (self.conf_generator.conf.get("compute", "image_ref"), self.conf_generator.conf.get("compute", "image_ref_alt")) self.assertEqual(sorted(expected), sorted(results)) @mock.patch("rally.osclients.glance") @mock.patch("rally.osclients.keystone") @mock.patch("six.moves.builtins.open") def test__set_compute_images_create(self, mock_open, mock_keystone, mock_glance): mock_glanceclient = mock.MagicMock() mock_glanceclient.images.list.return_value = [] mock_glanceclient.images.create.side_effect = [ fakes.FakeImage(id="id1"), fakes.FakeImage(id="id2")] mock_glance.Client.return_value = mock_glanceclient self.conf_generator._set_compute_images() self.assertEqual(mock_glanceclient.images.create.call_count, 2) expected = ("id1", "id2") results = (self.conf_generator.conf.get("compute", "image_ref"), self.conf_generator.conf.get("compute", "image_ref_alt")) self.assertEqual(sorted(expected), sorted(results)) @mock.patch("rally.osclients.glance") @mock.patch("rally.osclients.keystone") def test__set_compute_images_create_fails(self, mock_keystone, mock_glance): mock_glanceclient = mock.MagicMock() mock_glanceclient.images.list.return_value = [] mock_glanceclient.images.create.side_effect = Exception() mock_glance.Client.return_value = mock_glanceclient self.assertRaises(exceptions.TempestConfigCreationFailure, self.conf_generator._set_compute_images) def test__set_compute_ssh_connect_method_if_neutron(self): self.conf_generator._set_compute_ssh_connect_method() self.assertEqual("fixed", self.conf_generator.conf.get("compute", "ssh_connect_method")) # if neutron is available self.conf_generator.available_services = ["neutron"] self.conf_generator._set_compute_ssh_connect_method() self.assertEqual("floating", self.conf_generator.conf.get("compute", "ssh_connect_method")) @mock.patch("rally.verification.verifiers.tempest.config.os.path.exists") @mock.patch("rally.verification.verifiers.tempest.config.os.makedirs") def test__set_default(self, mock_makedirs, mock_exists): mock_exists.return_value = False self.conf_generator._set_default() lock_path = os.path.join(self.conf_generator.data_path, "lock_files_%s" % self.deploy_id) mock_makedirs.assert_called_once_with(lock_path) expected = (("debug", "True"), ("log_file", "tempest.log"), ("use_stderr", "False"), ("lock_path", lock_path)) results = self.conf_generator.conf.items("DEFAULT") self.assertEqual(sorted(expected), sorted(results)) def test__set_identity(self): self.conf_generator._set_identity() expected = (("username", self.endpoint["username"]), ("password", self.endpoint["password"]), ("tenant_name", self.endpoint["tenant_name"]), ("admin_username", self.endpoint["username"]), ("admin_password", self.endpoint["password"]), ("admin_tenant_name", self.endpoint["username"]), ("uri", self.endpoint["auth_url"]), ("uri_v3", self.endpoint["auth_url"].replace("/v2.0", "/v3"))) results = self._remove_default_section( self.conf_generator.conf.items("identity")) self.assertEqual(sorted(expected), sorted(results)) @mock.patch("rally.osclients.neutron") def test__set_network_if_neutron(self, mock_neutron): fake_neutronclient = mock.MagicMock() fake_neutronclient.list_networks.return_value = {"networks": [ {"status": "ACTIVE", "id": "test_id", "router:external": True}]} fake_neutronclient.list_routers.return_value = {"routers": [ {"id": "test_router"}]} fake_neutronclient.list_subnets.return_value = {"subnets": [ {"cidr": "10.0.0.0/24"}]} mock_neutron.Client.return_value = fake_neutronclient self.conf_generator.available_services = ["neutron"] self.conf_generator._set_network() expected = (("default_network", "10.0.0.0/24"), ("tenant_networks_reachable", "false"), ("api_version", "2.0"), ("public_network_id", "test_id"), ("public_router_id", "test_router")) results = self._remove_default_section( self.conf_generator.conf.items("network")) self.assertEqual(sorted(expected), sorted(results)) @mock.patch("rally.osclients.nova") def test__set_network_if_nova(self, mock_nova): network = "10.0.0.0/24" mock_novaclient = mock.MagicMock() mock_network = mock.MagicMock() mock_network.cidr = network mock_novaclient.networks.list.return_value = [mock_network] mock_nova.Client.return_value = mock_novaclient self.conf_generator._set_network() self.assertEqual(network, self.conf_generator.conf.get("network", "default_network")) @mock.patch("rally.verification.verifiers.tempest.config.requests") def test__set_service_available(self, mock_requests): mock_result = mock.MagicMock() mock_result.status_code = 404 mock_requests.get.return_value = mock_result available_services = ("nova", "cinder", "glance") self.conf_generator.available_services = available_services self.conf_generator._set_service_available() expected = (("neutron", "False"), ("heat", "False"), ("ceilometer", "False"), ("swift", "False"), ("cinder", "True"), ("nova", "True"), ("glance", "True"), ("horizon", "False")) options = self._remove_default_section( self.conf_generator.conf.items("service_available")) self.assertEqual(sorted(expected), sorted(options)) @mock.patch("rally.verification.verifiers.tempest.config.requests") def test__set_service_available_horizon(self, mock_requests): mock_result = mock.MagicMock() mock_result.status_code = 200 mock_requests.get.return_value = mock_result self.conf_generator._set_service_available() self.assertEqual(self.conf_generator.conf.get( "service_available", "horizon"), "True") @mock.patch('six.moves.builtins.open') def test_write_config(self, mock_open): self.conf_generator.conf = mock.Mock() mock_file = mock.MagicMock() mock_open.return_value = mock_file file_name = '/path/to/fake/conf' self.conf_generator.write_config(file_name) mock_open.assert_called_once_with(file_name, 'w+') self.conf_generator.conf.write.assert_called_once_with( mock_file.__enter__()) mock_file.__exit__.assert_called_once_with(None, None, None)