1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-10-30 23:37:45 +02:00

Allow tests that use ports to run in parallel.

Set the test index in the C unit test code so it can assign port numbers that won't conflict between tests.
This commit is contained in:
David Steele
2019-10-10 16:13:43 -04:00
parent 13fcbb24e9
commit 6db4e59a66
10 changed files with 76 additions and 34 deletions

View File

@@ -389,6 +389,7 @@ sub run
$strTestC =~ s/\{\[C\_TEST\_PROJECT\_EXE\]\}/$strProjectExePath/g;
$strTestC =~ s/\{\[C\_TEST\_PATH\]\}/$strTestPathC/g;
$strTestC =~ s/\{\[C\_TEST\_DATA_PATH\]\}/$self->{strDataPath}/g;
$strTestC =~ s/\{\[C\_TEST\_IDX\]\}/$self->{iVmIdx}/g;
$strTestC =~ s/\{\[C\_TEST\_REPO_PATH\]\}/$self->{strBackRestBase}/g;
$strTestC =~ s/\{\[C\_TEST\_SCALE\]\}/$self->{iScale}/g;

View File

@@ -186,6 +186,30 @@ testDataPathSet(const char *testDataPath)
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get and set test index
***********************************************************************************************************************************/
static unsigned int testIdxData = 0;
unsigned int
testIdx(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(UINT, testIdxData);
}
void
testIdxSet(unsigned int testIdx)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(UINT, testIdx);
FUNCTION_HARNESS_END();
testIdxData = testIdx;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get and set scale for performance testing
***********************************************************************************************************************************/

View File

@@ -41,6 +41,10 @@ bool testContainer(void);
// Location of the data path were the harness can write data that won't be visible to the test
const char *testDataPath(void);
// Get the 0-based index of the test. Useful for modifying resources like port numbers to avoid conflicts when running tests in
// parallel.
unsigned int testIdx(void);
// Location of the project exe
const char *testProjectExe(void);

View File

@@ -31,7 +31,7 @@ static SSL *testClientSSL = NULL;
Initialize TLS and listen on the specified port for TLS connections
***********************************************************************************************************************************/
void
harnessTlsServerInit(int port, const char *serverCert, const char *serverKey)
harnessTlsServerInit(unsigned int port, const char *serverCert, const char *serverKey)
{
// Add test hosts
if (testContainer())
@@ -92,11 +92,11 @@ void
harnessTlsServerInitDefault(void)
{
if (testContainer())
harnessTlsServerInit(TLS_TEST_PORT, TLS_CERT_TEST_CERT, TLS_CERT_TEST_KEY);
harnessTlsServerInit(harnessTlsTestPort(), TLS_CERT_TEST_CERT, TLS_CERT_TEST_KEY);
else
{
harnessTlsServerInit(
TLS_TEST_PORT,
harnessTlsTestPort(),
strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath())),
strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".key", testRepoPath())));
}
@@ -180,3 +180,9 @@ const String *harnessTlsTestHost(void)
{
return strNew(testContainer() ? TLS_TEST_HOST : "localhost");
}
/**********************************************************************************************************************************/
unsigned int harnessTlsTestPort(void)
{
return 44443 + testIdx();
}

View File

@@ -14,8 +14,6 @@ Path and prefix for test certificates
/***********************************************************************************************************************************
Tls test defaults
***********************************************************************************************************************************/
#define TLS_TEST_PORT 9443
#define TLS_CERT_FAKE_PATH "/etc/fake-cert"
#define TLS_CERT_TEST_CERT TLS_CERT_FAKE_PATH "/pgbackrest-test.crt"
#define TLS_CERT_TEST_KEY TLS_CERT_FAKE_PATH "/pgbackrest-test.key"
@@ -23,7 +21,7 @@ Tls test defaults
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void harnessTlsServerInit(int port, const char *serverCert, const char *serverKey);
void harnessTlsServerInit(unsigned int port, const char *serverCert, const char *serverKey);
// Initialize TLS with default parameters
void harnessTlsServerInitDefault(void);
@@ -39,4 +37,7 @@ Getters
// Hostname to use for testing -- this will vary based on whether the test is running in a container
const String *harnessTlsTestHost(void);
// Port to use for testing. This will be unique for each test running in parallel to avoid conflicts
unsigned int harnessTlsTestPort(void);
#endif

View File

@@ -410,22 +410,24 @@ testRun(void)
httpClientStatLocal = (HttpClientStat){0};
TEST_RESULT_STR(httpClientStatStr(), NULL, "no stats yet");
TEST_ASSIGN(client, httpClientNew(strNew("localhost"), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client");
TEST_ASSIGN(
client, httpClientNew(strNew("localhost"), harnessTlsTestPort(), 500, testContainer(), NULL, NULL), "new client");
TEST_ERROR_FMT(
httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), HostConnectError,
"unable to connect to 'localhost:%d': [111] Connection refused", TLS_TEST_PORT);
"unable to connect to 'localhost:%u': [111] Connection refused", harnessTlsTestPort());
// Start http test server
testHttpServer();
// Test no output from server
TEST_ASSIGN(client, httpClientNew(harnessTlsTestHost(), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client");
TEST_ASSIGN(
client, httpClientNew(harnessTlsTestHost(), harnessTlsTestPort(), 500, testContainer(), NULL, NULL), "new client");
client->timeout = 0;
TEST_ERROR_FMT(
httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), FileReadError,
"timeout after 500ms waiting for read from '%s:%d'", strPtr(harnessTlsTestHost()), TLS_TEST_PORT);
"timeout after 500ms waiting for read from '%s:%u'", strPtr(harnessTlsTestHost()), harnessTlsTestPort());
// Test invalid http version
TEST_ERROR(
@@ -576,7 +578,8 @@ testRun(void)
HttpClient *client1 = NULL;
HttpClient *client2 = NULL;
TEST_ASSIGN(cache, httpClientCacheNew(strNew("localhost"), TLS_TEST_PORT, 500, true, NULL, NULL), "new http client cache");
TEST_ASSIGN(
cache, httpClientCacheNew(strNew("localhost"), harnessTlsTestPort(), 500, true, NULL, NULL), "new http client cache");
TEST_ASSIGN(client1, httpClientCacheGet(cache), "get http client");
TEST_RESULT_PTR(client1, *(HttpClient **)lstGet(cache->clientList, 0), " check http client");
TEST_RESULT_PTR(httpClientCacheGet(cache), *(HttpClient **)lstGet(cache->clientList, 0), " get same http client");

View File

@@ -16,7 +16,7 @@ testTlsServerAltName(void)
if (fork() == 0)
{
harnessTlsServerInit(
TLS_TEST_PORT,
harnessTlsTestPort(),
strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-alt-name.crt", testRepoPath())),
strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".key", testRepoPath())));
@@ -121,7 +121,7 @@ testRun(void)
{
TlsClient *client = NULL;
TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), TLS_TEST_PORT, 0, true, NULL, NULL), "new client");
TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), harnessTlsTestPort(), 0, true, NULL, NULL), "new client");
TEST_RESULT_BOOL(tlsError(client, SSL_ERROR_WANT_READ), true, "continue after want read");
TEST_RESULT_BOOL(tlsError(client, SSL_ERROR_ZERO_RETURN), false, "check connection closed error");
@@ -135,14 +135,14 @@ testRun(void)
// Connection errors
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), TLS_TEST_PORT, 0, true, NULL, NULL), "new client");
TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), harnessTlsTestPort(), 0, true, NULL, NULL), "new client");
TEST_ERROR(
tlsClientOpen(client), HostConnectError, "unable to get address for '99.99.99.99.99': [-2] Name or service not known");
TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 100, true, NULL, NULL), "new client");
TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), harnessTlsTestPort(), 100, true, NULL, NULL), "new client");
TEST_ERROR_FMT(
tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:%d': [111] Connection refused",
TLS_TEST_PORT);
tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u': [111] Connection refused",
harnessTlsTestPort());
// Certificate location and validation errors
// -------------------------------------------------------------------------------------------------------------------------
@@ -161,28 +161,29 @@ testRun(void)
testTlsServerAltName();
TEST_ERROR(
tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, true, strNew("bogus.crt"), strNew("/bogus"))),
tlsClientOpen(
tlsClientNew(strNew("localhost"), harnessTlsTestPort(), 500, true, strNew("bogus.crt"), strNew("/bogus"))),
CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory");
TEST_ERROR_FMT(
tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, true, NULL, strNew("/bogus"))),
CryptoError, "unable to verify certificate presented by 'localhost:%d': [20] unable to get local issuer certificate",
TLS_TEST_PORT);
tlsClientOpen(tlsClientNew(strNew("localhost"), harnessTlsTestPort(), 500, true, NULL, strNew("/bogus"))),
CryptoError, "unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
harnessTlsTestPort());
if (testContainer())
{
TEST_RESULT_VOID(
tlsClientOpen(
tlsClientNew(strNew("test.pgbackrest.org"), TLS_TEST_PORT, 500, true,
tlsClientNew(strNew("test.pgbackrest.org"), harnessTlsTestPort(), 500, true,
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
"success on valid ca file and match common name");
TEST_RESULT_VOID(
tlsClientOpen(
tlsClientNew(strNew("host.test2.pgbackrest.org"), TLS_TEST_PORT, 500, true,
tlsClientNew(strNew("host.test2.pgbackrest.org"), harnessTlsTestPort(), 500, true,
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
"success on valid ca file and match alt name");
TEST_ERROR(
tlsClientOpen(
tlsClientNew(strNew("test3.pgbackrest.org"), TLS_TEST_PORT, 500, true,
tlsClientNew(strNew("test3.pgbackrest.org"), harnessTlsTestPort(), 500, true,
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
CryptoError,
"unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names");
@@ -191,13 +192,14 @@ testRun(void)
TEST_ERROR_FMT(
tlsClientOpen(
tlsClientNew(
strNew("localhost"), TLS_TEST_PORT, 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath()),
strNew("localhost"), harnessTlsTestPort(), 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt",
testRepoPath()),
NULL)),
CryptoError, "unable to verify certificate presented by 'localhost:%d': [20] unable to get local issuer certificate",
TLS_TEST_PORT);
CryptoError, "unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
harnessTlsTestPort());
TEST_RESULT_VOID(
tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, false, NULL, NULL)), "success on no verify");
tlsClientOpen(tlsClientNew(strNew("localhost"), harnessTlsTestPort(), 500, false, NULL, NULL)), "success on no verify");
}
// *****************************************************************************************************************************
if (testBegin("TlsClient general usage"))
@@ -211,7 +213,8 @@ testRun(void)
testTlsServer();
ioBufferSizeSet(12);
TEST_ASSIGN(client, tlsClientNew(harnessTlsTestHost(), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client");
TEST_ASSIGN(
client, tlsClientNew(harnessTlsTestHost(), harnessTlsTestPort(), 500, testContainer(), NULL, NULL), "new client");
TEST_RESULT_VOID(tlsClientOpen(client), "open client");
const Buffer *input = BUFSTRDEF("some protocol info");
@@ -234,7 +237,7 @@ testRun(void)
output = bufNew(12);
TEST_ERROR_FMT(
ioRead(tlsClientIoRead(client), output), FileReadError,
"timeout after 500ms waiting for read from '%s:%d'", strPtr(harnessTlsTestHost()), TLS_TEST_PORT);
"timeout after 500ms waiting for read from '%s:%u'", strPtr(harnessTlsTestHost()), harnessTlsTestPort());
// -------------------------------------------------------------------------------------------------------------------------
input = BUFSTRDEF("more protocol info");

View File

@@ -510,7 +510,7 @@ testRun(void)
const String *region = strNew("us-east-1");
const String *endPoint = strNew("s3.amazonaws.com");
const String *host = harnessTlsTestHost();
const unsigned int port = TLS_TEST_PORT;
const unsigned int port = harnessTlsTestPort();
const String *accessKey = strNew("AKIAIOSFODNN7EXAMPLE");
const String *secretAccessKey = strNew("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
const String *securityToken = strNew(

View File

@@ -32,6 +32,7 @@ The test code is included directly so it can freely interact with the included C
void testContainerSet(bool testContainer);
void testDataPathSet(const char *testDataPath);
void testIdxSet(unsigned int testIdx);
void testScaleSet(uint64_t testScale);
void testProjectExeSet(const char *testProjectExe);
@@ -88,6 +89,7 @@ main(int argListSize, const char *argList[])
testPathSet("{[C_TEST_PATH]}");
testRepoPathSet("{[C_TEST_REPO_PATH]}");
testDataPathSet("{[C_TEST_DATA_PATH]}");
testIdxSet({[C_TEST_IDX]});
testScaleSet({[C_TEST_SCALE]});
// Set default test log level

View File

@@ -201,8 +201,6 @@ eval
processEnd();
# Run tests
$strParam .= " --vm-max=2";
if ($strVm eq VM_U18)
{
$strParam .= " --container-only";
@@ -219,7 +217,7 @@ eval
processBegin(($strVm eq VM_NONE ? "no container" : $strVm) . ' test');
processExec(
"${strTestExe} --no-gen --vm-host=${strVmHost} --vm=${strVm}${strParam}",
"${strTestExe} --no-gen --vm-host=${strVmHost} --vm-max=2 --vm=${strVm}${strParam}",
{bShowOutputAsync => true, bOutLogOnError => false});
processEnd();
}