source: main/waeup.stress/trunk/src/waeup/stress/scripts.py @ 9876

Last change on this file since 9876 was 9876, checked in by uli, 12 years ago

Respect async ZODB when setting up a new instance. Basic stress tests
now work again.

File size: 4.4 KB
Line 
1"""Helpers when inside an instance context.
2"""
3import os
4import sys
5import transaction
6from zope.app.appsetup import database, config
7from zope.app.publication.zopepublication import ZopePublication
8from zope.app.wsgi import config as wsgi_config
9from waeup.kofa.app import University
10
11#: The name under which any artificially created University instance
12#: will be put into the root folder
13APP_NAME = 'stress_app'
14
15IMPORTERS = {
16    'faculties.csv': 'facultyprocessor',
17    'departments.csv': 'departmentprocessor',
18    'courses.csv': 'courseprocessor',
19    'certificates.csv': 'certificateprocessor',
20    'certificatecourses.csv': 'certificatecourseprocessor',
21    'applicantcontainers.csv': 'applicants container processor',
22    'applicants.csv': 'applicantprocessor',
23    }
24
25def configure(instance_path=''):
26    config_file = os.path.join(
27        instance_path, 'parts', 'etc', 'site.zcml')
28    print "WAEUP.STRESS: configuring ZODB from %s" % (
29        config_file,)
30    context = config(config_file)
31    return context
32
33def open_zodb(instance_path=''):
34    """Open a ZODB and configure it using a site.zcml file.
35
36    If `instance_path` is not given, we assume to be in the root of
37    some Zope instance and compute relative paths to
38    'parts/etc/site.zcml' and 'var/filestorage/Data.fs'.
39
40    If `instance_path` is given, these paths are os.path.joined with
41    it.
42
43    Returns a tuple containing a database object, an open connection
44    to this DB and the root folder.
45    """
46    zope_conf = os.path.join(
47        instance_path, 'parts', 'etc', 'zope.conf')
48    config_file = os.path.join(
49        instance_path, 'parts', 'etc', 'site.zcml')
50    print "WAEUP.STRESS: opening ZODB"
51    zodb_file = os.path.join(
52        instance_path, 'var', 'filestorage', 'Data.fs')
53
54    print "WAEUP.STRESS: configuring ZODB from %s" % (
55        zope_conf)
56
57    db = wsgi_config(zope_conf)
58
59    # The way to configure a ZODB if only a single ZODB has to be set up.
60    #context = config(config_file)
61    #db = database(zodb_file)
62
63    conn = db.open()
64    root = conn.root()
65    root_folder = root.get(ZopePublication.root_name, None)
66    return db, conn, root_folder
67
68def close_zodb(db):
69    print "WAEUP.STRESS: closing ZODB"
70    transaction.commit() # make sure changes are saved
71    db.close()
72    return
73
74def zodb(func):
75    """A decorator that does a ZODB setup and calls the decorated
76    function with the ZODB root folder as first argument.
77    """
78    def wrapped(*args, **kw):
79        instance_path = kw.get('instance_path', '')
80        db, conn, root_folder = open_zodb(instance_path)
81        try:
82            func(root_folder, *args, **kw)
83        finally:
84            close_zodb(db)
85    return wrapped
86
87@zodb
88def create_app(root_folder):
89    """Create a University instance named 'stress_app' in ZODB.
90
91    The `root_folder` arg is injected by the decorator and represents
92    the root folder of an opened, writable ZODB.
93    """
94    root_folder[APP_NAME] = University()
95    print "WAEUP.STRESS.SCRIPTS: created '%s' in root folder." % APP_NAME
96    return
97
98@zodb
99def import_files(root_folder, *args):
100    from zope.component.hooks import setSite
101    from zope.component import getUtility
102    from waeup.kofa.interfaces import IBatchProcessor
103    setSite(root_folder[APP_NAME])
104    for path in args:
105        if not os.path.isfile(path):
106            print "WAEUP.STRESS.SCRIPTS: no such file: %s" % path
107            continue
108        basename = os.path.basename(path)
109        util_name = IMPORTERS.get(basename, None)
110        if util_name is None:
111            print "WAEUP.STRESS.SCRIPTS: not a valid import filename: %s" % (
112                basename)
113            print "  valid names: %s" % IMPORTERS.keys()
114            continue
115        util = getUtility(IBatchProcessor, name=util_name)
116        for line in open(path, 'rb'):
117            break
118        headerfields = line.strip().split(',')
119        print "WAEUP.STRESS.SCRIPTS: importing %s" % os.path.basename(path)
120        results = util.doImport(path, headerfields)
121        print "WAEUP.STRESS.SCRIPTS: import done."
122    return
123
124def main(cmd, *args, **kw):
125    if cmd == 'install_app':
126        configure()
127        create_app()
128        return
129    elif cmd == 'import_csv':
130        configure()
131        create_app()
132        import_files(*args)
133        return
134
135if __name__ == '__main__':
136    cmd = sys.argv[1]
137    args = []
138    if len(sys.argv) > 2:
139        args = sys.argv[2:]
140    main(cmd, *args)
Note: See TracBrowser for help on using the repository browser.