1use strict; 2use warnings; 3 4use PostgresNode; 5use TestLib; 6use Test::More; 7 8if ($^O eq 'msys' && `uname -or` =~ /^[2-9].*Msys/) 9{ 10 plan skip_all => 'High bit name tests fail on Msys2'; 11} 12else 13{ 14 plan tests => 14; 15} 16 17# We're going to use byte sequences that aren't valid UTF-8 strings. Use 18# LATIN1, which accepts any byte and has a conversion from each byte to UTF-8. 19$ENV{LC_ALL} = 'C'; 20$ENV{PGCLIENTENCODING} = 'LATIN1'; 21 22# Create database and user names covering the range of LATIN1 23# characters, for use in a connection string by pg_dumpall. Skip ',' 24# because of pg_regress --create-role, skip [\n\r] because pg_dumpall 25# does not allow them. 26my $dbname1 = 27 generate_ascii_string(1, 9) 28 . generate_ascii_string(11, 12) 29 . generate_ascii_string(14, 33) 30 . ($TestLib::windows_os ? '' : '"x"') 31 . # IPC::Run mishandles '"' on Windows 32 generate_ascii_string(35, 43) 33 . generate_ascii_string(45, 63); # contains '=' 34my $dbname2 = 35 generate_ascii_string(67, 129); # skip 64-66 to keep length to 62 36my $dbname3 = generate_ascii_string(130, 192); 37my $dbname4 = generate_ascii_string(193, 255); 38 39my $node = get_new_node('main'); 40$node->init(extra => [ '--locale=C', '--encoding=LATIN1' ]); 41 42# prep pg_hba.conf and pg_ident.conf 43$node->run_log( 44 [ 45 $ENV{PG_REGRESS}, '--config-auth', 46 $node->data_dir, '--create-role', 47 "$dbname1,$dbname2,$dbname3,$dbname4" 48 ]); 49$node->start; 50 51my $backupdir = $node->backup_dir; 52my $discard = "$backupdir/discard.sql"; 53my $plain = "$backupdir/plain.sql"; 54my $dirfmt = "$backupdir/dirfmt"; 55 56foreach my $dbname ($dbname1, $dbname2, $dbname3, $dbname4, 'CamelCase') 57{ 58 $node->run_log([ 'createdb', $dbname ]); 59 $node->run_log([ 'createuser', '-s', $dbname ]); 60} 61 62 63# For these tests, pg_dumpall -r is used because it produces a short 64# dump. 65$node->command_ok( 66 [ 67 'pg_dumpall', '-r', '-f', $discard, '--dbname', 68 $node->connstr($dbname1), 69 '-U', $dbname4 70 ], 71 'pg_dumpall with long ASCII name 1'); 72$node->command_ok( 73 [ 74 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', 75 $node->connstr($dbname2), 76 '-U', $dbname3 77 ], 78 'pg_dumpall with long ASCII name 2'); 79$node->command_ok( 80 [ 81 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', 82 $node->connstr($dbname3), 83 '-U', $dbname2 84 ], 85 'pg_dumpall with long ASCII name 3'); 86$node->command_ok( 87 [ 88 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', 89 $node->connstr($dbname4), 90 '-U', $dbname1 91 ], 92 'pg_dumpall with long ASCII name 4'); 93$node->command_ok( 94 [ 'pg_dumpall', '--no-sync', '-r', '-l', 'dbname=template1' ], 95 'pg_dumpall -l accepts connection string'); 96 97$node->run_log([ 'createdb', "foo\n\rbar" ]); 98 99# not sufficient to use -r here 100$node->command_fails( 101 [ 'pg_dumpall', '--no-sync', '-f', $discard ], 102 'pg_dumpall with \n\r in database name'); 103$node->run_log([ 'dropdb', "foo\n\rbar" ]); 104 105 106# make a table, so the parallel worker has something to dump 107$node->safe_psql($dbname1, 'CREATE TABLE t0()'); 108 109# XXX no printed message when this fails, just SIGPIPE termination 110$node->command_ok( 111 [ 112 'pg_dump', '-Fd', '--no-sync', '-j2', '-f', $dirfmt, '-U', $dbname1, 113 $node->connstr($dbname1) 114 ], 115 'parallel dump'); 116 117# recreate $dbname1 for restore test 118$node->run_log([ 'dropdb', $dbname1 ]); 119$node->run_log([ 'createdb', $dbname1 ]); 120 121$node->command_ok( 122 [ 'pg_restore', '-v', '-d', 'template1', '-j2', '-U', $dbname1, $dirfmt ], 123 'parallel restore'); 124 125$node->run_log([ 'dropdb', $dbname1 ]); 126 127$node->command_ok( 128 [ 129 'pg_restore', '-C', '-v', '-d', 130 'template1', '-j2', '-U', $dbname1, 131 $dirfmt 132 ], 133 'parallel restore with create'); 134 135 136$node->command_ok([ 'pg_dumpall', '--no-sync', '-f', $plain, '-U', $dbname1 ], 137 'take full dump'); 138system_log('cat', $plain); 139my ($stderr, $result); 140my $bootstrap_super = 'boot'; 141my $restore_super = qq{a'b\\c=d\\ne"f}; 142 143 144# Restore full dump through psql using environment variables for 145# dbname/user connection parameters 146 147my $envar_node = get_new_node('destination_envar'); 148$envar_node->init( 149 extra => [ '-U', $bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); 150$envar_node->run_log( 151 [ 152 $ENV{PG_REGRESS}, '--config-auth', 153 $envar_node->data_dir, '--create-role', 154 "$bootstrap_super,$restore_super" 155 ]); 156$envar_node->start; 157 158# make superuser for restore 159$envar_node->run_log( 160 [ 'createuser', '-U', $bootstrap_super, '-s', $restore_super ]); 161 162{ 163 local $ENV{PGPORT} = $envar_node->port; 164 local $ENV{PGUSER} = $restore_super; 165 $result = run_log([ 'psql', '-X', '-f', $plain ], '2>', \$stderr); 166} 167ok($result, 168 'restore full dump using environment variables for connection parameters' 169); 170is($stderr, '', 'no dump errors'); 171 172 173# Restore full dump through psql using command-line options for 174# dbname/user connection parameters. "\connect dbname=" forgets 175# user/port from command line. 176 177$restore_super =~ s/"//g 178 if $TestLib::windows_os; # IPC::Run mishandles '"' on Windows 179my $cmdline_node = get_new_node('destination_cmdline'); 180$cmdline_node->init( 181 extra => [ '-U', $bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); 182$cmdline_node->run_log( 183 [ 184 $ENV{PG_REGRESS}, '--config-auth', 185 $cmdline_node->data_dir, '--create-role', 186 "$bootstrap_super,$restore_super" 187 ]); 188$cmdline_node->start; 189$cmdline_node->run_log( 190 [ 'createuser', '-U', $bootstrap_super, '-s', $restore_super ]); 191{ 192 $result = run_log( 193 [ 194 'psql', '-p', $cmdline_node->port, '-U', 195 $restore_super, '-X', '-f', $plain 196 ], 197 '2>', 198 \$stderr); 199} 200ok($result, 201 'restore full dump with command-line options for connection parameters'); 202is($stderr, '', 'no dump errors'); 203