Skip to content

Commit 5c22256

Browse files
committed
Burn-in: Add memory step
Add a clean step for memory burn-in via stress-ng. Get basic run parameters from the node's driver_info. Story: #2007523 Task: #42383 Change-Id: I33a83968c9f87cf795ec7ec922bce98b52c5181c
1 parent 6702fca commit 5c22256

6 files changed

Lines changed: 99 additions & 0 deletions

File tree

doc/source/admin/hardware_managers.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ Clean steps
7777
``deploy.burnin_cpu``
7878
Stress-test the CPUs of a node via stress-ng for a configurable
7979
amount of time. Disabled by default.
80+
``deploy.burnin_memory``
81+
Stress-test the memory of a node via stress-ng for a configurable
82+
amount of time. Disabled by default.
8083
``deploy.erase_devices``
8184
Securely erases all information from all recognized disk devices.
8285
Relatively fast when secure ATA erase is available, otherwise can take

ironic_python_agent/burnin.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,35 @@ def stress_ng_cpu(node):
4646
{'err': e})
4747
LOG.error(error_msg)
4848
raise errors.CommandExecutionError(error_msg)
49+
50+
51+
def stress_ng_vm(node):
52+
"""Burn-in the memory with the vm stressor in stress-ng
53+
54+
Run stress-ng with a configurable number of workers on
55+
a configurable amount of the available memory for
56+
a configurable amount of time. Without config use
57+
as many workers as CPUs, 98% of the memory and stress
58+
it for 24 hours.
59+
60+
:param node: Ironic node object
61+
:raises: CommandExecutionError if the execution of stress-ng fails.
62+
"""
63+
info = node.get('driver_info', {})
64+
vm = info.get('agent_burnin_vm_vm', 0)
65+
vm_bytes = info.get('agent_burnin_vm_vm-bytes', '98%')
66+
timeout = info.get('agent_burnin_vm_timeout', 86400)
67+
68+
args = ('stress-ng', '--vm', vm, '--vm-bytes', vm_bytes,
69+
'--timeout', timeout, '--metrics-brief')
70+
LOG.debug('Burn-in stress_ng_vm command: %s', args)
71+
72+
try:
73+
_, err = utils.execute(*args)
74+
# stress-ng reports on stderr only
75+
LOG.info(err)
76+
except (processutils.ProcessExecutionError, OSError) as e:
77+
error_msg = ("stress-ng (vm) failed with error %(err)s",
78+
{'err': e})
79+
LOG.error(error_msg)
80+
raise errors.CommandExecutionError(error_msg)

ironic_python_agent/hardware.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,14 @@ def burnin_cpu(self, node, ports):
14021402
"""
14031403
burnin.stress_ng_cpu(node)
14041404

1405+
def burnin_memory(self, node, ports):
1406+
"""Burn-in the memory
1407+
1408+
:param node: Ironic node object
1409+
:param ports: list of Ironic port objects
1410+
"""
1411+
burnin.stress_ng_vm(node)
1412+
14051413
def _shred_block_device(self, node, block_device):
14061414
"""Erase a block device using shred.
14071415
@@ -1882,6 +1890,13 @@ def get_clean_steps(self, node, ports):
18821890
'reboot_requested': False,
18831891
'abortable': True
18841892
},
1893+
{
1894+
'step': 'burnin_memory',
1895+
'priority': 0,
1896+
'interface': 'deploy',
1897+
'reboot_requested': False,
1898+
'abortable': True
1899+
},
18851900
]
18861901

18871902
def get_deploy_steps(self, node, ports):

ironic_python_agent/tests/unit/test_burnin.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,38 @@ def test_stress_ng_cpu_no_stress_ng(self, mock_execute):
5454

5555
self.assertRaises(errors.CommandExecutionError,
5656
burnin.stress_ng_cpu, node)
57+
58+
def test_stress_ng_vm_default(self, mock_execute):
59+
60+
node = {'driver_info': {}}
61+
mock_execute.return_value = (['out', 'err'])
62+
63+
burnin.stress_ng_vm(node)
64+
65+
mock_execute.assert_called_once_with(
66+
'stress-ng', '--vm', 0, '--vm-bytes', '98%',
67+
'--timeout', 86400, '--metrics-brief')
68+
69+
def test_stress_ng_vm_non_default(self, mock_execute):
70+
71+
node = {'driver_info': {'agent_burnin_vm_vm': 2,
72+
'agent_burnin_vm_vm-bytes': '25%',
73+
'agent_burnin_vm_timeout': 120}}
74+
mock_execute.return_value = (['out', 'err'])
75+
76+
burnin.stress_ng_vm(node)
77+
78+
mock_execute.assert_called_once_with(
79+
'stress-ng', '--vm', 2, '--vm-bytes', '25%',
80+
'--timeout', 120, '--metrics-brief')
81+
82+
def test_stress_ng_vm_no_stress_ng(self, mock_execute):
83+
84+
node = {'driver_info': {}}
85+
mock_execute.side_effect = (['out', 'err'],
86+
processutils.ProcessExecutionError())
87+
88+
burnin.stress_ng_vm(node)
89+
90+
self.assertRaises(errors.CommandExecutionError,
91+
burnin.stress_ng_vm, node)

ironic_python_agent/tests/unit/test_hardware.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ def test_get_clean_steps(self):
156156
'interface': 'deploy',
157157
'reboot_requested': False,
158158
'abortable': True
159+
},
160+
{
161+
'step': 'burnin_memory',
162+
'priority': 0,
163+
'interface': 'deploy',
164+
'reboot_requested': False,
165+
'abortable': True
159166
}
160167
]
161168
clean_steps = self.hardware.get_clean_steps(self.node, [])
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
features:
3+
- |
4+
Adds a burn-in cleaning step 'burnin_memory' to stress test memory for a
5+
configurable amount of time with stress-ng. To use this step, stress-ng
6+
needs to be installed on the RAM disk.
7+

0 commit comments

Comments
 (0)