2 # Copyright (c) 2016-2017 Intel Corporation
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 """NSBPERF main script.
20 from __future__ import absolute_import
21 from __future__ import print_function
27 from oslo_serialization import jsonutils
29 from six.moves import input
31 CLI_PATH = os.path.dirname(os.path.realpath(__file__))
32 REPO_PATH = os.path.abspath(os.path.join(CLI_PATH, os.pardir))
35 def sigint_handler(*args, **kwargs):
36 """ Capture ctrl+c and exit cli """
37 subprocess.call(["pkill", "-9", "yardstick"])
41 class YardstickNSCli(object):
42 """ This class handles yardstick network serivce testing """
45 super(YardstickNSCli, self).__init__()
48 def validate_input(cls, choice, choice_len):
49 """ Validate user inputs """
54 if not 1 <= choice <= choice_len:
55 print("\nInvalid wrong choice...")
56 input("Press Enter to continue...")
58 subprocess.call(['clear'])
62 def parse_arguments(cls):
64 Parse command line arguments.
67 argparse.ArgumentParser(
69 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
70 parser.add_argument('--version', action='version',
71 version='%(prog)s 0.1')
72 parser.add_argument('--list', '--list-tests', action='store_true',
73 help='list all tests and exit')
74 parser.add_argument('--list-vnfs', action='store_true',
75 help='list all system vnfs and exit')
77 group = parser.add_argument_group('test selection options')
78 group.add_argument('--vnf', help='vnf to use')
79 group.add_argument('--test', help='test in use')
81 args = vars(parser.parse_args())
86 def generate_kpi_results(cls, tkey, tgen):
87 """ Generate report for vnf & traffic generator kpis """
89 print("\n%s stats" % tkey)
90 print("----------------------------")
91 for key, value in tgen.items():
92 if key != "collect_stats":
93 print(json.dumps({key: value}, indent=2))
96 def generate_nfvi_results(cls, nfvi):
97 """ Generate report for vnf & traffic generator kpis """
99 nfvi_kpi = {k: v for k, v in nfvi.items() if k == 'collect_stats'}
101 print("\nNFVi stats")
102 print("----------------------------")
103 for key, value in nfvi_kpi.items():
104 print(json.dumps({key: value}, indent=2))
106 def generate_final_report(self, test_case):
107 """ Function will check if partial test results are available
108 and generates final report in rst format.
111 tc_name = os.path.splitext(test_case)[0]
112 report_caption = '{}\n{} ({})\n{}\n\n'.format(
113 '================================================================',
114 'Performance report for', tc_name.upper(),
115 '================================================================')
116 print(report_caption)
117 if os.path.isfile("/tmp/yardstick.out"):
119 with open("/tmp/yardstick.out") as infile:
120 lines = jsonutils.load(infile)
124 lines['result']["testcases"][tc_name]["tc_data"]
125 tc_res = lines.pop(len(lines) - 1)
126 for key, value in tc_res["data"].items():
127 self.generate_kpi_results(key, value)
128 self.generate_nfvi_results(value)
131 def handle_list_options(cls, args, test_path):
132 """ Process --list cli arguments if needed
134 :param args: A dictionary with all CLI arguments
136 if args['list_vnfs']:
137 vnfs = os.listdir(test_path)
139 print("================")
140 for index, vnf in enumerate(vnfs, 1):
141 print((' %-2s %s' % ('%s:' % str(index), vnf)))
145 vnfs = os.listdir(test_path)
147 print("Available Tests:")
148 print("*****************")
150 testcases = os.listdir(test_path + vnf)
151 print(("VNF :(%s)" % vnf))
152 print("================")
153 test_cases = [tc for tc in testcases if "tc_" in tc and "template" not in tc]
155 print("\tBareMetal Testcase:")
156 print("\t===================")
157 for testcase in [tc for tc in test_cases if "baremetal" in tc]:
158 print("\t%s" % testcase)
161 print("\tStandalone Virtualization Testcase:")
162 print("\t===================================")
163 for testcase in [tc for tc in test_cases if "ovs" in tc or "sriov" in tc]:
164 print("\t%s" % testcase)
167 print("\tOpenstack Testcase:")
168 print("\t===================")
169 for testcase in [tc for tc in test_cases if "heat" in tc]:
170 print("\t%s" % testcase)
175 def terminate_if_less_options(cls, args):
176 """ terminate cli if cmdline options is invalid """
177 if not (args["vnf"] and args["test"]):
178 print("CLI needs option, make sure to pass vnf, test")
179 print("eg: NSBperf.py --vnf <vnf untertest> --test <test yaml>")
182 def run_test(self, args, test_path):
183 """ run requested test """
185 vnf = args.get("vnf", "")
186 test = args.get("test", "")
188 vnf_dir = test_path + os.sep + vnf
189 if not os.path.exists(vnf_dir):
190 raise ValueError("'%s', vnf not supported." % vnf)
192 testcases = [tc for tc in os.listdir(vnf_dir) if "tc" in tc]
193 subtest = set([test]).issubset(testcases)
195 raise ValueError("'%s', testcase not supported." % test)
198 # fixme: Use REST APIs to initiate testcases
199 subprocess.check_output(["yardstick", "--debug",
200 "task", "start", test])
201 self.generate_final_report(test)
202 except (IOError, ValueError):
203 print("Value/I/O error...")
204 except BaseException:
205 print("Test failed. Please verify test inputs & re-run the test..")
206 print("eg: NSBperf.py --vnf <vnf untertest> --test <test yaml>")
211 test_path = os.path.join(REPO_PATH, "../samples/vnf_samples/nsut/")
212 os.chdir(os.path.join(REPO_PATH, "../"))
213 args = self.parse_arguments()
215 # if required, handle list-* operations
216 self.handle_list_options(args, test_path)
218 # check for input params
219 self.terminate_if_less_options(args)
222 self.run_test(args, test_path)
224 if __name__ == "__main__":
225 signal.signal(signal.SIGINT, sigint_handler)
226 NS_CLI = YardstickNSCli()