Skip to content

Commit c2687c6

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Prevent tests' unmocked access to utils.execute()"
2 parents 32ed014 + f57cbcc commit c2687c6

12 files changed

Lines changed: 113 additions & 47 deletions
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Copyright 2017 Cisco Systems, Inc
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12+
# implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
"""Common utilities and classes across all unit tests."""
17+
18+
import mock
19+
20+
from oslotest import base as test_base
21+
22+
from ironic_python_agent import utils
23+
24+
25+
class IronicAgentTest(test_base.BaseTestCase):
26+
"""Extends the base test to provide common features across agent tests."""
27+
28+
def setUp(self):
29+
super(IronicAgentTest, self).setUp()
30+
"""Add a blanket ban on running external processes via utils.execute().
31+
32+
`self` will grow a property called _exec_patch which is the Mock
33+
that replaces utils.execute.
34+
35+
If the mock is called, an exception is raised to warn the tester.
36+
"""
37+
# NOTE(bigjools): Not using a decorator on tests because I don't
38+
# want to force every test method to accept a new arg. Instead, they
39+
# can override or examine this self._exec_patch Mock as needed.
40+
self._exec_patch = mock.Mock()
41+
self._exec_patch.side_effect = Exception(
42+
"Don't call utils.execute in tests!")
43+
self.patch(utils, 'execute', self._exec_patch)

ironic_python_agent/tests/unit/test_agent.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from oslo_concurrency import processutils
2121
from oslo_config import cfg
2222
from oslo_serialization import jsonutils
23-
from oslotest import base as test_base
2423
import pkg_resources
2524
from stevedore import extension
2625

@@ -31,6 +30,7 @@
3130
from ironic_python_agent import hardware
3231
from ironic_python_agent import inspector
3332
from ironic_python_agent import netutils
33+
from ironic_python_agent.tests.unit import base as ironic_agent_base
3434
from ironic_python_agent import utils
3535

3636
EXPECTED_ERROR = RuntimeError('command execution failed')
@@ -49,7 +49,7 @@ class FakeExtension(base.BaseAgentExtension):
4949
pass
5050

5151

52-
class TestHeartbeater(test_base.BaseTestCase):
52+
class TestHeartbeater(ironic_agent_base.IronicAgentTest):
5353
def setUp(self):
5454
super(TestHeartbeater, self).setUp()
5555
self.mock_agent = mock.Mock()
@@ -129,7 +129,7 @@ def test_heartbeat(self, mock_uniform, mock_time, mock_poll, mock_read):
129129

130130
@mock.patch.object(hardware.GenericHardwareManager, '_wait_for_disks',
131131
lambda self: None)
132-
class TestBaseAgent(test_base.BaseTestCase):
132+
class TestBaseAgent(ironic_agent_base.IronicAgentTest):
133133

134134
def setUp(self):
135135
super(TestBaseAgent, self).setUp()
@@ -171,6 +171,10 @@ def test_get_status(self):
171171
self.assertEqual(pkg_resources.get_distribution('ironic-python-agent')
172172
.version, status.version)
173173

174+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
175+
@mock.patch(
176+
'ironic_python_agent.hardware_managers.cna._detect_cna_card',
177+
mock.Mock())
174178
@mock.patch.object(agent.IronicPythonAgent,
175179
'_wait_for_interface', autospec=True)
176180
@mock.patch.object(hardware, 'dispatch_to_managers', autospec=True)
@@ -203,6 +207,9 @@ def test_run(self, mock_make_server, mock_dispatch, mock_wait):
203207
mock_dispatch.assert_called_once_with("list_hardware_info")
204208
self.agent.heartbeater.start.assert_called_once_with()
205209

210+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
211+
@mock.patch('ironic_python_agent.hardware_managers.cna._detect_cna_card',
212+
mock.Mock())
206213
@mock.patch.object(agent.IronicPythonAgent,
207214
'_wait_for_interface', autospec=True)
208215
@mock.patch.object(inspector, 'inspect', autospec=True)
@@ -249,6 +256,10 @@ def test_run_with_inspection(self, mock_list_hardware, mock_make_server,
249256
mock_dispatch.assert_called_once_with("list_hardware_info")
250257
self.agent.heartbeater.start.assert_called_once_with()
251258

259+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
260+
@mock.patch(
261+
'ironic_python_agent.hardware_managers.cna._detect_cna_card',
262+
mock.Mock())
252263
@mock.patch.object(agent.IronicPythonAgent,
253264
'_wait_for_interface', autospec=True)
254265
@mock.patch.object(inspector, 'inspect', autospec=True)
@@ -298,6 +309,10 @@ def test_run_with_inspection_without_apiurl(self,
298309
self.assertFalse(mock_wait.called)
299310
self.assertFalse(mock_dispatch.called)
300311

312+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
313+
@mock.patch(
314+
'ironic_python_agent.hardware_managers.cna._detect_cna_card',
315+
mock.Mock())
301316
@mock.patch.object(agent.IronicPythonAgent,
302317
'_wait_for_interface', autospec=True)
303318
@mock.patch.object(inspector, 'inspect', autospec=True)
@@ -497,7 +512,7 @@ def test_get_route_source_indexerror(self, mock_execute, mock_log):
497512

498513
@mock.patch.object(hardware.GenericHardwareManager, '_wait_for_disks',
499514
lambda self: None)
500-
class TestAgentStandalone(test_base.BaseTestCase):
515+
class TestAgentStandalone(ironic_agent_base.IronicAgentTest):
501516

502517
def setUp(self):
503518
super(TestAgentStandalone, self).setUp()
@@ -515,6 +530,10 @@ def setUp(self):
515530
'agent_ipmitool',
516531
True)
517532

533+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
534+
@mock.patch(
535+
'ironic_python_agent.hardware_managers.cna._detect_cna_card',
536+
mock.Mock())
518537
@mock.patch('wsgiref.simple_server.make_server', autospec=True)
519538
@mock.patch.object(hardware.HardwareManager, 'list_hardware_info',
520539
autospec=True)
@@ -551,7 +570,7 @@ def test_run(self, mock_list_hardware, mock_make_server):
551570
lambda self: None)
552571
@mock.patch.object(socket, 'gethostbyname', autospec=True)
553572
@mock.patch.object(utils, 'execute', autospec=True)
554-
class TestAdvertiseAddress(test_base.BaseTestCase):
573+
class TestAdvertiseAddress(ironic_agent_base.IronicAgentTest):
555574
def setUp(self):
556575
super(TestAdvertiseAddress, self).setUp()
557576

ironic_python_agent/tests/unit/test_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@
1515
import time
1616

1717
import mock
18-
from oslotest import base as test_base
1918
import pecan
2019
import pecan.testing
2120

2221
from ironic_python_agent import agent
2322
from ironic_python_agent.extensions import base
23+
from ironic_python_agent.tests.unit import base as ironic_agent_base
2424

2525

2626
PATH_PREFIX = '/v1'
2727

2828

29-
class TestIronicAPI(test_base.BaseTestCase):
29+
class TestIronicAPI(ironic_agent_base.IronicAgentTest):
3030

3131
def setUp(self):
3232
super(TestIronicAPI, self).setUp()

ironic_python_agent/tests/unit/test_encoding.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15-
from oslotest import base as test_base
16-
1715
from ironic_python_agent import encoding
16+
from ironic_python_agent.tests.unit import base
1817

1918

2019
class SerializableTesting(encoding.Serializable):
@@ -33,7 +32,7 @@ def __init__(self, jack, jill):
3332
self.jill = jill
3433

3534

36-
class TestSerializable(test_base.BaseTestCase):
35+
class TestSerializable(base.IronicAgentTest):
3736
def test_baseclass_serialize(self):
3837
obj = encoding.Serializable()
3938
self.assertEqual({}, obj.serialize())
@@ -44,7 +43,7 @@ def test_childclass_serialize(self):
4443
self.assertEqual(expected, obj.serialize())
4544

4645

47-
class TestSerializableComparable(test_base.BaseTestCase):
46+
class TestSerializableComparable(base.IronicAgentTest):
4847

4948
def test_childclass_equal(self):
5049
obj1 = SerializableComparableTesting('hello', 'world')

ironic_python_agent/tests/unit/test_errors.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15-
from oslotest import base as test_base
16-
1715
from ironic_python_agent import errors
16+
from ironic_python_agent.tests.unit import base
1817

1918
DETAILS = 'details'
2019
SAME_CL_DETAILS = 'same_as_class_details'
@@ -32,7 +31,7 @@ def __init__(self, details=None):
3231
super(TestError, self).__init__(details)
3332

3433

35-
class TestErrors(test_base.BaseTestCase):
34+
class TestErrors(base.IronicAgentTest):
3635

3736
def test_RESTError(self):
3837
e = errors.RESTError()

ironic_python_agent/tests/unit/test_hardware.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
from oslo_concurrency import processutils
2323
from oslo_config import cfg
2424
from oslo_utils import units
25-
from oslotest import base as test_base
2625
import pyudev
2726
from stevedore import extension
2827

2928
from ironic_python_agent import errors
3029
from ironic_python_agent import hardware
30+
from ironic_python_agent.tests.unit import base
3131
from ironic_python_agent import utils
3232

3333
CONF = cfg.CONF
@@ -257,7 +257,7 @@ def evaluate_hardware_support(self):
257257
return self._hardware_support
258258

259259

260-
class TestHardwareManagerLoading(test_base.BaseTestCase):
260+
class TestHardwareManagerLoading(base.IronicAgentTest):
261261
def setUp(self):
262262
super(TestHardwareManagerLoading, self).setUp()
263263
# In order to use ExtensionManager.make_test_instance() without
@@ -286,7 +286,7 @@ def setUp(self):
286286

287287

288288
@mock.patch.object(hardware, '_udev_settle', lambda *_: None)
289-
class TestGenericHardwareManager(test_base.BaseTestCase):
289+
class TestGenericHardwareManager(base.IronicAgentTest):
290290
def setUp(self):
291291
super(TestGenericHardwareManager, self).setUp()
292292
self.hardware = hardware.GenericHardwareManager()
@@ -784,6 +784,9 @@ def test_list_hardware_info(self):
784784
self.hardware.get_boot_info.return_value = hardware.BootInfo(
785785
current_boot_mode='bios', pxe_interface='boot:if')
786786

787+
self.hardware.get_bmc_address = mock.Mock()
788+
self.hardware.get_system_vendor_info = mock.Mock()
789+
787790
hardware_info = self.hardware.list_hardware_info()
788791
self.assertEqual(self.hardware.get_memory(), hardware_info['memory'])
789792
self.assertEqual(self.hardware.get_cpus(), hardware_info['cpu'])
@@ -1490,6 +1493,7 @@ def test_evaluate_hw_waits_for_disks(self, mocked_root_dev, mocked_sleep,
14901493
self.assertEqual(2, mocked_root_dev.call_count)
14911494
mocked_sleep.assert_called_once_with(CONF.disk_wait_delay)
14921495

1496+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
14931497
@mock.patch.object(hardware.GenericHardwareManager, 'list_block_devices',
14941498
autospec=True)
14951499
@mock.patch.object(time, 'sleep', autospec=True)
@@ -1517,6 +1521,7 @@ def test_evaluate_hw_waits_for_disks_nonconfigured(self, mocked_root_dev,
15171521
mocked_root_dev.assert_called_with(mocked_block_dev.return_value)
15181522
self.assertEqual(10, mocked_root_dev.call_count)
15191523

1524+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
15201525
@mock.patch.object(hardware.GenericHardwareManager, 'list_block_devices',
15211526
autospec=True)
15221527
@mock.patch.object(time, 'sleep', autospec=True)
@@ -1539,6 +1544,7 @@ def test_evaluate_hw_waits_for_disks_configured(self, mocked_root_dev,
15391544
mocked_root_dev.assert_called_with(mocked_block_dev.return_value)
15401545
self.assertEqual(2, mocked_root_dev.call_count)
15411546

1547+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
15421548
@mock.patch.object(hardware.GenericHardwareManager, 'list_block_devices',
15431549
autospec=True)
15441550
@mock.patch.object(time, 'sleep', autospec=True)
@@ -1552,6 +1558,7 @@ def test_evaluate_hw_disks_timeout_unconfigured(self, mocked_root_dev,
15521558

15531559
mocked_sleep.assert_called_with(3)
15541560

1561+
@mock.patch.object(hardware, '_check_for_iscsi', mock.Mock())
15551562
@mock.patch.object(hardware.GenericHardwareManager, 'list_block_devices',
15561563
autospec=True)
15571564
@mock.patch.object(time, 'sleep', autospec=True)
@@ -1611,7 +1618,7 @@ def test_get_boot_info_uefi(self, mocked_isdir):
16111618

16121619
@mock.patch.object(os, 'listdir', lambda *_: [])
16131620
@mock.patch.object(utils, 'execute', autospec=True)
1614-
class TestModuleFunctions(test_base.BaseTestCase):
1621+
class TestModuleFunctions(base.IronicAgentTest):
16151622

16161623
@mock.patch.object(hardware, '_get_device_info',
16171624
lambda x, y, z: 'FooTastic')

0 commit comments

Comments
 (0)