~landscape/charms/xenial/mongodb/trunk

« back to all changes in this revision

Viewing changes to actions/perf

  • Committer: Tim Van Steenburgh
  • Date: 2015-05-15 15:17:07 UTC
  • mfrom: (68.1.3 mongodb)
  • Revision ID: tim.van.steenburgh@canonical.com-20150515151707-a0wn5yjktrekln6h
[aisrael] Add support for benchmarking mongodb with mongoperf, using juju actions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
import signal
 
3
import subprocess
 
4
import os
 
5
import json
 
6
import re
 
7
from tempfile import NamedTemporaryFile
 
8
from distutils.spawn import find_executable
 
9
 
 
10
try:
 
11
    from charmhelpers.contrib.benchmark import Benchmark
 
12
except ImportError:
 
13
    subprocess.check_call(['apt-get', 'install', '-y', 'python-pip'])
 
14
    subprocess.check_call(['pip', 'install', 'charmhelpers'])
 
15
    from charmhelpers.contrib.benchmark import Benchmark
 
16
 
 
17
 
 
18
def handler(signum, frame):
 
19
    raise IOError('Timeout')
 
20
 
 
21
 
 
22
def action_set(key, val):
 
23
    action_cmd = ['action-set']
 
24
    if isinstance(val, dict):
 
25
        for k, v in val.iteritems():
 
26
            action_set('%s.%s' % (key, k), v)
 
27
        return
 
28
 
 
29
    action_cmd.append('%s=%s' % (key, val))
 
30
    subprocess.check_call(action_cmd)
 
31
 
 
32
 
 
33
def action_get(key):
 
34
    if find_executable('action-get'):
 
35
        return subprocess.check_output(['action-get', key]).strip()
 
36
    return None
 
37
 
 
38
 
 
39
def main():
 
40
 
 
41
    Benchmark.start()
 
42
 
 
43
    """
 
44
    mongoperf runs until interupted so we have to use a
 
45
    signal handler to stop it and gather the results
 
46
    """
 
47
    signal.signal(signal.SIGALRM, handler)
 
48
    runtime = int(action_get('runtime') or 180)
 
49
    signal.alarm(runtime)
 
50
 
 
51
    js = {}
 
52
    js['nThreads'] = int(action_get('nthreads'))
 
53
    js['fileSizeMB'] = int(action_get('fileSizeMB'))
 
54
    js['sleepMicros'] = int(action_get('sleepMicros'))
 
55
    js['mmf'] = action_get('mmf')
 
56
    js['r'] = action_get('r')
 
57
    js['w'] = action_get('w')
 
58
    js['recSizeKB'] = int(action_get('recSizeKB'))
 
59
    js['syncDelay'] = int(action_get('syncDelay'))
 
60
 
 
61
    config = NamedTemporaryFile(delete=False)
 
62
    config.write(json.dumps(js))
 
63
    config.close()
 
64
    config = open(config.name, 'r')
 
65
 
 
66
    output = NamedTemporaryFile(delete=False)
 
67
 
 
68
    p = None
 
69
    try:
 
70
        p = subprocess.Popen(
 
71
            'mongoperf',
 
72
            stdin=config,
 
73
            stdout=output,
 
74
        )
 
75
        os.waitpid(p.pid, 0)
 
76
    except subprocess.CalledProcessError as e:
 
77
        rc = e.returncode
 
78
        print "Exit with error code %d" % rc
 
79
    except IOError as e:
 
80
        signal.alarm(0)
 
81
        os.kill(p.pid, signal.SIGKILL)
 
82
    finally:
 
83
        os.unlink(config.name)
 
84
 
 
85
    output.close()
 
86
    output = open(output.name, 'r')
 
87
    scores = []
 
88
    regex = re.compile(r'(\d+)\sops\/sec')
 
89
    for line in output:
 
90
        m = regex.match(line)
 
91
        if m:
 
92
            scores.append(int(m.group(1)))
 
93
 
 
94
    action_set(
 
95
        "results.total",
 
96
        {'value': sum(scores), 'units': 'ops'}
 
97
    )
 
98
 
 
99
    action_set(
 
100
        "results.iterations",
 
101
        {'value': len(scores), 'units': 'iterations'}
 
102
    )
 
103
 
 
104
    action_set(
 
105
        "results.average",
 
106
        {'value': sum(scores) / float(len(scores)), 'units': 'ops/sec'}
 
107
    )
 
108
    action_set(
 
109
        "results.max",
 
110
        {'value': max(scores), 'units': 'ops/sec'}
 
111
    )
 
112
    action_set(
 
113
        "results.min",
 
114
        {'value': min(scores), 'units': 'ops/sec'}
 
115
    )
 
116
 
 
117
    Benchmark.set_composite_score(
 
118
        sum(scores) / float(len(scores)),
 
119
        'ops/sec',
 
120
        'desc'
 
121
    )
 
122
 
 
123
    Benchmark.finish()
 
124
 
 
125
 
 
126
if __name__ == "__main__":
 
127
    main()