Merge "install: Ubuntu 16.xx support"
[vswitchperf.git] / tools / pkt_gen / testcenter / testcenter-rfc2889-rest.py
1 # Copyright 2016 Spirent Communications.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #   http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 '''
16 @author Spirent Communications
17
18 This test automates the RFC2544 tests using the Spirent
19 TestCenter REST APIs. This test supports Python 3.4
20
21 '''
22 import argparse
23 import logging
24 import os
25
26 # Logger Configuration
27 logger = logging.getLogger(__name__)
28
29
30 def create_dir(path):
31     """Create the directory as specified in path """
32     if not os.path.exists(path):
33         try:
34             os.makedirs(path)
35         except OSError as e:
36             logger.error("Failed to create directory %s: %s", path, str(e))
37             raise
38
39
40 def write_query_results_to_csv(results_path, csv_results_file_prefix,
41                                query_results):
42     """ Write the results of the query to the CSV """
43     create_dir(results_path)
44     filec = os.path.join(results_path, csv_results_file_prefix + ".csv")
45     with open(filec, "wb") as f:
46         f.write(query_results["Columns"].replace(" ", ",") + "\n")
47         for row in (query_results["Output"].replace("} {", ",").
48                     replace("{", "").replace("}", "").split(",")):
49             f.write(row.replace(" ", ",") + "\n")
50
51
52 def positive_int(value):
53     """ Positive Integer type for Arguments """
54     ivalue = int(value)
55     if ivalue <= 0:
56         raise argparse.ArgumentTypeError(
57             "%s is an invalid positive int value" % value)
58     return ivalue
59
60
61 def percent_float(value):
62     """ Floating type for Arguments """
63     pvalue = float(value)
64     if pvalue < 0.0 or pvalue > 100.0:
65         raise argparse.ArgumentTypeError(
66             "%s not in range [0.0, 100.0]" % pvalue)
67     return pvalue
68
69
70 def main():
71     """ Read the arguments, Invoke Test and Return the results"""
72     parser = argparse.ArgumentParser()
73     # Required parameters
74     required_named = parser.add_argument_group("required named arguments")
75     required_named.add_argument("--lab_server_addr",
76                                 required=True,
77                                 help=("The IP address of the "
78                                       "Spirent Lab Server"),
79                                 dest="lab_server_addr")
80     required_named.add_argument("--license_server_addr",
81                                 required=True,
82                                 help=("The IP address of the Spirent "
83                                       "License Server"),
84                                 dest="license_server_addr")
85     required_named.add_argument("--location_list",
86                                 required=True,
87                                 help=("A comma-delimited list of test port "
88                                       "locations"),
89                                 dest="location_list")
90     # Optional parameters
91     optional_named = parser.add_argument_group("optional named arguments")
92     optional_named.add_argument("--metric",
93                                 required=False,
94                                 help=("One among - Forwarding,\
95                                       Address Caching and Congestion"),
96                                 choices=["forwarding", "caching",
97                                          "congestion"],
98                                 default="forwarding",
99                                 dest="metric")
100     optional_named.add_argument("--test_session_name",
101                                 required=False,
102                                 default="Rfc2889Ses",
103                                 help=("The friendly name to identify "
104                                       "the Spirent Lab Server test session"),
105                                 dest="test_session_name")
106
107     optional_named.add_argument("--test_user_name",
108                                 required=False,
109                                 default="Rfc2889Usr",
110                                 help=("The friendly name to identify the "
111                                       "Spirent Lab Server test user"),
112                                 dest="test_user_name")
113     optional_named.add_argument("--results_dir",
114                                 required=False,
115                                 default="./Results",
116                                 help="The directory to copy results to",
117                                 dest="results_dir")
118     optional_named.add_argument("--csv_results_file_prefix",
119                                 required=False,
120                                 default="Rfc2889MaxFor",
121                                 help="The prefix for the CSV results files",
122                                 dest="csv_results_file_prefix")
123     optional_named.add_argument("--num_trials",
124                                 type=positive_int,
125                                 required=False,
126                                 default=1,
127                                 help=("The number of trials to execute during "
128                                       "the test"),
129                                 dest="num_trials")
130     optional_named.add_argument("--trial_duration_sec",
131                                 type=positive_int,
132                                 required=False,
133                                 default=60,
134                                 help=("The duration of each trial executed "
135                                       "during the test"),
136                                 dest="trial_duration_sec")
137     optional_named.add_argument("--traffic_pattern",
138                                 required=False,
139                                 choices=["BACKBONE", "MESH", "PAIR"],
140                                 default="MESH",
141                                 help="The traffic pattern between endpoints",
142                                 dest="traffic_pattern")
143     optional_named.add_argument("--frame_size_list",
144                                 type=lambda s: [int(item)
145                                                 for item in s.split(',')],
146                                 required=False,
147                                 default=[256],
148                                 help="A comma-delimited list of frame sizes",
149                                 dest="frame_size_list")
150     parser.add_argument("-v",
151                         "--verbose",
152                         required=False,
153                         default=True,
154                         help="More output during operation when present",
155                         action="store_true",
156                         dest="verbose")
157     args = parser.parse_args()
158
159     if args.verbose:
160         logger.debug("Creating results directory")
161     create_dir(args.results_dir)
162     locationList = [str(item) for item in args.location_list.split(',')]
163
164     session_name = args.test_session_name
165     user_name = args.test_user_name
166
167     try:
168         # Load Spirent REST Library
169         from stcrestclient import stchttp
170
171         stc = stchttp.StcHttp(args.lab_server_addr)
172         session_id = stc.new_session(user_name, session_name)
173         stc.join_session(session_id)
174     except RuntimeError as e:
175         logger.error(e)
176         raise
177
178     # Retrieve and display the server information
179     if args.verbose:
180         logger.debug("SpirentTestCenter system version: %s",
181                      stc.get("system1", "version"))
182
183     try:
184         if args.verbose:
185             logger.debug("Bring up license server")
186         license_mgr = stc.get("system1", "children-licenseservermanager")
187         if args.verbose:
188             logger.debug("license_mgr = %s", license_mgr)
189         stc.create("LicenseServer", under=license_mgr, attributes={
190                    "server": args.license_server_addr})
191
192         # Create the root project object
193         if args.verbose:
194             logger.debug("Creating project ...")
195         project = stc.get("System1", "children-Project")
196
197         # Create ports
198         if args.verbose:
199             logger.debug("Creating ports ...")
200
201         for location in locationList:
202             stc.perform("CreateAndReservePorts", params={"locationList":
203                                                          location,
204                                                          "RevokeOwner":
205                                                          "FALSE"})
206
207         port_list_get = stc.get("System1.project", "children-port")
208
209         if args.verbose:
210             logger.debug("Adding Host Gen PArams")
211         gen_params = stc.create("EmulatedDeviceGenParams",
212                                 under=project,
213                                 attributes={"Port": port_list_get})
214
215         # Create the DeviceGenEthIIIfParams object
216         stc.create("DeviceGenEthIIIfParams",
217                    under=gen_params)
218         # Configuring Ipv4 interfaces
219         stc.create("DeviceGenIpv4IfParams",
220                    under=gen_params)
221
222         stc.perform("DeviceGenConfigExpand",
223                     params={"DeleteExisting": "No",
224                             "GenParams": gen_params})
225
226         if args.verbose:
227             logger.debug("Set up the RFC2889 Forwarding test...")
228         stc.perform("Rfc2889SetupMaxForwardingRateTestCommand",
229                     params={"Duration": args.trial_duration_sec,
230                             "FrameSizeList": args.frame_size_list,
231                             "NumOfTrials": args.num_trials,
232                             "TrafficPattern": args.traffic_pattern})
233
234         # Save the configuration
235         stc.perform("SaveToTcc", params={"Filename": "2889.tcc"})
236         # Connect to the hardware...
237         stc.perform("AttachPorts", params={"portList": stc.get(
238             "system1.project", "children-port"), "autoConnect": "TRUE"})
239         # Apply configuration.
240         if args.verbose:
241             logger.debug("Apply configuration...")
242         stc.apply()
243
244         if args.verbose:
245             logger.debug("Starting the sequencer...")
246         stc.perform("SequencerStart")
247
248         # Wait for sequencer to finish
249         logger.info(
250             "Starting test... Please wait for the test to complete...")
251         stc.wait_until_complete()
252         logger.info("The test has completed... Saving results...")
253
254         # Determine what the results database filename is...
255         lab_server_resultsdb = stc.get(
256             "system1.project.TestResultSetting", "CurrentResultFileName")
257
258         if args.verbose:
259             logger.debug("The lab server results database is %s",
260                          lab_server_resultsdb)
261
262         stc.perform("CSSynchronizeFiles",
263                     params={"DefaultDownloadDir": args.results_dir})
264
265         resultsdb = args.results_dir + \
266             lab_server_resultsdb.split("/Results")[1]
267
268         logger.info(
269             "The local summary DB file has been saved to %s", resultsdb)
270
271         resultsdict = (
272             stc.perform("QueryResult",
273                         params={
274                             "DatabaseConnectionString":
275                             resultsdb,
276                             "ResultPath":
277                             ("RFC2889MaxForwardingRateTestResultDetailed"
278                              "SummaryView")}))
279         if args.verbose:
280             logger.debug("resultsdict[\"Columns\"]: %s",
281                          resultsdict["Columns"])
282             logger.debug("resultsdict[\"Output\"]: %s", resultsdict["Output"])
283             logger.debug("Result paths: %s",
284                          stc.perform("GetTestResultSettingPaths"))
285
286         # Write results to csv
287         if args.verbose:
288             logger.debug("Writing CSV file to results directory %s",
289                          args.results_dir)
290         write_query_results_to_csv(
291             args.results_dir, args.csv_results_file_prefix, resultsdict)
292
293     except RuntimeError as err:
294         logger.error(err)
295
296     if args.verbose:
297         logger.debug("Destroy session on lab server")
298
299     stc.end_session()
300
301     logger.info("Test complete!")
302
303 if __name__ == "__main__":
304     main()