1 # Copyright 2015 Intel Corporation.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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 implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 """Module with implementation of wrapper around the stress tool
22 from tools import tasks
23 from tools import systeminfo
24 from tools.load_gen.load_gen import ILoadGenerator
26 class Stress(ILoadGenerator):
27 """Wrapper around stress tool, which generates load based on testcase
28 configuration parameter 'load'
31 'cmd': ['sudo', 'stress'],
33 'logfile': '/tmp/stress.log',
34 'expect': r'stress: info:',
37 _logger = logging.getLogger(__name__)
39 def __init__(self, stress_config):
41 # copy stress process setings before its modification
42 process_args = copy.deepcopy(self._process_args)
43 # check if load is requested and correctly configured
44 if not (stress_config and 'load' in stress_config and
45 'pattern' in stress_config and stress_config['load'] > 0):
46 self._logger.error('stress test is not enabled')
49 if stress_config['load'] < 0 or stress_config['load'] > 100:
50 self._logger.error('defined load %s is out of range 0-100',
51 stress_config['load'])
54 # check if load tool binary is available
55 if not ('tool' in stress_config) or subprocess.call("which " + stress_config['tool'], shell=True) > 0:
56 self._logger.error("stress tool binary '%s' is not available", stress_config['tool'])
59 # calculate requested load details and load split among different
61 cpus = systeminfo.get_cpu_cores()
62 if 'reserved' in stress_config:
63 cpus = cpus - int(stress_config['reserved'])
67 workers = round(cpus/100 * int(stress_config['load']))
71 for p_type in ('c', 'i', 'm'):
72 p_count = stress_config['pattern'].lower().count(p_type)
74 p_types[p_type] = p_count
77 self._logger.error('stress test pattern does not contain any of ' \
78 'c, i or m pattern types')
80 for p_type in p_types:
81 cmd_dict['-'+p_type] = round(workers* p_types[p_type] / p_total)
83 # check for memory load in case that memory workers are detected
84 # in case of error or 0%, memory size is not specified and default
85 # amount of memory will be used by stress tool
86 if '-m' in cmd_dict and cmd_dict['-m'] > 0:
87 if 'load_memory' in stress_config and \
88 stress_config['load_memory'] > 0 and \
89 stress_config['load_memory'] <= 100:
91 mem = systeminfo.get_memory_bytes()
93 cmd_dict['--vm-bytes'] = round(int(mem) / 100 * \
94 stress_config['load_memory'] / cmd_dict['-m'])
96 # append stress arguments to cmd list used by parent class Process
97 for key, value in cmd_dict.items():
98 process_args['cmd'].append(key)
99 process_args['cmd'].append(str(value))
101 # append load generator options if specified
102 if 'options' in stress_config:
103 process_args['cmd'].append(stress_config['options'])
105 # initialize load generator and remember it
106 super(Stress, self).__init__(**process_args)
110 """Start stress load if it was requested
113 super(Stress, self).start()
115 def kill(self, signal='-15', sleep=2):
117 Kill stress load if it is active
119 if self._running and self._child and self._child.isalive():
120 tasks.run_task(['sudo', 'pkill', signal, self._proc_name], self._logger)
124 'Log available at %s', self._logfile)
125 self._running = False