Force bad connections in tests by closing sockets

Based on Andres' suggestion, I removed SetConnectionStatus, moving its
functionality directly into set_connection_status_bad, which now simply
shuts down the socket underlying a particular connection.

This keeps the functionality as-is while removing our questionable use
of internal libpq headers.
pull/476/head
Jason Petersen 2016-04-27 21:04:17 -07:00
parent 1859a285a0
commit 510783f84f
No known key found for this signature in database
GPG Key ID: 9F1D3510D110ABA9
2 changed files with 17 additions and 34 deletions

View File

@ -18,6 +18,7 @@
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <sys/socket.h>
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "distributed/connection_cache.h" #include "distributed/connection_cache.h"
@ -129,13 +130,16 @@ get_and_purge_connection(PG_FUNCTION_ARGS)
/* /*
* set_connection_status_bad does not remove the given connection from the connection hash. * set_connection_status_bad does not remove the given connection from the connection hash.
* It only sets its status to CONNECTION_BAD. On success, it returns true. * It simply shuts down the underlying socket. On success, it returns true.
*/ */
Datum Datum
set_connection_status_bad(PG_FUNCTION_ARGS) set_connection_status_bad(PG_FUNCTION_ARGS)
{ {
char *nodeName = PG_GETARG_CSTRING(0); char *nodeName = PG_GETARG_CSTRING(0);
int32 nodePort = PG_GETARG_INT32(1); int32 nodePort = PG_GETARG_INT32(1);
int socket = -1;
int shutdownStatus = 0;
int pqStatus PG_USED_FOR_ASSERTS_ONLY = 0;
PGconn *connection = GetOrEstablishConnection(nodeName, nodePort); PGconn *connection = GetOrEstablishConnection(nodeName, nodePort);
if (connection == NULL) if (connection == NULL)
@ -143,8 +147,18 @@ set_connection_status_bad(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false); PG_RETURN_BOOL(false);
} }
/* set the connection status */ /* Prevent further reads/writes... */
SetConnectionStatus(connection, CONNECTION_BAD); socket = PQsocket(connection);
shutdownStatus = shutdown(socket, SHUT_RDWR);
if (shutdownStatus != 0)
{
ereport(ERROR, (errcode_for_socket_access(), errmsg("shutdown failed")));
}
/* ... and make libpq notice by reading data. */
pqStatus = PQconsumeInput(connection);
Assert(pqStatus == 0); /* expect failure */
PG_RETURN_BOOL(true); PG_RETURN_BOOL(true);
} }

View File

@ -1,31 +0,0 @@
/*-------------------------------------------------------------------------
*
* test/src/connection_utils.c
*
* This file isolates a test function which modifies private connection
* state, ensuring the correct ("internal") headers are included, rather
* than the version-specific server ones. Without this kludge, builds on
* certain platforms (those which install a single libpq version but can
* have multiple PostgreSQL server versions) will faile.
*
* Copyright (c) 2014-2016, Citus Data, Inc.
*
*-------------------------------------------------------------------------
*/
#include "c.h"
#include "libpq-fe.h"
#include "libpq-int.h"
#include "distributed/test_helper_functions.h"
/*
* SetConnectionStatus simply uses the internal headers to access "private"
* fields of the connection struct in order to force a cache connection to a
* particular status.
*/
void
SetConnectionStatus(PGconn *connection, ConnStatusType status)
{
connection->status = status;
}