~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to tests/lib/server_mgmt/server_management.py

  • Committer: Mark Atwood
  • Date: 2011-10-11 22:37:47 UTC
  • mfrom: (2429.2.1 dbqp_revamp)
  • Revision ID: me@mark.atwood.name-20111011223747-vomebzgvnxxysqrm
mergeĀ lp:~patrick-crews/drizzle/dbqp_revamp

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
# -*- mode: python; indent-tabs-mode: nil; -*-
3
3
# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
4
#
5
 
# Copyright (C) 2010 Patrick Crews
 
5
# Copyright (C) 2010, 2011 Patrick Crews
6
6
#
7
7
# This program is free software; you can redistribute it and/or modify
8
8
# it under the terms of the GNU General Public License as published by
38
38
    """
39
39
 
40
40
    def __init__(self, system_manager, variables):
41
 
        self.skip_keys = [ 'ld_lib_paths'
42
 
                         , 'system_manager'
 
41
        self.skip_keys = [ 'system_manager'
 
42
                         , 'env_manager'
 
43
                         , 'code_manager'
43
44
                         , 'logging'
44
45
                         , 'gdb'
45
 
                         , 'code_tree'
46
46
                         ]
47
47
        self.debug = variables['debug']
48
48
        self.verbose = variables['verbose']
51
51
        self.server_base_name = 's'
52
52
        self.no_secure_file_priv = variables['nosecurefilepriv']
53
53
        self.system_manager = system_manager
 
54
        self.code_manager = system_manager.code_manager
 
55
        self.env_manager = system_manager.env_manager
54
56
        self.logging = system_manager.logging
55
57
        self.gdb  = self.system_manager.gdb
56
 
        self.code_tree = system_manager.code_tree
57
58
        self.default_storage_engine = variables['defaultengine']
 
59
        self.default_server_type = variables['defaultservertype']
58
60
        self.user_server_opts = variables['drizzledoptions']
59
61
        self.servers = {}
60
 
        # We track this
61
 
        self.ld_lib_paths = system_manager.ld_lib_paths
 
62
 
62
63
        self.mutex = thread.allocate_lock()
63
64
        self.timer_increment = .5
 
65
        self.libeatmydata = variables['libeatmydata']
 
66
        self.libeatmydata_path = variables['libeatmydatapath']
64
67
 
65
68
        self.logging.info("Using default-storage-engine: %s" %(self.default_storage_engine))
66
69
 
67
 
        if self.debug:
68
 
            self.logging.debug_class(self)
 
70
        self.logging.debug_class(self)
69
71
 
70
72
    def request_servers( self, requester, workdir, cnf_path, server_requirements
71
73
                       , working_environ, expect_fail = 0):
100
102
 
101
103
 
102
104
    
103
 
    def allocate_server(self, requester, server_options, workdir):
 
105
    def allocate_server( self, requester, server_options
 
106
                       , workdir, server_type=None, server_version=None):
104
107
        """ Intialize an appropriate server object.
105
108
            Start up occurs elsewhere
106
109
 
107
110
        """
 
111
        # use default server type unless specifically requested to do otherwise
 
112
        if not server_type:
 
113
            server_type = self.default_server_type
108
114
 
109
115
        # Get a name for our server
110
116
        server_name = self.get_server_name(requester)
111
117
 
112
118
        # initialize our new server_object
113
 
        if self.code_tree.type == 'Drizzle':
114
 
          from lib.server_mgmt.drizzled import drizzleServer as server_type
 
119
        # get the right codeTree type from the code manager
 
120
        code_tree = self.code_manager.get_tree(server_type, server_version)
 
121
 
 
122
        # import the correct server type object
 
123
        if server_type == 'drizzle':
 
124
            from lib.server_mgmt.drizzled import drizzleServer as server_type
 
125
        elif server_type == 'mysql':
 
126
            from lib.server_mgmt.mysqld import mysqlServer as server_type
 
127
 
115
128
        new_server = server_type( server_name
116
129
                                , self
 
130
                                , code_tree
117
131
                                , self.default_storage_engine
118
132
                                , server_options
119
133
                                , requester
123
137
    def start_servers(self, requester, working_environ, expect_fail):
124
138
        """ Start all servers for the requester """
125
139
        bad_start = 0
 
140
 
126
141
        for server in self.get_server_list(requester):
127
142
            if server.status == 0:
128
143
                bad_start = bad_start + self.start_server( server
130
145
                                                         , working_environ
131
146
                                                         , expect_fail
132
147
                                                         )
 
148
            else:
 
149
                self.logging.debug("Server %s already running" %(server.name))
133
150
        return bad_start
134
151
 
135
152
    def start_server(self, server, requester, working_environ, expect_fail):
143
160
            start up
144
161
 
145
162
        """
 
163
        # take care of any environment updates we need to do
 
164
        self.handle_environment_reqs(server, working_environ)
146
165
 
147
 
        if self.verbose:
148
 
            self.logging.verbose("Starting server: %s.%s" %(server.owner, server.name))
 
166
        self.logging.verbose("Starting server: %s.%s" %(server.owner, server.name))
149
167
        start_cmd = server.get_start_cmd()
150
 
        if self.debug:
151
 
            self.logging.debug("Starting server with:")
152
 
            self.logging.debug("%s" %(start_cmd))
 
168
        self.logging.debug("Starting server with:")
 
169
        self.logging.debug("%s" %(start_cmd))
153
170
        # we signal we tried to start as an attempt
154
171
        # to catch the case where a server is just 
155
172
        # starting up and the user ctrl-c's
214
231
                pid_file.close()
215
232
                server.pid = pid
216
233
 
217
 
        if server_retcode != 0 and not expect_fail and self.debug:
218
 
            self.logging.debug("Server startup command: %s failed with error code %d" %( start_cmd
 
234
        if server_retcode != 0 and not expect_fail:
 
235
            self.logging.error("Server startup command: %s failed with error code %d" %( start_cmd
219
236
                                                                                  , server_retcode))
220
237
        elif server_retcode == 0 and expect_fail:
221
238
        # catch a startup that should have failed and report
248
265
                attempts_remain = attempts_remain - 1
249
266
        # Now we try to shut the server down
250
267
        if self.ping_server(server, quiet=True):
251
 
            if self.verbose:
252
 
                self.logging.verbose("Stopping server %s.%s" %(server.owner, server.name))
 
268
            self.logging.verbose("Stopping server %s.%s" %(server.owner, server.name))
253
269
            stop_cmd = server.get_stop_cmd()
254
270
            #retcode, output = self.system_manager.execute_cmd(stop_cmd)
255
271
            shutdown_subproc = subprocess.Popen( stop_cmd
340
356
            We should have the proper number of servers at this point
341
357
 
342
358
        """
 
359
 
 
360
        # A dictionary that holds various tricks
 
361
        # we can do with our test servers
 
362
        special_processing_reqs = {}
 
363
 
343
364
        current_servers = self.servers[requester]
344
365
 
345
 
        # We have a config reader so we can do
346
 
        # special per-server magic for setting up more
347
 
        # complex scenario-based testing (eg we use a certain datadir)
348
 
        if cnf_path: 
349
 
            config_reader = RawConfigParser()
350
 
            config_reader.read(cnf_path)
351
 
        else:
352
 
            config_reader = None
353
 
        # A list that holds tuples of src,tgt pairs
354
 
        # for using a pre-loaded-datadirs on a test server
355
 
        datadir_requests = []
356
 
 
357
366
        for index,server in enumerate(current_servers):
358
 
            desired_server_options = server_requirements[index]
359
 
            # We add in any user-supplied options here
360
 
            desired_server_options = desired_server_options + self.user_server_opts
361
 
 
362
367
            # We handle a reset in case we need it:
363
368
            if server.need_reset:
364
369
                self.reset_server(server)
365
370
                server.need_reset = False
366
371
 
367
 
            # Do our checking for config-specific madness we need to do
368
 
            if config_reader and config_reader.has_section(server.name):
369
 
                # mark server for restart in case it hasn't yet
370
 
                # this method is a bit hackish - need better method later
371
 
                if '--restart' not in desired_server_options:
372
 
                    desired_server_options.append('--restart')
373
 
                # We handle various scenarios
374
 
                server_config_data = config_reader.items(server.name)
375
 
                for cnf_option, data in server_config_data:
376
 
                    if cnf_option == 'load-datadir':
377
 
                        datadir_path = data
378
 
                        datadir_requests.append((datadir_path,server))
 
372
            desired_server_options = server_requirements[index]
 
373
            
 
374
            # do any special config processing - this can alter
 
375
            # how we view our servers
 
376
            if cnf_path:
 
377
                self.handle_server_config_file( cnf_path
 
378
                                              , server
 
379
                                              , special_processing_reqs
 
380
                                              , desired_server_options
 
381
                                              )
379
382
 
380
383
            if self.compare_options( server.server_options
381
384
                                   , desired_server_options):
382
 
                return 1
 
385
                return
383
386
            else:
384
387
                # We need to reset what is running and change the server
385
388
                # options
386
389
                desired_server_options = self.filter_server_options(desired_server_options)
387
390
                self.reset_server(server)
388
391
                self.update_server_options(server, desired_server_options)
389
 
            self.load_datadirs(datadir_requests)
390
 
 
391
 
 
392
 
       
 
392
            
 
393
            self.handle_special_server_requests(special_processing_reqs)
 
394
 
 
395
    def handle_server_config_file( self
 
396
                                 , cnf_path
 
397
                                 , server
 
398
                                 , special_processing_reqs
 
399
                                 , desired_server_options
 
400
                                 ):
 
401
        # We have a config reader so we can do
 
402
        # special per-server magic for setting up more
 
403
        # complex scenario-based testing (eg we use a certain datadir)
 
404
        config_reader = RawConfigParser()
 
405
        config_reader.read(cnf_path)
 
406
 
 
407
        # Do our checking for config-specific madness we need to do
 
408
        if config_reader and config_reader.has_section(server.name):
 
409
            # mark server for restart in case it hasn't yet
 
410
            # this method is a bit hackish - need better method later
 
411
            if '--restart' not in desired_server_options:
 
412
                desired_server_options.append('--restart')
 
413
            # We handle various scenarios
 
414
            server_config_data = config_reader.items(server.name)
 
415
            for cnf_option, data in server_config_data:
 
416
                if cnf_option == 'load-datadir':
 
417
                    datadir_path = data
 
418
                    request_key = 'datadir_requests'
 
419
                if request_key not in special_processing_reqs:
 
420
                    special_processing_reqs[request_key] = []
 
421
                special_processing_reqs[request_key].append((datadir_path,server))
 
422
 
 
423
    def handle_special_server_requests(self, request_dictionary):
 
424
        """ We run through our set of special requests and do 
 
425
            the appropriate voodoo
 
426
 
 
427
        """
 
428
        for key, item in request_dictionary.items():
 
429
            if key == 'datadir_requests':
 
430
                self.load_datadirs(item)
393
431
 
394
432
    def filter_server_options(self, server_options):
395
433
        """ Remove a list of options we don't want passed to the server
479
517
 
480
518
    def update_server_options(self, server, server_options):
481
519
        """ Change the option_list a server has to use on startup """
482
 
        if self.debug:
483
 
            self.logging.debug("Updating server: %s options" %(server.name))
484
 
            self.logging.debug("FROM: %s" %(server.server_options))
485
 
            self.logging.debug("TO: %s" %(server_options))
 
520
        self.logging.debug("Updating server: %s options" %(server.name))
 
521
        self.logging.debug("FROM: %s" %(server.server_options))
 
522
        self.logging.debug("TO: %s" %(server_options))
486
523
        server.set_server_options(server_options)
487
524
 
488
525
    def get_server_count(self):
502
539
            if server.failed_test:
503
540
                self.reset_server(server)
504
541
 
505
 
 
 
542
    def handle_environment_reqs(self, server, working_environ):
 
543
        """ We update the working_environ as we need to
 
544
            before starting the server.
 
545
 
 
546
            This includes things like libeatmydata, ld_preloads, etc
 
547
 
 
548
        """
 
549
        environment_reqs = {}
 
550
 
 
551
        if self.libeatmydata:
 
552
            # We want to use libeatmydata to disable fsyncs
 
553
            # this speeds up test execution, but we only want
 
554
            # it to happen for the servers' environments
 
555
 
 
556
            environment_reqs.update({'LD_PRELOAD':self.libeatmydata_path})
 
557
 
 
558
        # handle ld_preloads
 
559
        ld_lib_paths = self.env_manager.join_env_var_values(server.code_tree.ld_lib_paths)
 
560
        environment_reqs.update({'LD_LIBRARY_PATH' : self.env_manager.append_env_var( 'LD_LIBRARY_PATH'
 
561
                                                                                    , ld_lib_paths
 
562
                                                                                    , suffix = 0
 
563
                                                                                    , quiet = 1
 
564
                                                                                    )
 
565
                                , 'DYLD_LIBRARY_PATH' : self.env_manager.append_env_var( 'DYLD_LIBRARY_PATH'
 
566
                                                                                       , ld_lib_paths
 
567
                                                                                       , suffix = 0
 
568
                                                                                       , quiet = 1
 
569
                                                                                       )
 
570
 
 
571
                                 })
 
572
        self.env_manager.update_environment_vars(environment_reqs)
506
573
 
507
574
 
508
575