Skip to content

Commit

Permalink
Avoid modifying the Mock class in test
Browse files Browse the repository at this point in the history
The rdb unit test defines a shutdown field on the Mock class
unintentionally. This causes that a later test in the same
executor expecting that mock.Mock().shutdown is a newly auto
generated mock.Mock() but it founds that is an already used
(called) object. This causes that the later test fails when
asserting the number of calls on that mock.

The original intention of the rbd unit test was to catch the
instantiation of the Rados object in test so it set Rados = mock.Mock()
so when the code under test called Rados() it actually called Mock().
It worked but it has that huge side effect. Instead of this a proper
mocking of the constructor can be done in two steps:

rados_inst = mock.Mock()
Rados = mock.Mock(return_value=rados_inst)

This makes sure that every Rados() call will return rados_inst that is a
mock without causing Mock class level side effect.

Change-Id: If71620e808744736cb4fe3abda76d81a6335311b
Closes-Bug: #1936849
  • Loading branch information
Balazs Gibizer committed Aug 23, 2021
1 parent 10b1dc8 commit 930b7c9
Showing 1 changed file with 21 additions and 21 deletions.
42 changes: 21 additions & 21 deletions nova/tests/unit/storage/test_rbd.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,15 @@ def setUp(self):
rados_patcher = mock.patch.object(rbd_utils, 'rados')
self.mock_rados = rados_patcher.start()
self.addCleanup(rados_patcher.stop)
self.mock_rados.Rados = mock.Mock
self.mock_rados.Rados.ioctx = mock.Mock()
self.mock_rados.Rados.connect = mock.Mock()
self.mock_rados.Rados.shutdown = mock.Mock()
self.mock_rados.Rados.open_ioctx = mock.Mock()
self.mock_rados.Rados.open_ioctx.return_value = \
self.mock_rados.Rados.ioctx
self.mock_rados.Rados = mock.Mock()
self.rados_inst = mock.Mock()
self.mock_rados.Rados.return_value = self.rados_inst
self.rados_inst.ioctx = mock.Mock()
self.rados_inst.connect = mock.Mock()
self.rados_inst.shutdown = mock.Mock()
self.rados_inst.open_ioctx = mock.Mock()
self.rados_inst.open_ioctx.return_value = \
self.rados_inst.ioctx
self.mock_rados.Error = Exception

rbd_patcher = mock.patch.object(rbd_utils, 'rbd')
Expand Down Expand Up @@ -339,33 +341,31 @@ def test_rbd_volume_proxy_init(self, mock_connect_from_rados,

def test_connect_to_rados_default(self):
ret = self.driver._connect_to_rados()
self.mock_rados.Rados.connect.assert_called_once_with(
self.rados_inst.connect.assert_called_once_with(
timeout=self.rbd_connect_timeout)
self.assertTrue(self.mock_rados.Rados.open_ioctx.called)
self.assertIsInstance(ret[0], self.mock_rados.Rados)
self.assertEqual(self.mock_rados.Rados.ioctx, ret[1])
self.mock_rados.Rados.open_ioctx.assert_called_with(self.rbd_pool)
self.assertTrue(self.rados_inst.open_ioctx.called)
self.assertEqual(self.rados_inst.ioctx, ret[1])
self.rados_inst.open_ioctx.assert_called_with(self.rbd_pool)

def test_connect_to_rados_different_pool(self):
ret = self.driver._connect_to_rados('alt_pool')
self.mock_rados.Rados.connect.assert_called_once_with(
self.rados_inst.connect.assert_called_once_with(
timeout=self.rbd_connect_timeout)
self.assertTrue(self.mock_rados.Rados.open_ioctx.called)
self.assertIsInstance(ret[0], self.mock_rados.Rados)
self.assertEqual(self.mock_rados.Rados.ioctx, ret[1])
self.mock_rados.Rados.open_ioctx.assert_called_with('alt_pool')
self.assertTrue(self.rados_inst.open_ioctx.called)
self.assertEqual(self.rados_inst.ioctx, ret[1])
self.rados_inst.open_ioctx.assert_called_with('alt_pool')

def test_connect_to_rados_error(self):
self.mock_rados.Rados.open_ioctx.side_effect = self.mock_rados.Error
self.rados_inst.open_ioctx.side_effect = self.mock_rados.Error
self.assertRaises(self.mock_rados.Error,
self.driver._connect_to_rados)
self.mock_rados.Rados.open_ioctx.assert_called_once_with(
self.rados_inst.open_ioctx.assert_called_once_with(
self.rbd_pool)
self.mock_rados.Rados.shutdown.assert_called_once_with()
self.rados_inst.shutdown.assert_called_once_with()

def test_connect_to_rados_unicode_arg(self):
self.driver._connect_to_rados(u'unicode_pool')
self.mock_rados.Rados.open_ioctx.assert_called_with(
self.rados_inst.open_ioctx.assert_called_with(
test.MatchType(str))

def test_ceph_args_none(self):
Expand Down

0 comments on commit 930b7c9

Please sign in to comment.