HC Test: update HC config file locations
[csit.git] / resources / libraries / python / honeycomb / Performance.py
1 # Copyright (c) 2017 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """Implementation of keywords for testing Honeycomb performance."""
15
16 from resources.libraries.python.ssh import SSH
17 from resources.libraries.python.constants import Constants as Const
18 from resources.libraries.python.honeycomb.HoneycombUtil import HoneycombError
19
20
21 class Performance(object):
22     """Keywords used in Honeycomb performance testing."""
23
24     def __init__(self):
25         """Initializer."""
26         pass
27
28     @staticmethod
29     def configure_netconf_threads(node, threads):
30         """Set Honeycomb's Netconf thread count in configuration.
31
32         :param node: Honeycomb node.
33         :param threads: Number of threads.
34         :type node: dict
35         :type threads: int
36         :raises HoneycombError: If the operation fails.
37         """
38
39         find = "netconf-netty-threads"
40         replace = '\\"netconf-netty-threads\\": {0},'.format(threads)
41
42         argument = '"/{0}/c\\ {1}"'.format(find, replace)
43         path = "{0}/config/netconf.json".format(Const.REMOTE_HC_DIR)
44         command = "sed -i {0} {1}".format(argument, path)
45
46         ssh = SSH()
47         ssh.connect(node)
48         (ret_code, _, stderr) = ssh.exec_command_sudo(command)
49         if ret_code != 0:
50             raise HoneycombError("Failed to modify configuration on "
51                                  "node {0}, {1}".format(node, stderr))
52
53     @staticmethod
54     def run_traffic_script_on_dut(node, script, cores, reserved=2,
55                                   *args, **kwargs):
56         """Copy traffic script over to the specified node and execute with
57         the provided arguments.
58
59         :param node: Node in topology.
60         :param script: Name of the script to execute.
61         :param cores: Number of processor cores to use.
62         :param reserved: Number of cores reserved for other tasks. Default is 2,
63         one for system tasks and one for VPP main thread.
64         :param args: Sequential arguments for the script.
65         :param kwargs: Named arguments for the script.
66         :type node: dict
67         :type script: str
68         :type cores: int
69         :type reserved: int
70         :type args: list
71         :type kwargs: dict
72         """
73
74         path = "resources/traffic_scripts/honeycomb/{0}".format(script)
75
76         # Assemble arguments for traffic script
77         arguments = ""
78         for arg in args:
79             arguments += "{0} ".format(arg)
80
81         for key, value in kwargs.items():
82             arguments += "--{0} {1} ".format(key, value)
83
84         ssh = SSH()
85         ssh.connect(node)
86         ssh.scp(path, "/tmp")
87
88         # Use alternate scheduler, Ubuntu's default can't load-balance
89         # over isolcpus
90         scheduler = "chrt -f 99"
91         core_afi = "taskset -c {first}-{last}".format(
92             first=reserved, last=cores-1)
93
94         cmd = "{scheduler} {affinity} python /tmp/{script} {args}".format(
95             scheduler=scheduler,
96             affinity=core_afi,
97             script=script,
98             args=arguments)
99
100         ret_code, stdout, _ = ssh.exec_command_sudo(cmd, timeout=600)
101
102         ssh.exec_command("sudo pkill python ; rm /tmp/{0}".format(script))
103         if ret_code != 0:
104             raise HoneycombError("Traffic script failed to execute.")
105         for line in stdout.splitlines():
106             if "Avg. requests" in line:
107                 return line
108
109     @staticmethod
110     def log_core_schedule(node, process):
111         """Determine which cores the process' threads are running on.
112
113         :param node: Honeycomb node.
114         :param process: Name of the process.
115         :type node: dict
116         :type process: str
117         """
118
119         # Get info on process and all of its children
120         cmd1 = """cat /proc/`pidof {0}`/task/*/stat""".format(process)
121
122         # Parse process ID, name and core index
123         cmd2 = """awk '{print $1" "$2" "$39}'"""
124
125         cmd = "{0} | {1}".format(cmd1, cmd2)
126
127         ssh = SSH()
128         ssh.connect(node)
129         ssh.exec_command(cmd)