~drizzle-trunk/drizzle/development

2144.1.1 by patrick crews
Overhaul of code. We can run rabbitmq : ) We now better encapsulate a per-executor working environment = one step closer to --parallel >: ) using subprocess goodness for server control
1
#! /usr/bin/env python
2235.5.2 by Stewart Smith
dbqp source (and all its libs) should use emacs python mode, not emacs C mode
2
# -*- mode: python; indent-tabs-mode: nil; -*-
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
3
# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
#
2337.1.15 by patrick crews
Code cleanup / reorganization
5
# Copyright (C) 2010, 2011 Patrick Crews
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
6
#
2121.3.2 by patrick crews
Updated license verbiage
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
2121.3.1 by patrick crews
Added licensing text to dbqp files
20
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
21
"""codeTree
22
23
   definition of what a code tree should look like
24
   to the test-runner (which files /directories it should find where)
25
   
26
   Files paths can be in one of several locations that we locate via
27
   systemManager methods
28
29
"""
30
# imports
31
import os
2337.1.17 by patrick crews
Additional work for running MySQL servers (still not ready for prime-time / working)
32
import sys
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
33
34
35
class codeTree:
36
    """ Defines what files / directories we should find and where
37
        allows for optional / required.
38
39
    """
40
  
41
    def __init__(self, variables, system_manager):
42
        self.debug = variables['debug']
43
        self.system_manager = system_manager
44
        self.logging = system_manager.logging
45
46
    def debug_status(self):
47
            self.logging.debug(self)
48
            for key, item in sorted(vars(self).items()):
49
                self.logging.debug("%s: %s" %(key, item))
50
51
class drizzleTree(codeTree):
52
    """ What a Drizzle code tree should look like to the test-runner
53
    
54
    """
55
56
    def __init__(self, variables,system_manager):
57
        self.system_manager = system_manager
58
        self.logging = self.system_manager.logging
2088.9.22 by patrick crews
Updated code to set LD_LIBRARY env vars
59
        self.skip_keys = ['ld_lib_paths']
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
60
        self.debug = variables['debug']
61
        self.verbose = variables['verbose']
2337.1.4 by patrick crews
Tweak of logging behavior (no more 'if debug' checks...) and related code cleanup. Also groundwork for allowing multiple basedirs (server code bases) to the test runner)
62
        self.basedir = self.system_manager.find_path([os.path.abspath(variables['basedir'][0])])
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
63
        self.source_dist = os.path.isdir(os.path.join(self.basedir, 'drizzled'))
2124.2.6 by Patrick Crews
make target for dbqp! : )
64
        self.builddir = self.system_manager.find_path([os.path.abspath(self.basedir)])
2232.1.1 by patrick crews
Added top_builddir/libdrizzle/.libs to LD_LIBRARY_PATH
65
        self.top_builddir = variables['topbuilddir']
2124.2.6 by Patrick Crews
make target for dbqp! : )
66
        self.testdir = self.system_manager.find_path([os.path.abspath(variables['testdir'])])
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
67
        self.clientbindir = self.system_manager.find_path([os.path.join(self.builddir, 'client')
68
                                     , os.path.join(self.basedir, 'client')
69
                                     , os.path.join(self.basedir, 'bin')])
70
        self.srcdir = self.system_manager.find_path([self.basedir])
2337.1.12 by patrick crews
Additional work on allowing dbqp to handle multiple server types / versions (even simultaneously)
71
        self.suite_paths = variables['suitepaths']
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
72
73
74
        self.drizzle_client = self.system_manager.find_path([os.path.join(self.clientbindir,
75
                                                     'drizzle')])
76
77
        self.drizzledump = self.system_manager.find_path([os.path.join(self.clientbindir,
78
                                                     'drizzledump')])
79
80
        self.drizzleimport = self.system_manager.find_path([os.path.join(self.clientbindir,
81
                                                     'drizzleimport')])
82
83
        self.drizzle_server = self.system_manager.find_path([os.path.join(self.basedir,'drizzled/drizzled'),
84
                                         os.path.join(self.clientbindir,'drizzled'),
85
                                         os.path.join(self.basedir,'libexec/drizzled'),
86
                                         os.path.join(self.basedir,'bin/drizzled'),
87
                                         os.path.join(self.basedir,'sbin/drizzled'),
88
                                         os.path.join(self.builddir,'drizzled/drizzled')])
89
90
91
        self.drizzleslap = self.system_manager.find_path([os.path.join(self.clientbindir,
92
                                                     'drizzleslap')])
93
94
        self.schemawriter = self.system_manager.find_path([os.path.join(self.basedir,
95
                                                     'drizzled/message/schema_writer'),
96
                                        os.path.join(self.builddir,
97
                                                     'drizzled/message/schema_writer')])
98
99
        self.drizzletest = self.system_manager.find_path([os.path.join(self.clientbindir,
100
                                                   'drizzletest')])
101
2337.1.12 by patrick crews
Additional work on allowing dbqp to handle multiple server types / versions (even simultaneously)
102
        self.trx_reader = self.system_manager.find_path([os.path.join(self.basedir,
2239.8.2 by David Shrewsbury
Changed name of drizzle_trx_reader to drizzletrx.
103
                                                                 'plugin/transaction_log/utilities/drizzletrx')])
2258.1.1 by patrick crews
Made the transaction_reader utility part of the codeTree. We now export the path an an env var that can be more easily called by drizzletest. Made adjustments to trx_log tests that need this
104
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
105
        self.server_version_string = None
106
        self.server_executable = None
107
        self.server_version = None
108
        self.server_compile_os = None
109
        self.server_platform = None
110
        self.server_compile_comment = None
2337.1.14 by patrick crews
Believed to be last tweaks needed to have different code trees / basedirs in a single dbqp run. Now to code for new servers : )
111
        self.type = 'drizzle'
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
112
113
        self.process_server_version()
2088.9.22 by patrick crews
Updated code to set LD_LIBRARY env vars
114
        self.ld_lib_paths = self.get_ld_lib_paths()
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
115
         
116
        self.report()
117
2337.1.4 by patrick crews
Tweak of logging behavior (no more 'if debug' checks...) and related code cleanup. Also groundwork for allowing multiple basedirs (server code bases) to the test runner)
118
        self.logging.debug_class(self)
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
119
120
    def report(self):
121
        self.logging.info("Using Drizzle source tree:")
122
        report_keys = ['basedir'
123
                      ,'clientbindir'
124
                      ,'testdir'
125
                      ,'server_version'
126
                      ,'server_compile_os'
127
                      ,'server_platform'
128
                      ,'server_comment']
129
        for key in report_keys:
130
            self.logging.info("%s: %s" %(key, vars(self)[key]))
131
        
132
133
134
    def process_server_version(self):
135
        """ Get the server version number from the found server executable """
136
        (retcode, self.server_version_string) = self.system_manager.execute_cmd(("%s --no-defaults --version" %(self.drizzle_server)))
137
        # This is a bit bobo, but we're doing it, so nyah
138
        # TODO fix this : )
139
        self.server_executable, data_string = [data_item.strip() for data_item in self.server_version_string.split('Ver ')]
140
        self.server_version, data_string = [data_item.strip() for data_item in data_string.split('for ')]
141
        self.server_compile_os, data_string = [data_item.strip() for data_item in data_string.split(' on')]
142
        self.server_platform = data_string.split(' ')[0].strip()
143
        self.server_comment = data_string.replace(self.server_platform,'').strip()
144
2088.9.22 by patrick crews
Updated code to set LD_LIBRARY env vars
145
    def get_ld_lib_paths(self):
146
        """ Return a list of paths we want added to LD_LIB variables
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
147
2337.1.15 by patrick crews
Code cleanup / reorganization
148
            These are processed later at the server_manager level, but we want to 
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
149
            specify them here (for a drizzle source tree) and now
150
  
151
        """
2088.9.22 by patrick crews
Updated code to set LD_LIBRARY env vars
152
        ld_lib_paths = []
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
153
        if self.source_dist:
2088.9.22 by patrick crews
Updated code to set LD_LIBRARY env vars
154
            ld_lib_paths = [ os.path.join(self.basedir,"libdrizzleclient/.libs/")
2337.1.12 by patrick crews
Additional work on allowing dbqp to handle multiple server types / versions (even simultaneously)
155
                           #, os.path.join(self.basedir,"libdrizzle-2.0/libdrizzle.libs")
2232.1.2 by patrick crews
Updates to make this work properly on mac - tested on hades
156
                           , os.path.join(self.basedir,"libdrizzle/.libs")
2246.2.1 by patrick crews
Fixed ld_lib_paths in dbqp to find the new libdrizzle locations in Monty's libdrizzle2.0 tree
157
                           , os.path.join(self.basedir,"libdrizzle-2.0/libdrizzle/.libs")
158
                           , os.path.join(self.basedir,"libdrizzle-1.0/libdrizzle/.libs")
2232.1.2 by patrick crews
Updates to make this work properly on mac - tested on hades
159
                           , os.path.join(self.basedir,"mysys/.libs/")
160
                           , os.path.join(self.basedir,"mystrings/.libs/")
161
                           , os.path.join(self.basedir,"drizzled/.libs/")
162
			                     , "/usr/local/lib"
163
                           ]
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
164
        else:
2088.9.22 by patrick crews
Updated code to set LD_LIBRARY env vars
165
            ld_lib_paths = [ os.path.join(self.basedir,"lib")]
166
        return ld_lib_paths
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
167
2337.1.15 by patrick crews
Code cleanup / reorganization
168
class mysqlTree(codeTree):
169
    """ What a MySQL code tree should look like to the test-runner
170
    
171
    """
172
173
    def __init__(self, variables,system_manager):
174
        self.system_manager = system_manager
175
        self.logging = self.system_manager.logging
176
        self.skip_keys = ['ld_lib_paths']
177
        self.debug = variables['debug']
178
        self.verbose = variables['verbose']
179
        self.basedir = self.system_manager.find_path([os.path.abspath(variables['basedir'][0])])
180
        self.source_dist = os.path.isdir(os.path.join(self.basedir, 'mysqld'))
181
        self.builddir = self.system_manager.find_path([os.path.abspath(self.basedir)])
182
        self.top_builddir = variables['topbuilddir']
183
        self.testdir = self.system_manager.find_path([os.path.abspath(variables['testdir'])])
184
        self.clientbindir = self.system_manager.find_path([os.path.join(self.basedir, 'client_release')
185
                                                         , os.path.join(self.basedir, 'client_debug')
186
                                                         , os.path.join(self.basedir, 'client')
187
                                                         , os.path.join(self.basedir, 'bin')])
188
        self.charsetdir = self.system_manager.find_path([os.path.join(self.basedir, 'mysql/charsets')
189
                                                       , os.path.join(self.basedir, 'sql/share/charsets')
190
                                                       , os.path.join(self.basedir, 'share/charsets')])
2337.1.17 by patrick crews
Additional work for running MySQL servers (still not ready for prime-time / working)
191
        self.langdir = self.system_manager.find_path([os.path.join(self.basedir, 'share/mysql')
192
                                                    , os.path.join(self.basedir, 'sql/share')
193
                                                    , os.path.join(self.basedir, 'share')])
194
2337.1.15 by patrick crews
Code cleanup / reorganization
195
196
        self.srcdir = self.system_manager.find_path([self.basedir])
197
        self.suite_paths = variables['suitepaths']
198
199
        self.mysql_client = self.system_manager.find_path([os.path.join(self.clientbindir,
200
                                                           'mysql')])
201
202
        self.mysqldump = self.system_manager.find_path([os.path.join(self.clientbindir,
203
                                                        'mysqldump')])
204
205
        self.mysqlimport = self.system_manager.find_path([os.path.join(self.clientbindir,
206
                                                          'mysqlimport')])
207
208
        self.mysqladmin = self.system_manager.find_path([os.path.join(self.clientbindir,
209
                                                         'mysqladmin')])
210
211
        self.mysql_server = self.system_manager.find_path([ os.path.join(self.basedir, '/sql/mysqld-debug')
212
                                                          , os.path.join(self.basedir, '/libexec/mysqld-debug')
213
                                                          , os.path.join(self.basedir, '/sbin/mysqld-debug')
214
                                                          , os.path.join(self.basedir, '/bin/mysqld-debug')
215
                                                          , os.path.join(self.basedir, '/sql/mysqld')
216
                                                          , os.path.join(self.basedir, '/libexec/mysqld')
217
                                                          , os.path.join(self.basedir, '/sbin/mysqld')
218
                                                          , os.path.join(self.basedir, '/bin/mysqld')
219
                                                          , os.path.join(self.basedir, '/sql/mysqld-max-nt')
220
                                                          , os.path.join(self.basedir, '/libexec/mysqld-max-nt')
221
                                                          , os.path.join(self.basedir, '/sbin/mysqld-max-nt')
222
                                                          , os.path.join(self.basedir, '/bin/mysqld-max-nt')
223
                                                          , os.path.join(self.basedir, '/sql/mysqld-max')
224
                                                          , os.path.join(self.basedir, '/libexec/mysqld-max')
225
                                                          , os.path.join(self.basedir, '/sbin/mysqld-max')
226
                                                          , os.path.join(self.basedir, '/bin/mysqld-max')
227
                                                          , os.path.join(self.basedir, '/sql/mysqld-nt')
228
                                                          , os.path.join(self.basedir, '/libexec/mysqld-nt')
229
                                                          , os.path.join(self.basedir, '/sbin/mysqld-nt')
230
                                                          , os.path.join(self.basedir, '/bin/mysqld-nt')
231
                                                          ])
232
233
234
235
        self.mysqlslap = self.system_manager.find_path([os.path.join(self.clientbindir,
236
                                                     'mysqlslap')])
237
238
        self.mysqltest = self.system_manager.find_path([os.path.join(self.clientbindir,
239
                                                   'mysqltest')])
240
        self.server_version_string = None
241
        self.server_executable = None
242
        self.server_version = None
243
        self.server_compile_os = None
244
        self.server_platform = None
245
        self.server_compile_comment = None
246
        self.type = 'mysql'
247
        self.process_server_version()
248
        self.ld_lib_paths = self.get_ld_lib_paths()
2337.1.17 by patrick crews
Additional work for running MySQL servers (still not ready for prime-time / working)
249
        self.bootstrap_path = os.path.join( self.system_manager.workdir
250
                                          , 'mysql_bootstrap.sql' )
251
        self.generate_bootstrap()
2337.1.15 by patrick crews
Code cleanup / reorganization
252
         
253
        self.report()
254
255
        self.logging.debug_class(self)
256
257
    def report(self):
258
        self.logging.info("Using mysql source tree:")
259
        report_keys = ['basedir'
260
                      ,'clientbindir'
261
                      ,'testdir'
262
                      ,'server_version'
263
                      ,'server_compile_os'
264
                      ,'server_platform'
265
                      ,'server_comment']
266
        for key in report_keys:
267
            self.logging.info("%s: %s" %(key, vars(self)[key]))
268
        
269
    def process_server_version(self):
270
        """ Get the server version number from the found server executable """
271
        (retcode, self.server_version_string) = self.system_manager.execute_cmd(("%s --no-defaults --version" %(self.mysql_server)))
272
        # This is a bit bobo, but we're doing it, so nyah
273
        # TODO fix this : )
274
        self.server_executable, data_string = [data_item.strip() for data_item in self.server_version_string.split('Ver ')]
275
        self.server_version, data_string = [data_item.strip() for data_item in data_string.split('for ')]
276
        self.server_compile_os, data_string = [data_item.strip() for data_item in data_string.split(' on')]
277
        self.server_platform = data_string.split(' ')[0].strip()
278
        self.server_comment = data_string.replace(self.server_platform,'').strip()
279
280
    def get_ld_lib_paths(self):
281
        """ Return a list of paths we want added to LD_LIB variables
282
283
            These are processed later at the server_manager level, but we want to 
284
            specify them here (for a mysql source tree) and now
285
  
286
        """
287
        ld_lib_paths = []
288
        if self.source_dist:
289
            ld_lib_paths = [ os.path.join(self.basedir,"libmysql/.libs/")
290
                           , os.path.join(self.basedir,"libmysql_r/.libs")
291
                           , os.path.join(self.basedir,"zlib/.libs")
292
                           ]
293
        else:
294
            ld_lib_paths = [ os.path.join(self.basedir,"lib")
295
                           , os.path.join(self.basedir,"lib/mysql")]
296
        return ld_lib_paths
297
2337.1.17 by patrick crews
Additional work for running MySQL servers (still not ready for prime-time / working)
298
    def generate_bootstrap(self):
299
        """ We do the voodoo that we need to in order to create the bootstrap
300
            file needed by MySQL
301
302
        """
303
        found_new_sql = False
304
        # determine if we have a proper area for our sql or if we
305
        # use the rigged method from 5.0 / 5.1
306
        # first we search various possible locations
307
        test_file = "mysql_system_tables.sql"
308
        for candidate_dir in [ "mysql"
309
                         , "sql/share"
310
                         , "share/mysql"
311
			                   , "share"
312
                         , "scripts"]:
313
            candidate_path = os.path.join(self.basedir, candidate_dir, test_file)
314
            if os.path.exists(candidate_path):
315
                bootstrap_file = open(self.bootstrap_path,'w')
316
                bootstrap_file.write("use mysql\n")
317
                for sql_file in [ 'mysql_system_tables.sql' #official mysql system tables
318
                                , 'mysql_system_tables_data.sql' #initial data for sys tables
319
                                , 'mysql_test_data_timezone.sql' # subset of full tz table data for testing
320
                                , 'fill_help_tables.sql' # fill help tables populated only w/ src dist(?)
321
                                ]:
322
                    sql_file_path = os.path.join(self.basedir,candidate_dir,sql_file)
323
                    sql_file_handle = open(sql_file_path,'r')
324
                    bootstrap_file.write(sql_file_handle.readlines())
325
                    sql_file_handle.close()
326
                found_new_sql = True
327
                break
328
        if not found_new_sql:
329
            # Install the system db's from init_db.sql
330
            # that is in early 5.1 and 5.0 versions of MySQL
331
            sql_file_path = os.path.join(self.basedir,'mysql-test/lib/init_db.sql')
332
            self.logging.info("Attempting to use bootstrap file - %s" %(sql_file_path))
333
            try:
334
                in_file = open(sql_file_path,'r')
335
                bootstrap_file = open(self.bootstrap_path,'w')
336
                bootstrap_file.write(in_file.readlines())
337
                in_file.close()
338
            except IOError:
339
                self.logging.error("Cannot find data for generating bootstrap file")
340
                self.logging.error("Cannot proceed without this, system exiting...")
341
                sys.exit(1)
342
        # Remove anonymous users
343
        bootstrap_file.write("DELETE FROM mysql.user where user= '';\n")
344
        # Create mtr database
345
        bootstrap_file.write("CREATE DATABASE mtr;\n")
346
        for sql_file in [ 'mtr_warnings.sql' # help tables + data for warning detection / suppression
347
                        , 'mtr_check.sql' # Procs for checking proper restore post-testcase
348
                        ]:
349
            sql_file_path = os.path.join(self.basedir,'mysql-test/include',sql_file)
350
            sql_file_handle = open(sql_file_path,'r')
351
            bootstrap_file.write(sql_file_handle.readlines())
352
            sql_file_handle.close()
353
        bootstrap_file.close()
354
        return
355
356
357
        
358
2337.1.15 by patrick crews
Code cleanup / reorganization
359
2088.9.1 by patrick crews
Updated tree so that test-run.pl and test-run.py may live together in peace for a time
360