Skip to content

Commit d66b23b

Browse files
committed
Enable almost all TAP tests involving symlinks on Windows
Windows has junction points which function as symbolic links for directories. This patch introduces a new function TestLib::dir_symlink() which creates a junction point on Windows and a standard Unix type symbolic link elsewhere. The function TestLib::perl2host is also modified, first to use cygpath where it's available (e.g. msys2) and second to allow it to succeed if the gandparent directory exists but the parent does not. Given these changes the only symlink tests that need to be skipped on Windows are those related to permissions or to use of readlink. The relevant tests for pg_basebackup and pg_rewind are therefore adjusted accordingly. Andrew Dunstan, reviewed by Peter Eisentraut and Michael Paquier. Discussion: https://postgr.es/m/[email protected]
1 parent 932f9fb commit d66b23b

File tree

4 files changed

+218
-152
lines changed

4 files changed

+218
-152
lines changed

src/bin/pg_basebackup/t/010_pg_basebackup.pl

+147-133
Original file line numberDiff line numberDiff line change
@@ -211,87 +211,93 @@
211211
'pg_basebackup tar with long name fails');
212212
unlink "$pgdata/$superlongname";
213213

214-
# The following tests test symlinks. Windows doesn't have symlinks, so
215-
# skip on Windows.
214+
# The following tests are for symlinks.
215+
216+
# Move pg_replslot out of $pgdata and create a symlink to it.
217+
$node->stop;
218+
219+
# Set umask so test directories and files are created with group permissions
220+
umask(0027);
221+
222+
# Enable group permissions on PGDATA
223+
chmod_recursive("$pgdata", 0750, 0640);
224+
225+
rename("$pgdata/pg_replslot", "$tempdir/pg_replslot")
226+
or BAIL_OUT "could not move $pgdata/pg_replslot";
227+
dir_symlink("$tempdir/pg_replslot", "$pgdata/pg_replslot")
228+
or BAIL_OUT "could not symlink to $pgdata/pg_replslot";
229+
230+
$node->start;
231+
232+
# Create a temporary directory in the system location and symlink it
233+
# to our physical temp location. That way we can use shorter names
234+
# for the tablespace directories, which hopefully won't run afoul of
235+
# the 99 character length limit.
236+
my $shorter_tempdir = TestLib::tempdir_short . "/tempdir";
237+
dir_symlink "$tempdir", $shorter_tempdir;
238+
239+
mkdir "$tempdir/tblspc1";
240+
my $realTsDir = TestLib::perl2host("$shorter_tempdir/tblspc1");
241+
my $real_tempdir = TestLib::perl2host($tempdir);
242+
$node->safe_psql('postgres',
243+
"CREATE TABLESPACE tblspc1 LOCATION '$realTsDir';");
244+
$node->safe_psql('postgres',
245+
"CREATE TABLE test1 (a int) TABLESPACE tblspc1;");
246+
$node->command_ok(
247+
[ 'pg_basebackup', '-D', "$real_tempdir/tarbackup2", '-Ft' ],
248+
'tar format with tablespaces');
249+
ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
250+
my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
251+
is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
252+
rmtree("$tempdir/tarbackup2");
253+
254+
# Create an unlogged table to test that forks other than init are not copied.
255+
$node->safe_psql('postgres',
256+
'CREATE UNLOGGED TABLE tblspc1_unlogged (id int) TABLESPACE tblspc1;');
257+
258+
my $tblspc1UnloggedPath = $node->safe_psql('postgres',
259+
q{select pg_relation_filepath('tblspc1_unlogged')});
260+
261+
# Make sure main and init forks exist
262+
ok( -f "$pgdata/${tblspc1UnloggedPath}_init",
263+
'unlogged init fork in tablespace');
264+
ok(-f "$pgdata/$tblspc1UnloggedPath", 'unlogged main fork in tablespace');
265+
266+
# Create files that look like temporary relations to ensure they are ignored
267+
# in a tablespace.
268+
@tempRelationFiles = qw(t888_888 t888888_888888_vm.1);
269+
my $tblSpc1Id = basename(
270+
dirname(
271+
dirname(
272+
$node->safe_psql(
273+
'postgres', q{select pg_relation_filepath('test1')}))));
274+
275+
foreach my $filename (@tempRelationFiles)
276+
{
277+
append_to_file(
278+
"$shorter_tempdir/tblspc1/$tblSpc1Id/$postgresOid/$filename",
279+
'TEMP_RELATION');
280+
}
281+
282+
$node->command_fails(
283+
[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
284+
'plain format with tablespaces fails without tablespace mapping');
285+
286+
$node->command_ok(
287+
[
288+
'pg_basebackup', '-D',
289+
"$tempdir/backup1", '-Fp',
290+
"-T$realTsDir=$real_tempdir/tbackup/tblspc1"
291+
],
292+
'plain format with tablespaces succeeds with tablespace mapping');
293+
ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
294+
295+
# This symlink check is not supported on Windows as -l
296+
# doesn't work with junctions
216297
SKIP:
217298
{
218-
skip "symlinks not supported on Windows", 18 if ($windows_os);
219-
220-
# Move pg_replslot out of $pgdata and create a symlink to it.
221-
$node->stop;
222-
223-
# Set umask so test directories and files are created with group permissions
224-
umask(0027);
225-
226-
# Enable group permissions on PGDATA
227-
chmod_recursive("$pgdata", 0750, 0640);
228-
229-
rename("$pgdata/pg_replslot", "$tempdir/pg_replslot")
230-
or BAIL_OUT "could not move $pgdata/pg_replslot";
231-
symlink("$tempdir/pg_replslot", "$pgdata/pg_replslot")
232-
or BAIL_OUT "could not symlink to $pgdata/pg_replslot";
233-
234-
$node->start;
235-
236-
# Create a temporary directory in the system location and symlink it
237-
# to our physical temp location. That way we can use shorter names
238-
# for the tablespace directories, which hopefully won't run afoul of
239-
# the 99 character length limit.
240-
my $shorter_tempdir = TestLib::tempdir_short . "/tempdir";
241-
symlink "$tempdir", $shorter_tempdir;
242-
243-
mkdir "$tempdir/tblspc1";
244-
$node->safe_psql('postgres',
245-
"CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';");
246-
$node->safe_psql('postgres',
247-
"CREATE TABLE test1 (a int) TABLESPACE tblspc1;");
248-
$node->command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
249-
'tar format with tablespaces');
250-
ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
251-
my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
252-
is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
253-
rmtree("$tempdir/tarbackup2");
254-
255-
# Create an unlogged table to test that forks other than init are not copied.
256-
$node->safe_psql('postgres',
257-
'CREATE UNLOGGED TABLE tblspc1_unlogged (id int) TABLESPACE tblspc1;'
258-
);
259-
260-
my $tblspc1UnloggedPath = $node->safe_psql('postgres',
261-
q{select pg_relation_filepath('tblspc1_unlogged')});
262-
263-
# Make sure main and init forks exist
264-
ok( -f "$pgdata/${tblspc1UnloggedPath}_init",
265-
'unlogged init fork in tablespace');
266-
ok(-f "$pgdata/$tblspc1UnloggedPath", 'unlogged main fork in tablespace');
267-
268-
# Create files that look like temporary relations to ensure they are ignored
269-
# in a tablespace.
270-
my @tempRelationFiles = qw(t888_888 t888888_888888_vm.1);
271-
my $tblSpc1Id = basename(
272-
dirname(
273-
dirname(
274-
$node->safe_psql(
275-
'postgres', q{select pg_relation_filepath('test1')}))));
276-
277-
foreach my $filename (@tempRelationFiles)
278-
{
279-
append_to_file(
280-
"$shorter_tempdir/tblspc1/$tblSpc1Id/$postgresOid/$filename",
281-
'TEMP_RELATION');
282-
}
283-
284-
$node->command_fails(
285-
[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
286-
'plain format with tablespaces fails without tablespace mapping');
287-
288-
$node->command_ok(
289-
[
290-
'pg_basebackup', '-D', "$tempdir/backup1", '-Fp',
291-
"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1"
292-
],
293-
'plain format with tablespaces succeeds with tablespace mapping');
294-
ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
299+
skip "symlink check not implemented on Windows", 1
300+
if ($windows_os);
295301
opendir(my $dh, "$pgdata/pg_tblspc") or die;
296302
ok( ( grep {
297303
-l "$tempdir/backup1/pg_tblspc/$_"
@@ -300,65 +306,73 @@
300306
} readdir($dh)),
301307
"tablespace symlink was updated");
302308
closedir $dh;
309+
}
310+
311+
# Group access should be enabled on all backup files
312+
SKIP:
313+
{
314+
skip "unix-style permissions not supported on Windows", 1
315+
if ($windows_os);
303316

304-
# Group access should be enabled on all backup files
305317
ok(check_mode_recursive("$tempdir/backup1", 0750, 0640),
306318
"check backup dir permissions");
319+
}
320+
321+
# Unlogged relation forks other than init should not be copied
322+
my ($tblspc1UnloggedBackupPath) =
323+
$tblspc1UnloggedPath =~ /[^\/]*\/[^\/]*\/[^\/]*$/g;
324+
325+
ok(-f "$tempdir/tbackup/tblspc1/${tblspc1UnloggedBackupPath}_init",
326+
'unlogged init fork in tablespace backup');
327+
ok(!-f "$tempdir/tbackup/tblspc1/$tblspc1UnloggedBackupPath",
328+
'unlogged main fork not in tablespace backup');
307329

308-
# Unlogged relation forks other than init should not be copied
309-
my ($tblspc1UnloggedBackupPath) =
310-
$tblspc1UnloggedPath =~ /[^\/]*\/[^\/]*\/[^\/]*$/g;
311-
312-
ok(-f "$tempdir/tbackup/tblspc1/${tblspc1UnloggedBackupPath}_init",
313-
'unlogged init fork in tablespace backup');
314-
ok(!-f "$tempdir/tbackup/tblspc1/$tblspc1UnloggedBackupPath",
315-
'unlogged main fork not in tablespace backup');
316-
317-
# Temp relations should not be copied.
318-
foreach my $filename (@tempRelationFiles)
319-
{
320-
ok( !-f "$tempdir/tbackup/tblspc1/$tblSpc1Id/$postgresOid/$filename",
321-
"[tblspc1]/$postgresOid/$filename not copied");
322-
323-
# Also remove temp relation files or tablespace drop will fail.
324-
my $filepath =
325-
"$shorter_tempdir/tblspc1/$tblSpc1Id/$postgresOid/$filename";
326-
327-
unlink($filepath)
328-
or BAIL_OUT("unable to unlink $filepath");
329-
}
330-
331-
ok( -d "$tempdir/backup1/pg_replslot",
332-
'pg_replslot symlink copied as directory');
333-
rmtree("$tempdir/backup1");
334-
335-
mkdir "$tempdir/tbl=spc2";
336-
$node->safe_psql('postgres', "DROP TABLE test1;");
337-
$node->safe_psql('postgres', "DROP TABLE tblspc1_unlogged;");
338-
$node->safe_psql('postgres', "DROP TABLESPACE tblspc1;");
339-
$node->safe_psql('postgres',
340-
"CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';");
341-
$node->command_ok(
342-
[
343-
'pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
344-
"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2"
345-
],
346-
'mapping tablespace with = sign in path');
347-
ok(-d "$tempdir/tbackup/tbl=spc2",
348-
'tablespace with = sign was relocated');
349-
$node->safe_psql('postgres', "DROP TABLESPACE tblspc2;");
350-
rmtree("$tempdir/backup3");
351-
352-
mkdir "$tempdir/$superlongname";
353-
$node->safe_psql('postgres',
354-
"CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';");
355-
$node->command_ok(
356-
[ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
357-
'pg_basebackup tar with long symlink target');
358-
$node->safe_psql('postgres', "DROP TABLESPACE tblspc3;");
359-
rmtree("$tempdir/tarbackup_l3");
330+
# Temp relations should not be copied.
331+
foreach my $filename (@tempRelationFiles)
332+
{
333+
ok(!-f "$tempdir/tbackup/tblspc1/$tblSpc1Id/$postgresOid/$filename",
334+
"[tblspc1]/$postgresOid/$filename not copied");
335+
336+
# Also remove temp relation files or tablespace drop will fail.
337+
my $filepath =
338+
"$shorter_tempdir/tblspc1/$tblSpc1Id/$postgresOid/$filename";
339+
340+
unlink($filepath)
341+
or BAIL_OUT("unable to unlink $filepath");
360342
}
361343

344+
ok( -d "$tempdir/backup1/pg_replslot",
345+
'pg_replslot symlink copied as directory');
346+
rmtree("$tempdir/backup1");
347+
348+
mkdir "$tempdir/tbl=spc2";
349+
$realTsDir = TestLib::perl2host("$shorter_tempdir/tbl=spc2");
350+
$node->safe_psql('postgres', "DROP TABLE test1;");
351+
$node->safe_psql('postgres', "DROP TABLE tblspc1_unlogged;");
352+
$node->safe_psql('postgres', "DROP TABLESPACE tblspc1;");
353+
$node->safe_psql('postgres',
354+
"CREATE TABLESPACE tblspc2 LOCATION '$realTsDir';");
355+
$realTsDir =~ s/=/\\=/;
356+
$node->command_ok(
357+
[
358+
'pg_basebackup', '-D',
359+
"$tempdir/backup3", '-Fp',
360+
"-T$realTsDir=$real_tempdir/tbackup/tbl\\=spc2"
361+
],
362+
'mapping tablespace with = sign in path');
363+
ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
364+
$node->safe_psql('postgres', "DROP TABLESPACE tblspc2;");
365+
rmtree("$tempdir/backup3");
366+
367+
mkdir "$tempdir/$superlongname";
368+
$realTsDir = TestLib::perl2host("$shorter_tempdir/$superlongname");
369+
$node->safe_psql('postgres',
370+
"CREATE TABLESPACE tblspc3 LOCATION '$realTsDir';");
371+
$node->command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
372+
'pg_basebackup tar with long symlink target');
373+
$node->safe_psql('postgres', "DROP TABLESPACE tblspc3;");
374+
rmtree("$tempdir/tarbackup_l3");
375+
362376
$node->command_ok([ 'pg_basebackup', '-D', "$tempdir/backupR", '-R' ],
363377
'pg_basebackup -R runs');
364378
ok(-f "$tempdir/backupR/postgresql.auto.conf", 'postgresql.auto.conf exists');
@@ -496,7 +510,7 @@
496510

497511
# set page header and block sizes
498512
my $pageheader_size = 24;
499-
my $block_size = $node->safe_psql('postgres', 'SHOW block_size;');
513+
my $block_size = $node->safe_psql('postgres', 'SHOW block_size;');
500514

501515
# induce corruption
502516
system_or_bail 'pg_ctl', '-D', $pgdata, 'stop';

src/bin/pg_dump/t/010_dump_connstr.pl

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use TestLib;
66
use Test::More;
77

8-
if ($^O eq 'msys' && `uname -or` =~ /^[2-9].*Msys/)
8+
if ($TestLib::is_msys2)
99
{
1010
plan skip_all => 'High bit name tests fail on Msys2';
1111
}
@@ -27,7 +27,7 @@
2727
# The odds of finding something interesting by testing all ASCII letters
2828
# seem too small to justify the cycles of testing a fifth name.
2929
my $dbname1 =
30-
'regression'
30+
'regression'
3131
. generate_ascii_string(1, 9)
3232
. generate_ascii_string(11, 12)
3333
. generate_ascii_string(14, 33)

src/bin/pg_rewind/t/004_pg_xlog_symlink.pl

+2-11
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,7 @@
66
use File::Copy;
77
use File::Path qw(rmtree);
88
use TestLib;
9-
use Test::More;
10-
if ($windows_os)
11-
{
12-
plan skip_all => 'symlinks not supported on Windows';
13-
exit;
14-
}
15-
else
16-
{
17-
plan tests => 5;
18-
}
9+
use Test::More tests => 5;
1910

2011
use FindBin;
2112
use lib $FindBin::RealBin;
@@ -36,7 +27,7 @@ sub run_test
3627
# turn pg_wal into a symlink
3728
print("moving $test_primary_datadir/pg_wal to $primary_xlogdir\n");
3829
move("$test_primary_datadir/pg_wal", $primary_xlogdir) or die;
39-
symlink($primary_xlogdir, "$test_primary_datadir/pg_wal") or die;
30+
dir_symlink($primary_xlogdir, "$test_primary_datadir/pg_wal") or die;
4031

4132
RewindTest::start_primary();
4233

0 commit comments

Comments
 (0)