File: privs.t

package info (click to toggle)
percona-toolkit 3.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 68,916 kB
  • sloc: perl: 241,287; sql: 22,868; sh: 19,746; javascript: 6,799; makefile: 353; awk: 38; python: 30; sed: 1
file content (198 lines) | stat: -rw-r--r-- 6,431 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/env perl

BEGIN {
   die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
      unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
   unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
};

use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use Test::More;

# Hostnames make testing less accurate.  Tests need to see
# that such-and-such happened on specific slave hosts, but
# the sandbox servers are all on one host so all slaves have
# the same hostname.
$ENV{PERCONA_TOOLKIT_TEST_USE_DSN_NAMES} = 1;

use Data::Dumper;
use PerconaTest;
use Sandbox;

# Fix @INC because pt-table-checksum uses subclass OobNibbleIterator.
require "$trunk/bin/pt-table-checksum";

my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $master_dbh = $sb->get_dbh_for('master');
my $slave1_dbh = $sb->get_dbh_for('slave1');
my $slave2_dbh = $sb->get_dbh_for('slave2');

if ( !$master_dbh ) {
   plan skip_all => 'Cannot connect to sandbox master';
}
elsif ( !$slave1_dbh ) {
   plan skip_all => 'Cannot connect to sandbox slave1';
}
elsif ( !@{$master_dbh->selectall_arrayref("show databases like 'sakila'")} ) {
   plan skip_all => 'sakila database is not loaded';
}

# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the tool will die.
my $master_dsn = 'h=127.1,P=12345';
my @args       = (qw(--set-vars innodb_lock_wait_timeout=3));
my $row;
my $output;
my $exit_status;
my $sample  = "t/pt-table-checksum/samples/";

# ############################################################################
# Should always create schema and tables with IF NOT EXISTS
# https://bugs.launchpad.net/percona-toolkit/+bug/950294
# ############################################################################

$master_dbh->do("DROP DATABASE IF EXISTS percona");
diag(`/tmp/12345/use -u root < $trunk/t/lib/samples/ro-checksum-user.sql 2>/dev/null`);
PerconaTest::wait_for_table($slave2_dbh, "mysql.user", "user='ro_checksum_user'");

$output = output(
   sub { $exit_status = pt_table_checksum::main(@args,
      "$master_dsn,u=ro_checksum_user,p=msandbox",
      qw(--recursion-method none)
   ) },
   stderr => 1,
);

like(
   $output,
   qr/\Qdatabase percona does not exist and it cannot be created automatically/,
   "Error if percona db doesn't exist and user can't create it",
);

$output = output(
   sub { pt_table_checksum::main(@args,
      "$master_dsn,u=ro_checksum_user,p=msandbox",
      qw(--recursion-method none --no-create-replicate-table)
   ) },
   stderr => 1,
);

like(
   $output,
   qr/\Qdatabase percona does not exist and --no-create-replicate-table was/,
   "Error if percona db doesn't exist and --no-create-replicate-table",
);

diag(`/tmp/12345/use -u root -e "drop user 'ro_checksum_user'\@'%'"`);
wait_until(
   sub {
      my $rows=$slave2_dbh->selectall_arrayref("SELECT user FROM mysql.user");
      return !grep { ($_->[0] || '') eq 'ro_checksum_user' } @$rows;
   }
);

# ############################################################################
# --recursion-method=none to avoid SHOW SLAVE HOSTS
# https://bugs.launchpad.net/percona-toolkit/+bug/987694
# ############################################################################

# Create percona.checksums because ro_checksum_user doesn't have the privs.
pt_table_checksum::main(@args,
   "$master_dsn,u=msandbox,p=msandbox",
   qw(-t sakila.country --quiet --quiet));

diag(`/tmp/12345/use -u root < $trunk/t/lib/samples/ro-checksum-user.sql 2>/dev/null`);
PerconaTest::wait_for_table($slave1_dbh, "mysql.tables_priv", "user='ro_checksum_user'");

$output = output(
   sub { $exit_status = pt_table_checksum::main(@args,
      "$master_dsn,u=ro_checksum_user,p=msandbox",
      # Comment out this line and the tests fail because ro_checksum_user
      # doesn't have privs to SHOW SLAVE HOSTS.  This proves that
      # --recursion-method none is working.
      qw(--recursion-method none --no-create-replicate-table)
   ) },
   stderr => 1,
);

is(
   $exit_status,
   0,
   "Read-only user (bug 987694): 0 exit"
);

like(
   $output,
   qr/ sakila.store$/m,
   "Read-only user (bug 987694): checksummed rows"
);

($output, $exit_status) = full_output(
   sub { pt_table_checksum::main(@args,
      "$master_dsn,u=ro_checksum_user,p=msandbox",
      qw(--recursion-method none)
   ) }
);

is(
   $exit_status,
   0,
   "No error if db exists on the master, can't CREATE DATABASE, --no-create-replicate-table was not specified, but the database does exist in all slaves"
);

diag(qx{/tmp/12345/use -u root -e 'DROP TABLE `percona`.`checksums`'});

($output, $exit_status) = full_output(
   sub { pt_table_checksum::main(@args,
      "$master_dsn,u=ro_checksum_user,p=msandbox",
      qw(--recursion-method none --no-create-replicate-table)
   ) },
);

like($output,
   qr/\Q--replicate table `percona`.`checksums` does not exist and --no/,
   "Error if checksums db doesn't exist and --no-create-replicate-table"
);

diag(`/tmp/12345/use -u root -e "drop user 'ro_checksum_user'\@'%'"`);
wait_until(
   sub {
      my $rows=$slave2_dbh->selectall_arrayref("SELECT user FROM mysql.user");
      return !grep { ($_->[0] || '') eq 'ro_checksum_user' } @$rows;
   }
);

# #############################################################################
# Bug 916168: bug in pt-table-checksum privileges check
# #############################################################################
diag(`/tmp/12345/use -u root < $trunk/t/pt-table-checksum/samples/privs-bug-916168.sql`);

$output = output(
   sub { $exit_status = pt_table_checksum::main(@args,
      "$master_dsn,u=test_user,p=foo", qw(-t sakila.country)) },
);

is(
   PerconaTest::count_checksum_results($output, 'rows'),
   109,
   "test_user privs work (bug 916168)"
);

diag(`/tmp/12345/use -u root -e "drop user 'test_user'\@'%'"`);
wait_until(
   sub {
      my $rows=$slave2_dbh->selectall_arrayref("SELECT user FROM mysql.user");
      return !grep { ($_->[0] || '') eq 'test_user' } @$rows;
   }
);

# #############################################################################
# Done.
# #############################################################################
$sb->wipe_clean($master_dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
done_testing;
exit;