[PATCH v2] RecipeCommon PerfRepo: move, modify perfrepo classes
by Kamil Jerabek
Moving all perfrepo related classes into RecipeCommon/PerfRepo directory.
Classes are modified so that it is usable within new LNST version.
Signed-off-by: Kamil Jerabek <kjerabek(a)redhat.com>
---
*v2:
* access to configuration changed, need to be implemented, hence few parts
of code commented and not used now
---
lnst/Controller/PerfRepoMapping.py | 74 -----
lnst/Controller/PerfRepoUtils.py | 72 -----
lnst/Controller/Task.py | 277 -------------------
lnst/RecipeCommon/PerfRepo.py | 44 ---
lnst/RecipeCommon/PerfRepo/PerfRepo.py | 384 ++++++++++++++++++++++++++
lnst/RecipeCommon/PerfRepo/PerfRepoMapping.py | 74 +++++
lnst/RecipeCommon/PerfRepo/PerfRepoUtils.py | 72 +++++
lnst/RecipeCommon/PerfRepo/__init__.py | 0
8 files changed, 530 insertions(+), 467 deletions(-)
delete mode 100644 lnst/Controller/PerfRepoMapping.py
delete mode 100644 lnst/Controller/PerfRepoUtils.py
delete mode 100644 lnst/RecipeCommon/PerfRepo.py
create mode 100644 lnst/RecipeCommon/PerfRepo/PerfRepo.py
create mode 100644 lnst/RecipeCommon/PerfRepo/PerfRepoMapping.py
create mode 100644 lnst/RecipeCommon/PerfRepo/PerfRepoUtils.py
create mode 100644 lnst/RecipeCommon/PerfRepo/__init__.py
diff --git a/lnst/Controller/PerfRepoMapping.py b/lnst/Controller/PerfRepoMapping.py
deleted file mode 100644
index 2cec2d8..0000000
--- a/lnst/Controller/PerfRepoMapping.py
+++ /dev/null
@@ -1,74 +0,0 @@
-"""
-This module defines the PerfRepoMapping class that is used as an interface to
-mapping files that map recipe keys to IDs in a PerfRepo instance.
-
-Copyright 2015 Red Hat, Inc.
-Licensed under the GNU General Public License, version 2 as
-published by the Free Software Foundation; see COPYING for details.
-"""
-
-__author__ = """
-olichtne(a)redhat.com (Ondrej Lichtner)
-"""
-
-import re
-import logging
-import pprint
-from lnst.Common.Path import Path
-
-class PerfRepoMapping(object):
- def __init__(self, filepath):
- if not isinstance(filepath, Path):
- filepath = Path(None, filepath)
-
- self._filepath = filepath.resolve()
- self._mapping = {}
- self.load_mapping_file(self._filepath)
-
- def load_mapping_file(self, filename):
- line_re = re.compile(r"^(\w+)\s*=\s*(\w+)\s*$")
- res_dict = {}
-
- lines = []
- try:
- with open(filename) as f:
- lines = f.readlines()
- except:
- self._mapping = {}
- raise
-
- lines = self._preprocess_lines(lines)
-
- for line in lines:
- match = line_re.match(line)
- if match is not None and len(match.groups()) == 2:
- res_dict[match.group(1)] = match.group(2)
- else:
- logging.warn("Skipping mapping line, invalid format:\n%s" %line)
- self._mapping = res_dict
-
- def _preprocess_lines(self, lines):
- comment_re = re.compile(r"^(.*?)#.*$")
- result_lines = []
-
- for line in lines:
- line = line.strip()
- match = comment_re.match(line)
- if match and len(match.groups()) == 1:
- line = match.group(1)
- line = line.strip()
- if line != "":
- result_lines.append(line)
- return result_lines
-
- def get_id(self, key):
- try:
- return self._mapping[key]
- except (KeyError, TypeError):
- return None
-
- def __str__(self):
- if self._mapping is None:
- return ""
- else:
- return pprint.pformat(self._mapping)
diff --git a/lnst/Controller/PerfRepoUtils.py b/lnst/Controller/PerfRepoUtils.py
deleted file mode 100644
index 4c545e4..0000000
--- a/lnst/Controller/PerfRepoUtils.py
+++ /dev/null
@@ -1,72 +0,0 @@
-"""
-This module contains helper functions useful when writing recipes
-that use PerfRepo.
-
-Copyright 2015 Red Hat, Inc.
-Licensed under the GNU General Public License, version 2 as
-published by the Free Software Foundation; see COPYING for details.
-"""
-
-__author__ = """
-olichtne(a)redhat.com (Ondrej Lichtner)
-"""
-
-import logging
-from lnst.Common.Utils import Noop
-
-def netperf_baseline_template(module, baseline):
- module.unset_option('threshold')
- module.unset_option('threshold_deviation')
-
- if baseline.get_texec() is None:
- return module
-
- try:
- throughput = baseline.get_value('throughput')
- deviation = baseline.get_value('throughput_deviation')
- except:
- logging.error("Invalid baseline TestExecution passed.")
- return module
-
- logging.debug("Setting Netperf threshold.")
- if throughput is not None and deviation is not None:
- module.update_options({'threshold': '%s bits/sec' % throughput,
- 'threshold_deviation': '%s bits/sec' % deviation})
- return module
-
-def perfrepo_baseline_to_dict(baseline):
- if baseline.get_texec() is None:
- return {}
-
- try:
- throughput = baseline.get_value('throughput')
- deviation = baseline.get_value('throughput_deviation')
- except:
- logging.error("Invalid baseline TestExecution passed.")
- return {}
-
- if throughput is not None and deviation is not None:
- return {'threshold': '%s bits/sec' % throughput,
- 'threshold_deviation': '%s bits/sec' % deviation}
- return {}
-
-def netperf_result_template(perfrepo_result, netperf_result):
- if isinstance(perfrepo_result, Noop):
- return perfrepo_result
-
- try:
- result = netperf_result.get_result()
- res_data = result['res_data']
- rate = res_data['rate']
- deviation = res_data['rate_deviation']
- except:
- logging.error("Netperf didn't return usable result data.")
- return perfrepo_result
-
- logging.debug("Adding Netperf results to PerfRepo object.")
- perfrepo_result.add_value('throughput', rate)
- perfrepo_result.add_value('throughput_min', rate - deviation)
- perfrepo_result.add_value('throughput_max', rate + deviation)
- perfrepo_result.add_value('throughput_deviation', deviation)
-
- return perfrepo_result
diff --git a/lnst/Controller/Task.py b/lnst/Controller/Task.py
index 5c288cc..fdb1734 100644
--- a/lnst/Controller/Task.py
+++ b/lnst/Controller/Task.py
@@ -822,280 +822,3 @@ class VolatileValue(object):
def __str__(self):
return str(self.get_val())
-class PerfRepoAPI(object):
- def __init__(self):
- self._rest_api = None
- self._mapping = None
-
- def load_mapping(self, file_path):
- try:
- self._mapping = PerfRepoMapping(file_path.resolve())
- except:
- logging.error("Failed to load PerfRepo mapping file '%s'" %\
- file_path.abs_path())
- self._mapping = None
-
- def get_mapping(self):
- return self._mapping
-
- def connected(self):
- if self._rest_api is not None and self._rest_api.connected() and\
- self._mapping is not None:
- return True
- else:
- return False
-
- def connect(self, url, username, password):
- if PerfRepoRESTAPI is not None:
- self._rest_api = PerfRepoRESTAPI(url, username, password)
- if not self._rest_api.connected():
- self._rest_api = None
- else:
- self._rest_api = None
-
- def new_result(self, mapping_key, name, hash_ignore=[]):
- if not self.connected():
- return Noop()
-
- mapping_id = self._mapping.get_id(mapping_key)
- if mapping_id is None:
- logging.debug("Test key '%s' has no mapping defined!" % mapping_key)
- return Noop()
-
- logging.debug("Test key '%s' mapped to id '%s'" % (mapping_key,
- mapping_id))
-
- test = self._rest_api.test_get_by_id(mapping_id, log=False)
- if test is None:
- test = self._rest_api.test_get_by_uid(mapping_id, log=False)
-
- if test is not None:
- test_url = self._rest_api.get_obj_url(test)
- logging.debug("Found Test with id='%s' and uid='%s'! %s" % \
- (test.get_id(), test.get_uid(), test_url))
- else:
- logging.debug("No Test with id or uid '%s' found!" % mapping_id)
- return Noop()
-
- logging.info("Creating a new result object for PerfRepo")
- result = PerfRepoResult(test, name, hash_ignore)
- return result
-
- def save_result(self, result):
- if isinstance(result, Noop):
- return
- elif not self.connected():
- raise TaskError("Not connected to PerfRepo.")
- elif isinstance(result, PerfRepoResult):
- if len(result.get_testExecution().get_values()) < 1:
- logging.debug("PerfRepoResult with no result data, skipping "\
- "send to PerfRepo.")
- return
- h = result.generate_hash()
- logging.debug("Adding hash '%s' as tag to result." % h)
- result.add_tag(h)
- logging.info("Sending TestExecution to PerfRepo.")
- self._rest_api.testExecution_create(result.get_testExecution())
-
- report_id = self._mapping.get_id(h)
- if not report_id and result.get_testExecution().get_id() != None:
- logging.debug("No mapping defined for hash '%s'" % h)
- logging.debug("If you want to create a new report and set "\
- "this result as the baseline run this command:")
- cmd = "perfrepo report create"
- cmd += " name REPORTNAME"
-
- test = result.get_test()
- cmd += " chart CHARTNAME"
- cmd += " testid %s" % test.get_id()
- series_num = 0
- for m in test.get_metrics():
- cmd += " series NAME%d" % series_num
- cmd += " metric %s" % m.get_id()
- cmd += " tags %s" % h
- series_num += 1
- cmd += " baseline BASELINENAME"
- cmd += " execid %s" % result.get_testExecution().get_id()
- cmd += " metric %s" % test.get_metrics()[0].get_id()
- logging.debug(cmd)
- else:
- raise TaskError("Parameter result must be an instance "\
- "of PerfRepoResult")
-
- def get_baseline(self, report_id):
- if report_id is None or not self.connected():
- return Noop()
-
- report = self._rest_api.report_get_by_id(report_id, log=False)
- if report is None:
- logging.debug("No report with id %s found!" % report_id)
- return Noop()
- logging.debug("Report found: %s" %\
- self._rest_api.get_obj_url(report))
-
- baseline = report.get_baseline()
-
- if baseline is None:
- logging.debug("No baseline set for report %s" %\
- self._rest_api.get_obj_url(report))
- return Noop()
-
- baseline_exec_id = baseline["execId"]
- baseline_testExec = self._rest_api.testExecution_get(baseline_exec_id,
- log=False)
-
- logging.debug("TestExecution of baseline: %s" %\
- self._rest_api.get_obj_url(baseline_testExec))
- return PerfRepoBaseline(baseline_testExec)
-
- def get_baseline_of_result(self, result):
- if not isinstance(result, PerfRepoResult) or not self.connected():
- return Noop()
-
- res_hash = result.generate_hash()
- logging.debug("Result hash is: '%s'" % res_hash)
-
- report_id = self._mapping.get_id(res_hash)
- if report_id is not None:
- logging.debug("Hash '%s' maps to report id '%s'" % (res_hash,
- report_id))
- else:
- logging.debug("Hash '%s' has no mapping defined!" % res_hash)
- return Noop()
-
- baseline = self.get_baseline(report_id)
-
- if baseline.get_texec() is None:
- logging.debug("No baseline set for results with hash %s" % res_hash)
- return baseline
-
- def compare_to_baseline(self, result, report_id, metric_name):
- if not self.connected():
- return False
- baseline_testExec = self.get_baseline(report_id)
- result_testExec = result.get_testExecution()
-
- return self.compare_testExecutions(result_testExec,
- baseline_testExec,
- metric_name)
-
- def compare_testExecutions(self, first, second, metric_name):
- first_value = first.get_value(metric_name)
- first_min = first.get_value(metric_name + "_min")
- first_max = first.get_value(metric_name + "_max")
-
- second_value = second.get_value(metric_name)
- second_min = second.get_value(metric_name + "_min")
- second_max = second.get_value(metric_name + "_max")
-
- comp = second_value.get_comparator()
- if comp == "HB":
- if second_min.get_result() > first_max.get_result():
- return False
- return True
- elif comp == "LB":
- if first_min.get_result() > second_max.get_result():
- return False
- return True
- else:
- return False
- return False
-
-class PerfRepoResult(object):
- def __init__(self, test, name, hash_ignore=[]):
- self._test = test
- self._testExecution = PerfRepoTestExecution()
- self._testExecution.set_testId(test.get_id())
- self._testExecution.set_testUid(test.get_uid())
- self._testExecution.set_name(name)
- self.set_configuration(ctl.get_configuration())
- self._hash_ignore = hash_ignore
-
- def add_value(self, val_name, value):
- perf_value = PerfRepoValue()
- perf_value.set_metricName(val_name)
- perf_value.set_result(value)
-
- self._testExecution.add_value(perf_value)
-
- def set_configuration(self, configuration=None):
- if configuration is None:
- configuration = ctl.get_configuration()
- for pair in dict_to_dot(configuration, "configuration."):
- self._testExecution.add_parameter(pair[0], pair[1])
-
- def set_mapping(self, mapping=None):
- if mapping is None:
- mapping = ctl.get_mapping()
- for pair in list_to_dot(mapping, "mapping.", "machine"):
- self._testExecution.add_parameter(pair[0], pair[1])
-
- def set_tag(self, tag):
- self._testExecution.add_tag(tag)
-
- def add_tag(self, tag):
- self.set_tag(tag)
-
- def set_tags(self, tags):
- for tag in tags:
- self.set_tag(tag)
-
- def add_tags(self, tags):
- self.set_tags(tags)
-
- def set_parameter(self, name, value):
- self._testExecution.add_parameter(name, value)
-
- def set_parameters(self, params):
- for name, value in params:
- self.set_parameter(name, value)
-
- def set_hash_ignore(self, hash_ignore):
- self._hash_ignore = hash_ignore
-
- def set_comment(self, comment):
- if comment:
- self._testExecution.set_comment(comment)
-
- def get_hash_ignore(self):
- return self._hash_ignore
-
- def get_testExecution(self):
- return self._testExecution
-
- def get_test(self):
- return self._test
-
- def generate_hash(self, ignore=[]):
- ignore.extend(self._hash_ignore)
- tags = self._testExecution.get_tags()
- params = self._testExecution.get_parameters()
-
- sha1 = hashlib.sha1()
- sha1.update(self._testExecution.get_testUid())
- for i in sorted(tags):
- sha1.update(i)
- for i in sorted(params, key=lambda x: x[0]):
- skip = False
- for j in ignore:
- if re.search(j, i[0]):
- skip = True
- break
- if skip:
- continue
- sha1.update(i[0])
- sha1.update(str(i[1]))
- return sha1.hexdigest()
-
-class PerfRepoBaseline(object):
- def __init__(self, texec):
- self._texec = texec
-
- def get_value(self, name):
- if self._texec is None:
- return None
- perfrepovalue = self._texec.get_value(name)
- return perfrepovalue.get_result()
-
- def get_texec(self):
- return self._texec
diff --git a/lnst/RecipeCommon/PerfRepo.py b/lnst/RecipeCommon/PerfRepo.py
deleted file mode 100644
index 432dad8..0000000
--- a/lnst/RecipeCommon/PerfRepo.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""
-This module defines helper functions for interacting with PerfRepo
-that can be imported directly into LNST Python tasks.
-
-Copyright 2016 Red Hat, Inc.
-Licensed under the GNU General Public License, version 2 as
-published by the Free Software Foundation; see COPYING for details.
-"""
-
-__author__ = """
-jtluka(a)redhat.com (Jan Tluka)
-"""
-
-import os
-
-def generate_perfrepo_comment(hosts=[], user_comment=None):
- """ Prepare the PerfRepo comment.
-
- By default it will include kernel versions used on the hosts and
- Beaker job url.
-
- Keyword arguments:
- hosts -- list of HostAPI objects
- user_comment -- additional user specified comment
- """
-
- comment = ""
-
- for host in hosts:
- host_cfg = host.get_configuration()
- comment += "Kernel (%s): %s<BR>" % \
- (host_cfg['id'], host_cfg['kernel_release'])
-
- # if we're running in Beaker environment, include job url
- if 'BEAKER' in os.environ and 'JOBID' in os.environ:
- bkr_server = os.environ['BEAKER']
- bkr_jobid = os.environ['JOBID']
- bkr_job_url = bkr_server + 'jobs/' + bkr_jobid
- comment += "Beaker job: %s<BR>" % bkr_job_url
-
- if user_comment:
- comment += user_comment
-
- return comment
diff --git a/lnst/RecipeCommon/PerfRepo/PerfRepo.py b/lnst/RecipeCommon/PerfRepo/PerfRepo.py
new file mode 100644
index 0000000..9737de0
--- /dev/null
+++ b/lnst/RecipeCommon/PerfRepo/PerfRepo.py
@@ -0,0 +1,384 @@
+"""
+This module defines helper functions for interacting with PerfRepo
+that can be imported directly into LNST Python tasks.
+
+Copyright 2016 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__author__ = """
+jtluka(a)redhat.com (Jan Tluka)
+"""
+
+import os
+import re
+import logging
+import hashlib
+
+from lnst.Common.Path import Path
+from lnst.RecipeCommon.PerfRepo.PerfRepoMapping import PerfRepoMapping
+from lnst.Common.Utils import dict_to_dot, list_to_dot
+from lnst.Common.Utils import Noop
+from lnst.Common.LnstError import LnstError
+
+try:
+ from perfrepo import PerfRepoRESTAPI
+ from perfrepo import PerfRepoTestExecution
+ from perfrepo import PerfRepoValue
+except:
+ PerfRepoRESTAPI = None
+ PerfRepoTestExecution = None
+ PerfRepoValue = None
+
+class PerfRepoError(LnstError):
+ """Exception used by PerfRepo related stuff"""
+ pass
+
+
+def generate_perfrepo_comment(hosts=[], user_comment=None):
+ """ Prepare the PerfRepo comment.
+
+ By default it will include kernel versions used on the hosts and
+ Beaker job url.
+
+ Keyword arguments:
+ hosts -- list of HostAPI objects
+ user_comment -- additional user specified comment
+ """
+
+ comment = ""
+
+ for host in hosts:
+ host_cfg = host.get_configuration()
+ comment += "Kernel (%s): %s<BR>" % \
+ (host_cfg['id'], host_cfg['kernel_release'])
+
+ # if we're running in Beaker environment, include job url
+ if 'BEAKER' in os.environ and 'JOBID' in os.environ:
+ bkr_server = os.environ['BEAKER']
+ bkr_jobid = os.environ['JOBID']
+ bkr_job_url = bkr_server + 'jobs/' + bkr_jobid
+ comment += "Beaker job: %s<BR>" % bkr_job_url
+
+ if user_comment:
+ comment += user_comment
+
+ return comment
+
+
+
+
+
+class PerfRepoAPI(object):
+ def __init__(self, mapping_file_path, url=None, username=None, password=None):
+ self._mapping_file_path = mapping_file_path
+ self._url = url
+ self._username = username
+ self._password = password
+
+ self._rest_api = None
+ self._mapping = None
+
+ def connect_PerfRepo(self):
+ if not self.connected():
+ #TODO: store credentials in config or not
+ #if self._url is None:
+ # self._url = lnst_config.get_option("perfrepo", "url")
+ #if self._username is None:
+ # self._username = lnst_config.get_option("perfrepo", "username")
+ #if self._password is None:
+ # self._password = lnst_config.get_option("perfrepo", "password")
+
+ if not self._url:
+ logging.warn("No PerfRepo URL specified in config file")
+ if not self._username:
+ logging.warn("No PerfRepo username specified in config file")
+ if not self._password:
+ logging.warn("No PerfRepo password specified in config file")
+ if self._url and self._username and self._password:
+ self.connect(self._url, self._username, self._password)
+
+ path = Path(None, self._mapping_file_path)
+ self.load_mapping(path)
+
+ if not self.connected():
+ if PerfRepoRESTAPI is None:
+ logging.warn("Python PerfRepo library not found.")
+ logging.warn("Connection to PerfRepo incomplete, further "\
+ "PerfRepo commands will be ignored.")
+
+ def load_mapping(self, file_path):
+ try:
+ self._mapping = PerfRepoMapping(file_path.resolve())
+ except:
+ logging.error("Failed to load PerfRepo mapping file '%s'" %\
+ file_path.abs_path())
+ self._mapping = None
+
+ def get_mapping(self):
+ return self._mapping
+
+ def connected(self):
+ if self._rest_api is not None and self._rest_api.connected() and\
+ self._mapping is not None:
+ return True
+ else:
+ return False
+
+ def connect(self, url, username, password):
+ if PerfRepoRESTAPI is not None:
+ self._rest_api = PerfRepoRESTAPI(url, username, password)
+ if not self._rest_api.connected():
+ self._rest_api = None
+ else:
+ self._rest_api = None
+
+ def new_result(self, mapping_key, name, hash_ignore=[]):
+ if not self.connected():
+ return Noop()
+
+ mapping_id = self._mapping.get_id(mapping_key)
+ if mapping_id is None:
+ logging.debug("Test key '%s' has no mapping defined!" % mapping_key)
+ return Noop()
+
+ logging.debug("Test key '%s' mapped to id '%s'" % (mapping_key,
+ mapping_id))
+
+ test = self._rest_api.test_get_by_id(mapping_id, log=False)
+ if test is None:
+ test = self._rest_api.test_get_by_uid(mapping_id, log=False)
+
+ if test is not None:
+ test_url = self._rest_api.get_obj_url(test)
+ logging.debug("Found Test with id='%s' and uid='%s'! %s" % \
+ (test.get_id(), test.get_uid(), test_url))
+ else:
+ logging.debug("No Test with id or uid '%s' found!" % mapping_id)
+ return Noop()
+
+ logging.info("Creating a new result object for PerfRepo")
+ result = PerfRepoResult(test, name, hash_ignore)
+ return result
+
+ def save_result(self, result):
+ if isinstance(result, Noop):
+ return
+ elif not self.connected():
+ raise PerfRepoError("Not connected to PerfRepo.")
+ elif isinstance(result, PerfRepoResult):
+ if len(result.get_testExecution().get_values()) < 1:
+ logging.debug("PerfRepoResult with no result data, skipping "\
+ "send to PerfRepo.")
+ return
+ h = result.generate_hash()
+ logging.debug("Adding hash '%s' as tag to result." % h)
+ result.add_tag(h)
+ logging.info("Sending TestExecution to PerfRepo.")
+ self._rest_api.testExecution_create(result.get_testExecution())
+
+ report_id = self._mapping.get_id(h)
+ if not report_id and result.get_testExecution().get_id() is not None:
+ logging.debug("No mapping defined for hash '%s'" % h)
+ logging.debug("If you want to create a new report and set "\
+ "this result as the baseline run this command:")
+ cmd = "perfrepo report create"
+ cmd += " name REPORTNAME"
+
+ test = result.get_test()
+ cmd += " chart CHARTNAME"
+ cmd += " testid %s" % test.get_id()
+ series_num = 0
+ for m in test.get_metrics():
+ cmd += " series NAME%d" % series_num
+ cmd += " metric %s" % m.get_id()
+ cmd += " tags %s" % h
+ series_num += 1
+ cmd += " baseline BASELINENAME"
+ cmd += " execid %s" % result.get_testExecution().get_id()
+ cmd += " metric %s" % test.get_metrics()[0].get_id()
+ logging.debug(cmd)
+ else:
+ raise PerfRepoError("Parameter result must be an instance "\
+ "of PerfRepoResult")
+
+ def get_baseline(self, report_id):
+ if report_id is None or not self.connected():
+ return Noop()
+
+ report = self._rest_api.report_get_by_id(report_id, log=False)
+ if report is None:
+ logging.debug("No report with id %s found!" % report_id)
+ return Noop()
+ logging.debug("Report found: %s" %\
+ self._rest_api.get_obj_url(report))
+
+ baseline = report.get_baseline()
+
+ if baseline is None:
+ logging.debug("No baseline set for report %s" %\
+ self._rest_api.get_obj_url(report))
+ return Noop()
+
+ baseline_exec_id = baseline["execId"]
+ baseline_testExec = self._rest_api.testExecution_get(baseline_exec_id,
+ log=False)
+
+ logging.debug("TestExecution of baseline: %s" %\
+ self._rest_api.get_obj_url(baseline_testExec))
+ return PerfRepoBaseline(baseline_testExec)
+
+ def get_baseline_of_result(self, result):
+ if not isinstance(result, PerfRepoResult) or not self.connected():
+ return Noop()
+
+ res_hash = result.generate_hash()
+ logging.debug("Result hash is: '%s'" % res_hash)
+
+ report_id = self._mapping.get_id(res_hash)
+ if report_id is not None:
+ logging.debug("Hash '%s' maps to report id '%s'" % (res_hash,
+ report_id))
+ else:
+ logging.debug("Hash '%s' has no mapping defined!" % res_hash)
+ return Noop()
+
+ baseline = self.get_baseline(report_id)
+
+ if baseline.get_texec() is None:
+ logging.debug("No baseline set for results with hash %s" % res_hash)
+ return baseline
+
+ def compare_to_baseline(self, result, report_id, metric_name):
+ if not self.connected():
+ return False
+ baseline_testExec = self.get_baseline(report_id)
+ result_testExec = result.get_testExecution()
+
+ return self.compare_testExecutions(result_testExec,
+ baseline_testExec,
+ metric_name)
+
+ def compare_testExecutions(self, first, second, metric_name):
+ first_value = first.get_value(metric_name)
+ first_min = first.get_value(metric_name + "_min")
+ first_max = first.get_value(metric_name + "_max")
+
+ second_value = second.get_value(metric_name)
+ second_min = second.get_value(metric_name + "_min")
+ second_max = second.get_value(metric_name + "_max")
+
+ comp = second_value.get_comparator()
+ if comp == "HB":
+ if second_min.get_result() > first_max.get_result():
+ return False
+ return True
+ elif comp == "LB":
+ if first_min.get_result() > second_max.get_result():
+ return False
+ return True
+ else:
+ return False
+ return False
+
+class PerfRepoResult(object):
+ def __init__(self, test, name, hash_ignore=[]):
+ self._test = test
+ self._testExecution = PerfRepoTestExecution()
+ self._testExecution.set_testId(test.get_id())
+ self._testExecution.set_testUid(test.get_uid())
+ self._testExecution.set_name(name)
+ #self.set_configuration(ctl.get_configuration())
+ self._hash_ignore = hash_ignore
+
+ def add_value(self, val_name, value):
+ perf_value = PerfRepoValue()
+ perf_value.set_metricName(val_name)
+ perf_value.set_result(value)
+
+ self._testExecution.add_value(perf_value)
+
+ def set_configuration(self, configuration=None):
+ #if configuration is None:
+ # configuration = ctl.get_configuration()
+ #for pair in dict_to_dot(configuration, "configuration."):
+ # self._testExecution.add_parameter(pair[0], pair[1])
+ pass
+
+ def set_mapping(self, mapping=None):
+ #if mapping is None:
+ # mapping = ctl.get_mapping()
+ #for pair in list_to_dot(mapping, "mapping.", "machine"):
+ # self._testExecution.add_parameter(pair[0], pair[1])
+ pass
+
+ def set_tag(self, tag):
+ self._testExecution.add_tag(tag)
+
+ def add_tag(self, tag):
+ self.set_tag(tag)
+
+ def set_tags(self, tags):
+ for tag in tags:
+ self.set_tag(tag)
+
+ def add_tags(self, tags):
+ self.set_tags(tags)
+
+ def set_parameter(self, name, value):
+ self._testExecution.add_parameter(name, value)
+
+ def set_parameters(self, params):
+ for name, value in params:
+ self.set_parameter(name, value)
+
+ def set_hash_ignore(self, hash_ignore):
+ self._hash_ignore = hash_ignore
+
+ def set_comment(self, comment):
+ if comment:
+ self._testExecution.set_comment(comment)
+
+ def get_hash_ignore(self):
+ return self._hash_ignore
+
+ def get_testExecution(self):
+ return self._testExecution
+
+ def get_test(self):
+ return self._test
+
+ def generate_hash(self, ignore=[]):
+ ignore.extend(self._hash_ignore)
+ tags = self._testExecution.get_tags()
+ params = self._testExecution.get_parameters()
+
+ sha1 = hashlib.sha1()
+ sha1.update(self._testExecution.get_testUid())
+ for i in sorted(tags):
+ sha1.update(i)
+ for i in sorted(params, key=lambda x: x[0]):
+ skip = False
+ for j in ignore:
+ if re.search(j, i[0]):
+ skip = True
+ break
+ if skip:
+ continue
+ sha1.update(i[0])
+ sha1.update(str(i[1]))
+ return sha1.hexdigest()
+
+class PerfRepoBaseline(object):
+ def __init__(self, texec):
+ self._texec = texec
+
+ def get_value(self, name):
+ if self._texec is None:
+ return None
+ perfrepovalue = self._texec.get_value(name)
+ return perfrepovalue.get_result()
+
+ def get_texec(self):
+ return self._texec
diff --git a/lnst/RecipeCommon/PerfRepo/PerfRepoMapping.py b/lnst/RecipeCommon/PerfRepo/PerfRepoMapping.py
new file mode 100644
index 0000000..2cec2d8
--- /dev/null
+++ b/lnst/RecipeCommon/PerfRepo/PerfRepoMapping.py
@@ -0,0 +1,74 @@
+"""
+This module defines the PerfRepoMapping class that is used as an interface to
+mapping files that map recipe keys to IDs in a PerfRepo instance.
+
+Copyright 2015 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__author__ = """
+olichtne(a)redhat.com (Ondrej Lichtner)
+"""
+
+import re
+import logging
+import pprint
+from lnst.Common.Path import Path
+
+class PerfRepoMapping(object):
+ def __init__(self, filepath):
+ if not isinstance(filepath, Path):
+ filepath = Path(None, filepath)
+
+ self._filepath = filepath.resolve()
+ self._mapping = {}
+ self.load_mapping_file(self._filepath)
+
+ def load_mapping_file(self, filename):
+ line_re = re.compile(r"^(\w+)\s*=\s*(\w+)\s*$")
+ res_dict = {}
+
+ lines = []
+ try:
+ with open(filename) as f:
+ lines = f.readlines()
+ except:
+ self._mapping = {}
+ raise
+
+ lines = self._preprocess_lines(lines)
+
+ for line in lines:
+ match = line_re.match(line)
+ if match is not None and len(match.groups()) == 2:
+ res_dict[match.group(1)] = match.group(2)
+ else:
+ logging.warn("Skipping mapping line, invalid format:\n%s" %line)
+ self._mapping = res_dict
+
+ def _preprocess_lines(self, lines):
+ comment_re = re.compile(r"^(.*?)#.*$")
+ result_lines = []
+
+ for line in lines:
+ line = line.strip()
+ match = comment_re.match(line)
+ if match and len(match.groups()) == 1:
+ line = match.group(1)
+ line = line.strip()
+ if line != "":
+ result_lines.append(line)
+ return result_lines
+
+ def get_id(self, key):
+ try:
+ return self._mapping[key]
+ except (KeyError, TypeError):
+ return None
+
+ def __str__(self):
+ if self._mapping is None:
+ return ""
+ else:
+ return pprint.pformat(self._mapping)
diff --git a/lnst/RecipeCommon/PerfRepo/PerfRepoUtils.py b/lnst/RecipeCommon/PerfRepo/PerfRepoUtils.py
new file mode 100644
index 0000000..4c545e4
--- /dev/null
+++ b/lnst/RecipeCommon/PerfRepo/PerfRepoUtils.py
@@ -0,0 +1,72 @@
+"""
+This module contains helper functions useful when writing recipes
+that use PerfRepo.
+
+Copyright 2015 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__author__ = """
+olichtne(a)redhat.com (Ondrej Lichtner)
+"""
+
+import logging
+from lnst.Common.Utils import Noop
+
+def netperf_baseline_template(module, baseline):
+ module.unset_option('threshold')
+ module.unset_option('threshold_deviation')
+
+ if baseline.get_texec() is None:
+ return module
+
+ try:
+ throughput = baseline.get_value('throughput')
+ deviation = baseline.get_value('throughput_deviation')
+ except:
+ logging.error("Invalid baseline TestExecution passed.")
+ return module
+
+ logging.debug("Setting Netperf threshold.")
+ if throughput is not None and deviation is not None:
+ module.update_options({'threshold': '%s bits/sec' % throughput,
+ 'threshold_deviation': '%s bits/sec' % deviation})
+ return module
+
+def perfrepo_baseline_to_dict(baseline):
+ if baseline.get_texec() is None:
+ return {}
+
+ try:
+ throughput = baseline.get_value('throughput')
+ deviation = baseline.get_value('throughput_deviation')
+ except:
+ logging.error("Invalid baseline TestExecution passed.")
+ return {}
+
+ if throughput is not None and deviation is not None:
+ return {'threshold': '%s bits/sec' % throughput,
+ 'threshold_deviation': '%s bits/sec' % deviation}
+ return {}
+
+def netperf_result_template(perfrepo_result, netperf_result):
+ if isinstance(perfrepo_result, Noop):
+ return perfrepo_result
+
+ try:
+ result = netperf_result.get_result()
+ res_data = result['res_data']
+ rate = res_data['rate']
+ deviation = res_data['rate_deviation']
+ except:
+ logging.error("Netperf didn't return usable result data.")
+ return perfrepo_result
+
+ logging.debug("Adding Netperf results to PerfRepo object.")
+ perfrepo_result.add_value('throughput', rate)
+ perfrepo_result.add_value('throughput_min', rate - deviation)
+ perfrepo_result.add_value('throughput_max', rate + deviation)
+ perfrepo_result.add_value('throughput_deviation', deviation)
+
+ return perfrepo_result
diff --git a/lnst/RecipeCommon/PerfRepo/__init__.py b/lnst/RecipeCommon/PerfRepo/__init__.py
new file mode 100644
index 0000000..e69de29
--
2.5.5
6 years, 4 months
[PATCH] regression_tests: add ipsec_esp_aead test
by Kamil Jerabek
This patch adds new ipsec_esp_aead test to our phase3 regression_tests. It is
similar to ipsec_esp_ah_comp test. There is difference in configuration.
In the test is configured only esp aead with algorithm rfc4106(gcm(aes)),
key length 160bit and IV length 96bit.
Signed-off-by: Kamil Jerabek <kjerabek(a)redhat.com>
---
.../regression_tests/phase3/ipsec_esp_aead.README | 90 +++++
recipes/regression_tests/phase3/ipsec_esp_aead.py | 434 +++++++++++++++++++++
recipes/regression_tests/phase3/ipsec_esp_aead.xml | 50 +++
3 files changed, 574 insertions(+)
create mode 100644 recipes/regression_tests/phase3/ipsec_esp_aead.README
create mode 100644 recipes/regression_tests/phase3/ipsec_esp_aead.py
create mode 100644 recipes/regression_tests/phase3/ipsec_esp_aead.xml
diff --git a/recipes/regression_tests/phase3/ipsec_esp_aead.README b/recipes/regression_tests/phase3/ipsec_esp_aead.README
new file mode 100644
index 0000000..8738da6
--- /dev/null
+++ b/recipes/regression_tests/phase3/ipsec_esp_aead.README
@@ -0,0 +1,90 @@
+Topology:
+
+ switch
+ +------+
+ | |
+ | |
+ +-------------+ +-------------+
+ | | | |
+ | | | |
+ | +------+ |
+ | |
+ | |
+ +-+--+ +-+--+
++-------|eth1|------+ +-------|eth1|------+
+| +-+--+ | | +-+--+ |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++-------------------+ +-------------------+
+
+Number of hosts: 2
+Host #1 description:
+ One ethernet device configured with ip addresses:
+ 192.168.99.1/24
+ fc00:1::1/64
+
+Host #2 description:
+ One ethernet device configured with ip addresses:
+ 192.168.100.1/24
+ fc00:2::1/64
+
+Test name:
+ ipsec_esp_aead.py
+Test description:
+ Ping:
+ + count: 10
+ + interval: 0.1s
+ + between ipsec encrypted ethernet interfaces headers check expecting PASS
+ + between ipsec encrypted ethernet interfaces compression check expecting PASS
+ Ping6:
+ + count: 10
+ + interval: 0.1s
+ + between ipsec encrypted ethernet interfaces headers check expecting PASS
+ + between ipsec encrypted ethernet interfaces compression check expecting PASS
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + ipv4 and ipv6
+ + between ipsec encrypted ethernet interfaces
+ IPsec
+ + tested with esp AEAD
+ + tested with algorithm rfc4106(gcm(aes))
+ + key length - 160bit
+ + IV length - 96bit
+
+PerfRepo integration:
+ First, preparation in PerfRepo is required - you need to create Test objects
+ through the web interface that properly describe the individual Netperf
+ tests that this recipe runs. Don't forget to also add appropriate metrics.
+ For these Netperf tests it's always:
+ * throughput
+ * throughput_min
+ * throughput_max
+ * throughput_deviation
+
+ After that, to enable support for PerfRepo you need to create the file
+ vxlan_remote.mapping and define the following id mappings:
+ tcp_ipv4_id -> to store ipv4 TCP_STREAM Netperf test results, maps to TestUid of a PerfRepo Test object
+ tcp_ipv6_id -> to store ipv6 TCP_STREAM Netperf test results, maps to TestUid of a PerfRepo Test object
+ udp_ipv4_id -> to store ipv4 UDP_STREAM Netperf test results, maps to TestUid of a PerfRepo Test object
+ udp_ipv6_id -> to store ipv4 UDP_STREAM Netperf test results, maps to TestUid of a PerfRepo Test object
+
+ To enable result comparison agains baselines you need to create a Report in
+ PerfRepo that will store the baseline. Set up the Report to only contain results
+ with the same hash tag and then add a new mapping to the mapping file, with
+ this format:
+ <some_hash> = <report_id>
+
+ The hash value is automatically generated during test execution and added
+ to each result stored in PerfRepo. To get the Report id you need to open
+ that report in our browser and find if in the URL.
+
+ When running this recipe you should also define the 'product_name' alias
+ (e.g. RHEL7) in order to tag the result object in PerfRepo.
diff --git a/recipes/regression_tests/phase3/ipsec_esp_aead.py b/recipes/regression_tests/phase3/ipsec_esp_aead.py
new file mode 100644
index 0000000..34ced74
--- /dev/null
+++ b/recipes/regression_tests/phase3/ipsec_esp_aead.py
@@ -0,0 +1,434 @@
+from lnst.Controller.Task import ctl
+from lnst.Controller.PerfRepoUtils import perfrepo_baseline_to_dict
+from lnst.Controller.PerfRepoUtils import netperf_result_template
+
+from lnst.RecipeCommon.ModuleWrap import ping, ping6, netperf
+from lnst.RecipeCommon.IRQ import pin_dev_irqs
+from lnst.RecipeCommon.PerfRepo import generate_perfrepo_comment
+import re
+
+# ---------------------------
+# ALGORITHM AND CIPHER CONFIG
+# ---------------------------
+
+#lenth param is in bits
+def generate_key(length):
+ key = "0x"
+ key = key + (length/8) * "0b"
+ return key
+
+algorithm = []
+
+algorithm.append(('rfc4106(gcm(aes))', 160, 96))
+
+# ------
+# SETUP
+# ------
+
+mapping_file = ctl.get_alias("mapping_file")
+perf_api = ctl.connect_PerfRepo(mapping_file)
+
+product_name = ctl.get_alias("product_name")
+
+m1 = ctl.get_host("machine1")
+m2 = ctl.get_host("machine2")
+
+m1.sync_resources(modules=["IcmpPing", "Icmp6Ping", "Netperf", "Custom"])
+m2.sync_resources(modules=["PacketAssert", "IcmpPing", "Icmp6Ping", "Netperf"])
+
+# ------
+# TESTS
+# ------
+
+ipv = ctl.get_alias("ipv")
+mtu = ctl.get_alias("mtu")
+netperf_duration = int(ctl.get_alias("netperf_duration"))
+nperf_reserve = int(ctl.get_alias("nperf_reserve"))
+nperf_confidence = ctl.get_alias("nperf_confidence")
+nperf_max_runs = int(ctl.get_alias("nperf_max_runs"))
+nperf_cpupin = ctl.get_alias("nperf_cpupin")
+nperf_cpu_util = ctl.get_alias("nperf_cpu_util")
+nperf_num_parallel = int(ctl.get_alias("nperf_num_parallel"))
+nperf_debug = ctl.get_alias("nperf_debug")
+nperf_max_dev = ctl.get_alias("nperf_max_dev")
+nperf_msg_size = ctl.get_alias("nperf_msg_size")
+pr_user_comment = ctl.get_alias("perfrepo_comment")
+ipsec_mode = ctl.get_alias("ipsec_mode")
+
+pr_comment = generate_perfrepo_comment([m1, m2], pr_user_comment)
+
+m1_if = m1.get_interface("eth")
+m2_if = m2.get_interface("eth")
+
+m1_if.set_mtu(mtu)
+m2_if.set_mtu(mtu)
+
+m1_if_name = m1_if.get_devname()
+m2_if_name = m2_if.get_devname()
+
+m1_if_addr = m1_if.get_ip()
+m2_if_addr = m2_if.get_ip()
+
+m1_if_addr6 = m1_if.get_ip(1)
+m2_if_addr6 = m2_if.get_ip(1)
+
+
+# add routing rulez ipv4
+# so the host knows where to send traffic destined to remote site
+m1.run("ip route add %s dev %s" % (m2_if_addr, m1_if_name))
+
+# so the host knows where to send traffic destined to remote site
+m2.run("ip route add %s dev %s" % (m1_if_addr, m2_if_name))
+
+# add routing rulez ipv6
+# so the host knows where to send traffic destined to remote site
+m1.run("ip route add %s dev %s" % (m2_if_addr6, m1_if_name))
+
+# so the host knows where to send traffic destined to remote site
+m2.run("ip route add %s dev %s" % (m1_if_addr6, m2_if_name))
+
+if nperf_msg_size is None:
+ nperf_msg_size = 16000
+
+if ipsec_mode is None:
+ ipsec_mode = "transport"
+
+res = m1.run("rpm -qa iproute", save_output=True)
+if (res.get_result()["res_data"]["stdout"].find("iproute-2") != -1):
+ m1_key="0x"
+else:
+ m1_key=""
+
+res = m2.run("rpm -qa iproute", save_output=True)
+if (res.get_result()["res_data"]["stdout"].find("iproute-2") != -1):
+ m2_key="0x"
+else:
+ m2_key=""
+
+if nperf_cpupin:
+ m1.run("service irqbalance stop")
+ m2.run("service irqbalance stop")
+
+ dev_list = [(m1, m1_if), (m2, m2_if)]
+
+ # this will pin devices irqs to cpu #0
+ for m, d in dev_list:
+ pin_dev_irqs(m, d, 0)
+
+nperf_opts = ""
+if nperf_cpupin and nperf_num_parallel == 1:
+ nperf_opts = " -T%s,%s" % (nperf_cpupin, nperf_cpupin)
+
+ctl.wait(15)
+
+def configure_ipsec(algo, algo_key, icv_len, ip_version):
+ if ip_version == "ipv4":
+ m1_addr = m1_if_addr
+ m2_addr = m2_if_addr
+ else:
+ m1_addr = m1_if_addr6
+ m2_addr = m2_if_addr6
+
+ # configure policy and state
+ m1.run("ip xfrm policy flush")
+ m1.run("ip xfrm state flush")
+ m2.run("ip xfrm policy flush")
+ m2.run("ip xfrm state flush")
+
+ m1.run("ip xfrm state add src %s dst %s proto esp spi 0x1001 "\
+ "aead '%s' %s %s mode %s "\
+ "sel src %s dst %s"\
+ % (m2_addr, m1_addr,
+ algo, algo_key, icv_len, ipsec_mode,
+ m2_addr, m1_addr))
+
+ m1.run("ip xfrm policy add src %s dst %s dir in tmpl "\
+ "src %s dst %s proto esp mode %s action allow"\
+ % (m2_addr, m1_addr,
+ m2_addr, m1_addr, ipsec_mode))
+
+ m1.run("ip xfrm state add src %s dst %s proto esp spi 0x1000 "\
+ "aead '%s' %s %s mode %s "\
+ "sel src %s dst %s"\
+ % (m1_addr, m2_addr,
+ algo, algo_key, icv_len, ipsec_mode,
+ m1_addr, m2_addr))
+
+ m1.run("ip xfrm policy add src %s dst %s dir out tmpl "\
+ "src %s dst %s proto esp mode %s action allow"\
+ % (m1_addr, m2_addr,
+ m1_addr, m2_addr, ipsec_mode))
+
+
+
+
+ m2.run("ip xfrm state add src %s dst %s proto esp spi 0x1000 "\
+ "aead '%s' %s %s mode %s "\
+ "sel src %s dst %s"\
+ % (m1_addr, m2_addr,
+ algo, algo_key, icv_len, ipsec_mode,
+ m1_addr, m2_addr))
+
+ m2.run("ip xfrm policy add src %s dst %s dir in tmpl "\
+ "src %s dst %s proto esp mode %s action allow"\
+ % (m1_addr, m2_addr,
+ m1_addr, m2_addr, ipsec_mode))
+
+ m2.run("ip xfrm state add src %s dst %s proto esp spi 0x1001 "\
+ "aead '%s' %s %s mode %s sel "\
+ "src %s dst %s"\
+ % (m2_addr, m1_addr,
+ algo, algo_key, icv_len, ipsec_mode,
+ m2_addr, m1_addr))
+
+ m2.run("ip xfrm policy add src %s dst %s dir out tmpl "\
+ "src %s dst %s proto esp mode %s action allow"\
+ % (m2_addr, m1_addr,
+ m2_addr, m1_addr, ipsec_mode))
+
+
+
+for algo, key_len, icv_len in algorithm:
+ # test: compressed check, TCP netperf, UDP netperf
+ if ipv in [ 'ipv4', 'both']:
+ configure_ipsec(algo,
+ generate_key(key_len),
+ icv_len,
+ "ipv4")
+
+ ctl.wait(15)
+
+ dump = m1.run("tcpdump -i %s -nn -vv" % m1_if_name, bg=True)
+
+ # ping + PacketAssert
+ assert_mod = ctl.get_module("PacketAssert",
+ options={
+ "interface": m2_if_name,
+ "filter": "esp",
+ "grep_for": [ "ESP\(spi=0x00001001" ],
+ "min": 10
+ })
+
+ assert_proc = m2.run(assert_mod, bg=True)
+
+ ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr": m2_if_addr,
+ "count": 10,
+ "interval": 0.1})
+
+ ctl.wait(2)
+
+ m1.run(ping_mod)
+
+ ctl.wait(2)
+
+ assert_proc.intr()
+
+ dump.intr()
+
+ # prepare PerfRepo result for tcp
+ result_tcp = perf_api.new_result("tcp_ipv4_id",
+ "tcp_ipv4_result",
+ hash_ignore=[
+ r'kernel_release',
+ r'redhat_release'])
+ result_tcp.add_tag(product_name)
+
+ if nperf_num_parallel > 1:
+ result_tcp.add_tag("multithreaded")
+ result_tcp.set_parameter('num_parallel', nperf_num_parallel)
+
+ result_tcp.set_parameter('ipsec_algorithm', algo)
+ result_tcp.set_parameter('key_length', key_len)
+ result_tcp.set_parameter('iv_length', icv_len)
+ result_tcp.set_parameter('msg_size', nperf_msg_size)
+ result_tcp.set_parameter('ipsec_mode', ipsec_mode)
+
+ baseline = perf_api.get_baseline_of_result(result_tcp)
+ baseline = perfrepo_baseline_to_dict(baseline)
+
+
+ tcp_res_data = netperf((m1, m1_if, 0, {"scope": 0}),
+ (m2, m2_if, 0, {"scope": 0}),
+ client_opts={"duration" : netperf_duration,
+ "testname" : "TCP_STREAM",
+ "confidence" : nperf_confidence,
+ "num_parallel" : nperf_num_parallel,
+ "cpu_util" : nperf_cpu_util,
+ "runs": nperf_max_runs,
+ "debug": nperf_debug,
+ "max_deviation": nperf_max_dev,
+ "msg_size" : nperf_msg_size,
+ "netperf_opts": nperf_opts},
+ baseline = baseline,
+ timeout = (netperf_duration + nperf_reserve)*nperf_max_runs)
+
+ netperf_result_template(result_tcp, tcp_res_data)
+ result_tcp.set_comment(pr_comment)
+ perf_api.save_result(result_tcp)
+
+ # prepare PerfRepo result for udp
+ result_udp = perf_api.new_result("udp_ipv4_id",
+ "udp_ipv4_result",
+ hash_ignore=[
+ r'kernel_release',
+ r'redhat_release'])
+ result_udp.add_tag(product_name)
+
+ if nperf_num_parallel > 1:
+ result_udp.add_tag("multithreaded")
+ result_udp.set_parameter('num_parallel', nperf_num_parallel)
+
+ result_udp.set_parameter('ipsec_algorithm', algo)
+ result_udp.set_parameter('key_length', key_len)
+ result_udp.set_parameter('iv_length', icv_len)
+ result_udp.set_parameter('msg_size', nperf_msg_size)
+ result_udp.set_parameter('ipsec_mode', ipsec_mode)
+
+ baseline = perf_api.get_baseline_of_result(result_udp)
+ baseline = perfrepo_baseline_to_dict(baseline)
+
+ udp_res_data = netperf((m1, m1_if, 0, {"scope": 0}),
+ (m2, m2_if, 0, {"scope": 0}),
+ client_opts={"duration" : netperf_duration,
+ "testname" : "UDP_STREAM",
+ "confidence" : nperf_confidence,
+ "num_parallel" : nperf_num_parallel,
+ "cpu_util" : nperf_cpu_util,
+ "runs": nperf_max_runs,
+ "debug": nperf_debug,
+ "max_deviation": nperf_max_dev,
+ "msg_size" : nperf_msg_size,
+ "netperf_opts": nperf_opts},
+ baseline = baseline,
+ timeout = (netperf_duration + nperf_reserve)*nperf_max_runs)
+
+ netperf_result_template(result_udp, udp_res_data)
+ result_udp.set_comment(pr_comment)
+ perf_api.save_result(result_udp)
+
+ if ipv in [ 'ipv6', 'both']:
+ configure_ipsec(algo,
+ generate_key(key_len),
+ icv_len,
+ "ipv6")
+
+ dump = m1.run("tcpdump -i %s -nn -vv" % m1_if_name, bg=True)
+
+ # ping + PacketAssert
+ assert_mod = ctl.get_module("PacketAssert",
+ options={
+ "interface": m2_if_name,
+ "filter": "esp",
+ "grep_for": [ "ESP\(spi=0x00001001" ],
+ "min": 10
+ })
+
+ assert_proc = m2.run(assert_mod, bg=True)
+
+ ping_mod = ctl.get_module("Icmp6Ping",
+ options={
+ "addr": m2_if_addr6,
+ "count": 10,
+ "interval": 0.1})
+
+ ctl.wait(2)
+
+ m1.run(ping_mod)
+
+ ctl.wait(2)
+
+ assert_proc.intr()
+
+ dump.intr()
+
+ # prepare PerfRepo result for tcp
+ result_tcp = perf_api.new_result("tcp_ipv6_id",
+ "tcp_ipv6_result",
+ hash_ignore=[
+ r'kernel_release',
+ r'redhat_release'])
+ result_tcp.add_tag(product_name)
+
+ if nperf_num_parallel > 1:
+ result_tcp.add_tag("multithreaded")
+ result_tcp.set_parameter('num_parallel', nperf_num_parallel)
+
+ result_tcp.set_parameter('ipsec_algorithm', algo)
+ result_tcp.set_parameter('key_length', key_len)
+ result_tcp.set_parameter('iv_length', icv_len)
+ result_tcp.set_parameter('msg_size', nperf_msg_size)
+ result_tcp.set_parameter('ipsec_mode', ipsec_mode)
+
+ baseline = perf_api.get_baseline_of_result(result_tcp)
+ baseline = perfrepo_baseline_to_dict(baseline)
+
+
+ tcp_res_data = netperf((m1, m1_if, 1, {"scope": 0}),
+ (m2, m2_if, 1, {"scope": 0}),
+ client_opts={"duration" : netperf_duration,
+ "testname" : "TCP_STREAM",
+ "confidence" : nperf_confidence,
+ "num_parallel" : nperf_num_parallel,
+ "cpu_util" : nperf_cpu_util,
+ "runs": nperf_max_runs,
+ "debug": nperf_debug,
+ "max_deviation": nperf_max_dev,
+ "msg_size" : nperf_msg_size,
+ "netperf_opts" : nperf_opts + " -6"},
+ baseline = baseline,
+ timeout = (netperf_duration + nperf_reserve)*nperf_max_runs)
+
+ netperf_result_template(result_tcp, tcp_res_data)
+ result_tcp.set_comment(pr_comment)
+ perf_api.save_result(result_tcp)
+
+ # prepare PerfRepo result for udp
+ result_udp = perf_api.new_result("udp_ipv6_id",
+ "udp_ipv6_result",
+ hash_ignore=[
+ r'kernel_release',
+ r'redhat_release'])
+ result_udp.add_tag(product_name)
+
+ if nperf_num_parallel > 1:
+ result_udp.add_tag("multithreaded")
+ result_udp.set_parameter('num_parallel', nperf_num_parallel)
+
+ result_udp.set_parameter('ipsec_algorithm', algo)
+ result_udp.set_parameter('key_length', key_len)
+ result_udp.set_parameter('iv_length', icv_len)
+ result_udp.set_parameter('msg_size', nperf_msg_size)
+ result_udp.set_parameter('ipsec_mode', ipsec_mode)
+
+ baseline = perf_api.get_baseline_of_result(result_udp)
+ baseline = perfrepo_baseline_to_dict(baseline)
+
+ udp_res_data = netperf((m1, m1_if, 1, {"scope": 0}),
+ (m2, m2_if, 1, {"scope": 0}),
+ client_opts={"duration" : netperf_duration,
+ "testname" : "UDP_STREAM",
+ "confidence" : nperf_confidence,
+ "num_parallel" : nperf_num_parallel,
+ "cpu_util" : nperf_cpu_util,
+ "runs": nperf_max_runs,
+ "debug": nperf_debug,
+ "max_deviation": nperf_max_dev,
+ "msg_size" : nperf_msg_size,
+ "netperf_opts" : nperf_opts + " -6"},
+ baseline = baseline,
+ timeout = (netperf_duration + nperf_reserve)*nperf_max_runs)
+
+ netperf_result_template(result_udp, udp_res_data)
+ result_udp.set_comment(pr_comment)
+ perf_api.save_result(result_udp)
+
+m1.run("ip xfrm policy flush")
+m1.run("ip xfrm state flush")
+m2.run("ip xfrm policy flush")
+m2.run("ip xfrm state flush")
+
+if nperf_cpupin:
+ m1.run("service irqbalance start")
+ m2.run("service irqbalance start")
diff --git a/recipes/regression_tests/phase3/ipsec_esp_aead.xml b/recipes/regression_tests/phase3/ipsec_esp_aead.xml
new file mode 100644
index 0000000..db504ac
--- /dev/null
+++ b/recipes/regression_tests/phase3/ipsec_esp_aead.xml
@@ -0,0 +1,50 @@
+<lnstrecipe>
+ <define>
+ <alias name="ipv" value="both" />
+ <alias name="mtu" value="1500" />
+ <alias name="netperf_duration" value="60" />
+ <alias name="nperf_reserve" value="20" />
+ <alias name="nperf_confidence" value="99,5" />
+ <alias name="nperf_max_runs" value="5"/>
+ <alias name="nperf_num_parallel" value="1"/>
+ <alias name="nperf_debug" value="0"/>
+ <alias name="nperf_max_dev" value="20%"/>
+ <alias name="mapping_file" value="ipsec_esp_aead.mapping"/>
+ <alias name="net_1" value="192.168.99"/>
+ <alias name="net6_1" value="fc00:1::"/>
+ <alias name="net_2" value="192.168.100"/>
+ <alias name="net6_2" value="fc00:2::"/>
+ <alias name="driver" value=""/>
+ </define>
+ <network>
+ <host id="machine1">
+ <interfaces>
+ <eth id="eth" label="localnet">
+ <params>
+ <param name="driver" value="{$driver}"/>
+ </params>
+ <addresses>
+ <address value="{$net_1}.1/24"/>
+ <address value="{$net6_1}1/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="machine2">
+ <interfaces>
+ <eth id="eth" label="localnet">
+ <params>
+ <param name="driver" value="{$driver}"/>
+ </params>
+ <addresses>
+ <address value="{$net_2}.1/24"/>
+ <address value="{$net6_2}1/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="ipsec_esp_aead.py"/>
+
+</lnstrecipe>
--
2.5.5
6 years, 4 months
lnst-developers:行政管理者的十项基本功 15:46:29
by 威
行 政 管 理 实 操 训 练
【时间地点】2017年12月02-3日上海 12月23-24日北京
【参加对象】行政总监、行政经理、办公室主任、董事长秘书、总经理秘书、行政助理、行政主管等其它行政管理人员。
【授课方式】案例分享、实务分析、互动讨论、专题研讨、培训游戏等
【学习费用】4600/人(含课程讲义、午餐、茶点等)
垂询热线:021-31006787、 13381601000 许先生
微信·QQ:320588808
注:如不需此类信件信息,请转发送“删除”至tuiding02(a)163.xn--com,,-zl2hwk444acim5sskrd67og69bca386g904fg8ha.
赠送资料:
行政管理部门全套岗位说明书
行政管理部门全套制度
行政管理部门全套流程
行政管理部门必须掌握的管理知识
PPT精美(400多个胚)模板
彼得德鲁克、稻盛和夫、杰克.韦尔奇等经典管理著作
课程背景:
随着企业管理水平的不断提升,对行政管理的专业素质要求也越来越高,他们在工作中常遇到以下问题,不清楚行政管理在企业中的价值,不明晰自己的工作职责与角色定位,或者不知道如何去管理团队。诸如此类的问题,都是每个行政管理人员都要面对的,如何把握正确思路和方向、找到最适当方法,迅速提升自身职业素养、有效控制行政成本,更好的达成企业管理的目的。
培训目的:
本课程专门为行政总监、行政经理、董事会或总经办秘书、行政部门工作人员、部门经理助理、其他行政人员设计提升专业能力,成为上司在工作中的得力助手而设计的,目的是要使学员能够帮助上司提升工作效率与品质,维护商业形象,取得事业更大成功,成为老板的“管家”, 做好办公室的上传下达、做好领导的左膀右臂和参谋助手。
课程大纲:
第一讲、 行政管理概述
公司老板如何看行政:高度不够、专业度不够、精细化不够
行政人员的困惑?
----杂、烦、琐碎、做得好大家没有感觉,做得不好大家都看得见
行政管理的定位—组织的心脏
行政管理的最高境界---润物细无声
行政管理的价值---安全、文化、省钱、省时间、满意度
行政管理的方法---标准、监督、能力提升
行政管理的操作思路----嘴勤、腿勤、脑勤
行政的管理业绩最大化---人岗匹配:管人、管事、管时间、管地域
第二讲、行政管理的八项基本技能
1、标准化:
司机接待标准化
会议室管理标准化
前台标准化
保安管理标准化
什么是优质的服务标准?
卡尔西威:第一次把事情做好
简尔森:每个接触点都是白金点
打造令顾客尖叫的服务体验:找出顾客期望,做早、做好、做多超越顾客期望
行政服务创新的5个步骤---工作分析
案例分享:
办公工作环境管理工作分析与最佳实践
会议室管理工作标准制定
保洁工作标准制定等
案例讨论
督导督办工作分析与最佳实践
2、行政组织设计与用人
如何设计行政部组织机构
如何招聘与面试行政管理人员
组织设计的八大原则
分工协作:用人所长、容人所短、搭建长板效应
用同事所长、用下属所长、用领导所长、用外部资源所长、用自己所长
3、带队伍
如何代理行政部管理团队
关系户如何处理
指令式领导、授权式领导、教练式领导、团队式领导
下属能力提升:70%自学、20%在岗辅导、10%培训
4、监督
行政部点检体系化设计
行政管理监督的层次、频次和路径设计
5、激励
如何打造满意的行政管理团队
成就感建设:绩效管理中的论功行赏
成长感建设:自学、辅导与培训
归属感建设:正直、热爱、用师者为王
企业文化与行政团队文化建设:理念、看到、听到、做到
6、解决问题能力
如何设计一个成功的企业10周年庆典
行政管理方案设计能力
结构化思考,让你的老板做多选题而不是给他提问题
行政管理人员解决问题能力建设----行政管理人员理性思维突破
界定问题—-成功的出发点
分解问题—-理性思维突破
优先排序—-行动指南
分析议题—-具体问题指引
关键性分析---具体问题具体分析
归纳建议---解决方案汇总
交流沟通—贯穿始终
7、决策能力
案例分享:如何处理进退两难的行政主管
决策模型构建:明确问题、构建决策模型、收集信息/分析问题/列出解决问题的方案、选择满意的方案、反馈执行
决策的四个要素
8、办事能力
如何举办一场:成功的年会
执行力提升的六个要素:明确目标、彩排推演、思考失败、优化方案、快速行动、反馈汇报
案例讨论:如何举办一场成功的公司聚会
第三讲、行政管理者的十项基本功
1、职业化
自我不良情绪处理
传递型不良情绪处理
如何面对陌生人投诉
行政的职业化态度:任何时候,自然体贴
如何面对恶意告状的人的投诉:先下手为强
工作中的职业化态度:热爱认真专心、爱学习勤练习、耐心决心坚持
工作中的责任心:对成果负责
2、时间管理
时间管理的三个核心要素
要事第一
效率第二
堵住时间漏洞
3、会议管理---三张表单搞定会议组织管理
会务分类-组织思路----会议准备表
组织阶段:会前准备、会中协助、会后整理----会议安排表
如何担任会议主持人
如何当好会议秘书?如何组织开会---会议点检表
如何避免陷于会议忙碌之中?
三现主义:现场、现物、现实
4、沟通能力
行政管理人员沟通能力建设
沟通的模型
语言与非语言沟通
成功沟通的四个步骤
沟通的三大法则
如何布置任务、批评和表扬助理
案例实战:根据企业实际情况撰写案例
5、公文写作:角度正确、创造价值、正确表达
如何正确的撰写工作汇报和工作计划
公文写作技巧---公文写作的5个关键步骤
金字塔写作原则---公文写作的最佳写作法则
案例:高级秘书何芬的烦恼
实操演练:年中总结
PPT写作法则与技巧
PPT吸引人的关键法则---伟大的思想与广告式表达
PPT的3R原则
实战案例:8步铸就世界级ppt演讲
分享收获与行动计划
讲师介绍:【欧阳少波】
* 咨询培训经验:10年
* 专注于的业务领域
* 行政管理
* 战略管理
* 组织结构设计
* HCM全面解决方案
* 流程与制度管理
* 欧阳少波先生毕业于北京大学,拥有工商管理硕士学位
曾在微软、艾默生电气、伊顿、IBM工作,担任过接待专员、总经理、办事处主任、合伙人等职位。
他具有多年丰富的管理咨询和培训经验,为不同行业的国内外客户提供卓有成效的培训和咨询服务,所服务过的客户包括上市公司、国有独资企业、外商独资企业、民营企业及合资企业,行业涉及金融、能源、制造业、快速消费品、电信运营商等多个行业
擅长课程:
《行政统筹管理实操训练》
《企业关键人才的招募、留用及管理实战解析》
《行政统筹管理》
《流程与制度管理》
《管理者与绩效管理》
《企业文化与品牌塑造》
《解决问题的能力塑造》
《金字塔公文写作》
《商务接待》
咨询项目:
2011 敏华控股组织人力项目 新奥燃气能力素质模型 人力资源专家
2010 格力电器绩效管理项目 项目经理
2010 中国电信运营中心人力资源战略规划 项目总监
2010 内蒙古锋威硅业流程、组织、制度、薪酬、绩效项目 项目经理
2010 江西煤炭集团战略规划 项目总监
2009 乌鲁木齐电信人力资源提升项目 项目经理
2009 长沙烟草服务品牌项目 项目经理
2009 江西蓝天驾校连锁项目一、项目二 项目经理
2008 宁波日升电器流程与制度、组织结构设计、薪酬与绩效管理项目 项目经理
2008 红松风力发电有限公司战略、组织与流程、薪酬与绩效项目 项目经理
2008 山东万丰集团组织、流程与制度、薪酬与绩效、股权激励项目 项目经理
2007上海豫园商城母子公司管控、子公司层激励、组织设计 项目经理
2007 用友移动商务有限公司组织、流程、薪酬与绩效、预算管理体系 项目经理
2007 中国石油西南销售公司绩效管理项目 项目经理
2006 中国电子信息产业集团公司战略项目 项目经理
培训特色:
授课层次清晰,条理性和逻辑性强。在培训过程中,活跃流畅,充分调动学员的积极性、参与性。注重启发式教学,充分运用案例和体验式教学方法,将理论与实际有效结合,在与大家分享心得的同时,使学员思考方式发生改变。此外欧阳老师亲和力非常强,亦很受客户领导、学员的喜爱。
曾培训或咨询过的企业有:
华润啤酒、山东电力、建亨集团、中国电信乌鲁木齐分公司、中国电信增值运营中心、中国移动网络管理中心、中石油华北油田钢管公司、中国石油西南销售公司、中国电子信息产业集团、中国南方电网、上海豫园、宁波日升电器有限公司等
客户评价:
行政统筹管理是杂烦乱的,但是培训老师能够使学员不觉得枯燥,气氛很活跃,学习到了平时工作中很理论知识 ,以及实操方法。
————上海英提尔交运汽车零部件有限公司 黄伟祥
行政人事工作杂乱、烦锁,通过华为,微软等案例,学习行政管理正确方法,行政管理正确思维和行政管理正确工具。
————江苏新亚房地产开发有限公司 曹丽华
课程精彩部份挺多的,但有一点,回去要实践的就是高效中的节约奖惩制度,做任何事,一定要“早一点,好一点,多一点”从事行政工作5年多,第一次参加有关行政管理类培训,让我把平常所做的事汇总,检讨。感觉很棒!!
————东莞万好 黄玉婵
老师的举例说明让人记忆深刻,能把学的内容用到实际的工作中去,把以往觉得难以处理的事务能有新方法更好的理顺,有信心在以后带领好自己的团队,课程时间有点短,能用三天来安排也许会更加理解深刻。
————明治(青岛)橡塑制品有限公司 彭大珍
课程非常有实操性,针对一件事情从最细节的地主出发分析,对我个人而言,课程让我更多关注到的就是行政管理方面的细节(会议接待,待人接物等)在行政基础如何做到出彩!
————宁波朗生医药有限公司 施佩佩
课程每一章都会有小组讨论,倾听同学的想法并进行点评,加深了课程的印象,对行政管理有了一个系统的理解。
————铿腾(上海)有限公司 陈朔涓
案例多,老师很幽默,课程气氛很好。认识到,一个人不是做越多越好,而且把重要的事做好。
————福建安健致远国际贸易有限公司 林聪
通过此次培训,对行政工作的定位作用,具体工作方法及领导者的能力有了全面的了解,同时也认识了各行各业的行政精英,正所谓"三人行,必有我师“,这将是一笔丰富的资源。
————湛江国联水产开发股份有限公司 唐岸莲
课程老师与学员互动,老师讲课非常的风趣,鼓励学员自己总结,根据老师的培训内容及案例,联系到自己的工作,有了很多新的想法和思路。
————耐驰(兰州)泵业有限公司 徐东
6 years, 4 months
lnst-developers:如何科学规划车间物流 ryazn
by 蒙
标准工时与生产线平衡管理
【时间地点】 2017年 11月25-26日上海
【参加对象】 企业劳动定额管理人员、人力资源管理人员、生产管理人员、采购管理人员
【授课方式】 讲师讲授 + 视频演绎 + 案例研讨 +角色扮演 + 讲师点评
【学习费用】 3200/人(含学习、教材、中餐、茶点等)
联系:13381601000 许先生 QQ、微信:320588808
课程背景:
二十多年前,我们曾为日本丰田推行“准时化”生产模式实现的“零库存”,感到震惊和羡慕。二十多年来,我们一直在为实现“零库存”而学习、模仿、推行丰田模式。二十多年后的今天,我们似乎又在为没有库存而感到苦恼。因为我们总是在为等待物料、如何保证交货期而憔虑。同时也为人工成本不断上升而生产能未能最大化而苦恼。这到底是为什么呢?是没有学好还是没有用好?或者说还是根本就没有领悟到其精髓的所在?
课程收益:
1、如何科学规划车间物流;
2、如何科学理顺生产计划(生产计划的15大要点);
3、如何减少超负荷加班;
4、怎样通过计算来决定生产节拍与工位人数;
5、如何使车间管理既有拉动力又有推动力;
6、如何让工作从劳动强化走向劳动改善;
8、怎样构建现场管理的四大基石与实现“盯、挖、抢、省”
课程大纲:
第一讲 钱,在哪里!——不专业付出的代价
管理者管理效率——被勿视的西瓜
管理者管理思路——一个中心两个基本点
管理者管理方向——多主观少客观
管理者管理方法——重经验凭习惯
没有结局的结局——布局决定结局
员工的生产效率——只有强化没有改善
新产品的研发 ——没有可批量制造性
第二讲 标准工时(ST)新概念
标准工时的定义与时间的两大特点;
标准工时确立的六个原则;
使用标准工时的六个目的;
不属于标准工时范围的五个方面;
标准工时组成的两个部份;
标准工时宽裕率的三个组成部份;
标准工时的三种计算方法;
标准工时导入过程中的技巧。
第三讲:马表测量过程与技巧
马表测量工程师的七大先决条件
被测工种标准化作业必备的四种规范化文件
马表测量工作的“文房四宝”
<记录数据的表格范本>
马表测量工作的“望闻问切”
<ST系统建立的调查问卷范本>
测量过程中的五大窍门
测量数据的运算过程与有效数字
测量结果分析与作业技巧评估
<测量过程练习>
<生产运行评估指标管理练习>
第四讲:WF标准工时系统导入及检测
WF的起源与定义
WF的基本内容(十三项)介绍
高精度标准工时系统导入的四种工具
标准工时系统的导入程序
标准工时运算体系的三种表格
标准工时检测的三大指标与计算方法
标准工时检测系统的三种表格
标准工时系统的其它用途
(综合能力与综合成本评估)
ST的修正理由与频率
第五讲:形成生产瓶颈的十大原因分析
原因1、终端绝对出货能力受到制约
原因2、中间某一设备能力造成瓶颈
原因3、产品结构未能调整制约设备能力的发挥
原因4、顽固性质量问题存在导致生产效率低下
原因5、设备性能未能完全达到设计参数
原因6、设备可动率低下导致停机时间长
原因7、生产计划制定不合理导致资原浪费
原因8、生产辅助时间过长导致时间有效利用率低下
原因9、工位设计不合理导致整体平衡性差
原因10、人体工程科学运用不到位导致生产效率低下
第六讲:生产效率向上----生产平衡从环节走向系统
生产效率的定义与两重性
生产线管理的“争分夺秒与步调一致”的意义
什么是生产节拍(由什么因素决定、怎样调整)
什么是生产原理与生产方式
什么是标准化的现场管理三要素应用
标准化作业与作业标准化的三要素应用
经济动作三不原则的灵活应用
现场管理的“三不坚守原则”应用
车间物流的“三不原则应用”
分享:减速、少超负荷加班的八大要点
第七讲:从市场变化走向生产变革的案例分享
案例一:生产线可变化
案例二:员工走向多技能
案例三:多品种小批量换型系统
案例四:生产计划生成的15大要点分享
讲师介绍:[陈志华]
工商管理硕士,国内制造管理专家
历任日资世界五百强企业生产主管、品质主管,生产经理、制造总经理等,陈老师精通制造业领先的COB&SMT&AI等高技术制造管理;曾师从小川一也(日本能率协会管理中心专家, 日本WF&IE研究第一人,日本制造业研究的国宝级人物)专门研习标准工时与动作研究曾先后多次被派往日本和新加坡进修及培训(丰田JIT生产方式,对NPS有系统及深入研究和实践), 陈老师尤其擅长现场一体化管理(计划,成本,纳期,质量,技术,人员)。主讲课程有:《构筑高精度标准工时ST管理系统》、《多技能员工培养体系》、《多批少量生产方式实务》、《微利时代的精细化现场管理》、《全能班组长训练》等,主要出版物《反省中国式工厂管理》、《挑战80后管理》等。
陈老师曾为联想、松下空调、格力电器、通用电气、艾默生、华为技术、飞利蒲医疗系统、霍尼韦尔、ABB、柯尼卡美能达、奥林巴斯、富士-施乐、友达光电、东方通信、裕元制造集团、李锦记、曼秀雷敦、科勒洁具、步步高、西安杨森、亚伦国际集团、一汽丰田、东风汽车、福田汽车、江铃汽车、延锋伟世通、秦山核电、创维、雅马哈、锦湖轮胎、广东溢达、镇泰玩具等近千家客户提供过培训或咨询服务,至今有近万以上人次接受其专业课程训练。
十几年知名日本企业的制造管理实战经验,精辟的案例讲解及深刻的观点阐释,让陈老师讲堂上游刃有余。因其授课内容的实用性高,被学员们誉为所见过的最实在、最切合实际的培训师!
6 years, 4 months
lnst-developers:产品需求分析与需求管理 051289
by 龙
产品需求分析与需求管理
时间地点: 2017年11月23-24日北京 11月27-28日上海 11月30-12.1日深圳
参加对象: 企业CEO/总经理、研发总监、研发经理/项目经理/技术经理/产品经理、产品规划专家等
授课方式: 讲师讲授 + 视频演绎 + 案例研讨 +角色扮演 + 讲师点评
学习费用: 3200/1人(含两天中餐、学习、教材、茶点等)
垂询热线: 0755-6128-0006、13381601000 许先生
QQ/微信:320588808
注:如不需此类信件信息,请发送“删除'至tuiding02@163.com,打扰之处,还请谅解。。。
课·程·背·景:
通过和众多国内科技企业接触,发现这些企业中普遍存在:
1.技术很牛,但最终倒闭的公司一大推;被技术人员嗤之以鼻的公司,反而活的还不错
2.研发从早忙到晚,产品开发的不少,但市场成功的产品屈指可数,开发的越多,死得越快
3.产品开发闭门造车,关注技术,不关注客户;产品开发出来才找客户、找卖点
4.了解市场的不懂技术,懂技术的不了解市场,不知道需求应该谁负责
5.需求准确把握决定产品成败,但没有人关注需求,即使偶尔想关注也不知道如何关注
6.需求的表达不够结构化,充斥着“故事会”格式的需求,直接影响了不同团队对需求理解的一致性
7.缺少完备的需求收集、汇总、分析机制,“公司神经末梢与大脑失去联系”
8.不能从自身能力提升来引导客户需求,反而天天在抱怨客户需求经常变动
9.针对需求大家“吵成一锅粥”:公司与客户吵,市场与开发吵,开发与测试吵,……
不能满足客户需求、给客户创造价值,再牛的技术也没有价值。根据权威机构统计项目缺陷的56%来源于需求定义错误,80%的缺陷修复成本用于修复需求导致的错误,把技术变成金钱的不二选择关注、锁定、满足市场需求,创造客户价值。
本课程重点讲解:
1.如何确定目标客户,如何分析需求关系人?
2.如何从市场(客户)角度进行有效的客户需求收集?
3.围绕产品成功2个核心因素差异化+成本优势,整理产品需求
4.如何对客户需求进行整理和分析,形成产品包需求?
5.如何基于产品需求与竞争友商对比分析,确定我们的核心诉求,形成产品概念?
课程贯穿案例分享,详细讲解目标客户 客户要求 客户需求 产品包需求 产品概念确定全过程,详细讲解把技术转变为金钱的方法和工具(利润区、回溯分析、决策模型分析、KJ、$APPEALS、BSA、概念定义7个核心秘诀、破坏性创新的3石蕊实验、Sweet Point模型、基于不同产品生命周期的12个创新思路等),提升产品的竞争力,确保市场成功、财务成功。
课·程·收·益:
1.掌握从市场角度进行有效的客户需求收集的机制和方法,筛选高质量的客户需求;
2.掌握对客户需求进行整理、分类、分析的方法,提高各个角色对需求理解的一致性,最终形成产品包需求,明确产品的竞争优势与卖点;
3.掌握外部需求和内部需求一体化管理的机制,从而降低产品的端到端生命周期成本;
4.掌握产品核心诉求的提炼方法,确定有吸引力的产品概念;
5.掌握支撑研发需求工程各个阶段工作运作的工具和操作方法;
课·程·大·纲:
一、案例分享
二、六个基本概念
1.什么是客户?
1)客户、用户、目标客户、潜在客户、可以送给竞争友商的毒药客户
2.什么是需求?
1)WANTS/NEEDS/DEMANDS、真假需求、客户需求、用户需求、产品需求、设计需求、需求规格、技术需求、
非技术需求
2)案例:某运营上广告折射对需求五层次的理解
3.需求工作的2个基本点:
1)差异化
2)成本优势
4.需求工程全过程:
1)需求收集需求整理需求分析概念确定需求分解需求实现与验证
5.官方体系对需求的定义:
1)RM(目的、关键实践、典型输出)
2)RD(目的、关键实践、典型输出)
6.产品经理3个核心素质特征:
1)敏锐的市场嗅觉
2)不屈不挠的战斗精神
3)团队协作和领导能力
7.演练与问题讨论
三、市场需求分析
1.产品不同阶段的创新思路不同
1)产品创新阶段(颠覆性创新、应用性创新、产品创新、平台创新)
案例视频:鼠标的产生
案例讲解:Iphone的Siri
2)产品成熟阶段(营销创新、体验式创新、价值工程创新、集成创新、价值转移创新)
支撑案例讲解:Nike专卖店、游戏卖装备、汽车5S店、星巴克咖啡
2.产品扩展方法论
1)市场的新颖程度分析
2)公司的新颖程度分析
3.识别客户?
1)跨越鸿沟:5类客户
创新者:特征、关注点、价值
早期接收者:特征、关注点、价值
前期主流客户:特征、关注点、价值
后期主流顾客:特征、关注点、价值
落伍者:特征、关注点、价值
2)早期客户策略:保龄球法则
保龄球道
找准一号瓶
龙卷风、引爆流行
3)客户购买过程回溯分析
最终用户、销售支持、集成分销、增值代理……
4.客户分析
1)决策影响模型分析
2)核心关注点分析
3)实战演练与问题讨论
5.需求收集需要注意的问题
1)一对一访谈的技巧
2)探究原因而非简单问题
3)聚焦期望
4)询问而非推销
6.需求收集基本技能
1)需求收集调查问卷设计
2)需求访谈问题梳理
3)需求问题访谈7步法
4)需求访谈信息记录的方法
5)实战演练与问题讨论
7.需求收集的输出:客户需求收集模板(单项需求收集模板)
1)真正理解客户的意图
“抽象之梯”法:深入探索、了解、洞察客户需求
“客户的一天”:展现客户特征、困惑、渴望
案例分享:听筒10米长的电话机
2)客户描述和需求陈述
3)客户描述 需求陈述五原则
案例分享:具体产品客户描述到需求陈述案例分享(对应需求工程的用户需求+业务需求)
案例分享:某业务软件情节串联板需求收集和确认案例分享(对应需求工程的需求收集、实现诱导用户需
求)
4)收集人信息、客户信息、需求信息、优先级、关联需求
5)需求收集和分拣流程介绍
6)案例分享:某公司单项需求描述要素讲解(客户需要翻译)
7)实战演练与问题讨论
8.如何构造例行化的需求收集机制?
1)需求收集的IT支持
2)业务流程改进(出差流程等)
3)员工任职资格牵引
4)员工具体绩效承诺落实
5)案例分享:某公司市场需求管理制度讲解
四、产品需求分析
1.需求群的划分
1)需求群划分的基本原则
2)需求分类方法(KJ亲和图法)
基本类型分类法、生命周期阶段分类法
优先级分类法、来源分类法
稳定性分类法、风险级别分类法
案例分享:某软件产品千条单项需求到产品特性转换的案例分享(实现需求工程的产品特性和业务需求)
3)如何保证需求的一致性
需求冲突矩阵分析法
案例分享:具体网络产品需求冲突矩阵分析讲解(实现CMMI所要求的需求一致性)
实战演练与问题讨论
2.如何区分需求优先等级(权重确定)
1)KANO需求类型
最好满足的需求、强制性需求、兴奋需求
如何通过二维矩阵正确区分以上3类需求?(正反求证法)
2)业界最佳产品需求等级划分法(BSA法)
3)需求(群)权重设置方法(AHP)
权重确定4步法
案例分享:具体需求权重设置样例介绍
3.实现成本优势:关注内部需求
1)DFX(DFT、DFM、DFA等)
2)RAS(可靠性、可用性、可维护性)
4.案例分享:具体系统产品需求包(特性需求清单)案例分享(完成需求工程要求的特性需求、业务需求的
分析)
5.产品包需求输出(产品包需求模板(关键要素介绍))
1)优秀产品包需求的标准
五、产品概念确定
1.业界最佳客户需求的八个要素介绍($APPEALS)
1)每个要素详细定义
2)每个要素的子要素分解
3)案例分享:某应用软件产品客户需求8要素子要素展开讲解(实现NPD要求的,基于竞争分析,确定不同特
性的优先等级)
2.差异化创新,不走寻常路
1)分析客户关心什么
2)分析竞争友商满足程度
3)分析潜在机会
4)确定自己的价值缺陷
5)案例分享:某高端服务器厂商的创新之路
3.创新4象限法
1)减少:案例分析
2)剔除:案例分析
3)增加:案例分析
4)创造:案例分析
4.产品概念确定
1)产品概念的定义
2)产品概念的测试(电梯测试法)
3)针对危害产品概念的客户需求3原则
倾听
赞美
全忘记
4)产品概念确定的7个核心法则:
不走寻常路才会有出路,案例讲解
我是第一,我怕谁,案例讲解
要么最老,要么最新,案例讲解
让客户觉得你有秘方,案例讲解
跟老大对着干,案例讲解
客户总是随波逐流,案例讲解
成为专家,案例讲解
5)案例分享:两个命运迥异的互联网软件的概念分析
6)实战演练与问题讨论
六、设计需求分析
1.需求分解与分配的基本理念
1)物理分解与功能分解
2)哲理案例:从人类飞行的梦想思考需求分解与分配
2.特性需求到设计需求的转化工具:FBS、PBS
1)工具原理介绍
2)案例分享:具体某业务应用软件某特性的FBS样例(实现特性需求和设计需求的衔接)
3.设计需求(功能需求)定义的工具:UseCase、情节串联板
1)Usecase的基本要素:角色、用例、用例名、系统边界
2)有效识别角色的方法介绍
3)用例识别方法介绍
4)用例的命名原则
5)6种常见的用例描述错误分析
6)实战演练与问题讨论
4.需求分解与分配操作
1)需求分配
需求分配表(RAS)介绍
什么是需求因子?
形成设计需求、产品规格定义
实战演练与问题讨论
2)案例分享:具体系统产品客户需求->产品包需求->设计需求->需求分解的全称需求案例分享
5.需求双向跟踪机制(RTM)
1)需求编号规范介绍
2)需求跟踪的必要性
3)前向跟踪
4)后向跟踪
七、总结
讲·师·介·绍: 董奎(Don)
研发管理咨询资深顾问 INCOSE(国际系统工程师联合会www.incose.org)会员
专·业·背·景:
十多年高科技企业的研发与管理实践经验,在某著名高科技企业工作期间,先后担当项目经理、系统工程师、产品经理、软件部经理;先后作为三个产品的主任系统工程师,带领系统分析团队开展客户需求调研、产品特性定义和详细的需求分解与分配等端到端的需求管理工作,奠定了产品市场的成功;长期与国际顶尖咨询顾问一起工作,全程参与该公司研发管理变革项目。曾驻印度工作一年半,先后负责四个合作项目(合作方分别为:BFL、Infosys)的实施,全程参与印度研究所CMM四级认证过程;对业务导向的研发质量管理体系的构建有深入地研究。
研发管理咨询经验:
曾作为项目总监或经理主导了10多个研发管理咨询项目,帮助这些企业全面建立研发管理体系(流程、组织、绩效),有效地提升了这些公司的研发效率和创新能力:
1)华大电子
2)超图软件
3)上海格尔
4)网易
5)重庆奥普泰
6)佳讯飞鸿
7)广联达软件
8)京信通信
9)华胜天成
10)信利半导体
研发管理培训经验:
曾为海尔、研祥科技、宇通重工、康佳集团、北京移动、北大方正、阿里巴巴、华胜天成、南太电子、网易、富港电子、用友软件、星网锐捷、东软股份、格林威尔、金蝶软件、天马微电子、超图地理、华动飞天、新奥特、信利半导体、郎坤软件、深圳桑菲、久其软件、德信无线、新意科技、沈阳移动、光桥科技、斯特奇、合力金桥、蓝托扑、绿盟科技、建行总行开发中心、成都迈普、上海电信、佳讯飞鸿、德信无线、创维集团、威创日新、TCL、日电电子、展讯通信、易思科技、盛大网络、威科姆科技、协同集团、成都索贝、重庆奥普泰、京信通信、汇川技术、亿力吉奥、迈瑞医疗、同方威视、大唐移动、中软国际、北大方正、思源电气、南京华瑞杰、联想网域、天津通广、兴唐通信、寿力亚洲、浪潮计算机、上海华虹、浦发银行、恒
宝股份、武大吉奥、广东电信研究院、华宁电子、三安光电、广西博联、东方通信、北京拓明等100多家企业提供了专业的研发管理培训,涉及的行业包括通信、软件、互联网、家电、运营商、芯片等。
部分培训和咨询客户:
本咨询公司自成立以来,已经为近2000家企业提供了专业的研发管理培训,同时也为近80家大中型企业提供了研发管理咨询服务,帮助这些企业建立研发管理体系并实现研发模式的转型。咨询的客户主要为知名的大中型企业、细分行业的龙头企业和快速增长的高科技公司,部分客户名单如下:
通信类企业:
诺基亚-西门子、摩托罗拉、大唐移动、普天研究院、康佳移动、神州数码、海信通信、信威通信、TCL移动通信、德信无线、威盛电子、格林威尔、经纬科技、东方通信、星网锐捷、鑫诺通讯、京信通信、广东普泰、金鹏通信、TCL网络、冠日通讯、佳讯飞鸿、和记澳普泰、飞通光电、东进通讯、海天天线、PBI国际、海格通信、阿尔西、福建敏讯、无限立通、瑞斯康达、全亚通讯、虹信科技、国人讯、杰赛科技、冠日通讯、实达网络……
软件及互联网类企业:
阿里巴巴、支付宝、淘宝网、中软国际、用友、东软、金蝶、网易、新浪、搜狐、盛大网络、腾讯、格尔软件、天融信、网御神州、广联达、北大方正、方正阿帕比、华胜天成、绿盟、超图、灵图、卫士通、亚信、亿阳信通、思特奇、神州数码软件集团、广州新太、金证科技、中国工商银行软件开发中心、卓望科技、黎明网络、新粤交通投资、中太数据、华友世纪、今朝科技、联友科技、穗彩科技、龙江风采、华友世纪、高阳金信、杭州虹软、中国银联、雁联……
计算机类企业:
联想集团、清华同方、华硕电脑、方正科技、TCL电脑、朗科科技、记忆科技、华旗资讯、研祥智能、国微电子、升腾资讯、普瑞尔电子、长城电脑、穗彩科技、冠捷电子、南京富士通计算机、三诺电子、多彩科技、伟创力、顶星数码、顶星科技、大将科技、清华比威、太极计算机……
家电电子类:
海尔集团、康佳集团、夏新电子、格力电器、美的电饭煲、美的空调、荣事达、TCL王牌、创维集团、海信集团、威创集团、同洲电子、赛科世纪、信利半导体、北洋电气、步步高、万家乐电器、苏泊尔、达实智能、卓力电器、美欧电子、豪恩科技、四达时代等……
通信运营商:
中国网通、中国电信北京研究院/广州研究院、北京移动、广东移动、深圳移动、吉林移动、上海电信、武汉电信、广东联通、深圳联通、东莞联通、新乡联通、深大电话、湛江移动、惠州移动、深圳市邮政局、天威视讯……
机械及交通运输:
北京奔驰、上汽通用泛亚研发中心、上海通用、上汽通用五菱、长城汽车、中兴汽车、北汽福田汽车、一汽轿车、一汽解放、一汽夏利、长安汽车、天津内燃机研究所、黄海汽车、徐工集团、中联重工、东风汽车、神龙汽车、江铃汽车、南汽汽车、南车集团、北京吉普、成都飞机制造厂、东风标致、江淮汽车、宇通客车、元征科技、西子OTIS、西子孚信、顺德震德、鹰牌控股、青岛英派斯、浙大中控等……
集成电路(芯片):
华大电子、上海华虹、天碁科技、上海展讯、珠海炬力、凯明、上海贝岭、复旦微电子、博奥生物、北方微电子、威睿电通等……
电源及其他电子类企业:
爱默生网络能源、比亚迪、山特电子、雄韬电源、皇源电子、伊博电源、核达中远通、斯比泰、珠海金电电源、泰坦科技、华德电子、福建科华、信瑞电子、湖南瑞翔、中达电通、天津中环电子、天津光电集团、天仪集团、中电集团第7研究所、中电集团第43研究所、中电集团第29研究所、公安部第一研究所、东进电子、威科姆电子、上海精伦等……
电力及自动化类企业:
国电南自、四方继保、南瑞继保、深圳南瑞、科陆电子、上海海得、华力特设备、上海思源、泰豪科技、汇港科技、金智科技、申瑞电力、如高高压、浪拜迪等……
医疗器械类:
迈瑞医疗、安科高技术、和佳医疗、宝莱特医用科技、金科威电子、三瑞医疗、广州白云蓝天科技、理邦精密、邦健电子、万东医疗、泰杰磁电研究所等……
医药化工类:
太太药业、先声药业、康缘药业、浙江现代中药与天然药研究所、石药集团、汇仁集团、华南药业、双鹤药业、威高集团、烟台万华、乐凯集团等 ……
航空航天及军工企业:……(行业特殊要求,客户名单保密)
6 years, 4 months
lnst-developers:如何兼技术与管理于一身? otwcf
by 祖
从技术走向管理——研发经理的领导力与执行力
【时间地点】2017年11月27-28日北京 11月30-12月1日上海 11月23-24日深圳
【参加对象】企业CEO/总经理、研发总经理/副总、公司总工/技术总监、研发项目经理/产品经理、中试部经理、研发质量部经理、PMO(项目管理办公室)主任、走上管理岗位的技术人员等
【学习费用】3200元/人(含课程讲义、税费、茶点等)
【咨询电话】021-31006787,0755-61280006 13381601000 许先生
注:不需此类信件信息,请发送“删除'至tuiding02(a)163.xn--com,,-zl2hwkp7ss5dfr6bmid67onr5fr4vba7213b
课程背景:
根据我司多年从事研发管理咨询的经验发现中国企业95%以上的研发中基层主管都是从技术能力比较强的工程师中提拔起来的,很多刚刚走上管理岗位的研发人员在从技术走向管理的过程中存在如下问题:
1.角色不能转换,过度关注技术细节;
2.认真帮助下属可是他们并不买账;
3.凡事亲力亲为,忙得焦头烂额,可是上司却嫌效率太低;
4.希望下属多提意见,可是他们却什么都不说,不愿意承担责任;
5.上司让制定工作计划,可却无从下手;
6.不知道如何分派工作,如何领导团队,更不知道如何确保你的团队不出差错;
7.……
这些问题致使走上管理工作岗位的技术人员疲惫不堪却还不能有效达到整体目标。
从一名只对技术负责的技术人员转变为对全流程负责的项目经理和对某一专业领域负责的部门经理,在这个转变的过程中,技术人员要实现哪些蜕变、要掌握哪些管理技能、如何培养自己的领导力等是本课程重点探讨的内容。
培训收益:
1.分享讲师500多场研发管理培训的专业经验,通过现场的互动帮助学员理清走向管理的困惑
2.总结和分析技术人员从技术走向管理过程中常见的问题
3.掌握实现从技术走向管理的过程中要实现的几个转变
4.了解从技术走向管理的五个好习惯(成果导向、综观全局、聚焦重点、发挥优势、集思广益)
5.掌握与领导沟通的方法技巧
6.掌握走上管理工作岗位后需要掌握的四个核心管理技能(目标与计划、组织与分派工作、控制与纠偏、领导与激励)
7.了解成功实现从技术走向管理转变的几个关键要素
8.分享讲师20多个咨询项目的研发管理的案例资料(模板、表格、样例……),帮助学员制定Action Plan,使得学员参训后回到自己的公司能够很好实践
课程介绍:
一、案例分析
1.讨论:技术走向管理的烦恼
二、从技术走向管理的角色定位和角色转换
1.为什么要从技术走向管理(背景、原因)
2.管理人员的角色定位和素质模型
3.有哪些技术管理职位
4.技术型管理者的角色与核心工作(技术管理者的不是说不要技术,而是层次越高的技术管理者,越需要技术广度、技术敏锐度与市场敏锐度,而且更需要沟通、管理与领导技能)
5.技术人员与管理人员的特质
6.研发人员的特点
7.研发人员与销售人员、工人的不同
8.角色转换过程中常见的问题分析
1)自己解决问题到推动他人解决问题
2)刚性和弹性的掌握
3)从管事到管人与事的转变;
4)从发现问题到推动解决问题的转变;
5)从好人到坏人的转变;
9.角色转换的成长之路(角色、态度、知识、技能)
10.演练与问题讨论
三、从技术走向管理必备的好习惯
1.习惯的价值与培养
2.习惯与原则
3.习惯之一:成果导向
1)过程和结果的关系
2)不同研发职位应完成的结果
3)追求过程的快乐还是成果的快乐
4)成果导向对研发管理者的要求
5)研讨:研发管理者在具体工作中怎么做才算是成果导向?
6)点评:研发整体资源管理方法论(保证研发资源整体投入产出比)
4.习惯之二:综观全局
1)对研发各级管理者来说全局在哪里?
2)综观全局的要求(理解自己在研发价值链中的位置和贡献)
3)建立研发技术团队的创造性与规范性相结合的文化
4)研发工作的特殊性决定了创造性和规范性的冲突
5)解决这个冲突的思路
6)团队游戏规则的建立
7)案例研讨:管理者在何种情况下可以破例?
8)案例研讨:研发团队提倡什么,反对什么?
9)案例研讨:游戏规则建立中的赏罚基本原则是什么?
10)研发型团队创造性文化的建立(鼓励创新,鼓励犯错误,鼓励创造性)
11)研发型团队规范性文化的建立(规范性、纪律性、过程标准性、可制造性、可服务性、bm性等)
5.习惯之三:聚焦重点
1)研发管理人员忙碌却无成效的原因剖析
2)研发管理人员的工作分类(四个象限)和时间管理
3)问题解答:谁都知道应当按四个象限安排工作顺序可为什么我们总安排不好?
4)讨论:对研发管理者来说到底什么是重要的工作?领导交代的工作到底属于哪个象限?
5)案例:张经理的工作如何聚焦重点
6.习惯之四:发挥优势
1)不同的研发人员有什么优势
2)是发挥优势还是克服弱点
3)发挥优势要求我们做到什么
4)采用什么方法才能发挥不同研发人员的优势
7.习惯之五:集思广益
1)怎样才能使研发团队绩效最大化
2)研发团队合作的5种方式
3)因为差异(四个层次)所以要集思广益
4)差异会导致冲突吗?差异与冲突的关系
5)研发冲突的原因
6)为什么研发人员与测试人员、QA会有冲突
7)冲突的破坏性和建设性
8)冲突的状况与组织绩效
9)看录象中的冲突进行讨论(项目经理、QA、下属的关系)
10)集思广益经常使用的方法论(脑力激荡法、德尔菲)
四、研发管理者如何与领导沟通
1.研发管理者自己沟通能力不强而领导又不懂技术怎么办?
2.为什么研发工作自己觉得开展的很好却得不到老板或领导的认可?
3.与领导沟通的重要性
4.无数“革命先烈”的教训分享
5.领导的沟通类型
6.领导的沟通类型对沟通的影响
7.与领导沟通的难题(尤其是没有技术背景的领导)
8.与领导沟通的要点
9.高层领导喜欢的沟通方式
10.与领导沟通的方式、方法与技巧
11.与领导沟通谨慎换位思考
12.向领导汇报方式和工具
13.汇报会上领导常问的问题分类
14.为什么领导在会上总是不断追着问?
15.高层管理者对研发的沟通信息需求(开发状况、资源状况、管理优化状况)详细介绍和模板演示
16.分辨领导的真正需求
17.要想成功从技术走向管理首先做个成功的下属
18.如何做个成功的下属
19.研讨:学习本单元的体会列出以后改进的三个要点
五、从技术走向管理的四个核心管理技能之一:目标与计划
1.目标对我们的影响
2.个人目标和团队目标的关系
3.如何根据公司的战略要求制定研发部门和研发项目的目标
4.研发部门和项目的目标如何分解到个人
5.如何帮助下属制定工作目标
6.目标的制定与下达(SMART化、愿景化、共享化、承诺化(PBC))
7.研发项目的目标为什么不容易SMART
8.为什么培训了很多次SMART研发项目目标还是做不到SMART
9.开发管理中为什么要用模板,模板使用的3个艺术、为什么模板推行中总有困难
10.研发工作计划的PDCA循环
11.研发流程与计划的关系
12.研发项目计划制定的流程
13.PERT、关键路径和GANNT
14.为什么研发项目计划不用PERT图
15.产品开发计划如何分成四级(这四级计划的责任主体和制定时间点)
16.演练:每个小组制定一个半年计划,发表!
六、从技术走向管理的四个核心管理技能之二:组织与分派工作
1.活动演练 30 分钟:扑克游戏——上中下三层互动(体验:管理对人与对事,三层角色定位,目标下达,控制与跟踪,愿景与目标共享,结果反馈等)
2.研发执行力缺失的原因分析
3.常见研发组织形式及优缺点
4.如何对研发工作进行分解
5.给研发人员分派工作的原则
6.给研发人员分派工作的步骤
7.给研发人员分派工作中容易出现的问题
8.研发沟通管理的内容
9.沟通的目的与功能
10.沟通的种类与方式
11.有效沟通的障碍/约哈里窗
12.面对面沟通避免的小动作
13.如何给其它部门分派研发工作
14.研发管理人员在分派工作中容易存在的问题、原因和克服
15.给研发技术人员创造愿景、描绘愿景,尤其是关于项目与团队前途
16.案例研讨:研发技术型团队的成员常被迫承担紧急的项目周期,该如何处理?
17.案例研讨:给予研发技术人员的空间到底多大,犯什么样的错误可以接受?
18.案例研讨:任务下达后完成得不好但因为是碰到困难又怎么处理?
19.案例研讨:一个人承担多个项目遇到资源冲突怎么办
20.案例研讨:两个领导意见不一致,怎么办?
七、 从技术走向管理的四个核心管理技能之三:控制与纠偏
1.研发工作为什么难以控制
2.研发工作的问题管理与风险管理
3.研发工作追踪的步骤
4.研发工作控制方法之一:会议(具体操作与模板)
5.研发工作控制方法之二:报告机制(具体操作与模板)
6.研发工作控制方法之三:审计(具体操作与模板)
7.研发工作控制方法之四:合同书与任务书(具体操作与模板)
8.研发工作控制方法之五:预警系统(具体操作与模板)
9.研发工作控制方法之六:经验教训总结(具体操作与模板)
10.研发工作控制方法之七:测评(具体操作与模板)
11.研发工作控制方法之八:非正规控制(具体操作与模板)
12.研发工作如何度量、量化管理(有哪些量化指标、PCB)
13.关于控制的误区(用人不疑、甩手掌柜、与创新的矛盾)
14.关于研发执行力
八、从技术走向管理的四个核心管理技能之四:领导与激励
1.研发领导权威力的来源
2.研发领导如何发展个人魅力
3.如何针对不同环境和不同的研发人员进行情景领导
4.讨论:如何增进研发团队的凝聚力和士气
5.研发领导如何授权
6.研发领导如何辅导下属和培养接班人
7.研发部门中的“因人而异”的管理方法
1)白金法则
2)如何管理你团队性格特征不同的下属
3)案例分析:如何考察与识别有管理潜力的技术型部属?
4)尊重研发技术人员个性的沟通模式与方法
5)案例研讨:如何管理技术型团队中的悍将、润滑油、老黄牛型的部属?
8.研发人员的考核与激励(专题讲解)
1)建立功能型团队与项目型团队面向结果的绩效考核办法
2)定性与定量考核法;
3)有效理解结果、过程、投入的考核之间的关系;
4)关键绩效指标考核法(KPI法):模板、业界案例、练习
5)平衡计分卡考核法(BSC法):模板、业界案例
6)个人业务承诺法(PBC法):模板、业界案例、练习
7)考核流程与360度考核法:业界案例比较分析
8)末位淘汰法
9)各层次技术人员考核要求及关键内容
9.研发技术型人才的培育与任职资格管理
1)研发技术型人才的素质模型与特点
2)培育部属(辅导的7步结构、研发技术人员积极意愿度的培育、能力度的培育、如何培养研发技术型新手、如何培养研发技术型骨干与高端人才)
3)任职资格管理(双阶梯职业通道模型、任职资格的目的与作用、任职资格的体系与标准、认证与成长、职涯发展)
4)基于任职资格的研发技术型人员的培训实习体系
5)专业技术人才和专业技术管理人才(系统工程师、QA、项目经理等)的正式培养机制——资源池
10.研发技术型人才的非物质激励与物质激励方法
1)研发技术型人才的需要
2)案例研讨:研发技术型人才受什么因素激励?
3)案例研讨:技术型团队的士气受哪些因素影响?
4)案例研讨:技术型团队的凝聚力受哪些因素影响?
5)管理者的红黑脸方法(勋章、鲜花、鼓励、期望、赞美;警告、批评、敲打、揉搓、杀鸡骇猴、痛骂等)
6)案例研讨:如何对技术型部属使用红脸?
7)案例研讨:如何对技术型部属使用黑脸?
8)案例研讨:能干的技术型部属犯了错误如何处理?
9)案例研讨:如何在能力比你强的技术型部属中树立你的威信?
10)研发技术型人员的物质型激励:薪酬包组合、组合结构、薪酬分配、薪酬梯级、工资奖金比例、
11)资力能力及报酬的关系、业界案例
12)技术人员离职的征兆管理以及如何留住有价值的知识型员工
11.演练与讨论
九、成功实现从技术走向管理转变的关键
1.成功的实现角色换位
2.管理技能的培养
3.个人修炼(习惯、领导力、沟通能力)
4.组织的融合和团队的打造
5.给刚走上管理岗位的技术人员推荐的书籍和电影
讲师介绍:
Giles:研发咨询资深顾问 PDMA(美国产品开发管理协会www.pdma.org)会员
《PDMA新产品开发手册》中文版主译 清华大学研发管理特聘教授
专业背景:
十多年高科技企业研发管理实践,典型的在企业实践中从技术走向管理的管理专家。在某著名通信公司工作期间,作为硬件工程师、软件工程师和系统工程师(系统总体设计总工)参与过多个小型、大型项目开发,有五年具体产品开发经验,承担过多个项目的管理工作,担任过研发项目管理部经理、研发管理办经理、技术管理部副总经理、研发IT中心主任,经历并参与主持了此公司研发管理(包括研发流程管理、研发项目管理、研发人力资源管理、研发IT管理等模块)混乱到规范化建设的全过程。1998年开始长期与国际顶尖咨询顾问一起工作,并作为第一批核心小组成员与国际著名的咨询公司合作主导了研发管理变革项目及其母项目公司级IT规划项目,同时兼任该公司高级讲师,负责企业文化建设在研发的推进和落地工作。
研发管理咨询经验:
曾作为项目总监、项目经理主导了10多个研发管理咨询项目,帮助这些企业全面建立研发管理体系(包括流程、组织、绩效、IT),有效地提升了这些公司的研发管理和创新能力,典型客户如下:
1)最大专业打印机供应商北洋电气
2)信利国际有限公司
3)国内系统集成行业第二名(华胜天成)
4)中电集团第七研究所
5)TCL家庭网络事业部
6)苏州科达
7)国内最大的网络安全厂商天融信……
研发管理培训经验:
曾为AO史密斯、海尔、TCL、TTE、美的、夏新、康佳、海信、创维、北大方正、格力电器、步步高、长虹、彩虹集团、苏泊尔、上海日立、成都索贝、云环电子、蓝微电子、威创科技、卓立电气、老板电器、南太集团、海洋王、航盛电子、华强信息、华阳多媒体、广东威特、信华精机、研祥智能、聚光科技、信利国际有限公司、北洋电气、CNNIC(中国互联网信息中心)、网易、华友世纪、阿里巴巴、淘宝网、新浪网、讯雷、优视动景、御风行科技、吉比特、朗科、冠捷电子、江苏富士通、福建富士通、格林威尔、信威通讯、中国电信北京研究院、中国普天公司、福建敏讯、无限立通、瑞斯康达、和协航电、全亚通讯、广州京信、虹信科技、国人通讯、杰赛科技、冠日通讯、星网锐捷、实达网络、鑫诺电子、神州数码、同洲电子、九洲信息科技、赛科世纪、四达时代、穗彩科技、龙江风采、东进电子、威科姆电子、金蝶软件、东软软件、高阳金信、杭州虹软、中国工商银行软件开发中心、中国银联、雁联、广联达软件、方正春元、灵图、科银京成、广州安凯、广州从兴、广州宏达信、拓尔思、青岛英派斯、浙大中控、上海精伦、中创信测、汇川技术、雄韬电源、核达中远通、斯比泰、山特电子、深圳南瑞、国电南自、上海思源、上海宝信、荣信电力电子、亿力吉奥、电力科学研究院、特变电工、上海海得、迈瑞医疗、和佳医疗、中集集团、众友科技、好易通科技、乐凯集团、金东纸业、徐工集团、三一集团、山河智能、安徽叉车、同洲电子、天融信、绿盟科技、北方微电子、深圳国微、珠海炬力、上海展讯、威盛电子、天綦、天马微电子、武汉电信器件公司、中电华大、杭州汉帆、中电集团第7研究所、中电集团第43研究所、中电集团第29研究所、公安部第一研究所、同方威视、北京矿冶研究总院、中国石化研究院、电子科学研究院、郑州三磨所、研祥智能、北京圣非凡、潍柴动力、长城华冠、北京现代、东风汽车、一汽集团、中国重汽、北汽福田、通用泛亚、江铃陆风、奇瑞汽车、上汽通用五菱、长安汽车、、苏州金龙新粤交通、威海广泰、大豪科技、西子OTIS、蒂森电梯、西子孚信、深圳和宏、顺德震德、鹰牌控股、烟台万化、先声药业、中国航空、中国航天、等500多家企业和研究机构提供了专业的研发管理培训。其中部分公司邀请讲课多次。
6 years, 4 months
[PATCH 1/5] InterfaceManager: add coalesce setting methods
by Jan Tluka
This patch adds new dependency on python-ethtool package.
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
---
lnst/Slave/InterfaceManager.py | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/lnst/Slave/InterfaceManager.py b/lnst/Slave/InterfaceManager.py
index e28682f..48c2ee2 100644
--- a/lnst/Slave/InterfaceManager.py
+++ b/lnst/Slave/InterfaceManager.py
@@ -15,6 +15,7 @@ olichtne(a)redhat.com (Ondrej Lichtner)
import re
import select
import logging
+import ethtool
from lnst.Slave.NetConfigDevice import NetConfigDevice
from lnst.Slave.NetConfigCommon import get_option
from lnst.Common.NetUtils import normalize_hwaddr
@@ -839,3 +840,16 @@ class Device(object):
cmd = "ip link set dev %s type bridge_slave mcast_router %d" % \
(self._name, state)
exec_cmd(cmd)
+
+ def get_coalesce(self):
+ try:
+ return ethtool.get_coalesce(self._name)
+ except IOError as e:
+ logging.error("Failed to get coalesce settings: %s", e)
+ return {}
+
+ def set_coalesce(self, cdata):
+ try:
+ ethtool.set_coalesce(self._name, cdata)
+ except IOError as e:
+ logging.error("Failed to set coalesce settings: %s", e)
--
2.9.5
6 years, 4 months
[PATCH lnst 0/2] switchdev: Add multipash hash recipes
by Yuval Mintz
From Ido:
Add two recipes to make sure the multipath hash is performed according
to the correct parameters.
Ido Schimmel (2):
switchdev: recipes: Add IPv4 multipath hash recipe
switchdev: recipes: Add IPv6 multipath hash recipe
recipes/switchdev/l3-012-ipv4-multipath-hash.py | 168 +++++++++++++++++++++++
recipes/switchdev/l3-012-ipv4-multipath-hash.xml | 58 ++++++++
recipes/switchdev/l3-013-ipv6-multipath-hash.py | 157 +++++++++++++++++++++
recipes/switchdev/l3-013-ipv6-multipath-hash.xml | 58 ++++++++
4 files changed, 441 insertions(+)
create mode 100644 recipes/switchdev/l3-012-ipv4-multipath-hash.py
create mode 100644 recipes/switchdev/l3-012-ipv4-multipath-hash.xml
create mode 100644 recipes/switchdev/l3-013-ipv6-multipath-hash.py
create mode 100644 recipes/switchdev/l3-013-ipv6-multipath-hash.xml
--
2.4.3
6 years, 4 months
[PATCH] recipes: limit SCTP to test interface only by adding
iptables rule
by Jan Tluka
SCTP can change interface while sending data. This can break stability
of performance testing. This patch adds iptables rule that limits SCTP
traffic to test interface only. I checked this in RH lab.
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
---
recipes/regression_tests/phase1/3_vlans.py | 14 ++++++++++++++
recipes/regression_tests/phase1/3_vlans_over_bond.py | 14 ++++++++++++++
recipes/regression_tests/phase1/bonding_test.py | 14 ++++++++++++++
recipes/regression_tests/phase1/simple_netperf.py | 14 ++++++++++++++
recipes/regression_tests/phase2/3_vlans_over_team.py | 14 ++++++++++++++
recipes/regression_tests/phase2/team_test.py | 14 ++++++++++++++
6 files changed, 84 insertions(+)
diff --git a/recipes/regression_tests/phase1/3_vlans.py b/recipes/regression_tests/phase1/3_vlans.py
index cfcacee..4c1e99e 100644
--- a/recipes/regression_tests/phase1/3_vlans.py
+++ b/recipes/regression_tests/phase1/3_vlans.py
@@ -224,6 +224,14 @@ if nperf_msg_size is not None:
netperf_cli_udp6.update_options({"msg_size" : nperf_msg_size})
netperf_cli_sctp6.update_options({"msg_size" : nperf_msg_size})
+# if we will run SCTP test make sure the SCTP will go out through the test
+# interfaces only
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ m1_vlan1.get_devname())
+ m2.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ m2_vlan1.get_devname())
+
for setting in offload_settings:
#apply offload setting
dev_features = ""
@@ -464,3 +472,9 @@ m2.run("ethtool -K %s %s" % (m2_phy1.get_devname(), dev_features))
if nperf_cpupin:
m1.run("service irqbalance start")
m2.run("service irqbalance start")
+
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ m1_vlan1.get_devname())
+ m2.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ m2_vlan1.get_devname())
diff --git a/recipes/regression_tests/phase1/3_vlans_over_bond.py b/recipes/regression_tests/phase1/3_vlans_over_bond.py
index 065f2ee..d30da40 100644
--- a/recipes/regression_tests/phase1/3_vlans_over_bond.py
+++ b/recipes/regression_tests/phase1/3_vlans_over_bond.py
@@ -226,6 +226,14 @@ if nperf_msg_size is not None:
netperf_cli_udp6.update_options({"msg_size" : nperf_msg_size})
netperf_cli_sctp6.update_options({"msg_size" : nperf_msg_size})
+# if we will run SCTP test make sure the SCTP will go out through the test
+# interfaces only
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ m1_vlan1.get_devname())
+ m2.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ m2_vlan1.get_devname())
+
for setting in offload_settings:
#apply offload setting
dev_features = ""
@@ -465,3 +473,9 @@ m2.run("ethtool -K %s %s" % (m2_phy1.get_devname(), dev_features))
if nperf_cpupin:
m1.run("service irqbalance start")
m2.run("service irqbalance start")
+
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ m1_vlan1.get_devname())
+ m2.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ m2_vlan1.get_devname())
diff --git a/recipes/regression_tests/phase1/bonding_test.py b/recipes/regression_tests/phase1/bonding_test.py
index 5bcbec0..c2c7ae3 100644
--- a/recipes/regression_tests/phase1/bonding_test.py
+++ b/recipes/regression_tests/phase1/bonding_test.py
@@ -244,6 +244,14 @@ if nperf_msg_size is not None:
netperf_cli_udp6.update_options({"msg_size" : nperf_msg_size})
netperf_cli_sctp6.update_options({"msg_size" : nperf_msg_size})
+# if we will run SCTP test make sure the SCTP will go out through the test
+# interfaces only
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ test_if1.get_devname())
+ m2.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ test_if2.get_devname())
+
ctl.wait(15)
for setting in offload_settings:
@@ -443,3 +451,9 @@ m2.run("ethtool -K %s %s" % (test_if2.get_devname(), dev_features))
if nperf_cpupin:
m1.run("service irqbalance start")
m2.run("service irqbalance start")
+
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ test_if1.get_devname())
+ m2.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ test_if2.get_devname())
diff --git a/recipes/regression_tests/phase1/simple_netperf.py b/recipes/regression_tests/phase1/simple_netperf.py
index 8ef4357..88e2314 100644
--- a/recipes/regression_tests/phase1/simple_netperf.py
+++ b/recipes/regression_tests/phase1/simple_netperf.py
@@ -204,6 +204,14 @@ if nperf_msg_size is not None:
netperf_cli_udp6.update_options({"msg_size" : nperf_msg_size})
netperf_cli_sctp6.update_options({"msg_size" : nperf_msg_size})
+# if we will run SCTP test make sure the SCTP will go out through the test
+# interfaces only
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ m1_testiface.get_devname())
+ m2.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ m2_testiface.get_devname())
+
ctl.wait(15)
for setting in offload_settings:
@@ -402,3 +410,9 @@ m2.run("ethtool -K %s %s" % (m2_testiface.get_devname(), dev_features))
if nperf_cpupin:
m1.run("service irqbalance start")
m2.run("service irqbalance start")
+
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ m1_testiface.get_devname())
+ m2.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ m2_testiface.get_devname())
diff --git a/recipes/regression_tests/phase2/3_vlans_over_team.py b/recipes/regression_tests/phase2/3_vlans_over_team.py
index 487be60..8f6747e 100644
--- a/recipes/regression_tests/phase2/3_vlans_over_team.py
+++ b/recipes/regression_tests/phase2/3_vlans_over_team.py
@@ -226,6 +226,14 @@ if nperf_msg_size is not None:
netperf_cli_udp6.update_options({"msg_size" : nperf_msg_size})
netperf_cli_sctp6.update_options({"msg_size" : nperf_msg_size})
+# if we will run SCTP test make sure the SCTP will go out through the test
+# interfaces only
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ m1_vlan1.get_devname())
+ m2.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ m2_vlan1.get_devname())
+
for setting in offload_settings:
#apply offload setting
dev_features = ""
@@ -465,3 +473,9 @@ m2.run("ethtool -K %s %s" % (m2_phy1.get_devname(), dev_features))
if nperf_cpupin:
m1.run("service irqbalance start")
m2.run("service irqbalance start")
+
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ m1_vlan1.get_devname())
+ m2.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ m2_vlan1.get_devname())
diff --git a/recipes/regression_tests/phase2/team_test.py b/recipes/regression_tests/phase2/team_test.py
index 8363890..22ca042 100644
--- a/recipes/regression_tests/phase2/team_test.py
+++ b/recipes/regression_tests/phase2/team_test.py
@@ -243,6 +243,14 @@ if nperf_msg_size is not None:
netperf_cli_udp6.update_options({"msg_size" : nperf_msg_size})
netperf_cli_sctp6.update_options({"msg_size" : nperf_msg_size})
+# if we will run SCTP test make sure the SCTP will go out through the test
+# interface only
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ test_if1.get_devname())
+ m2.run("iptables -I OUTPUT ! -o %s -p sctp -j DROP" %
+ test_if2.get_devname())
+
ctl.wait(15)
for setting in offload_settings:
@@ -698,3 +706,9 @@ m2.run("ethtool -K %s %s" % (test_if2.get_devname(), dev_features))
if nperf_cpupin:
m1.run("service irqbalance start")
m2.run("service irqbalance start")
+
+if nperf_protocols.find("sctp") > -1:
+ m1.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ test_if1.get_devname())
+ m2.run("iptables -D OUTPUT ! -o %s -p sctp -j DROP" %
+ test_if2.get_devname())
--
2.9.5
6 years, 4 months
[PATCH] recipes: use different variable while pinging between vlans
by Jan Tluka
Same variable name is used for initial assignment of test interface and for
assignment of vlan interface in ping loop. This could have undesired effects
when someone wants to use the variable from initial assignment. To fix this
I renamed the variables in the loop.
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
---
recipes/regression_tests/phase1/3_vlans.py | 12 ++++++------
recipes/regression_tests/phase1/3_vlans_over_bond.py | 12 ++++++------
recipes/regression_tests/phase2/3_vlans_over_team.py | 12 ++++++------
3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/recipes/regression_tests/phase1/3_vlans.py b/recipes/regression_tests/phase1/3_vlans.py
index a8e7c23..cfcacee 100644
--- a/recipes/regression_tests/phase1/3_vlans.py
+++ b/recipes/regression_tests/phase1/3_vlans.py
@@ -241,15 +241,15 @@ for setting in offload_settings:
# Ping test
for vlan1 in vlans:
- m1_vlan1 = m1.get_interface(vlan1)
+ m1_vlan1_if = m1.get_interface(vlan1)
for vlan2 in vlans:
- m2_vlan2 = m2.get_interface(vlan2)
+ m2_vlan2_if = m2.get_interface(vlan2)
- ping_mod.update_options({"addr": m2_vlan2.get_ip(0),
- "iface": m1_vlan1.get_devname()})
+ ping_mod.update_options({"addr": m2_vlan2_if.get_ip(0),
+ "iface": m1_vlan1_if.get_devname()})
- ping_mod6.update_options({"addr": m2_vlan2.get_ip(1),
- "iface": m1_vlan1.get_ip(1)})
+ ping_mod6.update_options({"addr": m2_vlan2_if.get_ip(1),
+ "iface": m1_vlan1_if.get_ip(1)})
if vlan1 == vlan2:
# These tests should pass
diff --git a/recipes/regression_tests/phase1/3_vlans_over_bond.py b/recipes/regression_tests/phase1/3_vlans_over_bond.py
index 81c4c5c..065f2ee 100644
--- a/recipes/regression_tests/phase1/3_vlans_over_bond.py
+++ b/recipes/regression_tests/phase1/3_vlans_over_bond.py
@@ -241,15 +241,15 @@ for setting in offload_settings:
# Ping test
for vlan1 in vlans:
- m1_vlan1 = m1.get_interface(vlan1)
+ m1_vlan1_if = m1.get_interface(vlan1)
for vlan2 in vlans:
- m2_vlan2 = m2.get_interface(vlan2)
+ m2_vlan2_if = m2.get_interface(vlan2)
- ping_mod.update_options({"addr": m2_vlan2.get_ip(0),
- "iface": m1_vlan1.get_devname()})
+ ping_mod.update_options({"addr": m2_vlan2_if.get_ip(0),
+ "iface": m1_vlan1_if.get_devname()})
- ping_mod6.update_options({"addr": m2_vlan2.get_ip(1),
- "iface": m1_vlan1.get_ip(1)})
+ ping_mod6.update_options({"addr": m2_vlan2_if.get_ip(1),
+ "iface": m1_vlan1_if.get_ip(1)})
if vlan1 == vlan2:
# These tests should pass
diff --git a/recipes/regression_tests/phase2/3_vlans_over_team.py b/recipes/regression_tests/phase2/3_vlans_over_team.py
index ed92bca..487be60 100644
--- a/recipes/regression_tests/phase2/3_vlans_over_team.py
+++ b/recipes/regression_tests/phase2/3_vlans_over_team.py
@@ -241,15 +241,15 @@ for setting in offload_settings:
# Ping test
for vlan1 in vlans:
- m1_vlan1 = m1.get_interface(vlan1)
+ m1_vlan1_if = m1.get_interface(vlan1)
for vlan2 in vlans:
- m2_vlan2 = m2.get_interface(vlan2)
+ m2_vlan2_if = m2.get_interface(vlan2)
- ping_mod.update_options({"addr": m2_vlan2.get_ip(0),
- "iface": m1_vlan1.get_devname()})
+ ping_mod.update_options({"addr": m2_vlan2_if.get_ip(0),
+ "iface": m1_vlan1_if.get_devname()})
- ping_mod6.update_options({"addr": m2_vlan2.get_ip(1),
- "iface": m1_vlan1.get_ip(1)})
+ ping_mod6.update_options({"addr": m2_vlan2_if.get_ip(1),
+ "iface": m1_vlan1_if.get_ip(1)})
if vlan1 == vlan2:
# These tests should pass
--
2.9.5
6 years, 4 months