1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Use standard HARNESS_FORK*() macros to fork test servers.

These forks were done in a custom way (not sure why) and lack the capability of the standard macros for the parent to wait for child exit.

This mean that the server would continue to run after the tests were complete and that multiple servers could run at once. This caused subtle timing and connection issues that required larger timeouts to resolve.

Don't change the timeouts here since they need to be adjusted in future commits anyway.
This commit is contained in:
David Steele 2020-04-12 09:01:41 -04:00
parent 42246401b8
commit 71ce637557
3 changed files with 1196 additions and 1158 deletions

View File

@ -3,9 +3,11 @@ Test Http
***********************************************************************************************************************************/
#include <unistd.h>
#include "common/harnessTls.h"
#include "common/time.h"
#include "common/harnessFork.h"
#include "common/harnessTls.h"
/***********************************************************************************************************************************
Test server
***********************************************************************************************************************************/
@ -14,11 +16,6 @@ testHttpServer(void)
{
FUNCTION_HARNESS_VOID();
if (fork() == 0)
{
// Change log process id to aid in debugging
hrnLogProcessIdSet(1);
harnessTlsServerInitDefault();
// Test no output from server
@ -317,9 +314,6 @@ testHttpServer(void)
harnessTlsServerClose();
exit(0);
}
FUNCTION_HARNESS_RESULT_VOID();
}
@ -446,21 +440,32 @@ testRun(void)
// Reset statistics
httpClientStatLocal = (HttpClientStat){0};
TEST_RESULT_PTR(httpClientStatStr(), NULL, "no stats yet");
TEST_ASSIGN(
client, httpClientNew(strNew("localhost"), harnessTlsTestPort(), 500, testContainer(), NULL, NULL), "new client");
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:%u': [111] Connection refused", harnessTlsTestPort());
HARNESS_FORK_BEGIN()
{
HARNESS_FORK_CHILD_BEGIN(0, false)
{
// Start http test server
TEST_RESULT_VOID(testHttpServer(), "http server begin");
}
HARNESS_FORK_CHILD_END();
HARNESS_FORK_PARENT_BEGIN()
{
// Test no output from server
TEST_ASSIGN(
client, httpClientNew(harnessTlsTestHost(), harnessTlsTestPort(), 500, testContainer(), NULL, NULL), "new client");
client, httpClientNew(harnessTlsTestHost(), harnessTlsTestPort(), 500, testContainer(), NULL, NULL),
"new client");
client->timeout = 0;
TEST_ERROR_FMT(
@ -498,7 +503,9 @@ testRun(void)
"'transfer-encoding' and 'content-length' headers are both set");
// Test 5xx error with no retry
TEST_ERROR(httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), ServiceError, "[503] Slow Down");
TEST_ERROR(
httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), ServiceError,
"[503] Slow Down");
// Request with no content
client->timeout = 2000;
@ -511,7 +518,8 @@ testRun(void)
httpQueryAdd(query, strNew("type"), strNew("test"));
TEST_RESULT_VOID(
httpClientRequest(client, strNew("GET"), strNew("/"), query, headerRequest, NULL, false), "request with no content");
httpClientRequest(client, strNew("GET"), strNew("/"), query, headerRequest, NULL, false),
"request with no content");
TEST_RESULT_UINT(httpClientResponseCode(client), 200, " check response code");
TEST_RESULT_STR_Z(httpClientResponseMessage(client), "OK", " check response message");
TEST_RESULT_UINT(httpClientEof(client), true, " io is eof");
@ -539,7 +547,8 @@ testRun(void)
TEST_RESULT_BOOL(httpClientEof(client), true, " io is eof");
TEST_RESULT_BOOL(httpClientBusy(client), false, " client is not busy");
TEST_RESULT_STR_Z(
httpHeaderToLog(httpClientResponseHeader(client)), "{transfer-encoding: 'chunked'}", " check response headers");
httpHeaderToLog(httpClientResponseHeader(client)), "{transfer-encoding: 'chunked'}",
" check response headers");
// Head request with connection close but no content
TEST_RESULT_VOID(
@ -564,7 +573,8 @@ testRun(void)
Buffer *buffer = NULL;
TEST_ASSIGN(
buffer, httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), "error with content length");
buffer, httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false),
"error with content length");
TEST_RESULT_UINT(httpClientResponseCode(client), 403, " check response code");
TEST_RESULT_STR_Z(httpClientResponseMessage(client), "Auth Error", " check response message");
TEST_RESULT_STR_Z(
@ -605,9 +615,11 @@ testRun(void)
// Request with content using chunked encoding
TEST_RESULT_VOID(
httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), "request with chunked encoding");
httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false),
"request with chunked encoding");
TEST_RESULT_STR_Z(
httpHeaderToLog(httpClientResponseHeader(client)), "{transfer-encoding: 'chunked'}", " check response headers");
httpHeaderToLog(httpClientResponseHeader(client)), "{transfer-encoding: 'chunked'}",
" check response headers");
buffer = bufNew(35);
TEST_RESULT_VOID(ioRead(httpClientIoRead(client), buffer), " read response");
@ -617,6 +629,10 @@ testRun(void)
TEST_RESULT_VOID(httpClientFree(client), "free client");
}
HARNESS_FORK_PARENT_END();
}
HARNESS_FORK_END();
}
// *****************************************************************************************************************************
if (testBegin("HttpClientCache"))

View File

@ -6,6 +6,7 @@ Test Tls Client
#include "common/time.h"
#include "common/harnessFork.h"
#include "common/harnessTls.h"
/***********************************************************************************************************************************
@ -16,11 +17,6 @@ testTlsServerAltName(void)
{
FUNCTION_HARNESS_VOID();
if (fork() == 0)
{
// Change log process id to aid in debugging
hrnLogProcessIdSet(1);
harnessTlsServerInit(
harnessTlsTestPort(),
strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-alt-name.crt", testRepoPath())),
@ -53,9 +49,6 @@ testTlsServerAltName(void)
harnessTlsServerAccept();
harnessTlsServerClose();
exit(0);
}
FUNCTION_HARNESS_RESULT_VOID();
}
@ -67,11 +60,6 @@ testTlsServer(void)
{
FUNCTION_HARNESS_VOID();
if (fork() == 0)
{
// Change log process id to aid in debugging
hrnLogProcessIdSet(1);
harnessTlsServerInitDefault();
// First protocol exchange
@ -99,9 +87,6 @@ testTlsServer(void)
harnessTlsServerReply("0123456789AB");
harnessTlsServerClose();
exit(0);
}
FUNCTION_HARNESS_RESULT_VOID();
}
@ -289,9 +274,17 @@ testRun(void)
}
}
HARNESS_FORK_BEGIN()
{
HARNESS_FORK_CHILD_BEGIN(0, false)
{
// Start server to test various certificate errors
TEST_RESULT_VOID(testTlsServerAltName(), "tls alt name server begin");
}
HARNESS_FORK_CHILD_END();
HARNESS_FORK_PARENT_BEGIN()
{
TEST_ERROR(
tlsClientOpen(
tlsClientNew(
@ -300,8 +293,10 @@ testRun(void)
CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory");
TEST_ERROR_FMT(
tlsClientOpen(
tlsClientNew(sckClientNew(strNew("localhost"), harnessTlsTestPort(), 500), 500, true, NULL, strNew("/bogus"))),
CryptoError, "unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
tlsClientNew(
sckClientNew(strNew("localhost"), harnessTlsTestPort(), 500), 500, true, NULL, strNew("/bogus"))),
CryptoError,
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
harnessTlsTestPort());
if (testContainer())
@ -333,7 +328,8 @@ testRun(void)
sckClientNew(strNew("localhost"), harnessTlsTestPort(), 500), 500, true,
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath()),
NULL)),
CryptoError, "unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
CryptoError,
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
harnessTlsTestPort());
TEST_RESULT_VOID(
@ -341,6 +337,10 @@ testRun(void)
tlsClientNew(sckClientNew(strNew("localhost"), harnessTlsTestPort(), 500), 500, false, NULL, NULL)),
"success on no verify");
}
HARNESS_FORK_PARENT_END();
}
HARNESS_FORK_END();
}
// *****************************************************************************************************************************
if (testBegin("TlsClient general usage"))
@ -353,11 +353,21 @@ testRun(void)
tlsClientStatLocal = (TlsClientStat){0};
TEST_RESULT_PTR(tlsClientStatStr(), NULL, "no stats yet");
HARNESS_FORK_BEGIN()
{
HARNESS_FORK_CHILD_BEGIN(0, false)
{
TEST_RESULT_VOID(testTlsServer(), "tls server begin");
}
HARNESS_FORK_CHILD_END();
HARNESS_FORK_PARENT_BEGIN()
{
ioBufferSizeSet(12);
TEST_ASSIGN(
client, tlsClientNew(sckClientNew(harnessTlsTestHost(), harnessTlsTestPort(), 500), 500, testContainer(), NULL, NULL),
client,
tlsClientNew(sckClientNew(harnessTlsTestHost(), harnessTlsTestPort(), 500), 500, testContainer(), NULL, NULL),
"new client");
TEST_RESULT_VOID(tlsClientOpen(client), "open client");
@ -383,7 +393,7 @@ testRun(void)
ioRead(tlsClientIoRead(client), output), FileReadError,
"timeout after 500ms waiting for read from '%s:%u'", strPtr(harnessTlsTestHost()), harnessTlsTestPort());
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
input = BUFSTRDEF("more protocol info");
TEST_RESULT_VOID(tlsClientOpen(client), "open client again (it is already open)");
TEST_RESULT_VOID(ioWrite(tlsClientIoWrite(client), input), "write input");
@ -398,7 +408,7 @@ testRun(void)
TEST_RESULT_UINT(ioRead(tlsClientIoRead(client), output), 0, "read no output after eof");
TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), true, " check eof = true");
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_RESULT_VOID(tlsClientOpen(client), "open client again (was closed by server)");
TEST_RESULT_BOOL(tlsWriteContinue(client, -1, SSL_ERROR_WANT_READ, 1), true, "continue on WANT_READ");
TEST_RESULT_BOOL(tlsWriteContinue(client, 0, SSL_ERROR_NONE, 1), true, "continue on WANT_READ");
@ -407,12 +417,16 @@ testRun(void)
"unable to write to tls, write size 77 does not match expected size 88");
TEST_ERROR(tlsWriteContinue(client, 0, SSL_ERROR_ZERO_RETURN, 1), FileWriteError, "unable to write to tls [6]");
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_RESULT_BOOL(sckClientStatStr() != NULL, true, "check statistics exist");
TEST_RESULT_BOOL(tlsClientStatStr() != NULL, true, "check statistics exist");
TEST_RESULT_VOID(tlsClientFree(client), "free client");
}
HARNESS_FORK_PARENT_END();
}
HARNESS_FORK_END();
}
FUNCTION_HARNESS_RESULT_VOID();
}

View File

@ -4,6 +4,7 @@ Test S3 Storage
#include <unistd.h>
#include "common/harnessConfig.h"
#include "common/harnessFork.h"
#include "common/harnessStorage.h"
#include "common/harnessTls.h"
@ -87,11 +88,6 @@ testS3Server(void)
{
FUNCTION_HARNESS_VOID();
if (fork() == 0)
{
// Change log process id to aid in debugging
hrnLogProcessIdSet(1);
harnessTlsServerInitDefault();
harnessTlsServerAccept();
@ -520,8 +516,6 @@ testS3Server(void)
harnessTlsServerReply(testS3ServerResponse(204, "No Content", NULL, NULL));
harnessTlsServerClose();
exit(0);
}
FUNCTION_HARNESS_RESULT_VOID();
}
@ -758,25 +752,34 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("storageS3*(), StorageReadS3, and StorageWriteS3"))
{
HARNESS_FORK_BEGIN()
{
HARNESS_FORK_CHILD_BEGIN(0, false)
{
TEST_RESULT_VOID(testS3Server(), "s3 server begin");
}
HARNESS_FORK_CHILD_END();
HARNESS_FORK_PARENT_BEGIN()
{
Storage *s3 = storageS3New(
path, true, NULL, bucket, endPoint, storageS3UriStyleHost, region, accessKey, secretAccessKey, NULL, 16, 2, host, port,
1000, testContainer(), NULL, NULL);
path, true, NULL, bucket, endPoint, storageS3UriStyleHost, region, accessKey, secretAccessKey, NULL, 16, 2,
host, port, 1000, testContainer(), NULL, NULL);
// Coverage for noop functions
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_RESULT_VOID(storagePathSyncP(s3, strNew("path")), "path sync is a noop");
// storageS3NewRead() and StorageS3FileRead
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_RESULT_PTR(
storageGetP(storageNewReadP(s3, strNew("fi&le.txt"), .ignoreMissing = true)), NULL, "ignore missing file");
TEST_ERROR(
storageGetP(storageNewReadP(s3, strNew("file.txt"))), FileMissingError,
"unable to open '/file.txt': No such file or directory");
TEST_RESULT_STR_Z(strNewBuf(storageGetP(storageNewReadP(s3, strNew("file.txt")))), "this is a sample file", "get file");
TEST_RESULT_STR_Z(
strNewBuf(storageGetP(storageNewReadP(s3, strNew("file.txt")))), "this is a sample file", "get file");
TEST_RESULT_STR_Z(strNewBuf(storageGetP(storageNewReadP(s3, strNew("file0.txt")))), "", "get zero-length file");
StorageRead *read = NULL;
@ -801,7 +804,7 @@ testRun(void)
"CONTENT")
// storageS3NewWrite() and StorageWriteS3
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
// File is written all at once
StorageWrite *write = NULL;
TEST_ASSIGN(write, storageNewWriteP(s3, strNew("file.txt")), "new write file");
@ -834,12 +837,12 @@ testRun(void)
"write file in chunks -- something left on close");
// storageDriverExists()
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_RESULT_BOOL(storageExistsP(s3, strNew("BOGUS")), false, "file does not exist");
TEST_RESULT_BOOL(storageExistsP(s3, strNew("subdir/file1.txt")), true, "file exists");
// Info()
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_RESULT_BOOL(storageInfoP(s3, strNew("BOGUS"), .ignoreMissing = true).exists, false, "file does not exist");
StorageInfo info;
@ -857,7 +860,7 @@ testRun(void)
TEST_RESULT_UINT(info.size, 0, " check exists");
TEST_RESULT_INT(info.timeModified, 0, " check time");
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("list basic level");
HarnessStorageInfoListCallbackData callbackData =
@ -877,7 +880,7 @@ testRun(void)
"test_file {file, s=787, t=1255369830}\n",
" check content");
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("various errors");
TEST_ERROR(
@ -923,7 +926,7 @@ testRun(void)
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><Error><Code>RequestTimeTooSkewed</Code>"
"<Message>The difference between the request time and the current time is too large.</Message></Error>");
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("list exists level");
callbackData.content = strNew("");
@ -949,7 +952,8 @@ testRun(void)
callbackData.content = strNew("");
TEST_RESULT_VOID(
storageInfoListP(s3, strNew("/path/to"), hrnStorageInfoListCallback, &callbackData, .level = storageInfoLevelExists),
storageInfoListP(
s3, strNew("/path/to"), hrnStorageInfoListCallback, &callbackData, .level = storageInfoLevelExists),
"list files with continuation");
TEST_RESULT_STR_Z(
callbackData.content,
@ -974,11 +978,11 @@ testRun(void)
" check content");
// storageDriverPathRemove()
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
// Switch to path-style URIs
s3 = storageS3New(
path, true, NULL, bucket, endPoint, storageS3UriStylePath, region, accessKey, secretAccessKey, NULL, 16, 2, host, port,
1000, testContainer(), NULL, NULL);
path, true, NULL, bucket, endPoint, storageS3UriStylePath, region, accessKey, secretAccessKey, NULL, 16, 2,
host, port, 1000, testContainer(), NULL, NULL);
TEST_ERROR(
storagePathRemoveP(s3, strNew("/")), AssertError,
@ -991,9 +995,13 @@ testRun(void)
"unable to remove file 'sample2.txt': [AccessDenied] Access Denied");
// storageDriverRemove()
// -------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------
TEST_RESULT_VOID(storageRemoveP(s3, strNew("/path/to/test.txt")), "remove file");
}
HARNESS_FORK_PARENT_END();
}
HARNESS_FORK_END();
}
FUNCTION_HARNESS_RESULT_VOID();
}