Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit20e0e7d

Browse files
committed
Add test for early backend startup errors
The new test tests the libpq fallback behavior on an early error,which was fixed in the previous commit.This adds an IS_INJECTION_POINT_ATTACHED() macro, to allow writinginjected test code alongside the normal source code. In principle, thenew test could've been implemented by an extra test module with acallback that sets the FrontendProtocol global variable, but I thinkit's more clear to have the test code right where the injection pointis, because it has pretty intimate knowledge of the surroundingcontext it runs in.Reviewed-by: Michael PaquierDiscussion:https://www.postgresql.org/message-id/CAOYmi%2Bnwvu21mJ4DYKUa98HdfM_KZJi7B1MhyXtnsyOO-PB6Ww%40mail.gmail.com
1 parentb9e5249 commit20e0e7d

File tree

7 files changed

+118
-1
lines changed

7 files changed

+118
-1
lines changed

‎doc/src/sgml/xfunc.sgml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3672,6 +3672,31 @@ custom_injection_callback(const char *name, const void *private_data)
36723672
logic.
36733673
</para>
36743674

3675+
<para>
3676+
An alternative way to define the action to take when an injection point
3677+
is reached is to add the testing code alongside the normal source
3678+
code. This can be useful if the action e.g. depends on local variables
3679+
that are not accessible to loaded modules. The
3680+
<function>IS_INJECTION_POINT_ATTACHED</function> macro can then be used
3681+
to check if an injection point is attached, for example:
3682+
<programlisting>
3683+
#ifdef USE_INJECTION_POINTS
3684+
if (IS_INJECTION_POINT_ATTACHED("before-foobar"))
3685+
{
3686+
/* change a local variable if injection point is attached */
3687+
local_var = 123;
3688+
3689+
/* also execute the callback */
3690+
INJECTION_POINT_CACHED("before-foobar");
3691+
}
3692+
#endif
3693+
</programlisting>
3694+
Note that the callback attached to the injection point will not be
3695+
executed by the <function>IS_INJECTION_POINT_ATTACHED</function>
3696+
macro. If you want to execute the callback, you must also call
3697+
<function>INJECTION_POINT_CACHED</function> like in the above example.
3698+
</para>
3699+
36753700
<para>
36763701
Optionally, it is possible to detach an injection point by calling:
36773702
<programlisting>

‎src/backend/tcop/backend_startup.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include"tcop/backend_startup.h"
3434
#include"tcop/tcopprot.h"
3535
#include"utils/builtins.h"
36+
#include"utils/injection_point.h"
3637
#include"utils/memutils.h"
3738
#include"utils/ps_status.h"
3839
#include"utils/timeout.h"
@@ -213,6 +214,21 @@ BackendInitialize(ClientSocket *client_sock, CAC_state cac)
213214
remote_host)));
214215
}
215216

217+
/* For testing client error handling */
218+
#ifdefUSE_INJECTION_POINTS
219+
INJECTION_POINT("backend-initialize");
220+
if (IS_INJECTION_POINT_ATTACHED("backend-initialize-v2-error"))
221+
{
222+
/*
223+
* This simulates an early error from a pre-v14 server, which used the
224+
* version 2 protocol for any errors that occurred before processing
225+
* the startup packet.
226+
*/
227+
FrontendProtocol=PG_PROTOCOL(2,0);
228+
elog(FATAL,"protocol version 2 error triggered");
229+
}
230+
#endif
231+
216232
/*
217233
* If we did a reverse lookup to name, we might as well save the results
218234
* rather than possibly repeating the lookup during authentication.

‎src/backend/utils/misc/injection_point.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,3 +570,17 @@ InjectionPointCached(const char *name)
570570
elog(ERROR,"Injection points are not supported by this build");
571571
#endif
572572
}
573+
574+
/*
575+
* Test if an injection point is defined.
576+
*/
577+
bool
578+
IsInjectionPointAttached(constchar*name)
579+
{
580+
#ifdefUSE_INJECTION_POINTS
581+
returnInjectionPointCacheRefresh(name)!=NULL;
582+
#else
583+
elog(ERROR,"Injection points are not supported by this build");
584+
return false;/* silence compiler */
585+
#endif
586+
}

‎src/include/utils/injection_point.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
#defineINJECTION_POINT_LOAD(name) InjectionPointLoad(name)
1919
#defineINJECTION_POINT(name) InjectionPointRun(name)
2020
#defineINJECTION_POINT_CACHED(name) InjectionPointCached(name)
21+
#defineIS_INJECTION_POINT_ATTACHED(name) IsInjectionPointAttached(name)
2122
#else
2223
#defineINJECTION_POINT_LOAD(name) ((void) name)
2324
#defineINJECTION_POINT(name) ((void) name)
2425
#defineINJECTION_POINT_CACHED(name) ((void) name)
26+
#defineIS_INJECTION_POINT_ATTACHED(name) (false)
2527
#endif
2628

2729
/*
@@ -41,6 +43,7 @@ extern void InjectionPointAttach(const char *name,
4143
externvoidInjectionPointLoad(constchar*name);
4244
externvoidInjectionPointRun(constchar*name);
4345
externvoidInjectionPointCached(constchar*name);
46+
externboolIsInjectionPointAttached(constchar*name);
4447
externboolInjectionPointDetach(constchar*name);
4548

4649
#ifdefEXEC_BACKEND

‎src/interfaces/libpq/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
#
1010
#-------------------------------------------------------------------------
1111

12+
EXTRA_INSTALL=src/test/modules/injection_points
13+
1214
subdir = src/interfaces/libpq
1315
top_builddir = ../../..
1416
include$(top_builddir)/src/Makefile.global
1517

16-
exportwith_sslwith_gssapiwith_krb_srvnam
18+
exportwith_sslwith_gssapiwith_krb_srvnamenable_injection_points
1719

1820
PGFILEDESC = "PostgreSQL Access Library"
1921

‎src/interfaces/libpq/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ tests += {
121121
't/005_negotiate_encryption.pl',
122122
],
123123
'env': {
124+
'enable_injection_points':get_option('injection_points') ?'yes' :'no',
124125
'with_ssl': ssl_library,
125126
'with_gssapi': gssapi.found() ?'yes' :'no',
126127
'with_krb_srvnam':'postgres',

‎src/interfaces/libpq/t/005_negotiate_encryption.pl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@
9090
$ENV{PG_TEST_EXTRA} &&$ENV{PG_TEST_EXTRA} =~/\bkerberos\b/;
9191
my$ssl_supported =$ENV{with_ssl}eq'openssl';
9292

93+
my$injection_points_supported =$ENV{enable_injection_points}eq'yes';
94+
9395
###
9496
### Prepare test server for GSSAPI and SSL authentication, with a few
9597
### different test users and helper functions. We don't actually
@@ -155,6 +157,10 @@
155157
$node->safe_psql('postgres','CREATE USER nossluser;');
156158
$node->safe_psql('postgres','CREATE USER gssuser;');
157159
$node->safe_psql('postgres','CREATE USER nogssuser;');
160+
if ($injection_points_supported != 0)
161+
{
162+
$node->safe_psql('postgres','CREATE EXTENSION injection_points;');
163+
}
158164

159165
my$unixdir =$node->safe_psql('postgres','SHOW unix_socket_directories;');
160166
chomp($unixdir);
@@ -312,6 +318,29 @@ BEGIN
312318
['disable'], \@all_sslmodes, \@all_sslnegotiations,
313319
parse_table($test_table));
314320

321+
if ($injection_points_supported != 0)
322+
{
323+
$node->safe_psql(
324+
'postgres',
325+
"SELECT injection_points_attach('backend-initialize', 'error');",
326+
connstr=>"user=localuser host=$unixdir");
327+
connect_test(
328+
$node,
329+
"user=testuser sslmode=prefer",
330+
'connect, backenderror -> fail');
331+
$node->restart;
332+
333+
$node->safe_psql(
334+
'postgres',
335+
"SELECT injection_points_attach('backend-initialize-v2-error', 'error');",
336+
connstr=>"user=localuser host=$unixdir");
337+
connect_test(
338+
$node,
339+
"user=testuser sslmode=prefer",
340+
'connect, v2error -> fail');
341+
$node->restart;
342+
}
343+
315344
# Disable SSL again
316345
$node->adjust_conf('postgresql.conf','ssl','off');
317346
$node->reload;
@@ -393,6 +422,29 @@ BEGIN
393422
test_matrix($node, ['testuser','gssuser','nogssuser' ],
394423
\@all_gssencmodes,$sslmodes,$sslnegotiations,
395424
parse_table($test_table));
425+
426+
if ($injection_points_supported != 0)
427+
{
428+
$node->safe_psql(
429+
'postgres',
430+
"SELECT injection_points_attach('backend-initialize', 'error');",
431+
connstr=>"user=localuser host=$unixdir");
432+
connect_test(
433+
$node,
434+
"user=testuser gssencmode=prefer sslmode=disable",
435+
'connect, backenderror, reconnect, backenderror -> fail');
436+
$node->restart;
437+
438+
$node->safe_psql(
439+
'postgres',
440+
"SELECT injection_points_attach('backend-initialize-v2-error', 'error');",
441+
connstr=>"user=localuser host=$unixdir");
442+
connect_test(
443+
$node,
444+
"user=testuser gssencmode=prefer sslmode=disable",
445+
'connect, v2error -> fail');
446+
$node->restart;
447+
}
396448
}
397449

398450
###
@@ -738,6 +790,10 @@ sub parse_log_events
738790
push@events,"gssreject"if$line =~/GSSENCRequest rejected/;
739791
push@events,"authfail"if$line =~/no pg_hba.conf entry/;
740792
push@events,"authok"if$line =~/connection authenticated/;
793+
push@events,"backenderror"
794+
if$line =~/error triggered for injection point backend-/;
795+
push@events,"v2error"
796+
if$line =~/protocol version 2 error triggered/;
741797
}
742798

743799
# No events at all is represented by "-"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp