|
2 | 2 | use warnings; |
3 | 3 | use Cwd; |
4 | 4 | use Config; |
| 5 | +use PostgresNode; |
5 | 6 | use TestLib; |
6 | 7 | use Test::More tests => 51; |
7 | 8 |
|
8 | 9 | program_help_ok('pg_basebackup'); |
9 | 10 | program_version_ok('pg_basebackup'); |
10 | 11 | program_options_handling_ok('pg_basebackup'); |
11 | 12 |
|
12 | | -my $tempdir = tempdir; |
13 | | -start_test_server $tempdir; |
| 13 | +my $tempdir = TestLib::tempdir; |
14 | 14 |
|
15 | | -command_fails(['pg_basebackup'], |
| 15 | +my $node = get_new_node(); |
| 16 | + |
| 17 | +# Initialize node without replication settings |
| 18 | +$node->init(hba_permit_replication => 0); |
| 19 | +$node->start; |
| 20 | +my $pgdata = $node->data_dir; |
| 21 | + |
| 22 | +$node->command_fails(['pg_basebackup'], |
16 | 23 | 'pg_basebackup needs target directory specified'); |
17 | | -command_fails( |
| 24 | +$node->command_fails( |
18 | 25 | [ 'pg_basebackup', '-D', "$tempdir/backup" ], |
19 | 26 | 'pg_basebackup fails because of hba'); |
20 | 27 |
|
|
26 | 33 | close BADCHARS; |
27 | 34 | } |
28 | 35 |
|
29 | | -configure_hba_for_replication "$tempdir/pgdata"; |
30 | | -system_or_bail 'pg_ctl', '-D', "$tempdir/pgdata", 'reload'; |
| 36 | +$node->set_replication_conf(); |
| 37 | +system_or_bail 'pg_ctl', '-D', $pgdata, 'reload'; |
31 | 38 |
|
32 | | -command_fails( |
| 39 | +$node->command_fails( |
33 | 40 | [ 'pg_basebackup', '-D', "$tempdir/backup" ], |
34 | 41 | 'pg_basebackup fails because of WAL configuration'); |
35 | 42 |
|
36 | | -open CONF, ">>$tempdir/pgdata/postgresql.conf"; |
| 43 | +open CONF, ">>$pgdata/postgresql.conf"; |
37 | 44 | print CONF "max_replication_slots = 10\n"; |
38 | 45 | print CONF "max_wal_senders = 10\n"; |
39 | 46 | print CONF "wal_level = archive\n"; |
40 | 47 | close CONF; |
41 | | -restart_test_server; |
| 48 | +$node->restart; |
42 | 49 |
|
43 | | -command_ok([ 'pg_basebackup', '-D', "$tempdir/backup" ], |
| 50 | +$node->command_ok([ 'pg_basebackup', '-D', "$tempdir/backup" ], |
44 | 51 | 'pg_basebackup runs'); |
45 | 52 | ok(-f "$tempdir/backup/PG_VERSION", 'backup was created'); |
46 | 53 |
|
47 | | -is_deeply([sort(slurp_dir("$tempdir/backup/pg_xlog/"))], |
48 | | - [sort qw(. .. archive_status)], |
49 | | - 'no WAL files copied'); |
| 54 | +is_deeply( |
| 55 | + [ sort(slurp_dir("$tempdir/backup/pg_xlog/")) ], |
| 56 | + [ sort qw(. .. archive_status) ], |
| 57 | + 'no WAL files copied'); |
50 | 58 |
|
51 | | -command_ok( |
| 59 | +$node->command_ok( |
52 | 60 | [ 'pg_basebackup', '-D', "$tempdir/backup2", '--xlogdir', |
53 | 61 | "$tempdir/xlog2" ], |
54 | 62 | 'separate xlog directory'); |
55 | 63 | ok(-f "$tempdir/backup2/PG_VERSION", 'backup was created'); |
56 | 64 | ok(-d "$tempdir/xlog2/", 'xlog directory was created'); |
57 | 65 |
|
58 | | -command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup", '-Ft' ], |
| 66 | +$node->command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup", '-Ft' ], |
59 | 67 | 'tar format'); |
60 | 68 | ok(-f "$tempdir/tarbackup/base.tar", 'backup tar was created'); |
61 | 69 |
|
62 | | -command_fails( |
| 70 | +$node->command_fails( |
63 | 71 | [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ], |
64 | 72 | '-T with empty old directory fails'); |
65 | | -command_fails( |
| 73 | +$node->command_fails( |
66 | 74 | [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ], |
67 | 75 | '-T with empty new directory fails'); |
68 | | -command_fails( |
| 76 | +$node->command_fails( |
69 | 77 | [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', |
70 | 78 | "-T/foo=/bar=/baz" ], |
71 | 79 | '-T with multiple = fails'); |
72 | | -command_fails( |
| 80 | +$node->command_fails( |
73 | 81 | [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ], |
74 | 82 | '-T with old directory not absolute fails'); |
75 | | -command_fails( |
| 83 | +$node->command_fails( |
76 | 84 | [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ], |
77 | 85 | '-T with new directory not absolute fails'); |
78 | | -command_fails( |
| 86 | +$node->command_fails( |
79 | 87 | [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ], |
80 | 88 | '-T with invalid format fails'); |
81 | 89 |
|
82 | 90 | # Tar format doesn't support filenames longer than 100 bytes. |
83 | 91 | my $superlongname = "superlongname_" . ("x" x 100); |
84 | | -my $superlongpath = "$tempdir/pgdata/$superlongname"; |
| 92 | +my $superlongpath = "$pgdata/$superlongname"; |
85 | 93 |
|
86 | 94 | open FILE, ">$superlongpath" or die "unable to create file $superlongpath"; |
87 | 95 | close FILE; |
88 | | -command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ], |
| 96 | +$node->command_fails( |
| 97 | + [ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ], |
89 | 98 | 'pg_basebackup tar with long name fails'); |
90 | | -unlink "$tempdir/pgdata/$superlongname"; |
| 99 | +unlink "$pgdata/$superlongname"; |
91 | 100 |
|
92 | 101 | # The following tests test symlinks. Windows doesn't have symlinks, so |
93 | 102 | # skip on Windows. |
94 | | -SKIP: { |
95 | | - skip "symlinks not supported on Windows", 10 if ($windows_os); |
| 103 | +SKIP: |
| 104 | +{ |
| 105 | + skip "symlinks not supported on Windows", 10 if ($windows_os); |
96 | 106 |
|
97 | 107 | # Create a temporary directory in the system location and symlink it |
98 | 108 | # to our physical temp location. That way we can use shorter names |
99 | 109 | # for the tablespace directories, which hopefully won't run afoul of |
100 | 110 | # the 99 character length limit. |
101 | | - my $shorter_tempdir = tempdir_short . "/tempdir"; |
| 111 | + my $shorter_tempdir = TestLib::tempdir_short . "/tempdir"; |
102 | 112 | symlink "$tempdir", $shorter_tempdir; |
103 | 113 |
|
104 | 114 | mkdir "$tempdir/tblspc1"; |
105 | | - psql 'postgres', |
106 | | - "CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';"; |
107 | | - psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;"; |
108 | | - command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ], |
109 | | - 'tar format with tablespaces'); |
| 115 | + $node->psql('postgres', |
| 116 | + "CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';"); |
| 117 | + $node->psql('postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;"); |
| 118 | + $node->command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ], |
| 119 | + 'tar format with tablespaces'); |
110 | 120 | ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created'); |
111 | 121 | my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar"; |
112 | 122 | is(scalar(@tblspc_tars), 1, 'one tablespace tar was created'); |
113 | 123 |
|
114 | | - command_fails( |
| 124 | + $node->command_fails( |
115 | 125 | [ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ], |
116 | 126 | 'plain format with tablespaces fails without tablespace mapping'); |
117 | 127 |
|
118 | | - command_ok( |
| 128 | + $node->command_ok( |
119 | 129 | [ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp', |
120 | 130 | "-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ], |
121 | 131 | 'plain format with tablespaces succeeds with tablespace mapping'); |
122 | 132 | ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated'); |
123 | | - opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die; |
| 133 | + opendir(my $dh, "$pgdata/pg_tblspc") or die; |
124 | 134 | ok( ( grep { |
125 | | - -l "$tempdir/backup1/pg_tblspc/$_" |
126 | | - and readlink "$tempdir/backup1/pg_tblspc/$_" eq |
127 | | - "$tempdir/tbackup/tblspc1" |
128 | | - } readdir($dh)), |
| 135 | + -l "$tempdir/backup1/pg_tblspc/$_" |
| 136 | + and readlink "$tempdir/backup1/pg_tblspc/$_" eq |
| 137 | + "$tempdir/tbackup/tblspc1" |
| 138 | + } readdir($dh)), |
129 | 139 | "tablespace symlink was updated"); |
130 | 140 | closedir $dh; |
131 | 141 |
|
132 | 142 | mkdir "$tempdir/tbl=spc2"; |
133 | | - psql 'postgres', "DROP TABLE test1;"; |
134 | | - psql 'postgres', "DROP TABLESPACE tblspc1;"; |
135 | | - psql 'postgres', |
136 | | - "CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';"; |
137 | | - command_ok( |
| 143 | + $node->psql('postgres', "DROP TABLE test1;"); |
| 144 | + $node->psql('postgres', "DROP TABLESPACE tblspc1;"); |
| 145 | + $node->psql('postgres', |
| 146 | + "CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';"); |
| 147 | + $node->command_ok( |
138 | 148 | [ 'pg_basebackup', '-D', "$tempdir/backup3", '-Fp', |
139 | 149 | "-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ], |
140 | 150 | 'mapping tablespace with = sign in path'); |
141 | | - ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated'); |
142 | | - psql 'postgres', "DROP TABLESPACE tblspc2;"; |
| 151 | + ok(-d "$tempdir/tbackup/tbl=spc2", |
| 152 | + 'tablespace with = sign was relocated'); |
| 153 | + $node->psql('postgres', "DROP TABLESPACE tblspc2;"); |
143 | 154 |
|
144 | 155 | mkdir "$tempdir/$superlongname"; |
145 | | - psql 'postgres', |
146 | | - "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';"; |
147 | | - command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ], |
148 | | - 'pg_basebackup tar with long symlink target'); |
149 | | - psql 'postgres', "DROP TABLESPACE tblspc3;"; |
| 156 | + $node->psql('postgres', |
| 157 | + "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';"); |
| 158 | + $node->command_ok( |
| 159 | + [ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ], |
| 160 | + 'pg_basebackup tar with long symlink target'); |
| 161 | + $node->psql('postgres', "DROP TABLESPACE tblspc3;"); |
150 | 162 | } |
151 | 163 |
|
152 | | -command_ok([ 'pg_basebackup', '-D', "$tempdir/backupR", '-R' ], |
| 164 | +$node->command_ok([ 'pg_basebackup', '-D', "$tempdir/backupR", '-R' ], |
153 | 165 | 'pg_basebackup -R runs'); |
154 | 166 | ok(-f "$tempdir/backupR/recovery.conf", 'recovery.conf was created'); |
155 | 167 | my $recovery_conf = slurp_file "$tempdir/backupR/recovery.conf"; |
| 168 | + |
156 | 169 | # using a character class for the final "'" here works around an apparent |
157 | 170 | # bug in several version of the Msys DTK perl |
158 | | -like($recovery_conf, qr/^standby_mode = 'on[']$/m, 'recovery.conf sets standby_mode'); |
159 | | -like($recovery_conf, qr/^primary_conninfo = '.*port=$ENV{PGPORT}.*'$/m, 'recovery.conf sets primary_conninfo'); |
160 | | - |
161 | | -command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxf", '-X', 'fetch' ], |
| 171 | +like( |
| 172 | + $recovery_conf, |
| 173 | + qr/^standby_mode = 'on[']$/m, |
| 174 | + 'recovery.conf sets standby_mode'); |
| 175 | +like( |
| 176 | + $recovery_conf, |
| 177 | + qr/^primary_conninfo = '.*port=$ENV{PGPORT}.*'$/m, |
| 178 | + 'recovery.conf sets primary_conninfo'); |
| 179 | + |
| 180 | +$node->command_ok( |
| 181 | + [ 'pg_basebackup', '-D', "$tempdir/backupxf", '-X', 'fetch' ], |
162 | 182 | 'pg_basebackup -X fetch runs'); |
163 | | -ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_xlog")), 'WAL files copied'); |
164 | | -command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs", '-X', 'stream' ], |
| 183 | +ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_xlog")), |
| 184 | + 'WAL files copied'); |
| 185 | +$node->command_ok( |
| 186 | + [ 'pg_basebackup', '-D', "$tempdir/backupxs", '-X', 'stream' ], |
165 | 187 | 'pg_basebackup -X stream runs'); |
166 | | -ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_xlog")), 'WAL files copied'); |
| 188 | +ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_xlog")), |
| 189 | + 'WAL files copied'); |
167 | 190 |
|
168 | | -command_fails([ 'pg_basebackup', '-D', "$tempdir/fail", '-S', 'slot1' ], |
| 191 | +$node->command_fails( |
| 192 | + [ 'pg_basebackup', '-D', "$tempdir/fail", '-S', 'slot1' ], |
169 | 193 | 'pg_basebackup with replication slot fails without -X stream'); |
170 | | -command_fails([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_fail", '-X', 'stream', '-S', 'slot1' ], |
| 194 | +$node->command_fails( |
| 195 | + [ 'pg_basebackup', '-D', |
| 196 | + "$tempdir/backupxs_sl_fail", '-X', |
| 197 | + 'stream', '-S', |
| 198 | + 'slot1' ], |
171 | 199 | 'pg_basebackup fails with nonexistent replication slot'); |
172 | 200 |
|
173 | | -psql 'postgres', q{SELECT * FROM pg_create_physical_replication_slot('slot1')}; |
174 | | -my $lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'}; |
| 201 | +$node->psql('postgres', |
| 202 | + q{SELECT * FROM pg_create_physical_replication_slot('slot1')}); |
| 203 | +my $lsn = $node->psql('postgres', |
| 204 | + q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'} |
| 205 | +); |
175 | 206 | is($lsn, '', 'restart LSN of new slot is null'); |
176 | | -command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl", '-X', 'stream', '-S', 'slot1' ], |
| 207 | +$node->command_ok( |
| 208 | + [ 'pg_basebackup', '-D', "$tempdir/backupxs_sl", '-X', |
| 209 | + 'stream', '-S', 'slot1' ], |
177 | 210 | 'pg_basebackup -X stream with replication slot runs'); |
178 | | -$lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'}; |
| 211 | +$lsn = $node->psql('postgres', |
| 212 | + q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'} |
| 213 | +); |
179 | 214 | like($lsn, qr!^0/[0-9A-Z]{7,8}$!, 'restart LSN of slot has advanced'); |
180 | 215 |
|
181 | | -command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_R", '-X', 'stream', '-S', 'slot1', '-R' ], |
| 216 | +$node->command_ok( |
| 217 | + [ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_R", '-X', |
| 218 | + 'stream', '-S', 'slot1', '-R' ], |
182 | 219 | 'pg_basebackup with replication slot and -R runs'); |
183 | | -like(slurp_file("$tempdir/backupxs_sl_R/recovery.conf"), |
184 | | - qr/^primary_slot_name = 'slot1'$/m, |
185 | | - 'recovery.conf sets primary_slot_name'); |
| 220 | +like( |
| 221 | + slurp_file("$tempdir/backupxs_sl_R/recovery.conf"), |
| 222 | + qr/^primary_slot_name = 'slot1'$/m, |
| 223 | + 'recovery.conf sets primary_slot_name'); |
0 commit comments