090_multicluster.t 13.7 KB
Newer Older
1 2 3 4 5 6
# Check operation with multiple clusters

use strict; 

use lib 't';
use TestLib;
7
use Socket;
8 9
use PgCommon;

10
use Test::More tests => 125;
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

# Replace all md5 and password authentication methods with 'trust' in given
# pg_hba.conf file.
sub hba_password_to_ident {
    open F, $_[0] or die "open $_[0]: $!";
    my $hba;
    read F, $hba, 10000;
    $hba =~ s/md5/trust/g;
    $hba =~ s/password/trust/g;
    close F;
    open F, ">$_[0]" or die "open $_[0]: $!";
    print F $hba;
    close F;
    chmod 0644, $_[0] or die "chmod $_[0]: $!";
}
26 27 28

# create fake socket at 5433 to verify that this port is skipped
socket (SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die "socket: $!";
29
bind (SOCK, sockaddr_in(5433, INADDR_ANY)) || die "bind: $! ";
30 31

# create clusters
32 33 34
is ((system "pg_createcluster $MAJORS[0] old >/dev/null"), 0, "pg_createcluster $MAJORS[0] old");
is ((system "pg_createcluster $MAJORS[-1] new1 >/dev/null"), 0, "pg_createcluster $MAJORS[-1] new1");
is ((system "pg_createcluster $MAJORS[-1] new2 -p 5440 >/dev/null"), 0, "pg_createcluster $MAJORS[-1] new2");
35 36 37 38 39

my $old = "$MAJORS[0]/old";
my $new1 = "$MAJORS[-1]/new1";
my $new2 = "$MAJORS[-1]/new2";

40 41 42 43 44 45 46 47 48
# disable password auth for network cluster selection tests
hba_password_to_ident "/etc/postgresql/$old/pg_hba.conf";
hba_password_to_ident "/etc/postgresql/$new1/pg_hba.conf";
hba_password_to_ident "/etc/postgresql/$new2/pg_hba.conf";

is ((system "pg_ctlcluster $MAJORS[0] old start >/dev/null"), 0, "starting cluster $old");
is ((system "pg_ctlcluster $MAJORS[-1] new1 start >/dev/null"), 0, "starting cluster $new1");
is ((system "pg_ctlcluster $MAJORS[-1] new2 start >/dev/null"), 0, "starting cluster $new2");

49
like_program_out 'postgres', 'pg_lsclusters -h | sort -k3', 0, qr/.*5432.*5434.*5440.*/s,
50 51
    'clusters have the correct ports, skipping used 5433';

52 53 54 55 56 57 58 59 60 61
# move user_clusters aside for the test; this will ensure that client programs
# work correctly without any file at all
if (-f '/etc/postgresql-common/user_clusters') {
    ok ((rename '/etc/postgresql-common/user_clusters',
    '/etc/postgresql-common/user_clusters.psqltestsuite'),
    'Temporarily moving away /etc/postgresql-common/user_clusters');
} else {
    pass '/etc/postgresql-common/user_clusters does not exist';
}

62
# check basic cluster selection
63
like_program_out 0, 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[0]/, 
64
    'pg_wrapper selects port 5432 as default cluster';
65 66
like_program_out 0, "createdb --cluster $new1 --version", 0, 
    qr/^createdb \(PostgreSQL\) $MAJORS[-1]/, 
67
    'pg_wrapper --cluster works';
68
like_program_out 0, "createdb --cluster $MAJORS[-1]/foo --version", 1, 
69
    qr/Cluster .* does not exist/,
70 71 72
    'pg_wrapper --cluster errors out for invalid cluster';

# create a database in new1 and check that it doesn't appear in new2
73
is_program_out 'postgres', "createdb --cluster $new1 test", 0, ($MAJORS[-1] < 8.3 ? "CREATE DATABASE\n" : '');
74 75 76 77 78 79 80 81 82
like_program_out 'postgres', "psql -Atl --cluster $new1", 0, 
    qr/test\|postgres\|/,
    'test db appears in cluster new1';
unlike_program_out 'postgres', "psql -Atl --cluster $new2", 0, 
    qr/test\|postgres\|/,
    'test db does not appear in cluster new2';
unlike_program_out 'postgres', "psql -Atl", 0, qr/test\|postgres\|/,
    'test db does not appear in default cluster';

83 84 85
# check network cluster selection
is_program_out 'postgres', "psql --cluster $MAJORS[0]/127.0.0.1: -Atc 'show port' template1", 0, "5432\n", 
    "psql --cluster $MAJORS[0]/127.0.0.1: defaults to port 5432";
86 87 88
like_program_out 'postgres', "createdb --cluster $MAJORS[-1]/127.0.0.1:5432 --version", 0, 
    qr/^createdb \(PostgreSQL\) $MAJORS[-1]/, 
    "createdb --cluster $MAJORS[-1]/127.0.0.1:5432 uses latest client version";
89 90 91 92 93 94
like_program_out 'postgres', "psql -Atl --cluster $MAJORS[-1]/localhost:5434", 0, 
    qr/test\|postgres\|/, "test db appears in cluster $MAJORS[-1]/localhost:5434";
unlike_program_out 'postgres', "psql -Atl --cluster $MAJORS[-1]/localhost:5440", 0, 
    qr/test\|postgres\|/, "test db does not appear in cluster $MAJORS[-1]/localhost:5440";

# check some erroneous cluster specifications
95
like_program_out 'postgres', "LC_MESSAGES=C psql -Atl --cluster $MAJORS[-1]/localhost:5435", 2, 
96
    qr/could not connect/, "psql --cluster $MAJORS[-1]/localhost:5435 fails due to nonexisting port";
97
like_program_out 'postgres', "LC_MESSAGES=C psql -Atl --cluster $MAJORS[-1]/localhost:a", 1, 
98
    qr/Cluster .* does not exist/, "psql --cluster $MAJORS[-1]/localhost:a fails due to invalid syntax";
99
like_program_out 'postgres', "LC_MESSAGES=C psql -Atl --cluster $MAJORS[-1]/doesnotexi.st", 1, 
100
    qr/Cluster .* does not exist/, "psql --cluster $MAJORS[-1]/doesnotexi.st fails due to invalid syntax";
101 102 103
like_program_out 'postgres', "psql -Atl --cluster 6.4/localhost:", 1, 
    qr/Invalid version/, "psql --cluster 6.4/localhost: fails due to invalid version";

104 105 106 107 108 109 110 111 112
# check that environment variables work
$ENV{'PGCLUSTER'} = $new1;
like_program_out 'postgres', "psql -Atl", 0, qr/test\|postgres\|/, 
    'PGCLUSTER selection (1)';
$ENV{'PGCLUSTER'} = $new2;
unlike_program_out 'postgres', "psql -Atl", 0, qr/test\|postgres\|/, 
    'PGCLUSTER selection (2)';
$ENV{'PGCLUSTER'} = 'foo';
like_program_out 'postgres', "psql -l", 1, 
113
    qr/Invalid version .* specified in PGCLUSTER/,
114
    'invalid PGCLUSTER value';
115
$ENV{'PGCLUSTER'} = "$MAJORS[-1]/127.0.0.1:";
116
like_program_out 0, 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[-1]/, 
117 118 119 120 121 122 123 124
    'PGCLUSTER network cluster selection (1)';
$ENV{'PGCLUSTER'} = "$MAJORS[-1]/localhost:5434";
like_program_out 'postgres', 'psql -Atl', 0, 
    qr/test\|postgres\|/, 'PGCLUSTER network cluster selection (2)';
$ENV{'PGCLUSTER'} = "$MAJORS[-1]/localhost:5440";
unlike_program_out 'postgres', 'psql -Atl', 0, 
    qr/test\|postgres\|/, 'PGCLUSTER network cluster selection (3)';
$ENV{'PGCLUSTER'} = "$MAJORS[-1]/localhost:5435";
125
like_program_out 'postgres', 'LC_MESSAGES=C psql -Atl', 2, 
126
    qr/could not connect/, "psql --cluster $MAJORS[-1]/localhost:5435 fails due to nonexisting port";
127 128 129
delete $ENV{'PGCLUSTER'};

# check that PGPORT works
130 131
$ENV{'PGPORT'} = '5434';
is_program_out 'postgres', 'psql -Atc "show port" template1', 0, "5434\n", 
132 133 134 135 136 137 138
    'PGPORT selection (1)';
$ENV{'PGPORT'} = '5432';
is_program_out 'postgres', 'psql -Atc "show port" template1', 0, "5432\n", 
    'PGPORT selection (2)';
$ENV{'PGCLUSTER'} = $new2;
delete $ENV{'PGPORT'};
$ENV{'PGPORT'} = '5432';
139
like_program_out 'postgres', 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[-1]/, 
140 141 142
    'PGPORT+PGCLUSTER, PGCLUSTER selects version';
is_program_out 'postgres', 'psql -Atc "show port" template1', 0, "5432\n", 
    'PGPORT+PGCLUSTER, PGPORT selects port';
143 144 145
delete $ENV{'PGPORT'};
delete $ENV{'PGCLUSTER'};

146 147 148 149 150 151
# check that PGDATABASE works
$ENV{'PGDATABASE'} = 'test';
is_program_out 'postgres', "psql --cluster $new1 -Atc 'select current_database()'", 0, "test\n", 
    'PGDATABASE environment variable works';
delete $ENV{'PGDATABASE'};

152 153 154 155
# check cluster selection with an empty user_clusters
open F, '>/etc/postgresql-common/user_clusters' or die "Could not create user_clusters: $!";
close F;
chmod 0644, '/etc/postgresql-common/user_clusters';
156
like_program_out 0, 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[0]/, 
157
    'pg_wrapper selects port 5432 as default cluster with empty user_clusters';
158 159
like_program_out 0, "createdb --cluster $new1 --version", 0, 
    qr/^createdb \(PostgreSQL\) $MAJORS[-1]/, 
160 161 162 163
    'pg_wrapper --cluster works with empty user_clusters';

# check default cluster selection with user_clusters
open F, '>/etc/postgresql-common/user_clusters' or die "Could not create user_clusters: $!";
164
print F "* * $MAJORS[-1] new1 *\n";
165 166
close F;
chmod 0644, '/etc/postgresql-common/user_clusters';
167
like_program_out 'postgres', 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[-1]/, 
168 169
    "pg_wrapper selects correct cluster with user_clusters '* * $MAJORS[-1] new1 *'";

170 171
# check default database selection with user_clusters
open F, '>/etc/postgresql-common/user_clusters' or die "Could not create user_clusters: $!";
172
print F "* * $MAJORS[-1] new1 test\n";
173 174 175 176 177 178 179 180 181
close F;
chmod 0644, '/etc/postgresql-common/user_clusters';
is_program_out 'postgres', 'psql -Atc "select current_database()"', 0, "test\n",
    "pg_wrapper selects correct database with user_clusters '* * $MAJORS[-1] new1 test'";
$ENV{'PGDATABASE'} = 'template1';
is_program_out 'postgres', "psql -Atc 'select current_database()'", 0, "template1\n", 
    'PGDATABASE environment variable is not overridden by user_clusters';
delete $ENV{'PGDATABASE'};

182 183 184 185 186 187
# check by-user cluster selection with user_clusters
# (also check invalid cluster reporting)
open F, '>/etc/postgresql-common/user_clusters' or die "Could not create user_clusters: $!";
print F "postgres * $MAJORS[-1] new1 *\nnobody * $MAJORS[0] old *\n* * 5.5 * *";
close F;
chmod 0644, '/etc/postgresql-common/user_clusters';
188
like_program_out 'postgres', 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[-1]/, 
189
    'pg_wrapper selects correct cluster with per-user user_clusters';
190
like_program_out 'nobody', 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[0]/, 
191
    'pg_wrapper selects correct cluster with per-user user_clusters';
192 193
like_program_out 0, 'createdb --version', 0, qr/user_clusters.*line 3.*version.*not exist/i,
    'pg_wrapper warning for invalid per-user user_clusters line';
194 195 196 197 198 199 200

# check by-user network cluster selection with user_clusters
# (also check invalid cluster reporting)
open F, '>/etc/postgresql-common/user_clusters' or die "Could not create user_clusters: $!";
print F "postgres * $MAJORS[0] localhost: *\nnobody * $MAJORS[-1] new1 *\n* * $MAJORS[-1] localhost:a *";
close F;
chmod 0644, '/etc/postgresql-common/user_clusters';
201
like_program_out 'postgres', 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[0]/, 
202
    'pg_wrapper selects correct version with per-user user_clusters';
203
like_program_out 'nobody', 'createdb --version', 0, qr/^createdb \(PostgreSQL\) $MAJORS[-1]/, 
204
    'pg_wrapper selects correct version with per-user user_clusters';
205 206
like_program_out 0, 'createdb --version', 0, qr/user_clusters.*line 3.*cluster.*not exist/i,
    'pg_wrapper warning for invalid per-user user_clusters line';
207 208 209 210 211 212
# check PGHOST environment variable precedence
$ENV{'PGHOST'} = '127.0.0.2';
like_program_out 'postgres', 'psql -Atl', 2, qr/127.0.0.2/, '$PGHOST overrides user_clusters';
is_program_out 'postgres', "psql --cluster $MAJORS[-1]/localhost:5434 -Atc 'select current_database()' test", 
    0, "test\n", '--cluster overrides $PGHOST';
delete $ENV{'PGHOST'};
213 214 215 216 217 218

# check invalid user_clusters
open F, '>/etc/postgresql-common/user_clusters' or die "Could not create user_clusters: $!";
print F 'foo';
close F;
chmod 0644, '/etc/postgresql-common/user_clusters';
219
like_program_out 'postgres', 'createdb --version', 0, qr/ignoring invalid line 1/, 
220 221
    'pg_wrapper ignores invalid lines in user_clusters';

222 223 224 225
# remove test user_clusters
unlink '/etc/postgresql-common/user_clusters' or die
    "unlink user_clusters: $!";

226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
# check that pg_service.conf works
open F, '>/etc/postgresql-common/pg_service.conf' or die "Could not create pg_service.conf: $!";
print F "[old_t1]
user=postgres
dbname=template1
port=5432

[new1_test]
user=postgres
dbname=test
port=5434

# these do not exist
[new2_test]
user=postgres
dbname=test
port=5440
";
close F;
chmod 0644, '/etc/postgresql-common/pg_service.conf';
246

247
$ENV{'PGSERVICE'} = 'old_t1';
248
is_program_out 'postgres', "psql -Atc 'select current_database()'", 0,
249 250
    "template1\n", 'pg_service conf selection 1';
$ENV{'PGSERVICE'} = 'new1_test';
251
is_program_out 'postgres', "psql -Atc 'select current_database()'", 0,
252 253
    "test\n", 'pg_service conf selection 2';
$ENV{'PGSERVICE'} = 'new2_test';
254
like_program_out 'postgres', "psql -Atc 'select current_database()'", 2,
255 256 257 258
    qr/FATAL.*test/, 'pg_service conf selection 3';
delete $ENV{'PGSERVICE'};
unlink '/etc/postgresql-common/pg_service.conf';

259 260
# check proper error message if no cluster could be determined as default for
# pg_wrapper
261 262 263 264
is ((system "pg_ctlcluster $MAJORS[0] old stop >/dev/null"), 0, "stopping cluster $old");
PgCommon::set_conf_value $MAJORS[0], 'old', 'postgresql.conf', 'port', '5435';
is ((system "pg_ctlcluster $MAJORS[0] old start >/dev/null"), 0, "restarting cluster $old");
like_program_out 'postgres', 'pg_lsclusters -h | sort -k3', 0, qr/.*5434.*5435.*5440.*/s,
265
    'port of first cluster was successfully changed';
266 267 268
like_program_out 'postgres', "psql -l", 2,
    qr/no.*default.*man pg_wrapper.*psql:.*\.s\.PGSQL.5432/is,
    'proper pg_wrapper warning and psql error if no cluster is suitable as default target';
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
like_program_out 'postgres', "psql -Atl --cluster $new1", 0, 
    qr/test\|postgres\|/,
    '--cluster selects appropriate cluster';
like_program_out 'postgres', "psql -Atl -p 5434", 0, 
    qr/test\|postgres\|/,
    '-p selects appropriate cluster';
like_program_out 'postgres', "psql -Atlp 5434", 0, 
    qr/test\|postgres\|/,
    '-Atlp selects appropriate cluster';
like_program_out 'postgres', "psql -Atl --port 5434", 0, 
    qr/test\|postgres\|/,
    '--port selects appropriate cluster';
like_program_out 'postgres', "env PGPORT=5434 psql -Atl", 0, 
    qr/test\|postgres\|/,
    '$PGPORT selects appropriate cluster';

# but specifying -p explicitly should work
286

287 288 289 290 291 292 293 294
# restore original user_clusters
if (-f '/etc/postgresql-common/user_clusters.psqltestsuite') {
    ok ((rename '/etc/postgresql-common/user_clusters.psqltestsuite',
    '/etc/postgresql-common/user_clusters'),
    'Restoring original /etc/postgresql-common/user_clusters');
} else {
    pass '/etc/postgresql-common/user_clusters did not exist, not restoring';
}
295 296

# clean up
297 298 299
is ((system "pg_dropcluster $MAJORS[-1] new1 --stop"), 0, "dropping $new1");
is ((system "pg_dropcluster $MAJORS[-1] new2 --stop"), 0, "dropping $new2");
is ((system "pg_dropcluster $MAJORS[0] old --stop"), 0, "dropping $old");
300 301

check_clean;
302 303

# vim: filetype=perl