pymtt
 All Classes Namespaces Files Functions Variables Groups
Harasser.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2015-2018 Intel, Inc. All rights reserved.
4 # $COPYRIGHT$
5 #
6 # Additional copyrights may follow
7 #
8 # $HEADER$
9 #
10 
11 from __future__ import print_function
12 import os
13 import re
14 from HarasserMTTTool import *
15 import datetime
16 import multiprocessing
17 import sys
18 
19 ## @addtogroup Tools
20 # @{
21 # @addtogroup Harasser
22 # @section Harasser
23 # Run harasser scripts while test-content is running
24 # @param trigger_scripts Scripts to run to launch harassers
25 # @param stop_scripts Scripts to run to stop and clean-up harassers
26 # @param join_timeout Seconds to wait for process to finish
27 # @}
29  def __init__(self):
30  HarasserMTTTool.__init__(self)
31  self.activated = False
33  self.testDef = None
35  self.options = {}
36  self.options['trigger_scripts'] = (None, "Scripts to run to launch harassers")
37  self.options['stop_scripts'] = (None, "Scripts to run to stop and clean-up harassers")
38  self.options['join_timeout'] = (None, "Seconds to wait for processes to finish")
39  return
40 
41  ##
42  # Configures plugin outside of INI file
43  #
44  def config(self, cfg):
45  for k in cfg:
46  if k in self.options:
47  self.options[k] = (cfg[k], self.options[k][1])
48 
49  ##
50  # Activates plugin
51  #
52  def activate(self):
53  if not self.activated:
54  # use the automatic procedure from IPlugin
55  IPlugin.activate(self)
56  self.activated = True
57  return
58 
59  ##
60  # Deactivates plugin
61  #
62  def deactivate(self):
63  if self.activated:
64  IPlugin.deactivate(self)
65  self.activated = False
66  if self.execution_counter > 0:
67  self.testDef.logger.verbose_print("Harasser plugin stopped while harassers were running. Cleaning up harassers...")
68  self.stop(self.running_harassers.keys(), self.testDef)
69  self.testDef.logger.verbose_print("Harassers were cleaned up.")
70  return
71 
72  def print_name(self):
73  return "Harasser"
74 
75  ##
76  # Prints current configuration of plugin
77  #
78  def print_options(self, testDef, prefix):
79  lines = testDef.printOptions(self.options)
80  for line in lines:
81  print(prefix + line)
82  return
83 
84  ##
85  # Returns information about what harassers are currently running
86  #
88  return self.running_harassers
89 
90  ##
91  # This function is passed into multiprocessing as a target
92  #
93  def parallel_execute(self, cmds, cmdargs, testDef):
94  status,stdout,stderr,time = testDef.execmd.execute(cmds, cmdargs, testDef)
95 
96  ##
97  # Harassment is started on the system
98  #
99  def start(self, testDef):
100  # Parse input for lists of scripts to run
101  trigger_scripts = self.options['trigger_scripts'][0]
102  if trigger_scripts is None or trigger_scripts == '':
103  trigger_scripts = []
104  else:
105  trigger_scripts = trigger_scripts.split(',')
106  stop_scripts = self.options['stop_scripts'][0]
107  if stop_scripts is None or stop_scripts == '':
108  stop_scripts = []
109  else:
110  stop_scripts = stop_scripts.split(',')
111 
112  # Execute scripts while pairing which scripts
113  # are used to stop/cleanup each start script
114  exec_ids = []
115  for trigger_script,stop_script in zip(trigger_scripts,stop_scripts):
116  trigger_script = trigger_script.strip()
117  stop_script = stop_script.strip()
118  ops = {(k[:-1] if k.endswith('_scripts') else k):\
119  (trigger_script if k == 'trigger_scripts' else (\
120  stop_script if k == 'stop_scripts' \
121  else v[0])) \
122  for k,v in self.options.items()}
123 
124  cmdargs = trigger_script.split()
125 
126  process = multiprocessing.Process(name='p'+str(self.execution_counter), \
127  target=self.parallel_execute, \
128  args=({k:v[0] for k,v in self.options.items()},cmdargs,testDef))
129  process.start()
130 
131  self.running_harassers[self.execution_counter] = (process, ops, datetime.datetime.now())
132  exec_ids.append(self.execution_counter)
133  self.execution_counter += 1
134 
135  return exec_ids
136 
137  ##
138  # A check to see if harassers are working properly
139  #
140  def check(self, exec_ids, testDef):
141  dead_processes = []
142  for exec_id in exec_ids:
143  if not self.running_harassers[exec_id][0].is_alive() \
144  and self.running_harassers[exec_id][0].exitcode != 0:
145  dead_processes.append(self.running_harassers[exec_id])
146  if dead_processes:
147  process_run_info = self.stop(exec_ids, testDef)
148  return dead_processes, process_run_info
149  return None
150 
151  ##
152  # Calls the stop-scripts provided with harasser scripts to stop and clean up harassment
153  #
154  def stop(self, exec_ids, testDef):
155  process_info = [self.running_harassers[exec_id] for exec_id in exec_ids]
156  for exec_id in exec_ids:
157  del self.running_harassers[exec_id]
158 
159  return_info = []
160  for process,ops,starttime in process_info:
161  cmdargs = ops['stop_script'].split()
162  status,stdout,stderr,time = testDef.execmd.execute({k:v[0] for k,v in self.options.items()}, cmdargs, testDef)
163  return_info.append((status,stdout,stderr,datetime.datetime.now()-starttime))
164 
165  for (process,ops,starttime),(status,stdout,stderr,time) in zip(process_info,return_info):
166  if status == 0:
167  if self.options['join_timeout'][0] is None:
168  process.join()
169  else:
170  process.join(int(self.options['join_timeout'][0]))
171  elif status == 1:
172  process.terminate()
173 
174  self.execution_counter -= 1
175 
176  return return_info
177 
178  ##
179  # Configure the harasser plugin on whether to run and what to run
180  #
181  def execute(self, log, keyvals, testDef):
182  testDef.logger.verbose_print("Harasser Execute")
183 
184  self.testDef = testDef
185 
186  try:
187  if log['section'] is not None:
188  if "Default" in log['section']:
189  # this section contains default settings
190  # for this launcher
191  myopts = {}
192  testDef.parseOptions(log, self.options, keyvals, myopts)
193  # transfer the findings into our local storage
194  keys = list(self.options.keys())
195  optkeys = list(myopts.keys())
196  for optkey in optkeys:
197  for key in keys:
198  if key == optkey:
199  self.options[key] = (myopts[optkey],self.options[key][1])
200 
201  # we captured the default settings, so we can
202  # now return with success
203  log['status'] = 0
204  return
205  except KeyError:
206  # error - the section should have been there
207  log['status'] = 1
208  log['stderr'] = "Section not specified"
209  return
210 
211  log['status'] = 1
212  log['stderr'] = "Must be used in a Default stage"
213 
def check
A check to see if harassers are working properly.
Definition: Harasser.py:140
def activate
Activates plugin.
Definition: Harasser.py:52
def get_running_harassers
Returns information about what harassers are currently running.
Definition: Harasser.py:87
def parallel_execute
This function is passed into multiprocessing as a target.
Definition: Harasser.py:93
def config
Configures plugin outside of INI file.
Definition: Harasser.py:44
def deactivate
Deactivates plugin.
Definition: Harasser.py:62
def start
Harassment is started on the system.
Definition: Harasser.py:99
def stop
Calls the stop-scripts provided with harasser scripts to stop and clean up harassment.
Definition: Harasser.py:154
def print_options
Prints current configuration of plugin.
Definition: Harasser.py:78
def execute
Configure the harasser plugin on whether to run and what to run.
Definition: Harasser.py:181