comparison test/benchmark.py @ 7876:7a3392f1f7ac

test: update benchmark add basic CLI support for backend arguments Also docstring for file. Handle ^C interruption and cleanup partly created databases. Support postgresql and mysql.
author John Rouillard <rouilj@ieee.org>
date Tue, 16 Apr 2024 22:19:29 -0400
parents 867418c24339
children 9c3ec0a5c7fc
comparison
equal deleted inserted replaced
7875:d4f6ba8e3c1e 7876:7a3392f1f7ac
1 """ Usage: python benchmark.py ["database backend list" | backend1] [backend2]
2
3 Import the backend (anydbm, sqlite by default) and run some performance
4 tests. Example:
5
6 test default anypy and sqlite backends
7
8 python benchmark.py
9
10 test mysql and sqlite backends
11
12 python benchmark.py mysql sqlite
13
14 or
15
16 python benchmark.py "mysql sqlite"
17
18 test all backends
19
20 python benchmark.py anydbm mysql postgresql sqlite
21
22
23 """
1 from __future__ import print_function 24 from __future__ import print_function
2 import sys, os, time 25 import sys, os, time
3 import importlib, signal, shutil 26 import importlib, signal, shutil
4 27
5 # --- patch sys.path to make sure 'import roundup' finds correct version 28 # --- patch sys.path to make sure 'import roundup' finds correct version
15 Interval, DatabaseError, Boolean, Number 38 Interval, DatabaseError, Boolean, Number
16 from roundup import date, password 39 from roundup import date, password
17 40
18 from test.db_test_base import config 41 from test.db_test_base import config
19 42
43 # global for the default signal hander so
44 # my signal handler can reset before it raises signal.
20 int_sig_default_handler = None 45 int_sig_default_handler = None
21 46
22 def setupSchema(db, module): 47 def setupSchema(db, module):
23 status = module.Class(db, "status", name=String()) 48 status = module.Class(db, "status", name=String())
24 status.setkey("name") 49 status.setkey("name")
36 db.commit() 61 db.commit()
37 62
38 def rm_db_on_signal(sig, frame): 63 def rm_db_on_signal(sig, frame):
39 print("removing incomplete database %s due to interruption." % 64 print("removing incomplete database %s due to interruption." %
40 config.DATABASE) 65 config.DATABASE)
66
41 shutil.rmtree(config.DATABASE) 67 shutil.rmtree(config.DATABASE)
68
42 signal.signal(signal.SIGINT, int_sig_default_handler) 69 signal.signal(signal.SIGINT, int_sig_default_handler)
70 # re-raise the signal so the normal signal handling runs.
43 signal.raise_signal(signal.SIGTERM) 71 signal.raise_signal(signal.SIGTERM)
44 72
45 def main(backendname, time=time.time, numissues=10): 73 def main(backendname, time=time.time, numissues=10):
46 global int_sig_default_handler 74 global int_sig_default_handler
75
47 try: 76 try:
48 backend = importlib.import_module("roundup.backends.back_%s" % 77 backend = importlib.import_module("roundup.backends.back_%s" %
49 backendname) 78 backendname)
50 except ImportError: 79 except ImportError:
80 print("Unable to import %s backend." % backendname)
51 return 81 return
52 82
53 times = [] 83 times = []
54 84
55 config.DATABASE = os.path.join('_benchmark', '%s-%s'%(backendname, 85 config.DATABASE = os.path.join('_benchmark', '%s-%s'%(backendname,
56 numissues)) 86 numissues))
87
88 config.RDBMS_NAME = "rounduptest_%s" % numissues
89
57 if not os.path.exists(config.DATABASE): 90 if not os.path.exists(config.DATABASE):
58 int_sig_default_handler = signal.signal(signal.SIGINT, rm_db_on_signal) 91 int_sig_default_handler = signal.signal(signal.SIGINT, rm_db_on_signal)
59 db = backend.Database(config, 'admin') 92 db = backend.Database(config, 'admin')
60 setupSchema(db, backend) 93 setupSchema(db, backend)
94
95 # if we are re-initializing, delete any existing db
96 db.clear()
97 db.commit()
98
61 # create a whole bunch of stuff 99 # create a whole bunch of stuff
62 db.user.create(**{'username': 'admin', 'roles': 'Admin'}) 100 db.user.create(**{'username': 'admin', 'roles': 'Admin'})
63 db.status.create(name="unread") 101 db.status.create(name="unread")
64 db.status.create(name="in-progress") 102 db.status.create(name="in-progress")
65 db.status.create(name="testing") 103 db.status.create(name="testing")
83 signal.signal(signal.SIGINT, int_sig_default_handler) 121 signal.signal(signal.SIGINT, int_sig_default_handler)
84 else: 122 else:
85 db = backend.Database(config, 'admin') 123 db = backend.Database(config, 'admin')
86 setupSchema(db, backend) 124 setupSchema(db, backend)
87 125
88 sys.stdout.write('%7s: %-6d'%(backendname, numissues)) 126 sys.stdout.write('%10s: %-6d'%(backendname[:10], numissues))
89 sys.stdout.flush() 127 sys.stdout.flush()
90 128
91 times.append(('start', time())) 129 times.append(('start', time()))
92 130
93 # fetch 131 # fetch
140 last = stamp 178 last = stamp
141 print(' %-6.2f'%(last-first)) 179 print(' %-6.2f'%(last-first))
142 sys.stdout.flush() 180 sys.stdout.flush()
143 181
144 if __name__ == '__main__': 182 if __name__ == '__main__':
183 if len(sys.argv) == 2:
184 test_databases = sys.argv[1].split()
185 elif len(sys.argv) > 2:
186 test_databases = sys.argv[1:]
187 else:
188 test_databases = ['anydbm', 'sqlite']
189
145 # 0 1 2 3 4 5 6 190 # 0 1 2 3 4 5 6
146 # 01234567890123456789012345678901234567890123456789012345678901234 191 # 01234567890123456789012345678901234567890123456789012345678901234
147 print('Test name fetch journl jprops lookup filter filtml TOTAL ') 192 print('Test name fetch journl jprops lookup filter filtml TOTAL ')
148 for name in 'anydbm sqlite'.split(): 193 for name in test_databases:
149 main(name) 194 main(name)
150 for name in 'anydbm sqlite'.split(): 195 for name in test_databases:
151 main(name, numissues=20) 196 main(name, numissues=20)
152 for name in 'anydbm sqlite'.split(): 197 for name in test_databases:
153 main(name, numissues=100) 198 main(name, numissues=100)
199
154 # don't even bother benchmarking the dbm backends > 100! 200 # don't even bother benchmarking the dbm backends > 100!
155 for name in 'sqlite'.split(): 201 try:
202 test_databases.remove('anydbm')
203 except ValueError:
204 # anydbm not present; this is fine
205 pass
206
207 for name in test_databases:
156 main(name, numissues=1000) 208 main(name, numissues=1000)
157 209
210 for name in test_databases:
211 main(name, numissues=10000)
212
213
158 # vim: set et sts=4 sw=4 : 214 # vim: set et sts=4 sw=4 :

Roundup Issue Tracker: http://roundup-tracker.org/