Browse Source

Add OMSimulator nodule

Ilya Shakhat 3 years ago
parent
commit
4ab6709723

+ 3
- 0
performa/engine/report.py View File

@@ -95,6 +95,9 @@ def _make_dir(name):
95 95
 
96 96
 def generate_report(scenario, base_dir, mongo_url, db_name, doc_folder,
97 97
                     tag=None):
98
+    if 'report' not in scenario:
99
+        return  # nothing to do
100
+
98 101
     LOG.info('Generate report')
99 102
 
100 103
     doc_folder = doc_folder or tempfile.mkdtemp(prefix='performa')

+ 125
- 0
performa/modules/omsimulator.py View File

@@ -0,0 +1,125 @@
1
+#!/usr/bin/python
2
+
3
+import os
4
+import tempfile
5
+
6
+ATOP_FILE_NAME = os.path.join(tempfile.gettempdir(), 'performa.atop')
7
+UNIQUE_NAME = 'performa_omsimulator'
8
+DIR = '/tmp/performa/oslo.messaging/tools/'
9
+
10
+PATTERNS = [
11
+    r'(?P<msg_sent>\d+) messages were sent for (?P<duration>\d+) sec',
12
+    r'(?P<bytes_sent>\d+) bytes were sent for',
13
+]
14
+TRANSFORM_FIELDS = {
15
+    'msg_sent': int,
16
+    'bytes_sent': int,
17
+    'duration': int,
18
+}
19
+
20
+
21
+def parse_output(raw):
22
+    result = {}
23
+
24
+    for pattern in PATTERNS:
25
+        for parsed in re.finditer(pattern, raw):
26
+            result.update(parsed.groupdict())
27
+
28
+    for k in result.keys():
29
+        if k in TRANSFORM_FIELDS:
30
+            result[k] = TRANSFORM_FIELDS[k](result[k])
31
+
32
+    result['msg_sent_bandwidth'] = (result.get('msg_sent', 0) /
33
+                                    result.get('duration', 1))
34
+    result['bytes_sent_bandwidth'] = (result.get('bytes_sent', 0) /
35
+                                      result.get('duration', 1))
36
+
37
+    return result
38
+
39
+
40
+def chdir(module):
41
+    try:
42
+        os.chdir(DIR)
43
+    except Exception as e:
44
+        module.fail_json(msg='Failed to change dir to %s: %s' % (DIR, e))
45
+
46
+
47
+def start_daemon(module, cmd):
48
+    cmd = ('daemon -n %(name)s -D %(dir)s -- %(cmd)s' %
49
+           dict(name=UNIQUE_NAME, dir=DIR, cmd=cmd))
50
+
51
+    rc, stdout, stderr = module.run_command(cmd)
52
+    result = dict(changed=True, rc=rc, stdout=stdout, stderr=stderr, cmd=cmd)
53
+
54
+    if rc:
55
+        module.fail_json(msg='Failed to start OMSimulator', **result)
56
+
57
+
58
+def run(module):
59
+    params = module.params
60
+
61
+    if params['mode'] == 'notify':
62
+        server_tool = 'notify-server'
63
+        client_tool = 'notify-client'
64
+    else:
65
+        server_tool = 'rpc-server'
66
+        client_tool = 'rpc-client'
67
+
68
+    params['server_tool'] = server_tool
69
+    params['client_tool'] = client_tool
70
+
71
+    server = ('python simulator.py '
72
+              '--url %(url)s '
73
+              '%(server_tool)s '
74
+              '--show-stats true') % params
75
+    client = ('python simulator.py '
76
+              '--url=%(url)s '
77
+              '-l %(duration)s '
78
+              '%(client_tool)s '
79
+              '-p %(threads)s ') % params
80
+
81
+    if params['mode'] == 'cast':
82
+        client += '--is-cast True '
83
+
84
+    if params['mode'] == 'fanout':
85
+        client += '--is-fanout True '
86
+
87
+    start_daemon(module, server)
88
+
89
+    start = int(time.time())
90
+    rc, stdout, stderr = module.run_command(client)
91
+    end = int(time.time())
92
+
93
+    if rc:
94
+        module.fail_json(msg='Failed to run omsimulator client', stderr=stderr)
95
+
96
+    try:
97
+        parsed = parse_output(stdout)
98
+        parsed['start'] = start
99
+        parsed['end'] = end
100
+
101
+        result = dict(records=[parsed])
102
+        module.exit_json(**result)
103
+    except Exception as e:
104
+        msg = 'Failed to start omsimulator client %s' % e
105
+        module.fail_json(msg=msg, rc=rc, stderr=stderr, stdout=stdout)
106
+
107
+
108
+def main():
109
+    module = AnsibleModule(
110
+        argument_spec=dict(
111
+            mode=dict(required=True,
112
+                      choices=['call', 'cast', 'fanout', 'notify']),
113
+            url=dict(required=True),
114
+            threads=dict(type='int', default=10),
115
+            duration=dict(type='int', default=10),
116
+        ))
117
+
118
+    chdir(module)
119
+    run(module)
120
+
121
+
122
+from ansible.module_utils.basic import *  # noqa
123
+
124
+if __name__ == '__main__':
125
+    main()

+ 32
- 0
performa/scenarios/mq/omsimulator.rst View File

@@ -0,0 +1,32 @@
1
+Sysbench Report
2
+---------------
3
+
4
+This is the report of execution test plan
5
+:ref:`mq_test_plan` with `Sysbench`_ tool.
6
+
7
+Results
8
+^^^^^^^
9
+
10
+Chart and table:
11
+
12
+{{'''
13
+    title: Messages per second
14
+    axes:
15
+      x: threads
16
+      y: messages per sec
17
+    chart: line
18
+    pipeline:
19
+    - { $match: { task: omsimulator, status: OK }}
20
+    - { $group: { _id: { threads: "$threads" },
21
+                  msg_sent_per_sec: { $avg: { $divide: ["$msg_sent", "$duration"] }}
22
+                }}
23
+    - { $project: { x: "$_id.threads",
24
+                    y: "$msg_sent_per_sec"
25
+                  }}
26
+    - { $sort: { x: 1 }}
27
+''' | chart
28
+}}
29
+
30
+.. references:
31
+
32
+.. _Sysbench: https://github.com/akopytov/sysbench

+ 40
- 0
performa/scenarios/mq/omsimulator.yaml View File

@@ -0,0 +1,40 @@
1
+title: OMSimulator
2
+
3
+description:
4
+  This scenario uses oslo.messaging simulator tool to execute MQ test plan.
5
+
6
+setup:
7
+  -
8
+    hosts: $target
9
+    tasks:
10
+    - name: installing omsimulator
11
+      git: repo=git://git.openstack.org/openstack/oslo.messaging
12
+           dest=/tmp/performa/oslo.messaging
13
+    - apt: name=atop
14
+      become: yes
15
+    - apt: name=daemon
16
+      become: yes
17
+  -
18
+    hosts: $target
19
+    tasks:
20
+    - atop: command=start
21
+
22
+execution:
23
+  -
24
+    hosts: $target
25
+    matrix:
26
+      threads: [ 1, 2, 5, 10, 25, 50, 100 ]
27
+    tasks:
28
+    - omsimulator:
29
+        mode: call
30
+        duration: 10
31
+        url: "rabbit://stackrabbit:swordfish@localhost:5672/"
32
+  -
33
+    hosts: $target
34
+    tasks:
35
+    - atop:
36
+        command: stop
37
+        labels: [ CPU, PRC, PRM ]
38
+
39
+report:
40
+  template: omsimulator.rst

+ 5
- 0
performa/tests/omsimulator_sample.txt View File

@@ -0,0 +1,5 @@
1
+2016-02-29 10:33:51,044 INFO root Preparing 1 messages
2
+2016-02-29 10:33:51,046 INFO root Messages has been prepared
3
+2016-02-29 10:34:01,062 INFO root 5313 messages were sent for 10 seconds. Bandwidth was 530 msg/sec
4
+2016-02-29 10:34:01,062 INFO root 14897652 bytes were sent for 10 seconds. Bandwidth is 1487420 b/s
5
+2016-02-29 10:34:01,062 INFO root calls finished, wait 0 seconds

+ 31
- 0
performa/tests/test_omsimulator.py View File

@@ -0,0 +1,31 @@
1
+# Copyright (c) 2016 OpenStack Foundation
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
12
+# implied.
13
+# See the License for the specific language governing permissions and
14
+# limitations under the License.
15
+
16
+import testtools
17
+
18
+from performa.modules import omsimulator
19
+
20
+
21
+def _read_sample():
22
+    with open('performa/tests/omsimulator_sample.txt') as f:
23
+        return f.read()
24
+
25
+
26
+class TestOMSimulator(testtools.TestCase):
27
+    def test_parse_client_call(self):
28
+        expected = dict(msg_sent=5313, bytes_sent=14897652, duration=10,
29
+                        msg_sent_bandwidth=531, bytes_sent_bandwidth=1489765)
30
+
31
+        self.assertEqual(expected, omsimulator.parse_output(_read_sample()))

Loading…
Cancel
Save