Update sla check for scenarios
[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, context):
58         self.context = context
59         self.setup_done = False
60
61     def setup(self):
62         '''scenario setup'''
63         self.target_script = pkg_resources.resource_filename(
64             "yardstick.benchmark.scenarios.compute",
65             Cyclictest.TARGET_SCRIPT)
66         user = self.context.get("user", "root")
67         host = self.context.get("host", None)
68         key_filename = self.context.get("key_filename", "~/.ssh/id_rsa")
69
70         LOG.debug("user:%s, host:%s", user, host)
71         print "key_filename:" + key_filename
72         self.client = ssh.SSH(user, host, key_filename=key_filename)
73         self.client.wait(timeout=600)
74
75         # copy script to host
76         self.client.run("cat > ~/cyclictest_benchmark.sh",
77                         stdin=open(self.target_script, "rb"))
78
79         self.setup_done = True
80
81     def run(self, args, result):
82         """execute the benchmark"""
83         default_args = "-m -n -q"
84
85         if not self.setup_done:
86             self.setup()
87
88         options = args["options"]
89         affinity = options.get("affinity", 1)
90         interval = options.get("interval", 1000)
91         priority = options.get("priority", 99)
92         loops = options.get("loops", 1000)
93         threads = options.get("threads", 1)
94         histogram = options.get("histogram", 90)
95
96         cmd_args = "-a %s -i %s -p %s -l %s -t %s -h %s %s" \
97                    % (affinity, interval, priority, loops,
98                       threads, histogram, default_args)
99         cmd = "sudo bash cyclictest_benchmark.sh %s" % (cmd_args)
100         LOG.debug("Executing command: %s", cmd)
101         status, stdout, stderr = self.client.execute(cmd)
102         if status:
103             raise RuntimeError(stderr)
104
105         result.update(json.loads(stdout))
106
107         if "sla" in args:
108             sla_error = ""
109             for t, latency in result.items():
110                 if 'max_%s_latency' % t not in args['sla']:
111                     continue
112
113                 sla_latency = int(args['sla']['max_%s_latency' % t])
114                 latency = int(latency)
115                 if latency > sla_latency:
116                     sla_error += "%s latency %d > sla:max_%s_latency(%d); " % \
117                         (t, latency, t, sla_latency)
118             assert sla_error == "", sla_error
119
120
121 def _test():
122     '''internal test function'''
123     key_filename = pkg_resources.resource_filename("yardstick.resources",
124                                                    "files/yardstick_key")
125     ctx = {
126         "host": "192.168.50.28",
127         "user": "root",
128         "key_filename": key_filename
129     }
130
131     logger = logging.getLogger("yardstick")
132     logger.setLevel(logging.DEBUG)
133
134     cyclictest = Cyclictest(ctx)
135
136     options = {
137         "affinity": 2,
138         "interval": 100,
139         "priority": 88,
140         "loops": 10000,
141         "threads": 2,
142         "histogram": 80
143     }
144     sla = {
145         "max_min_latency": 100,
146         "max_avg_latency": 500,
147         "max_max_latency": 1000,
148     }
149     args = {
150         "options": options,
151         "sla": sla
152     }
153
154     result = cyclictest.run(args)
155     print result
156
157 if __name__ == '__main__':
158     _test()