1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-18 04:58:51 +02:00

Use unique port for each server unit test.

If the same port is reused too quickly bind may fail with this error:

FileOpenError: unable to bind socket: [98] Address already in use

We specify SO_REUSEADDR when creating the socket but apparently this is not always enough if the port is reused very rapidly.

Fix this (hopefully) by using a unique port for each test that needs one. This does in theory limit the number of tests that can use ports, but we allow 768 per test, whereas the test that uses the most ports is common/io-tls with 4.
This commit is contained in:
David Steele 2023-11-30 16:43:09 -03:00
parent a14732789b
commit 7ce0f5a94c
9 changed files with 136 additions and 110 deletions

View File

@ -44,6 +44,14 @@ Constants
***********************************************************************************************************************************/
#define HRN_SERVER_HOST "tls.test.pgbackrest.org"
/***********************************************************************************************************************************
Local data
***********************************************************************************************************************************/
struct HrnServerLocal
{
unsigned int portOffsetNext; // Next server port offset to be returned
} hrnServerLocal;
/**********************************************************************************************************************************/
void
hrnServerInit(void)
@ -230,21 +238,18 @@ hrnServerScriptSleep(IoWrite *write, TimeMSec sleepMs)
/**********************************************************************************************************************************/
void
hrnServerRun(IoRead *read, HrnServerProtocol protocol, HrnServerRunParam param)
hrnServerRun(IoRead *const read, const HrnServerProtocol protocol, const unsigned int port, HrnServerRunParam param)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(IO_READ, read);
FUNCTION_HARNESS_PARAM(ENUM, protocol);
FUNCTION_HARNESS_PARAM(UINT, param.port);
FUNCTION_HARNESS_PARAM(UINT, port);
FUNCTION_HARNESS_PARAM(STRING, param.certificate);
FUNCTION_HARNESS_PARAM(STRING, param.key);
FUNCTION_HARNESS_END();
ASSERT(read != NULL);
// Set port to index 0 if not specified
if (param.port == 0)
param.port = hrnServerPort(0);
ASSERT(port >= HRN_SERVER_PORT_MIN);
// Initialize ssl and create a context
IoServer *tlsServer = NULL;
@ -263,7 +268,7 @@ hrnServerRun(IoRead *read, HrnServerProtocol protocol, HrnServerRunParam param)
tlsServer = tlsServerNew(STRDEF(HRN_SERVER_HOST), param.ca, param.key, param.certificate, 5000);
}
IoServer *socketServer = sckServerNew(STRDEF("localhost"), param.port, 5000);
IoServer *socketServer = sckServerNew(STRDEF("localhost"), port, 5000);
// Loop until no more commands
IoSession *serverSession = NULL;
@ -377,9 +382,12 @@ hrnServerHost(void)
/**********************************************************************************************************************************/
unsigned int
hrnServerPort(unsigned int portIdx)
hrnServerPortNext(void)
{
ASSERT(portIdx < HRN_SERVER_PORT_MAX);
CHECK(AssertError, testIdx() < 32, "test max exceeds limit of 32");
CHECK(
AssertError, hrnServerLocal.portOffsetNext < HRN_SERVER_PORT_MAX,
"requested port exceeds limit of " STRINGIFY(HRN_SERVER_PORT_MAX));
return 44443 + (HRN_SERVER_PORT_MAX * testIdx()) + portIdx;
return HRN_SERVER_PORT_MIN + (HRN_SERVER_PORT_MAX * testIdx()) + hrnServerLocal.portOffsetNext++;
}

View File

@ -23,9 +23,16 @@ typedef enum
} HrnServerProtocol;
/***********************************************************************************************************************************
Maximum number of ports allowed for each test
Port constants
***********************************************************************************************************************************/
#define HRN_SERVER_PORT_MAX 4
// Maximum number of ports allowed for each test
#define HRN_SERVER_PORT_MAX 768
// Bogus port to be used where the port does not matter or must fail
#define HRN_SERVER_PORT_BOGUS 34342
// Minimum port to be assigned to a test
#define HRN_SERVER_PORT_MIN (HRN_SERVER_PORT_BOGUS + 1)
/***********************************************************************************************************************************
Path and prefix for test certificates
@ -47,16 +54,15 @@ void hrnServerInit(void);
typedef struct HrnServerRunParam
{
VAR_PARAM_HEADER;
unsigned int port; // Server port, defaults to hrnServerPort(0)
const String *ca; // TLS CA store when protocol = hrnServerProtocolTls
const String *certificate; // TLS certificate when protocol = hrnServerProtocolTls
const String *key; // TLS key when protocol = hrnServerProtocolTls
} HrnServerRunParam;
#define hrnServerRunP(read, protocol, ...) \
hrnServerRun(read, protocol, (HrnServerRunParam){VAR_PARAM_INIT, __VA_ARGS__})
#define hrnServerRunP(read, protocol, port, ...) \
hrnServerRun(read, protocol, port, (HrnServerRunParam){VAR_PARAM_INIT, __VA_ARGS__})
void hrnServerRun(IoRead *read, HrnServerProtocol protocol, HrnServerRunParam param);
void hrnServerRun(IoRead *read, HrnServerProtocol protocol, unsigned int port, HrnServerRunParam param);
// Begin/end server script
IoWrite *hrnServerScriptBegin(IoWrite *write);
@ -89,7 +95,7 @@ Getters/Setters
const String *hrnServerHost(void);
// Port to use for testing. This will be unique for each test running in parallel to avoid conflicts. A range is allocated to each
// test so multiple ports can be requested.
unsigned int hrnServerPort(unsigned int portIdx);
// test so multiple ports can be requested and no port is ever reused to eliminate rebinding issues.
unsigned int hrnServerPortNext(void);
#endif

View File

@ -29,6 +29,8 @@ testRun(void)
HRN_FORK_BEGIN(.timeout = 15000)
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "client repo")
{
StringList *argList = strLstNew();
@ -41,7 +43,7 @@ testRun(void)
#endif
hrnCfgArgRawZ(argList, cfgOptRepoHostCertFile, HRN_SERVER_CLIENT_CERT);
hrnCfgArgRawZ(argList, cfgOptRepoHostKeyFile, HRN_SERVER_CLIENT_KEY);
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", testPort);
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
HRN_CFG_LOAD(cfgCmdArchiveGet, argList);
@ -87,7 +89,7 @@ testRun(void)
#endif
hrnCfgArgRawZ(argList, cfgOptPgHostCertFile, HRN_SERVER_CLIENT_CERT);
hrnCfgArgRawZ(argList, cfgOptPgHostKeyFile, HRN_SERVER_CLIENT_KEY);
hrnCfgArgRawFmt(argList, cfgOptPgHostPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptPgHostPort, "%u", testPort);
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
hrnCfgArgRawZ(argList, cfgOptProcess, "1");
HRN_CFG_LOAD(cfgCmdBackup, argList, .role = cfgCmdRoleLocal);
@ -129,7 +131,7 @@ testRun(void)
StringList *argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptConfig, TEST_PATH "/pgbackrest.conf");
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", testPort);
hrnCfgArgRawZ(argList, cfgOptLogLevelStderr, CFGOPTVAL_ARCHIVE_MODE_OFF_Z);
HRN_CFG_LOAD(cfgCmdServer, argList);
@ -206,12 +208,14 @@ testRun(void)
HRN_FORK_BEGIN(.timeout = 15000)
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "client")
{
TEST_TITLE("ping localhost");
argList = strLstNew();
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", testPort);
HRN_CFG_LOAD(cfgCmdServerPing, argList);
TEST_RESULT_VOID(cmdServerPing(), "ping");
@ -220,7 +224,7 @@ testRun(void)
TEST_TITLE("ping 12.0.0.1");
argList = strLstNew();
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", testPort);
strLstAddZ(argList, "127.0.0.1");
HRN_CFG_LOAD(cfgCmdServerPing, argList);
@ -242,7 +246,7 @@ testRun(void)
hrnCfgArgRawZ(argList, cfgOptTlsServerCertFile, HRN_SERVER_CERT);
hrnCfgArgRawZ(argList, cfgOptTlsServerKeyFile, HRN_SERVER_KEY);
hrnCfgArgRawZ(argList, cfgOptTlsServerAuth, "bogus=*");
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", testPort);
HRN_CFG_LOAD(cfgCmdServer, argList);
// Init exit signal handlers

View File

@ -307,21 +307,22 @@ testRun(void)
char logBuf[STACK_TRACE_PARAM_MAX];
HttpClient *client = NULL;
TEST_ASSIGN(client, httpClientNew(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 500, 500), 500), "new client");
TEST_ASSIGN(client, httpClientNew(sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 500, 500), 500), "new client");
TEST_ERROR_FMT(
httpRequestResponse(httpRequestNewP(client, STRDEF("GET"), STRDEF("/")), false), HostConnectError,
"unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused\n"
"unable to connect to 'localhost:34342 (127.0.0.1)': [111] Connection refused\n"
"[RETRY DETAIL OMITTED]\n"
"[RETRY DETAIL OMITTED]",
hrnServerPort(0));
"[RETRY DETAIL OMITTED]");
HRN_FORK_BEGIN()
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
{
// Start HTTP test server
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket), "http server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket, testPort), "http server");
}
HRN_FORK_CHILD_END();
@ -334,7 +335,7 @@ testRun(void)
ioBufferSizeSet(35);
TEST_ASSIGN(client, httpClientNew(sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), 5000), "new client");
TEST_ASSIGN(client, httpClientNew(sckClientNew(hrnServerHost(), testPort, 5000, 5000), 5000), "new client");
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("no output from server");
@ -684,13 +685,15 @@ testRun(void)
HRN_FORK_BEGIN()
{
const unsigned int testPort = hrnServerPortNext();
// Start HTTPS test server
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
{
// Set buffer size large enough for server to read expect messages
ioBufferSizeSet(65536);
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls), "http server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, testPort), "http server");
}
HRN_FORK_CHILD_END();
@ -707,7 +710,7 @@ testRun(void)
client,
httpClientNew(
tlsClientNewP(
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 0, 0, TEST_IN_CONTAINER),
sckClientNew(hrnServerHost(), testPort, 5000, 5000), hrnServerHost(), 0, 0, TEST_IN_CONTAINER),
5000),
"new client");

View File

@ -366,33 +366,33 @@ testRun(void)
{
IoClient *client = NULL;
TEST_ASSIGN(client, sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100, 100), "new client");
TEST_ERROR_FMT(
TEST_ASSIGN(client, sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 100, 100), "new client");
TEST_ERROR(
ioClientOpen(client), HostConnectError,
"unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused\n"
"[RETRY DETAIL OMITTED]",
hrnServerPort(0));
"unable to connect to 'localhost:34342 (127.0.0.1)': [111] Connection refused\n"
"[RETRY DETAIL OMITTED]");
// This address should not be in use in a test environment -- if it is the test will fail
TEST_ASSIGN(client, sckClientNew(STRDEF("172.31.255.255"), hrnServerPort(0), 100, 100), "new client");
TEST_ERROR_FMT(
TEST_ASSIGN(client, sckClientNew(STRDEF("172.31.255.255"), HRN_SERVER_PORT_BOGUS, 100, 100), "new client");
TEST_ERROR(
ioClientOpen(client), HostConnectError,
"timeout connecting to '172.31.255.255:%u'\n"
"[RETRY DETAIL OMITTED]",
hrnServerPort(0));
"timeout connecting to '172.31.255.255:34342'\n"
"[RETRY DETAIL OMITTED]");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("sckServerAccept() returns NULL on interrupt");
HRN_FORK_BEGIN(.timeout = 5000)
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "sighup server")
{
// Ignore SIGHUP
sigaction(SIGHUP, &(struct sigaction){.sa_handler = testSignalHandler}, NULL);
// Wait for connection. Use port 1 to avoid port conflicts later.
IoServer *server = sckServerNew(STRDEF("127.0.0.1"), hrnServerPort(1), 5000);
IoServer *server = sckServerNew(STRDEF("127.0.0.1"), testPort, 5000);
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("ioServerToLog()");
@ -401,7 +401,7 @@ testRun(void)
TEST_RESULT_VOID(FUNCTION_LOG_OBJECT_FORMAT(server, ioServerToLog, buffer, sizeof(buffer)), "ioServerToLog");
TEST_RESULT_Z(
buffer, zNewFmt("{type: socket, driver: {address: 127.0.0.1, port: %u, timeout: 5000}}", hrnServerPort(1)),
buffer, zNewFmt("{type: socket, driver: {address: 127.0.0.1, port: %u, timeout: 5000}}", testPort),
"check log");
HRN_FORK_CHILD_NOTIFY_PUT();
@ -455,13 +455,12 @@ testRun(void)
// Set TLS client timeout higher than socket timeout to ensure that TLS retries are covered
TEST_ASSIGN(
client, tlsClientNewP(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100, 100), STRDEF("X"), 250, 250, true),
client, tlsClientNewP(sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 100, 100), STRDEF("X"), 250, 250, true),
"new client");
TEST_ERROR_FMT(
TEST_ERROR(
ioClientOpen(client), HostConnectError,
"unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused\n"
"[RETRY DETAIL OMITTED]",
hrnServerPort(0));
"unable to connect to 'localhost:34342 (127.0.0.1)': [111] Connection refused\n"
"[RETRY DETAIL OMITTED]");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("missing ca cert/path");
@ -469,7 +468,7 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.caFile = STRDEF("bogus.crt"), .caPath = STRDEF("/bogus"))),
CryptoError, "unable to set user-defined CA certificate location: "
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
@ -484,7 +483,7 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF("/bogus"), .keyFile = STRDEF("/bogus"))),
CryptoError, "unable to load cert file '/bogus': "
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
@ -499,7 +498,7 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF("/bogus"))),
CryptoError, "unable to load key file '/bogus': "
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
@ -514,7 +513,7 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(HRN_SERVER_KEY))),
CryptoError, "unable to load key file '" HRN_PATH_REPO "/test/certificate/pgbackrest-test-server.key': "
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
@ -533,7 +532,7 @@ testRun(void)
{
TEST_ERROR(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-pwd.key")),
CryptoError, "unable to load key file '" TEST_PATH "/client-pwd.key': "
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
@ -547,7 +546,7 @@ testRun(void)
{
TEST_ERROR( // {uncovered - 32-bit error}
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-pwd.key")),
CryptoError, "unable to load key file '" TEST_PATH "/client-pwd.key': [151429224] bad password read");
}
@ -563,7 +562,7 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-bad-perm.key"))),
FileReadError,
"key file '" TEST_PATH "/client-bad-perm.key' has group or other permissions\n"
@ -582,7 +581,7 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-bad-perm.key"))),
FileReadError, "key file '" TEST_PATH "/client-bad-perm.key' must be owned by the '" TEST_USER "' user or root");
@ -594,7 +593,7 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), HRN_SERVER_PORT_BOGUS, 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-bad-perm.key"))),
FileReadError,
"key file '" TEST_PATH "/client-bad-perm.key' has group or other permissions\n"
@ -612,15 +611,16 @@ testRun(void)
HRN_FORK_BEGIN()
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
{
// Start server to test various certificate errors
TEST_RESULT_VOID(
hrnServerRunP(
HRN_FORK_CHILD_READ(), hrnServerProtocolTls,
.certificate = STRDEF(HRN_SERVER_CERT),
HRN_FORK_CHILD_READ(), hrnServerProtocolTls, testPort, .certificate = STRDEF(HRN_SERVER_CERT),
.key = STRDEF(HRN_SERVER_KEY)),
"tls alt name server run");
"tls alt name server");
}
HRN_FORK_CHILD_END();
@ -637,12 +637,12 @@ testRun(void)
TEST_ERROR_FMT(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), testPort, 5000, 5000), STRDEF("X"), 0, 0, true,
.caPath = STRDEF("/bogus"))),
CryptoError,
"unable to verify certificate presented by 'localhost:%u (127.0.0.1)': [20] unable to get local issuer"
" certificate",
hrnServerPort(0));
testPort);
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("valid ca file and match common name");
@ -653,7 +653,7 @@ testRun(void)
TEST_RESULT_VOID(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("test.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
sckClientNew(STRDEF("test.pgbackrest.org"), testPort, 5000, 5000),
STRDEF("test.pgbackrest.org"), 0, 0, true, .caFile = STRDEF(HRN_SERVER_CA))),
"open connection");
@ -666,7 +666,7 @@ testRun(void)
TEST_RESULT_VOID(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("host.test2.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
sckClientNew(STRDEF("host.test2.pgbackrest.org"), testPort, 5000, 5000),
STRDEF("host.test2.pgbackrest.org"), 0, 0, true, .caFile = STRDEF(HRN_SERVER_CA))),
"open connection");
@ -679,7 +679,7 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("test3.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
sckClientNew(STRDEF("test3.pgbackrest.org"), testPort, 5000, 5000),
STRDEF("test3.pgbackrest.org"), 0, 0, true, .caFile = STRDEF(HRN_SERVER_CA))),
CryptoError,
"unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names");
@ -693,12 +693,12 @@ testRun(void)
TEST_ERROR_FMT(
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
sckClientNew(STRDEF("localhost"), testPort, 5000, 5000), STRDEF("X"), 0, 0, true,
.caFile = STRDEF(HRN_SERVER_CERT))),
CryptoError,
"unable to verify certificate presented by 'localhost:%u (127.0.0.1)': [20] unable to get local issuer"
" certificate",
hrnServerPort(0));
testPort);
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("no certificate verify");
@ -708,7 +708,7 @@ testRun(void)
TEST_RESULT_VOID(
ioClientOpen(
tlsClientNewP(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, false)),
tlsClientNewP(sckClientNew(STRDEF("localhost"), testPort, 5000, 5000), STRDEF("X"), 0, 0, false)),
"open connection");
// -----------------------------------------------------------------------------------------------------------------
@ -736,17 +736,19 @@ testRun(void)
HRN_FORK_BEGIN()
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
{
// TLS server to accept connections
IoServer *socketServer = sckServerNew(STRDEF("localhost"), hrnServerPort(0), 5000);
IoServer *socketServer = sckServerNew(STRDEF("localhost"), testPort, 5000);
IoServer *tlsServer = tlsServerNew(
STRDEF("localhost"), STRDEF(HRN_SERVER_CA), STRDEF(TEST_PATH "/server-root-perm-link"),
STRDEF(TEST_PATH "/server-cn-only.crt"), 5000);
IoSession *socketSession = NULL;
TEST_RESULT_STR(
ioServerName(socketServer), strNewFmt("localhost:%u (127.0.0.1)", hrnServerPort(0)), "socket server name");
ioServerName(socketServer), strNewFmt("localhost:%u (127.0.0.1)", testPort), "socket server name");
TEST_RESULT_STR_Z(ioServerName(tlsServer), "localhost", "tls server name");
// Invalid client cert
@ -799,7 +801,7 @@ testRun(void)
clientSession,
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000,
sckClientNew(STRDEF("127.0.0.1"), testPort, 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000,
true, .certFile = STRDEF(TEST_PATH "/client-bad-ca.crt"),
.keyFile = STRDEF(HRN_SERVER_CLIENT_KEY))),
"client open");
@ -823,7 +825,7 @@ testRun(void)
clientSession,
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000, true,
sckClientNew(STRDEF("127.0.0.1"), testPort, 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(HRN_SERVER_CLIENT_KEY))),
"client open");
@ -840,7 +842,7 @@ testRun(void)
clientSession,
ioClientOpen(
tlsClientNewP(
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000,
sckClientNew(STRDEF("127.0.0.1"), testPort, 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000,
true)),
"client open");
@ -867,9 +869,11 @@ testRun(void)
HRN_FORK_BEGIN()
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
{
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls), "tls server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, testPort), "tls server");
}
HRN_FORK_CHILD_END();
@ -881,7 +885,7 @@ testRun(void)
TEST_ASSIGN(
client,
tlsClientNewP(
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 0, 0, TEST_IN_CONTAINER),
sckClientNew(hrnServerHost(), testPort, 5000, 5000), hrnServerHost(), 0, 0, TEST_IN_CONTAINER),
"new client");
hrnServerScriptAccept(tls);
@ -902,7 +906,7 @@ testRun(void)
zNewFmt(
"{type: tls, driver: {ioClient: {type: socket, driver: {host: %s, port: %u, timeoutConnect: 5000"
", timeoutSession: 5000}}, timeoutConnect: 0, timeoutSession: 0, verifyPeer: %s}}",
strZ(hrnServerHost()), hrnServerPort(0), cvtBoolToConstZ(TEST_IN_CONTAINER)),
strZ(hrnServerHost()), testPort, cvtBoolToConstZ(TEST_IN_CONTAINER)),
"check log");
TEST_RESULT_VOID(FUNCTION_LOG_OBJECT_FORMAT(session, ioSessionToLog, buffer, sizeof(buffer)), "ioSessionToLog");
@ -911,7 +915,7 @@ testRun(void)
zNewFmt(
"{type: tls, role: client, driver: {ioSession: {type: socket, role: client, driver: {host: %s, port: %u"
", fd: %d, timeout: 5000}}, timeout: 0, shutdownOnClose: true}}",
strZ(hrnServerHost()), hrnServerPort(0),
strZ(hrnServerHost()), testPort,
((SocketSession *)((TlsSession *)session->pub.driver)->ioSession->pub.driver)->fd),
"check log");
@ -971,7 +975,7 @@ testRun(void)
((IoFdRead *)((SocketSession *)tlsSession->ioSession->pub.driver)->read->pub.driver)->timeout = 100;
TEST_ERROR_FMT(
ioRead(ioSessionIoReadP(session), output), FileReadError,
"timeout after 100ms waiting for read from '%s:%u'", strZ(hrnServerHost()), hrnServerPort(0));
"timeout after 100ms waiting for read from '%s:%u'", strZ(hrnServerHost()), testPort);
((IoFdRead *)((SocketSession *)tlsSession->ioSession->pub.driver)->read->pub.driver)->timeout = 5000;
// -----------------------------------------------------------------------------------------------------------------

View File

@ -725,6 +725,8 @@ testRun(void)
HRN_FORK_BEGIN()
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN()
{
// -----------------------------------------------------------------------------------------------------------------
@ -732,7 +734,7 @@ testRun(void)
// Connect to server without any verification
IoClient *tlsClient = tlsClientNewP(
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 5000, 5000, false);
sckClientNew(hrnServerHost(), testPort, 5000, 5000), hrnServerHost(), 5000, 5000, false);
IoSession *tlsSession = ioClientOpen(tlsClient);
// Send ping
@ -752,7 +754,7 @@ testRun(void)
hrnCfgArgRawZ(argList, cfgOptRepoHostType, "tls");
hrnCfgArgRawZ(argList, cfgOptRepoHostCertFile, HRN_SERVER_CLIENT_CERT);
hrnCfgArgRawZ(argList, cfgOptRepoHostKeyFile, HRN_SERVER_CLIENT_KEY);
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", testPort);
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
HRN_CFG_LOAD(cfgCmdArchiveGet, argList);
@ -783,7 +785,7 @@ testRun(void)
hrnCfgArgRawZ(argList, cfgOptRepoHostType, "tls");
hrnCfgArgRawZ(argList, cfgOptRepoHostCertFile, HRN_SERVER_CLIENT_CERT);
hrnCfgArgRawZ(argList, cfgOptRepoHostKeyFile, HRN_SERVER_CLIENT_KEY);
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", testPort);
HRN_CFG_LOAD(cfgCmdInfo, argList);
TEST_ERROR_FMT(
@ -800,7 +802,7 @@ testRun(void)
hrnCfgArgRawZ(argList, cfgOptPgHostType, "tls");
hrnCfgArgRawZ(argList, cfgOptPgHostCertFile, HRN_SERVER_CLIENT_CERT);
hrnCfgArgRawZ(argList, cfgOptPgHostKeyFile, HRN_SERVER_CLIENT_KEY);
hrnCfgArgRawFmt(argList, cfgOptPgHostPort, "%u", hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptPgHostPort, "%u", testPort);
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
hrnCfgArgRawZ(argList, cfgOptProcess, "1");
HRN_CFG_LOAD(cfgCmdBackup, argList, .role = cfgCmdRoleLocal);
@ -816,7 +818,7 @@ testRun(void)
{
IoServer *const tlsServer = tlsServerNew(
STRDEF("localhost"), STRDEF(HRN_SERVER_CA), STRDEF(HRN_SERVER_KEY), STRDEF(HRN_SERVER_CERT), 5000);
IoServer *const socketServer = sckServerNew(STRDEF("localhost"), hrnServerPort(0), 5000);
IoServer *const socketServer = sckServerNew(STRDEF("localhost"), testPort, 5000);
ProtocolServer *server = NULL;
// Server ping

View File

@ -457,9 +457,11 @@ testRun(void)
{
HRN_FORK_BEGIN()
{
const unsigned int testPort = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "azure server", .timeout = 5000)
{
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls), "azure server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, testPort), "azure server");
}
HRN_FORK_CHILD_END();
@ -475,7 +477,7 @@ testRun(void)
hrnCfgArgRawStrId(argList, cfgOptRepoType, STORAGE_AZURE_TYPE);
hrnCfgArgRawZ(argList, cfgOptRepoPath, "/");
hrnCfgArgRawZ(argList, cfgOptRepoAzureContainer, TEST_CONTAINER);
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "https://%s:%u", strZ(hrnServerHost()), hrnServerPort(0));
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "https://%s:%u", strZ(hrnServerHost()), testPort);
hrnCfgArgRawBool(argList, cfgOptRepoStorageVerifyTls, TEST_IN_CONTAINER);
hrnCfgEnvRawZ(cfgOptRepoAzureAccount, TEST_ACCOUNT);
hrnCfgEnvRawZ(cfgOptRepoAzureKey, TEST_KEY_SHARED);

View File

@ -204,12 +204,6 @@ testRun(void)
Storage *storageTest = storagePosixNewP(TEST_PATH_STR, .write = true);
// Get test host and ports
const String *const testHost = hrnServerHost();
const unsigned int testPort = hrnServerPort(0);
const unsigned int testPortAuth = hrnServerPort(1);
const unsigned int testPortMeta = hrnServerPort(2);
// *****************************************************************************************************************************
if (testBegin("storageRepoGet()"))
{
@ -292,27 +286,30 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("StorageGcs, StorageReadGcs, and StorageWriteGcs"))
{
HRN_STORAGE_PUT(storageTest, TEST_KEY_FILE, BUFSTR(strNewFmt(TEST_KEY, strZ(testHost), testPortAuth)));
HRN_FORK_BEGIN()
{
const String *const testHost = hrnServerHost();
const unsigned int testPort = hrnServerPortNext();
const unsigned int testPortAuth = hrnServerPortNext();
const unsigned int testPortMeta = hrnServerPortNext();
HRN_STORAGE_PUT(storageTest, TEST_KEY_FILE, BUFSTR(strNewFmt(TEST_KEY, strZ(testHost), testPortAuth)));
HRN_FORK_CHILD_BEGIN(.prefix = "gcs server", .timeout = 10000)
{
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, .port = testPort), "gcs server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, testPort), "gcs server");
}
HRN_FORK_CHILD_END();
HRN_FORK_CHILD_BEGIN(.prefix = "auth server", .timeout = 10000)
{
TEST_RESULT_VOID(
hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, .port = testPortAuth), "auth server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, testPortAuth), "auth server");
}
HRN_FORK_CHILD_END();
HRN_FORK_CHILD_BEGIN(.prefix = "meta server", .timeout = 30000)
{
TEST_RESULT_VOID(
hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket, .port = testPortMeta), "meta server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket, testPortMeta), "meta server");
}
HRN_FORK_CHILD_END();

View File

@ -250,8 +250,6 @@ testRun(void)
const String *region = STRDEF("us-east-1");
const String *endPoint = STRDEF("s3.amazonaws.com");
const String *host = hrnServerHost();
const unsigned int port = hrnServerPort(0);
const unsigned int authPort = hrnServerPort(1);
const String *accessKey = STRDEF("AKIAIOSFODNN7EXAMPLE");
const String *secretAccessKey = STRDEF("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
const String *securityToken = STRDEF(
@ -404,16 +402,18 @@ testRun(void)
{
HRN_FORK_BEGIN()
{
const unsigned int testPort = hrnServerPortNext();
const unsigned int testPortAuth = hrnServerPortNext();
HRN_FORK_CHILD_BEGIN(.prefix = "s3 server", .timeout = 5000)
{
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, .port = port), "s3 server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, testPort), "s3 server");
}
HRN_FORK_CHILD_END();
HRN_FORK_CHILD_BEGIN(.prefix = "auth server", .timeout = 10000)
{
TEST_RESULT_VOID(
hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket, .port = authPort), "auth server run");
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket, testPortAuth), "auth server");
}
HRN_FORK_CHILD_END();
@ -429,7 +429,7 @@ testRun(void)
TEST_TITLE("config with keys, token, and host with custom port");
StringList *argList = strLstDup(commonArgList);
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "%s:%u", strZ(host), port);
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "%s:%u", strZ(host), testPort);
hrnCfgEnvRaw(cfgOptRepoS3Token, securityToken);
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
@ -488,7 +488,7 @@ testRun(void)
hrnServerScriptClose(service);
argList = strLstDup(commonArgList);
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "%s:%u", strZ(host), port);
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "%s:%u", strZ(host), testPort);
hrnCfgArgRaw(argList, cfgOptRepoS3Role, credRole);
hrnCfgArgRawStrId(argList, cfgOptRepoS3KeyType, storageS3KeyTypeAuto);
hrnCfgArgRawZ(argList, cfgOptRepoS3KmsKeyId, "kmskey1");
@ -508,7 +508,7 @@ testRun(void)
// Testing requires the auth http client to be redirected
driver->credHost = hrnServerHost();
driver->credHttpClient = httpClientNew(sckClientNew(host, authPort, 5000, 5000), 5000);
driver->credHttpClient = httpClientNew(sckClientNew(host, testPortAuth, 5000, 5000), 5000);
// Now that we have checked the role when set explicitly, null it out to make sure it is retrieved automatically
driver->credRole = NULL;
@ -926,7 +926,7 @@ testRun(void)
HRN_STORAGE_PUT_Z(storagePosixNewP(TEST_PATH_STR, .write = true), "web-id-token", TEST_SERVICE_TOKEN);
argList = strLstDup(commonArgList);
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "%s:%u", strZ(host), port);
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "%s:%u", strZ(host), testPort);
hrnCfgArgRawStrId(argList, cfgOptRepoS3KeyType, storageS3KeyTypeWebId);
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
@ -953,7 +953,7 @@ testRun(void)
// Testing requires the auth http client to be redirected
driver->credHost = hrnServerHost();
driver->credHttpClient = httpClientNew(sckClientNew(host, authPort, 5000, 5000), 5000);
driver->credHttpClient = httpClientNew(sckClientNew(host, testPortAuth, 5000, 5000), 5000);
hrnServerScriptAccept(service);
@ -1243,7 +1243,7 @@ testRun(void)
argList = strLstDup(commonArgList);
hrnCfgArgRawStrId(argList, cfgOptRepoS3UriStyle, storageS3UriStylePath);
hrnCfgArgRawFmt(argList, cfgOptRepoStorageHost, "https://%s", strZ(host));
hrnCfgArgRawFmt(argList, cfgOptRepoStoragePort, "%u", port);
hrnCfgArgRawFmt(argList, cfgOptRepoStoragePort, "%u", testPort);
hrnCfgEnvRemoveRaw(cfgOptRepoS3Token);
HRN_CFG_LOAD(cfgCmdArchivePush, argList);