Improve unit tests for UserGenerator

Our experiments with unit tests for UserGenerator, especially those for
UserGenerator.create_tenants(), have revealed that it is the excessive use
of mocks:

    ...
    context = {"admin": {"endpoint": mock.MagicMock()},
               "task": mock.MagicMock()}
    ...

that leads to race conditions:
    http://paste.openstack.org/show/137037/

Here, we fix the mocking of the task object that caused these race conditions
and unify the UTs code.

We also modify the UserGenerator so that it uses the more efficient collections.deque
instead of ordinary lists.

Change-Id: I8696287ecf9bc8bb44f67f70c81c6c93fdb8acbe
Closes-Bug: #1394158
This commit is contained in:
Mikhail Dubov 2014-11-19 14:42:56 +04:00
parent d79a96a507
commit e7c5ed3805
2 changed files with 14 additions and 29 deletions

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import collections
import uuid
from oslo.config import cfg
@ -134,7 +135,7 @@ class UserGenerator(base.Context):
def _create_tenants(self):
threads = self.config["resource_management_workers"]
tenants = []
tenants = collections.deque()
def publish(queue):
for i in range(self.config["tenants"]):
@ -153,14 +154,14 @@ class UserGenerator(base.Context):
# NOTE(msdubov): cosume() will fill the tenants list in the closure.
broker.run(publish, consume, threads)
return tenants
return list(tenants)
def _create_users(self):
# NOTE(msdubov): This should be called after _create_tenants().
threads = self.config["resource_management_workers"]
users_per_tenant = self.config["users_per_tenant"]
users = []
users = collections.deque()
def publish(queue):
for tenant in self.context["tenants"]:
@ -191,7 +192,7 @@ class UserGenerator(base.Context):
# NOTE(msdubov): cosume() will fill the users list in the closure.
broker.run(publish, consume, threads)
return users
return list(users)
def _delete_tenants(self):
threads = self.config["resource_management_workers"]

View File

@ -38,7 +38,7 @@ class UserGeneratorTestCase(test.TestCase):
}
},
"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()
"task": {"uuid": "task_id"}
}
def setUp(self):
@ -70,9 +70,7 @@ class UserGeneratorTestCase(test.TestCase):
clients.nova.return_value = nova_admin
nova_admin.networks.list.return_value = networks
nova_admin.networks.get = fake_get_network
context = {"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()}
user_generator = users.UserGenerator(context)
user_generator = users.UserGenerator(self.context)
user_generator.context["tenants"] = [tenant1, tenant2]
user_generator._remove_associated_networks()
mock_check_service_status.assert_called_once_with(mock.ANY,
@ -100,9 +98,7 @@ class UserGeneratorTestCase(test.TestCase):
nova_admin.networks.list.return_value = networks
nova_admin.networks.get = fake_get_network
nova_admin.networks.disassociate.side_effect = Exception()
context = {"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()}
user_generator = users.UserGenerator(context)
user_generator = users.UserGenerator(self.context)
user_generator.context["tenants"] = [tenant1, tenant2]
user_generator._remove_associated_networks()
mock_check_service_status.assert_called_once_with(mock.ANY,
@ -112,9 +108,7 @@ class UserGeneratorTestCase(test.TestCase):
@mock.patch("rally.benchmark.context.users.broker.time.sleep")
@mock.patch("rally.benchmark.context.users.keystone")
def test__create_tenants(self, mock_keystone, mock_sleep):
context = {"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()}
user_generator = users.UserGenerator(context)
user_generator = users.UserGenerator(self.context)
user_generator.config["tenants"] = 2
tenants = user_generator._create_tenants()
self.assertEqual(2, len(tenants))
@ -125,9 +119,7 @@ class UserGeneratorTestCase(test.TestCase):
@mock.patch("rally.benchmark.context.users.broker.time.sleep")
@mock.patch("rally.benchmark.context.users.keystone")
def test__create_users(self, mock_keystone, mock_sleep):
context = {"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()}
user_generator = users.UserGenerator(context)
user_generator = users.UserGenerator(self.context)
tenant1 = mock.MagicMock()
tenant2 = mock.MagicMock()
user_generator.context["tenants"] = [tenant1, tenant2]
@ -140,9 +132,7 @@ class UserGeneratorTestCase(test.TestCase):
@mock.patch("rally.benchmark.context.users.keystone")
def test__delete_tenants(self, mock_keystone):
context = {"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()}
user_generator = users.UserGenerator(context)
user_generator = users.UserGenerator(self.context)
tenant1 = mock.MagicMock()
tenant2 = mock.MagicMock()
user_generator.context["tenants"] = [tenant1, tenant2]
@ -153,9 +143,7 @@ class UserGeneratorTestCase(test.TestCase):
def test__delete_tenants_failure(self, mock_keystone):
wrapped_keystone = mock_keystone.wrap.return_value
wrapped_keystone.delete_project.side_effect = Exception()
context = {"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()}
user_generator = users.UserGenerator(context)
user_generator = users.UserGenerator(self.context)
tenant1 = mock.MagicMock()
tenant2 = mock.MagicMock()
user_generator.context["tenants"] = [tenant1, tenant2]
@ -164,9 +152,7 @@ class UserGeneratorTestCase(test.TestCase):
@mock.patch("rally.benchmark.context.users.keystone")
def test__delete_users(self, mock_keystone):
context = {"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()}
user_generator = users.UserGenerator(context)
user_generator = users.UserGenerator(self.context)
user1 = mock.MagicMock()
user2 = mock.MagicMock()
user_generator.context["users"] = [user1, user2]
@ -177,9 +163,7 @@ class UserGeneratorTestCase(test.TestCase):
def test__delete_users_failure(self, mock_keystone):
wrapped_keystone = mock_keystone.wrap.return_value
wrapped_keystone.delete_user.side_effect = Exception()
context = {"admin": {"endpoint": mock.MagicMock()},
"task": mock.MagicMock()}
user_generator = users.UserGenerator(context)
user_generator = users.UserGenerator(self.context)
user1 = mock.MagicMock()
user2 = mock.MagicMock()
user_generator.context["users"] = [user1, user2]