Heat context code refactor part 2
[yardstick.git] / yardstick / benchmark / scenarios / compute / cyclictest.py
1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd and other.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 import pkg_resources
10 import logging
11 import json
12
13 import yardstick.ssh as ssh
14 from yardstick.benchmark.scenarios import base
15
16 LOG = logging.getLogger(__name__)
17 LOG.setLevel(logging.DEBUG)
18
19
20 class Cyclictest(base.Scenario):
21     """Execute cyclictest benchmark on guest vm
22
23   Parameters
24     affinity - run thread #N on processor #N, if possible
25         type:    int
26         unit:    na
27         default: 1
28     interval - base interval of thread
29         type:    int
30         unit:    us
31         default: 1000
32     loops - number of loops, 0 for endless
33         type:    int
34         unit:    na
35         default: 1000
36     priority - priority of highest prio thread
37         type:    int
38         unit:    na
39         default: 99
40     threads - number of threads
41         type:    int
42         unit:    na
43         default: 1
44     histogram - dump a latency histogram to stdout after the run
45                 here set the max time to be tracked
46         type:    int
47         unit:    ms
48         default: 90
49
50     Read link below for more fio args description:
51         https://rt.wiki.kernel.org/index.php/Cyclictest
52     """
53     __scenario_type__ = "Cyclictest"
54
55     TARGET_SCRIPT = "cyclictest_benchmark.bash"
56
57     def __init__(self, scenario_cfg, context_cfg):
58         self.scenario_cfg = scenario_cfg
59         self.context_cfg = context_cfg
60         self.setup_done = False
61
62     def setup(self):
63         '''scenario setup'''
64         self.target_script = pkg_resources.resource_filename(
65             "yardstick.benchmark.scenarios.compute",
66             Cyclictest.TARGET_SCRIPT)
67         host = self.context_cfg["host"]
68         user = host.get("user", "root")
69         ip = host.get("ip", None)
70         key_filename = host.get("key_filename", "~/.ssh/id_rsa")
71
72         LOG.debug("user:%s, host:%s", user, ip)
73         print "key_filename:" + key_filename
74         self.client = ssh.SSH(user, ip, key_filename=key_filename)
75         self.client.wait(timeout=600)
76
77         # copy script to host
78         self.client.run("cat > ~/cyclictest_benchmark.sh",
79                         stdin=open(self.target_script, "rb"))
80
81         self.setup_done = True
82
83     def run(self, result):
84         """execute the benchmark"""
85         default_args = "-m -n -q"
86
87         if not self.setup_done:
88             self.setup()
89
90         options = self.scenario_cfg["options"]
91         affinity = options.get("affinity", 1)
92         interval = options.get("interval", 1000)
93         priority = options.get("priority", 99)
94         loops = options.get("loops", 1000)
95         threads = options.get("threads", 1)
96         histogram = options.get("histogram", 90)
97
98         cmd_args = "-a %s -i %s -p %s -l %s -t %s -h %s %s" \
99                    % (affinity, interval, priority, loops,
100                       threads, histogram, default_args)
101         cmd = "sudo bash cyclictest_benchmark.sh %s" % (cmd_args)
102         LOG.debug("Executing command: %s", cmd)
103         status, stdout, stderr = self.client.execute(cmd)
104         if status:
105             raise RuntimeError(stderr)
106
107         result.update(json.loads(stdout))
108
109         if "sla" in self.scenario_cfg:
110             sla_error = ""
111             for t, latency in result.items():
112                 if 'max_%s_latency' % t not in self.scenario_cfg['sla']:
113                     continue
114
115                 sla_latency = int(self.scenario_cfg['sla'][
116                                   'max_%s_latency' % t])
117                 latency = int(latency)
118                 if latency > sla_latency:
119                     sla_error += "%s latency %d > sla:max_%s_latency(%d); " % \
120                         (t, latency, t, sla_latency)
121             assert sla_error == "", sla_error
122
123
124 def _test():
125     '''internal test function'''
126     key_filename = pkg_resources.resource_filename("yardstick.resources",
127                                                    "files/yardstick_key")
128     ctx = {
129         "host": {
130             "ip": "10.229.47.137",
131             "user": "root",
132             "key_filename": key_filename
133         }
134     }
135
136     logger = logging.getLogger("yardstick")
137     logger.setLevel(logging.DEBUG)
138
139     options = {
140         "affinity": 2,
141         "interval": 100,
142         "priority": 88,
143         "loops": 10000,
144         "threads": 2,
145         "histogram": 80
146     }
147     sla = {
148         "max_min_latency": 100,
149         "max_avg_latency": 500,
150         "max_max_latency": 1000,
151     }
152     args = {
153         "options": options,
154         "sla": sla
155     }
156     result = {}
157
158     cyclictest = Cyclictest(args, ctx)
159     cyclictest.run(result)
160     print result
161
162 if __name__ == '__main__':
163     _test()