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
21 from tools import tasks
22 from tools import systeminfo
23 from tools.load_gen.load_gen import ILoadGenerator
25 class Stress(ILoadGenerator):
26 """Wrapper around stress tool, which generates load based on testcase
27 configuration parameter 'load'
30 'cmd': ['sudo', 'stress'],
32 'logfile': '/tmp/stress.log',
33 'expect': r'stress: info:',
36 _logger = logging.getLogger(__name__)
38 def __init__(self, stress_config):
40 # copy stress process setings before its modification
41 process_args = copy.deepcopy(self._process_args)
42 # check if load is requested and correctly configured
43 if not (stress_config and 'load' in stress_config and
44 'pattern' in stress_config and stress_config['load'] > 0):
45 self._logger.error('stress test is not enabled')
48 if stress_config['load'] < 0 or stress_config['load'] > 100:
49 self._logger.error('defined load %s is out of range 0-100',
50 stress_config['load'])
53 # check if load tool binary is available
54 if not ('tool' in stress_config) or subprocess.call("which " + stress_config['tool'], shell=True) > 0:
55 self._logger.error("stress tool binary '%s' is not available", stress_config['tool'])
58 # calculate requested load details and load split among different
60 cpus = systeminfo.get_cpu_cores()
61 if 'reserved' in stress_config:
62 cpus = cpus - int(stress_config['reserved'])
66 workers = round(cpus/100 * int(stress_config['load']))
70 for p_type in ('c', 'i', 'm'):
71 p_count = stress_config['pattern'].lower().count(p_type)
73 p_types[p_type] = p_count
76 self._logger.error('stress test pattern does not contain any of ' \
77 'c, i or m pattern types')
79 for p_type in p_types:
80 cmd_dict['-'+p_type] = round(workers* p_types[p_type] / p_total)
82 # check for memory load in case that memory workers are detected
83 # in case of error or 0%, memory size is not specified and default
84 # amount of memory will be used by stress tool
85 if '-m' in cmd_dict and cmd_dict['-m'] > 0:
86 if 'load_memory' in stress_config and \
87 stress_config['load_memory'] > 0 and \
88 stress_config['load_memory'] <= 100:
90 mem = systeminfo.get_memory_bytes()
92 cmd_dict['--vm-bytes'] = round(int(mem) / 100 * \
93 stress_config['load_memory'] / cmd_dict['-m'])
95 # append stress arguments to cmd list used by parent class Process
96 for key, value in cmd_dict.items():
97 process_args['cmd'].append(key)
98 process_args['cmd'].append(str(value))
100 # append load generator options if specified
101 if 'options' in stress_config:
102 process_args['cmd'].append(stress_config['options'])
104 # initialize load generator and remember it
105 super(Stress, self).__init__(**process_args)
109 """Start stress load if it was requested
112 super(Stress, self).start()
116 Kill stress load if it is active
118 if self._running and self._child and self._child.isalive():
119 tasks.run_task(['sudo', 'pkill', self._proc_name],
123 'Log available at %s', self._logfile)
124 self._running = False