~longbow/percona-pam-for-mysql/pamtest_py

« back to all changes in this revision

Viewing changes to percona_tests/xtrabackup_main/bug722638_test.py

  • Committer: Patrick Crews
  • Date: 2012-01-05 02:48:07 UTC
  • Revision ID: gleebix@gmail.com-20120105024807-iob2emmrylinos8d
Ported the last of the xtrabackup tests...huzzah \o/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
# -*- mode: python; indent-tabs-mode: nil; -*-
 
3
# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
4
#
 
5
# Copyright (C) 2011 Patrick Crews
 
6
#
 
7
#
 
8
# This program is free software; you can redistribute it and/or modify
 
9
# it under the terms of the GNU General Public License as published by
 
10
# the Free Software Foundation; either version 2 of the License, or
 
11
# (at your option) any later version.
 
12
#
 
13
# This program is distributed in the hope that it will be useful,
 
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
# GNU General Public License for more details.
 
17
#
 
18
# You should have received a copy of the GNU General Public License
 
19
# along with this program; if not, write to the Free Software
 
20
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
 
 
22
import os
 
23
import time
 
24
import shutil
 
25
import signal
 
26
import subprocess
 
27
 
 
28
from lib.util.mysqlBaseTestCase import mysqlBaseTestCase
 
29
 
 
30
server_requirements = [['--innodb-file-per-table']]
 
31
servers = []
 
32
server_manager = None
 
33
test_executor = None
 
34
# we explicitly use the --no-timestamp option
 
35
# here.  We will be using a generic / vanilla backup dir
 
36
backup_path = None
 
37
 
 
38
class basicTest(mysqlBaseTestCase):
 
39
 
 
40
    def setUp(self):
 
41
        master_server = servers[0] # assumption that this is 'master'
 
42
        backup_path = os.path.join(master_server.vardir, 'full_backup')
 
43
        # remove backup paths
 
44
        for del_path in [backup_path]:
 
45
            if os.path.exists(del_path):
 
46
                shutil.rmtree(del_path)
 
47
 
 
48
    def test_bug722638(self):
 
49
        self.servers = servers
 
50
        logging = test_executor.logging
 
51
        innobackupex = test_executor.system_manager.innobackupex_path
 
52
        xtrabackup = test_executor.system_manager.xtrabackup_path
 
53
        master_server = servers[0] # assumption that this is 'master'
 
54
        backup_path = os.path.join(master_server.vardir, 'full_backup')
 
55
        output_path = os.path.join(master_server.vardir, 'innobackupex.out')
 
56
        suspended_file = os.path.join(backup_path, 'xtrabackup_debug_sync')
 
57
        exec_path = os.path.dirname(innobackupex)
 
58
        
 
59
        # test to ensure we have a debug build
 
60
        cmd = "%s --help"
 
61
        retcode, output = self.execute_cmd(cmd, output_path, exec_path, True)
 
62
        if 'debug-sync' not in output:
 
63
            logging.warning("Requires --debug-sync support. Skipping test...")
 
64
            return
 
65
        else:
 
66
            # populate our server with a test bed
 
67
            queries = [ "CREATE TABLE t1(a INT) ENGINE=InnoDB"
 
68
                      , "INSERT INTO t1 VALUES (1), (2), (3)"
 
69
                      , "CREATE TABLE t2(a INT) ENGINE=InnoDB"
 
70
                      , "INSERT INTO t2 VALUES (1), (2), (3)"
 
71
                      , "CREATE TABLE t3(a INT) ENGINE=InnoDB"
 
72
                      , "INSERT INTO t3 VALUES (1), (2), (3)"
 
73
                      , "CREATE TABLE t4_old(a INT) ENGINE=InnoDB"
 
74
                      , "INSERT INTO t4_old VALUES (1), (2), (3)"
 
75
                      ]
 
76
            retcode, result = self.execute_queries(queries, master_server)
 
77
            self.assertEqual(retcode, 0, msg=result)
 
78
 
 
79
            # take a backup
 
80
            cmd = [ xtrabackup
 
81
                  , "--defaults-file=%s" %master_server.cnf_file
 
82
                  , "--datadir=%s" %master_server.datadir
 
83
                  , "--backup"
 
84
                  , "--target-dir=%s" %backup_path
 
85
                  , '--debug-sync="data_copy_thread_func"'
 
86
                  ]
 
87
            output_file = open(output_path,'w')
 
88
            xtrabackup_subproc = subprocess.Popen( cmd
 
89
                                                 , cwd=exec_path
 
90
                                                 , env=test_executor.working_environment
 
91
                                                 , stdout = output_file
 
92
                                                 , stderr = subprocess.STDOUT 
 
93
                                                 )
 
94
 
 
95
            # Wait for the xtrabackup_suspended file to be created
 
96
            timeout = 30
 
97
            decrement = 1
 
98
            while timeout and not os.path.exists(suspended_file):
 
99
                time.sleep(decrement)
 
100
                timeout -= decrement
 
101
 
 
102
            # Modify the original tables, then change space_ids by running DDL
 
103
            queries = [ "INSERT INTO t1 VALUES (4), (5), (6)"
 
104
                      , "DROP TABLE t1"
 
105
                      , "CREATE TABLE t1(a CHAR(1)) ENGINE=InnoDB"
 
106
                      , 'INSERT INTO t1 VALUES ("1"), ("2"), ("3")'
 
107
                      , "INSERT INTO t2 VALUES (4), (5), (6)"
 
108
                      , "ALTER TABLE t2 MODIFY a BIGINT"
 
109
                      , "INSERT INTO t2 VALUES (7), (8), (9)"
 
110
                      , "INSERT INTO t3 VALUES (4), (5), (6)"
 
111
                      , "TRUNCATE t3"
 
112
                      , "INSERT INTO t3 VALUES (7), (8), (9)"
 
113
                      , "INSERT INTO t4_old VALUES (4), (5), (6)"
 
114
                      , "ALTER TABLE t4_old RENAME t4"
 
115
                      , "INSERT INTO t4 VALUES (7), (8), (9)"
 
116
                      ]
 
117
            retcode, result = self.execute_queries(queries, master_server)
 
118
            self.assertEqual(retcode, 0, msg=result)
 
119
 
 
120
            #calculate_checksums
 
121
            orig_checksums = []
 
122
            for i in range(4):
 
123
                query = "CHECKSUM TABLE t%d" %(i+1)
 
124
                retcode, result = self.execute_query(query, master_server)
 
125
                self.assertEqual(retcode, 0, msg=result)
 
126
                orig_checksums.append(result)
 
127
           
 
128
            # Resume the xtrabackup process and remove the suspended file
 
129
            xtrabackup_subproc.send_signal(signal.SIGCONT)
 
130
 
 
131
            xtrabackup_subproc.wait()
 
132
            output_file.close()
 
133
            output_file = open(output_path,'r')
 
134
            output = ''.join(output_file.readlines())
 
135
            self.assertEqual(xtrabackup_subproc.returncode,0,msg="Xtrabackup: uh-oh >;)")
 
136
 
 
137
            # Clear our schema so we know the backup restored
 
138
            queries = [ "DROP SCHEMA test"
 
139
                      , "CREATE SCHEMA test"
 
140
                      ]
 
141
            retcode, result = self.execute_queries(queries,master_server)
 
142
            self.assertEqual(retcode, 0, result) 
 
143
        
 
144
            # prepare our main backup
 
145
            cmd = [ xtrabackup
 
146
                  , "--prepare"
 
147
                  , "--datadir=%s" %master_server.datadir
 
148
                  , "--use-memory=500M"
 
149
                  , "--target-dir=%s" %backup_path
 
150
                  ]
 
151
            cmd = " ".join(cmd)
 
152
            retcode, output = self.execute_cmd(cmd, output_path, exec_path, True)
 
153
            self.assertTrue(retcode==0,output)
 
154
 
 
155
            # do final prepare on main backup
 
156
            cmd = [ xtrabackup
 
157
                  , "--prepare"
 
158
                  , "--datadir=%s" %master_server.datadir
 
159
                  , "--use-memory=500M"
 
160
                  , "--target-dir=%s" %backup_path
 
161
                  ]
 
162
            cmd = " ".join(cmd)
 
163
            #retcode, output = self.execute_cmd(cmd, output_path, exec_path, True)
 
164
            #self.assertTrue(retcode==0,output)
 
165
 
 
166
            # stop our server
 
167
            master_server.stop()
 
168
           
 
169
            # remove some files
 
170
            clear_paths = [master_server.datadir
 
171
                          ,os.path.join(master_server.datadir,'test')
 
172
                          ]
 
173
            for clear_path in clear_paths:
 
174
                for file_name in os.listdir(clear_path):
 
175
                    if file_name.startswith('ib_logfile') or file_name == 'ibdata1' or file_name.endswith('.ibd'):
 
176
                        os.remove(os.path.join(clear_path,file_name))
 
177
        
 
178
            # copy our data files back
 
179
            for root, dirs, files in os.walk(backup_path):
 
180
                if files:
 
181
                    file_info = root.split(backup_path)[1]
 
182
                    for file_name in files:
 
183
                        # We do a quick check to make sure
 
184
                        # no names start with '/' as os.path
 
185
                        # throws a hissy when it sees such things
 
186
                        if file_info.startswith('/'):
 
187
                            file_info = file_info[1:]
 
188
                        if file_name.startswith('/'):
 
189
                            file_name = file_name[1:]
 
190
                        to_path = os.path.join(master_server.datadir
 
191
                                              , file_info
 
192
                                              , file_name)
 
193
                        new_dir = os.path.dirname(to_path)
 
194
                        try:
 
195
                           if not os.path.exists(new_dir):
 
196
                               os.makedirs(new_dir)
 
197
                        except OSError, e:
 
198
                            logging.error("Could not create directory: %s | %s" %(new_dir, e))
 
199
                        try:
 
200
                            shutil.copy(os.path.join(root,file_name),to_path)
 
201
                        except IOError, e:
 
202
                            logging.error( "ERROR:  Could not copy file: %s | %s" %(file_name, e))
 
203
 
 
204
            # restart server (and ensure it doesn't crash)
 
205
            master_server.start()
 
206
            self.assertTrue(master_server.status==1, 'Server failed restart from restored datadir...')
 
207
 
 
208
            query = "SHOW TABLES IN test"
 
209
            retcode, result = self.execute_query(query, master_server)
 
210
            logging.test_debug("%s: %s" %(query, result)) 
 
211
 
 
212
            #calculate_checksums
 
213
            for i in range(4):
 
214
                query = "CHECKSUM TABLE t%d" %(i+1)
 
215
                retcode, result = self.execute_query(query, master_server)
 
216
                self.assertEqual(retcode, 0, msg=result)
 
217
                self.assertEqual(result, orig_checksums[i], msg = "%s:  %s || %s" %(query, orig_checksums[i], result))
 
218
 
 
219
    def tearDown(self):
 
220
            server_manager.reset_servers(test_executor.name)
 
221
 
 
222