Code

- merge Zope Collector #538 fix from ZPT CVS trunk (path expressions with a
[roundup.git] / test / benchmark.py
1 import sys, os, time, shutil
3 from roundup.hyperdb import String, Password, Link, Multilink, Date, \
4     Interval, DatabaseError, Boolean, Number
5 from roundup import date, password
6 from roundup.indexer import Indexer
8 def setupSchema(db, module):
9     status = module.Class(db, "status", name=String())
10     status.setkey("name")
11     user = module.Class(db, "user", username=String(), password=Password(),
12         assignable=Boolean(), age=Number(), roles=String())
13     user.setkey("username")
14     file = module.FileClass(db, "file", name=String(), type=String(),
15         comment=String(indexme="yes"))
16     issue = module.IssueClass(db, "issue", title=String(indexme="yes"),
17         status=Link("status"), nosy=Multilink("user"), deadline=Date(),
18         foo=Interval(), files=Multilink("file"), assignedto=Link('user'))
19     session = module.Class(db, 'session', title=String())
20     session.disableJournalling()
21     db.post_init()
22     db.commit()
24 class config:
25     DATABASE='_benchmark'
26     GADFLY_DATABASE = ('test', DATABASE)
27     MAILHOST = 'localhost'
28     MAIL_DOMAIN = 'fill.me.in.'
29     TRACKER_NAME = 'Roundup issue tracker'
30     TRACKER_EMAIL = 'issue_tracker@%s'%MAIL_DOMAIN
31     TRACKER_WEB = 'http://some.useful.url/'
32     ADMIN_EMAIL = 'roundup-admin@%s'%MAIL_DOMAIN
33     FILTER_POSITION = 'bottom'      # one of 'top', 'bottom', 'top and bottom'
34     ANONYMOUS_ACCESS = 'deny'       # either 'deny' or 'allow'
35     ANONYMOUS_REGISTER = 'deny'     # either 'deny' or 'allow'
36     MESSAGES_TO_AUTHOR = 'no'       # either 'yes' or 'no'
37     EMAIL_SIGNATURE_POSITION = 'bottom'
39 def main(backendname, time=time.time, numissues=10):
40     try:
41         exec('from roundup.backends import %s as backend'%backendname)
42     except ImportError:
43         return
45     times = []
47     config.DATABASE = os.path.join('_benchmark', '%s-%s'%(backendname,
48         numissues))
49     if not os.path.exists(config.DATABASE):
50         db = backend.Database(config, 'admin')
51         setupSchema(db, backend)
52         # create a whole bunch of stuff
53         db.user.create(**{'username': 'admin'})
54         db.status.create(name="unread")
55         db.status.create(name="in-progress")
56         db.status.create(name="testing")
57         db.status.create(name="resolved")
58         pc = -1
59         for i in range(numissues):
60             db.user.create(**{'username': 'user %s'%i})
61             for j in range(10):
62                 db.user.set(str(i+1), assignable=1)
63                 db.user.set(str(i+1), assignable=0)
64             db.issue.create(**{'title': 'issue %s'%i})
65             for j in range(10):
66                 db.issue.set(str(i+1), status='2', assignedto='2', nosy=[])
67                 db.issue.set(str(i+1), status='1', assignedto='1',
68                     nosy=['1','2'])
69             if (i*100/numissues) != pc:
70                 pc = (i*100/numissues)
71                 sys.stdout.write("%d%%\r"%pc)
72                 sys.stdout.flush()
73             db.commit()
74     else:
75         db = backend.Database(config, 'admin')
76         setupSchema(db, backend)
78     sys.stdout.write('%7s: %-6d'%(backendname, numissues))
79     sys.stdout.flush()
81     times.append(('start', time()))
83     # fetch
84     db.clearCache()
85     for i in db.issue.list():
86         db.issue.get(i, 'title')
87     times.append(('fetch', time()))
89     # journals
90     db.clearCache()
91     for i in db.issue.list():
92         db.issue.history(i)
93     times.append(('journal', time()))
95     # "calculated" props
96     db.clearCache()
97     for i in db.issue.list():
98         db.issue.get(i, 'activity')
99         db.issue.get(i, 'creator')
100         db.issue.get(i, 'creation')
101     times.append(('jprops', time()))
103     # lookup
104     db.clearCache()
105     for i in range(numissues):
106         db.user.lookup('user %s'%i)
107     times.append(('lookup', time()))
109     # filter
110     db.clearCache()
111     for i in range(100):
112         db.issue.filter(None, {'assignedto': '1', 'title':'issue'},
113             ('+', 'activity'), ('+', 'status'))
114     times.append(('filter', time()))
116     # filter with multilink
117     db.clearCache()
118     for i in range(100):
119         db.issue.filter(None, {'nosy': ['1'], 'assignedto': '1',
120             'title':'issue'}, ('+', 'activity'), ('+', 'status'))
121     times.append(('filtml', time()))
123     # results
124     last = None
125     for event, stamp in times:
126         if last is None:
127             first = stamp
128         else:
129             sys.stdout.write(' %-6.2f'%(stamp-last))
130         last = stamp
131     print ' %-6.2f'%(last-first)
132     sys.stdout.flush()
134 if __name__ == '__main__':
135     #      0         1         2         3         4         5         6
136     #      01234567890123456789012345678901234567890123456789012345678901234
137     print 'Test name       fetch  journl jprops lookup filter filtml TOTAL '
138     for name in 'anydbm bsddb bsddb3 metakit sqlite'.split():
139         main(name)
140     for name in 'anydbm bsddb bsddb3 metakit sqlite'.split():
141         main(name, numissues=20)
142     for name in 'anydbm bsddb bsddb3 metakit sqlite'.split():
143         main(name, numissues=100)
144     # don't even bother benchmarking the dbm backends > 100!
145     for name in 'metakit sqlite'.split():
146         main(name, numissues=1000)