~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2011-02-22 06:12:02 UTC
  • mfrom: (2190.1.6 drizzle-build)
  • Revision ID: brian@tangent.org-20110222061202-k03czxykqy4x9hjs
List update, header fixes, multiple symbols, and David deletes some code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
# -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
3
# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
4
#
 
5
# Copyright (C) 2010 Patrick Crews
 
6
#
 
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
 
20
 
 
21
 
 
22
""" drizzled.py:  code to allow a serverManager
 
23
    to provision and start up a drizzled server object
 
24
    for test execution
 
25
 
 
26
"""
 
27
 
 
28
# imports
 
29
import os
 
30
 
 
31
class drizzleServer():
 
32
    """ represents a drizzle server, its possessions
 
33
        (datadir, ports, etc), and methods for controlling
 
34
        and querying it
 
35
 
 
36
        TODO: create a base server class that contains
 
37
              standard methods from which we can inherit
 
38
              Currently there are definitely methods / attr
 
39
              which are general
 
40
 
 
41
    """
 
42
 
 
43
    def __init__( self
 
44
                , name
 
45
                , server_manager
 
46
                , default_storage_engine
 
47
                , server_options
 
48
                , requester
 
49
                , workdir_root):
 
50
        self.skip_keys = [ 'server_manager'
 
51
                         , 'system_manager'
 
52
                         , 'dirset'
 
53
                         , 'preferred_base_port'
 
54
                         , 'no_secure_file_priv'
 
55
                         , 'secure_file_string'
 
56
                         , 'port_block'
 
57
                         ]
 
58
        self.debug = server_manager.debug
 
59
        self.verbose = server_manager.verbose
 
60
        self.initial_run = 1
 
61
        self.owner = requester
 
62
        self.server_options = server_options
 
63
        self.default_storage_engine = default_storage_engine
 
64
        self.server_manager = server_manager
 
65
        # We register with server_manager asap
 
66
        self.server_manager.log_server(self, requester)
 
67
 
 
68
        self.system_manager = self.server_manager.system_manager
 
69
        self.valgrind = self.system_manager.valgrind
 
70
        self.gdb = self.system_manager.gdb
 
71
        if self.valgrind:
 
72
            self.valgrind_time_buffer = 10
 
73
        else:
 
74
            self.valgrind_time_buffer = 1
 
75
        self.cmd_prefix = self.system_manager.cmd_prefix
 
76
        self.logging = self.system_manager.logging
 
77
        self.no_secure_file_priv = self.server_manager.no_secure_file_priv
 
78
        self.code_tree = self.system_manager.code_tree
 
79
        self.preferred_base_port = 9306
 
80
        self.name = name
 
81
        self.status = 0 # stopped, 1 = running
 
82
        self.tried_start = 0
 
83
        self.failed_test = 0 # was the last test a failure?  our state is suspect
 
84
        self.server_start_timeout = 60 * self.valgrind_time_buffer
 
85
 
 
86
        # Get our ports
 
87
        self.port_block = self.system_manager.port_manager.get_port_block( self.name
 
88
                                                                         , self.preferred_base_port
 
89
                                                                         , 5 )
 
90
        self.master_port = self.port_block[0]
 
91
        self.drizzle_tcp_port = self.port_block[1]
 
92
        self.mc_port = self.port_block[2]
 
93
        self.pbms_port = self.port_block[3]
 
94
        self.rabbitmq_node_port = self.port_block[4]
 
95
        
 
96
 
 
97
        # Generate our working directories
 
98
        self.dirset = { self.name : { 'var': {'std_data_ln':( os.path.join(self.code_tree.testdir,'std_data'))
 
99
                                             ,'log':None
 
100
                                             ,'run':None
 
101
                                             ,'tmp':None
 
102
                                             ,'master-data': {'local': { 'test':None
 
103
                                                                       , 'mysql':None
 
104
                                                                       }
 
105
                                                             }
 
106
                                             }  
 
107
                                    } 
 
108
                      }
 
109
        self.workdir = self.system_manager.create_dirset( workdir_root
 
110
                                                        , self.dirset)
 
111
        self.vardir = os.path.join(self.workdir,'var')
 
112
        self.tmpdir = os.path.join(self.vardir,'tmp')
 
113
        self.rundir = os.path.join(self.vardir,'run')
 
114
        self.logdir = os.path.join(self.vardir,'log')
 
115
        self.datadir = os.path.join(self.vardir,'master-data')
 
116
 
 
117
        self.error_log = os.path.join(self.logdir,('%s.err' %(self.name)))
 
118
        self.pid_file = os.path.join(self.rundir,('%s.pid' %(self.name)))
 
119
        self.socket_file = os.path.join(self.vardir, ('%s.sock' %(self.name)))
 
120
        self.timer_file = os.path.join(self.logdir,('timer'))
 
121
        self.snapshot_path = os.path.join(self.tmpdir,('snapshot_%s' %(self.master_port)))
 
122
        # We want to use --secure-file-priv = $vardir by default
 
123
        # but there are times / tools when we need to shut this off
 
124
        if self.no_secure_file_priv:
 
125
            self.secure_file_string = ''
 
126
        else:
 
127
            self.secure_file_string = "--secure-file-priv='%s'" %(self.vardir)
 
128
        self.user_string = '--user=root'
 
129
 
 
130
        # client files
 
131
        self.drizzledump = self.code_tree.drizzledump
 
132
        self.drizzle_client = self.code_tree.drizzle_client
 
133
        self.drizzleimport = self.code_tree.drizzleimport
 
134
        self.drizzleadmin = self.code_tree.drizzleadmin
 
135
        self.drizzleslap = self.code_tree.drizzleslap
 
136
        self.server_path = self.code_tree.drizzle_server
 
137
        self.drizzle_client_path = self.code_tree.drizzle_client
 
138
        self.schemawriter = self.code_tree.schemawriter
 
139
 
 
140
        self.initialize_databases()
 
141
        self.take_db_snapshot()
 
142
 
 
143
        if self.debug:
 
144
            self.logging.debug_class(self)
 
145
 
 
146
    def report(self):
 
147
        """ We print out some general useful info """
 
148
        report_values = [ 'name'
 
149
                        , 'master_port'
 
150
                        , 'drizzle_tcp_port'
 
151
                        , 'mc_port'
 
152
                        , 'pbms_port'
 
153
                        , 'rabbitmq_node_port'
 
154
                        , 'vardir'
 
155
                        , 'status'
 
156
                        ]
 
157
        self.logging.info("%s master server:" %(self.owner))
 
158
        for key in report_values:
 
159
          value = vars(self)[key] 
 
160
          self.logging.info("%s: %s" %(key.upper(), value))
 
161
 
 
162
    def get_start_cmd(self):
 
163
        """ Return the command string that will start up the server 
 
164
            as desired / intended
 
165
 
 
166
        """
 
167
 
 
168
        server_args = [ self.process_server_options()
 
169
                      , "--mysql-protocol.port=%d" %(self.master_port)
 
170
                      , "--mysql-protocol.connect-timeout=60"
 
171
                      , "--innodb.data-file-path=ibdata1:20M:autoextend"
 
172
                      , "--sort-buffer-size=256K"
 
173
                      , "--max-heap-table-size=1M"
 
174
                      , "--mysql-unix-socket-protocol.path=%s" %(self.socket_file)
 
175
                      , "--pid-file=%s" %(self.pid_file)
 
176
                      , "--drizzle-protocol.port=%d" %(self.drizzle_tcp_port)
 
177
                      , "--default-storage-engine=%s" %(self.default_storage_engine)
 
178
                      , "--datadir=%s" %(self.datadir)
 
179
                      , "--tmpdir=%s" %(self.tmpdir)
 
180
                      , self.secure_file_string
 
181
                      , self.user_string
 
182
                      ]
 
183
 
 
184
        if self.gdb:
 
185
            server_args.append('--gdb')
 
186
            return self.system_manager.handle_gdb_reqs(self, server_args)
 
187
        else:
 
188
            return "%s %s %s & " % ( self.cmd_prefix
 
189
                                   , self.server_path
 
190
                                   , " ".join(server_args)
 
191
                                   )
 
192
 
 
193
 
 
194
    def get_stop_cmd(self):
 
195
        """ Return the command that will shut us down """
 
196
        
 
197
        return "%s --user=root --port=%d --shutdown " %(self.drizzle_client_path, self.master_port)
 
198
           
 
199
 
 
200
    def get_ping_cmd(self):
 
201
        """Return the command string that will 
 
202
           ping / check if the server is alive 
 
203
 
 
204
        """
 
205
 
 
206
        return "%s --ping --port=%d --user=root" % (self.drizzle_client_path, self.master_port)
 
207
 
 
208
    def process_server_options(self):
 
209
        """Consume the list of options we have been passed.
 
210
           Return a string with them joined
 
211
 
 
212
        """
 
213
        
 
214
        return " ".join(self.server_options)
 
215
                  
 
216
    def initialize_databases(self):
 
217
        """ Call schemawriter to make db.opt files """
 
218
        databases = [ 'test'
 
219
                    , 'mysql'
 
220
                    ]
 
221
        for database in databases:
 
222
            db_path = os.path.join(self.datadir,'local',database,'db.opt')
 
223
            cmd = "%s %s %s" %(self.schemawriter, database, db_path)
 
224
            self.system_manager.execute_cmd(cmd)
 
225
 
 
226
    def take_db_snapshot(self):
 
227
        """ Take a snapshot of our vardir for quick restores """
 
228
       
 
229
        self.logging.info("Taking clean db snapshot...")
 
230
        if os.path.exists(self.snapshot_path):
 
231
            # We need to remove an existing path as python shutil
 
232
            # doesn't want an existing target
 
233
            self.system_manager.remove_dir(self.snapshot_path)
 
234
        self.system_manager.copy_dir(self.datadir, self.snapshot_path)
 
235
 
 
236
    def restore_snapshot(self):
 
237
        """ Restore from a stored snapshot """
 
238
        
 
239
        if self.verbose:
 
240
            self.logging.verbose("Restoring from db snapshot")
 
241
        if not os.path.exists(self.snapshot_path):
 
242
            self.logging.error("Could not find snapshot: %s" %(self.snapshot_path))
 
243
        self.system_manager.remove_dir(self.datadir)
 
244
        self.system_manager.copy_dir(self.snapshot_path, self.datadir)
 
245
 
 
246
    def cleanup(self):
 
247
        """ Cleanup - just free ports for now..."""
 
248
        self.system_manager.port_manager.free_ports(self.port_block)
 
249
 
 
250
    def set_server_options(self, server_options):
 
251
        """ We update our server_options to the new set """
 
252
        self.server_options = server_options
 
253
 
 
254
    def reset(self):
 
255
        """ Voodoo to reset ourselves """
 
256
        self.failed_test = 0
 
257
         
 
258
 
 
259
 
 
260
 
 
261