mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Automatically create IoRead/IoWrite interfaces in HRN_FORK*() macros.
This removes a lot of boiler plate where every instance needs to create these interfaces. Also add HRN_FORK_*_NOTIFY*() macros to standardize synchronizing between the parent and child processes. In both cases update the tests with the new macros.
This commit is contained in:
parent
be7b8a485b
commit
d791bb7298
@ -259,6 +259,7 @@ unit:
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: io
|
||||
total: 4
|
||||
feature: IO
|
||||
|
||||
coverage:
|
||||
- common/io/bufferRead
|
||||
|
@ -6,22 +6,17 @@ polluting memory in the main process with something that can't easily be undone.
|
||||
|
||||
The general form of the fork harness is:
|
||||
|
||||
// Parameters may be passed, see HrnForkParam.
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
// This block is required and can be repeated up to HRN_FORK_CHILD_MAX times.
|
||||
//
|
||||
// The first parameter is the expected exit code. If the child block does not have an explicit exit then it will automatically
|
||||
// exit on 0.
|
||||
//
|
||||
// The second parameter specifies whether pipes should be setup between the parent and child processes. These can be accessed
|
||||
// with the HRN_FORK_*() macros;
|
||||
// This block is required and can be repeated up to HRN_FORK_CHILD_MAX times. Parameters may be passed, see HrnForkChildParam.
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
// Child test code goes here
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
// This block is optional but generally useful
|
||||
// This block is optional but generally useful. Parameters may be passed, see HrnForkParentParam.
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
// Parent test code goes here
|
||||
@ -45,6 +40,11 @@ Define the max number of child processes allowed
|
||||
***********************************************************************************************************************************/
|
||||
#define HRN_FORK_CHILD_MAX 4
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Default timeout for IoRead/IoWrite interfaces
|
||||
***********************************************************************************************************************************/
|
||||
#define HRN_FORK_TIMEOUT 2000
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Total number of child processes forked
|
||||
***********************************************************************************************************************************/
|
||||
@ -84,6 +84,59 @@ Get read/write pipe file descriptors
|
||||
#define HRN_FORK_PARENT_WRITE_FD(processIdx) \
|
||||
HRN_FORK_PIPE(processIdx)[1][1]
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get IoRead/IoWrite interfaces. These are automatically created at fork time and are available via these macros(). Since
|
||||
IoRead/IoWrite buffer internally using both the interfaces and the file descriptors will be unpredictable unless the IoRead/IoWrite
|
||||
buffers are known to be empty, e.g. ioWriteFlush() has been called.
|
||||
***********************************************************************************************************************************/
|
||||
#ifdef HRN_FEATURE_IO
|
||||
#define HRN_FORK_CHILD_READ() \
|
||||
HRN_FORK_ioReadChild
|
||||
|
||||
#define HRN_FORK_CHILD_WRITE() \
|
||||
HRN_FORK_ioWriteChild
|
||||
|
||||
#define HRN_FORK_PARENT_READ(processIdx) \
|
||||
HRN_FORK_ioReadParent[processIdx]
|
||||
|
||||
#define HRN_FORK_PARENT_WRITE(processIdx) \
|
||||
HRN_FORK_ioWriteParent[processIdx]
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get/put notify messages. These macros allow the parent and child process to synchronize which is useful, e.g. releasing locks.
|
||||
***********************************************************************************************************************************/
|
||||
#ifdef HRN_FEATURE_IO
|
||||
// General notify get macro used by parent/child
|
||||
#define HRN_FORK_NOTIFY_GET(read) \
|
||||
ioReadLine(read)
|
||||
|
||||
// General notify put macro used by parent/child
|
||||
#define HRN_FORK_NOTIFY_PUT(write) \
|
||||
do \
|
||||
{ \
|
||||
ioWriteStrLine(write, EMPTY_STR); \
|
||||
ioWriteFlush(write); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
// Put notification to parent from child
|
||||
#define HRN_FORK_CHILD_NOTIFY_GET() \
|
||||
HRN_FORK_NOTIFY_GET(HRN_FORK_CHILD_READ())
|
||||
|
||||
// Get notification from parent to child
|
||||
#define HRN_FORK_CHILD_NOTIFY_PUT() \
|
||||
HRN_FORK_NOTIFY_PUT(HRN_FORK_CHILD_WRITE())
|
||||
|
||||
// Put notification to child from parent
|
||||
#define HRN_FORK_PARENT_NOTIFY_GET(processIdx) \
|
||||
HRN_FORK_NOTIFY_GET(HRN_FORK_PARENT_READ(processIdx))
|
||||
|
||||
// Get notification from child to parent
|
||||
#define HRN_FORK_PARENT_NOTIFY_PUT(processIdx) \
|
||||
HRN_FORK_NOTIFY_PUT(HRN_FORK_PARENT_WRITE(processIdx))
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
At the end of the HRN_FORK block the parent will wait for the child to exit. By default an exit code of 0 is expected but that can
|
||||
be modified when the child begins.
|
||||
@ -94,9 +147,24 @@ be modified when the child begins.
|
||||
/***********************************************************************************************************************************
|
||||
Begin the fork block
|
||||
***********************************************************************************************************************************/
|
||||
#define HRN_FORK_BEGIN() \
|
||||
typedef struct HrnForkParam
|
||||
{
|
||||
VAR_PARAM_HEADER;
|
||||
|
||||
// Timeout in ms for IoRead/IoWrite interfaces (defaults to HRN_FORK_TIMEOUT). May be overridden in HRN_FORK_CHILD_BEGIN() or
|
||||
// HRN_FORK_PARENT_BEGIN().
|
||||
uint64_t timeout;
|
||||
} HrnForkParam;
|
||||
|
||||
#define HRN_FORK_BEGIN(...) \
|
||||
do \
|
||||
{ \
|
||||
HrnForkParam param = {VAR_PARAM_INIT, __VA_ARGS__}; \
|
||||
\
|
||||
/* Set timeout default */ \
|
||||
if (param.timeout == 0) \
|
||||
param.timeout = HRN_FORK_TIMEOUT; \
|
||||
\
|
||||
unsigned int HRN_FORK_PROCESS_TOTAL() = 0; \
|
||||
pid_t HRN_FORK_PROCESS_ID(HRN_FORK_CHILD_MAX) = {0}; \
|
||||
int HRN_FORK_CHILD_EXPECTED_EXIT_STATUS(HRN_FORK_CHILD_MAX) = {0}; \
|
||||
@ -108,14 +176,49 @@ Create a child process
|
||||
typedef struct HrnForkChildParam
|
||||
{
|
||||
VAR_PARAM_HEADER;
|
||||
|
||||
// Expected exit status. Defaults to 0. This does not need to be changed unless the child is expected to exit with a non-zero
|
||||
// code for testing purposes.
|
||||
int expectedExitStatus;
|
||||
|
||||
// Prefix used to name IoRead/IoWrite interfaces. Defaults to "child" so the default name is "child [idx] read/write".
|
||||
const char *prefix;
|
||||
|
||||
// Timeout in ms for IoRead/IoWrite interfaces. Defaults to the value passed in HRN_FORK_BEGIN().
|
||||
uint64_t timeout;
|
||||
} HrnForkChildParam;
|
||||
|
||||
// Declare/assign IoRead/IoWrite
|
||||
#ifdef HRN_FEATURE_IO
|
||||
#include "common/io/fdRead.h"
|
||||
#include "common/io/fdWrite.h"
|
||||
#include "common/type/string.h"
|
||||
|
||||
#define HRN_FORK_CHILD_IO() \
|
||||
IoRead *HRN_FORK_CHILD_READ() = ioFdReadNewOpen( \
|
||||
strNewFmt("%s %u read", paramChild.prefix, HRN_FORK_PROCESS_IDX()), HRN_FORK_CHILD_READ_FD(), paramChild.timeout); \
|
||||
(void)HRN_FORK_CHILD_READ(); \
|
||||
IoWrite *HRN_FORK_CHILD_WRITE() = ioFdWriteNewOpen( \
|
||||
strNewFmt("%s %u write", paramChild.prefix, HRN_FORK_PROCESS_IDX()), HRN_FORK_CHILD_WRITE_FD(), paramChild.timeout); \
|
||||
(void)HRN_FORK_CHILD_WRITE()
|
||||
#else
|
||||
#define HRN_FORK_CHILD_IO()
|
||||
#endif
|
||||
|
||||
#define HRN_FORK_CHILD_BEGIN(...) \
|
||||
do \
|
||||
{ \
|
||||
const HrnForkChildParam param = {VAR_PARAM_INIT, __VA_ARGS__}; \
|
||||
HRN_FORK_CHILD_EXPECTED_EXIT_STATUS(HRN_FORK_PROCESS_TOTAL()) = param.expectedExitStatus; \
|
||||
HrnForkChildParam paramChild = {VAR_PARAM_INIT, __VA_ARGS__}; \
|
||||
\
|
||||
/* Set prefix default */ \
|
||||
if (paramChild.prefix == NULL) \
|
||||
paramChild.prefix = "child"; \
|
||||
\
|
||||
/* Set timeout default */ \
|
||||
if (paramChild.timeout == 0) \
|
||||
paramChild.timeout = param.timeout; \
|
||||
\
|
||||
HRN_FORK_CHILD_EXPECTED_EXIT_STATUS(HRN_FORK_PROCESS_TOTAL()) = paramChild.expectedExitStatus; \
|
||||
\
|
||||
/* Create pipe for parent/child communication */ \
|
||||
THROW_ON_SYS_ERROR_FMT( \
|
||||
@ -132,6 +235,9 @@ typedef struct HrnForkChildParam
|
||||
{ \
|
||||
unsigned int HRN_FORK_PROCESS_IDX() = HRN_FORK_PROCESS_TOTAL(); \
|
||||
\
|
||||
/* Declare/assign IoRead/IoWrite */ \
|
||||
HRN_FORK_CHILD_IO(); \
|
||||
\
|
||||
/* Change log process id to aid in debugging */ \
|
||||
hrnLogProcessIdSet(HRN_FORK_PROCESS_IDX() + 1); \
|
||||
\
|
||||
@ -154,14 +260,59 @@ typedef struct HrnForkChildParam
|
||||
/***********************************************************************************************************************************
|
||||
Process in the parent
|
||||
***********************************************************************************************************************************/
|
||||
#define HRN_FORK_PARENT_BEGIN() \
|
||||
typedef struct HrnForkParentParam
|
||||
{
|
||||
VAR_PARAM_HEADER;
|
||||
|
||||
// Prefix used to name IoRead/IoWrite interfaces. Defaults to "parent" so the default name is "parent [idx] read/write".
|
||||
const char *prefix;
|
||||
|
||||
// Timeout in ms for IoRead/IoWrite interfaces. Defaults to the value passed in HRN_FORK_BEGIN().
|
||||
uint64_t timeout;
|
||||
} HrnForkParentParam;
|
||||
|
||||
// Declare IoRead/IoWrite
|
||||
#ifdef HRN_FEATURE_IO
|
||||
#define HRN_FORK_PARENT_IO_DECLARE() \
|
||||
IoRead *HRN_FORK_PARENT_READ(HRN_FORK_CHILD_MAX) = {0}; \
|
||||
(void)HRN_FORK_PARENT_READ(0); \
|
||||
IoWrite *HRN_FORK_PARENT_WRITE(HRN_FORK_CHILD_MAX) = {0}; \
|
||||
(void)HRN_FORK_PARENT_WRITE(0)
|
||||
|
||||
#define HRN_FORK_PARENT_IO_ASSIGN(processIdx) \
|
||||
HRN_FORK_PARENT_READ(processIdx) = ioFdReadNewOpen( \
|
||||
strNewFmt("%s %u read", paramParent.prefix, processIdx), HRN_FORK_PARENT_READ_FD(processIdx), paramParent.timeout); \
|
||||
HRN_FORK_PARENT_WRITE(processIdx) = ioFdWriteNewOpen( \
|
||||
strNewFmt("%s %u write", paramParent.prefix, processIdx), HRN_FORK_PARENT_WRITE_FD(processIdx), paramParent.timeout)
|
||||
#else
|
||||
#define HRN_FORK_PARENT_IO_DECLARE()
|
||||
#define HRN_FORK_PARENT_IO_ASSIGN(processIdx)
|
||||
#endif
|
||||
|
||||
#define HRN_FORK_PARENT_BEGIN(...) \
|
||||
do \
|
||||
{ \
|
||||
HrnForkParentParam paramParent = {VAR_PARAM_INIT, __VA_ARGS__}; \
|
||||
\
|
||||
/* Set prefix default */ \
|
||||
if (paramParent.prefix == NULL) \
|
||||
paramParent.prefix = "parent"; \
|
||||
\
|
||||
/* Set timeout default */ \
|
||||
if (paramParent.timeout == 0) \
|
||||
paramParent.timeout = param.timeout; \
|
||||
\
|
||||
/* Declare IoRead/IoWrite */ \
|
||||
HRN_FORK_PARENT_IO_DECLARE(); \
|
||||
\
|
||||
for (unsigned int processIdx = 0; processIdx < HRN_FORK_PROCESS_TOTAL(); processIdx++) \
|
||||
{ \
|
||||
/* Close child side of pipe */ \
|
||||
close(HRN_FORK_PIPE(processIdx)[1][0]); \
|
||||
close(HRN_FORK_PIPE(processIdx)[0][1]); \
|
||||
\
|
||||
/* Assign IoRead/IoWrite */ \
|
||||
HRN_FORK_PARENT_IO_ASSIGN(processIdx); \
|
||||
}
|
||||
|
||||
#define HRN_FORK_PARENT_END() \
|
||||
|
@ -78,8 +78,6 @@ IoWrite *hrnServerScriptBegin(IoWrite *write)
|
||||
|
||||
ASSERT(write != NULL);
|
||||
|
||||
ioWriteOpen(write);
|
||||
|
||||
FUNCTION_HARNESS_RETURN(IO_WRITE, write);
|
||||
}
|
||||
|
||||
@ -225,9 +223,6 @@ void hrnServerRun(IoRead *read, HrnServerProtocol protocol, HrnServerRunParam pa
|
||||
if (param.port == 0)
|
||||
param.port = hrnServerPort(0);
|
||||
|
||||
// Open read connection to client
|
||||
ioReadOpen(read);
|
||||
|
||||
// Add test hosts
|
||||
if (testContainer())
|
||||
{
|
||||
|
@ -735,19 +735,17 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("child read"), HRN_FORK_CHILD_READ_FD(), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("child write"), HRN_FORK_CHILD_WRITE_FD(), 2000);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
lockAcquire(
|
||||
cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), STRDEF("999-dededede"), cfgLockType(), 30000,
|
||||
true),
|
||||
"acquire lock");
|
||||
|
||||
// Let the parent know the lock has been acquired and wait for the parent to allow lock release
|
||||
ioWriteStrLine(write, strNew());
|
||||
ioWriteFlush(write);
|
||||
ioReadLine(read);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
lockRelease(true);
|
||||
}
|
||||
@ -755,19 +753,15 @@ testRun(void)
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("parent read"), HRN_FORK_PARENT_READ_FD(0), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("parent write"), HRN_FORK_PARENT_WRITE_FD(0), 2000);
|
||||
|
||||
// Wait for the child to acquire the lock
|
||||
ioReadLine(read);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
TEST_ERROR(
|
||||
cmdArchiveGet(), ArchiveTimeoutError,
|
||||
"unable to get WAL file '000000010000000100000001' from the archive asynchronously after 1 second(s)");
|
||||
|
||||
// Notify the child to release the lock
|
||||
ioWriteLine(write, bufNew(0));
|
||||
ioWriteFlush(write);
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
|
@ -713,16 +713,14 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("child read"), HRN_FORK_CHILD_READ_FD(), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("child write"), HRN_FORK_CHILD_WRITE_FD(), 2000);
|
||||
|
||||
lockAcquire(
|
||||
cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), STRDEF("555-fefefefe"), cfgLockType(), 30000, true);
|
||||
|
||||
// Let the parent know the lock has been acquired and wait for the parent to allow lock release
|
||||
ioWriteStrLine(write, strNew());
|
||||
ioWriteFlush(write);
|
||||
ioReadLine(read);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
lockRelease(true);
|
||||
}
|
||||
@ -730,19 +728,15 @@ testRun(void)
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("parent read"), HRN_FORK_PARENT_READ_FD(0), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("parent write"), HRN_FORK_PARENT_WRITE_FD(0), 2000);
|
||||
|
||||
// Wait for the child to acquire the lock
|
||||
ioReadLine(read);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
TEST_ERROR(
|
||||
cmdArchivePush(), ArchiveTimeoutError,
|
||||
"unable to push WAL file '000000010000000100000001' to the archive asynchronously after 1 second(s)");
|
||||
|
||||
// Notify the child to release the lock
|
||||
ioWriteLine(write, bufNew(0));
|
||||
ioWriteFlush(write);
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
|
@ -164,19 +164,15 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("child read"), HRN_FORK_CHILD_READ_FD(), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("child write"), HRN_FORK_CHILD_WRITE_FD(), 2000);
|
||||
|
||||
int lockFd = open(HRN_PATH "/lock/empty" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
|
||||
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the empty file");
|
||||
|
||||
// Let the parent know the lock has been acquired and wait for the parent to allow lock release
|
||||
ioWriteStrLine(write, strNew());
|
||||
// All writes are buffered so need to flush because buffer is not full
|
||||
ioWriteFlush(write);
|
||||
// Wait for a linefeed from the parent ioWriteLine below
|
||||
ioReadLine(read);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
// Parent removed the file so just close the file descriptor
|
||||
close(lockFd);
|
||||
@ -185,20 +181,16 @@ testRun(void)
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("parent read"), HRN_FORK_PARENT_READ_FD(0), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("parent write"), HRN_FORK_PARENT_WRITE_FD(0), 2000);
|
||||
|
||||
// Wait for the child to acquire the lock
|
||||
ioReadLine(read);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
cmdStop(), "stanza, create stop file, force - empty lock file with another process lock, processId == NULL");
|
||||
TEST_STORAGE_LIST(
|
||||
hrnStorage, "lock", "db" STOP_FILE_EXT "\n", .comment = "stop file created, lock file was removed");
|
||||
|
||||
// Notify the child to release the lock
|
||||
ioWriteLine(write, bufNew(0));
|
||||
ioWriteFlush(write);
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
@ -214,19 +206,15 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("child read"), HRN_FORK_CHILD_READ_FD(), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("child write"), HRN_FORK_CHILD_WRITE_FD(), 2000);
|
||||
|
||||
int lockFd = open(HRN_PATH "/lock/empty" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
|
||||
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the non-empty file");
|
||||
|
||||
// Let the parent know the lock has been acquired and wait for the parent to allow lock release
|
||||
ioWriteStrLine(write, strNew());
|
||||
// All writes are buffered so need to flush because buffer is not full
|
||||
ioWriteFlush(write);
|
||||
// Wait for a linefeed from the parent ioWriteLine below
|
||||
ioReadLine(read);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
// Parent removed the file so just close the file descriptor
|
||||
close(lockFd);
|
||||
@ -235,20 +223,16 @@ testRun(void)
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("parent read"), HRN_FORK_PARENT_READ_FD(0), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("parent write"), HRN_FORK_PARENT_WRITE_FD(0), 2000);
|
||||
|
||||
// Wait for the child to acquire the lock
|
||||
ioReadLine(read);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
cmdStop(), "stanza, create stop file, force - empty lock file with another process lock, processId size 0");
|
||||
TEST_STORAGE_LIST(
|
||||
hrnStorage, "lock", "db" STOP_FILE_EXT "\n", .comment = "stop file created, lock file was removed");
|
||||
|
||||
// Notify the child to release the lock
|
||||
ioWriteLine(write, bufNew(0));
|
||||
ioWriteFlush(write);
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
@ -262,28 +246,22 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("child read"), HRN_FORK_CHILD_READ_FD(), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("child write"), HRN_FORK_CHILD_WRITE_FD(), 2000);
|
||||
|
||||
TEST_RESULT_BOOL(
|
||||
lockAcquire(STRDEF(HRN_PATH "/lock"), cfgOptionStr(cfgOptStanza), cfgOptionStr(cfgOptExecId), 0, 30000, true),
|
||||
true, "child process acquires lock");
|
||||
|
||||
// Let the parent know the lock has been acquired and wait for the parent to allow lock release
|
||||
ioWriteStrLine(write, strNew());
|
||||
// All writes are buffered so need to flush because buffer is not full
|
||||
ioWriteFlush(write);
|
||||
// Wait for a linefeed from the parent but it will not arrive before the process is terminated
|
||||
ioReadLine(read);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock but it will not arrive before the process is terminated
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("parent read"), HRN_FORK_PARENT_READ_FD(0), 2000);
|
||||
|
||||
// Wait for the child to acquire the lock
|
||||
ioReadLine(read);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
cmdStop(), "stanza, create stop file, force - lock file with another process lock, processId is valid");
|
||||
@ -304,19 +282,15 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("child read"), HRN_FORK_CHILD_READ_FD(), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("child write"), HRN_FORK_CHILD_WRITE_FD(), 2000);
|
||||
|
||||
int lockFd = open(HRN_PATH "/lock/badpid" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
|
||||
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the badpid file");
|
||||
|
||||
// Let the parent know the lock has been acquired and wait for the parent to allow lock release
|
||||
ioWriteStrLine(write, strNew());
|
||||
// All writes are buffered so need to flush because buffer is not full
|
||||
ioWriteFlush(write);
|
||||
// Wait for a linefeed from the parent ioWriteLine below
|
||||
ioReadLine(read);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
// Remove the file and close the file descriptor
|
||||
HRN_STORAGE_REMOVE(hrnStorage, "lock/badpid" LOCK_FILE_EXT);
|
||||
@ -326,20 +300,16 @@ testRun(void)
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("parent read"), HRN_FORK_PARENT_READ_FD(0), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("parent write"), HRN_FORK_PARENT_WRITE_FD(0), 2000);
|
||||
|
||||
// Wait for the child to acquire the lock
|
||||
ioReadLine(read);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
cmdStop(), "stanza, create stop file, force - lock file with another process lock, processId is invalid");
|
||||
TEST_RESULT_LOG("P00 WARN: unable to send term signal to process -32768");
|
||||
TEST_STORAGE_EXISTS(hrnStorage, "lock/db" STOP_FILE_EXT, .comment = "stanza stop file not removed");
|
||||
|
||||
// Notify the child to release the lock
|
||||
ioWriteLine(write, bufNew(0));
|
||||
ioWriteFlush(write);
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
|
@ -234,14 +234,20 @@ testRun(void)
|
||||
lockAcquire(cfgOptionStr(cfgOptLockPath), STRDEF("stanza1"), STRDEF("999-ffffffff"), lockTypeBackup, 0, true),
|
||||
-1, "create backup/expire lock");
|
||||
|
||||
sleepMSec(1000);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
lockRelease(true);
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
sleepMSec(250);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
HRN_CFG_LOAD(cfgCmdInfo, argList);
|
||||
TEST_RESULT_STR_Z(
|
||||
@ -306,6 +312,8 @@ testRun(void)
|
||||
" wal archive min/max (9.4): none present\n",
|
||||
"text - single stanza, no valid backups, backup/expire lock detected");
|
||||
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
@ -417,14 +425,20 @@ testRun(void)
|
||||
lockAcquire(cfgOptionStr(cfgOptLockPath), STRDEF("stanza1"), STRDEF("777-afafafaf"), lockTypeBackup, 0, true),
|
||||
-1, "create backup/expire lock");
|
||||
|
||||
sleepMSec(1000);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
lockRelease(true);
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
sleepMSec(250);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
HRN_CFG_LOAD(cfgCmdInfo, argList);
|
||||
TEST_RESULT_STR_Z(
|
||||
@ -588,6 +602,9 @@ testRun(void)
|
||||
" database size: 25.7MB, database backup size: 25.7MB\n"
|
||||
" repo1: backup set size: 3MB, backup size: 3KB\n",
|
||||
"text - single stanza, valid backup, no priors, no archives in latest DB, backup/expire lock detected");
|
||||
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
@ -997,14 +1014,20 @@ testRun(void)
|
||||
lockAcquire(cfgOptionStr(cfgOptLockPath), STRDEF("stanza2"), STRDEF("999-ffffffff"), lockTypeBackup, 0, true),
|
||||
-1, "create backup/expire lock");
|
||||
|
||||
sleepMSec(1000);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
lockRelease(true);
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
sleepMSec(250);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
HRN_CFG_LOAD(cfgCmdInfo, argListMultiRepoJson);
|
||||
TEST_RESULT_STR_Z(
|
||||
@ -1402,6 +1425,9 @@ testRun(void)
|
||||
"}"
|
||||
"]",
|
||||
"json - multiple stanzas, some with valid backups, archives in latest DB, backup lock held on one stanza");
|
||||
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
@ -1415,14 +1441,20 @@ testRun(void)
|
||||
lockAcquire(cfgOptionStr(cfgOptLockPath), STRDEF("stanza2"), STRDEF("999-ffffffff"), lockTypeBackup, 0, true),
|
||||
-1, "create backup/expire lock");
|
||||
|
||||
sleepMSec(1000);
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
lockRelease(true);
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
sleepMSec(250);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
HRN_CFG_LOAD(cfgCmdInfo, argListMultiRepo);
|
||||
TEST_RESULT_STR_Z(
|
||||
@ -1506,6 +1538,9 @@ testRun(void)
|
||||
" database size: 25.7MB, database backup size: 25.7MB\n"
|
||||
" repo2: backup set size: 3MB, backup size: 3KB\n",
|
||||
"text - multiple stanzas, multi-repo with valid backups, backup lock held on one stanza");
|
||||
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
|
@ -44,9 +44,7 @@ testRun(void)
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
ProtocolClient *client = protocolClientNew(
|
||||
STRDEF("test"), PROTOCOL_SERVICE_LOCAL_STR,
|
||||
ioFdReadNewOpen(STRDEF("server read"), HRN_FORK_PARENT_READ_FD(0), 2000),
|
||||
ioFdWriteNewOpen(STRDEF("server write"), HRN_FORK_PARENT_WRITE_FD(0), 2000));
|
||||
STRDEF("test"), PROTOCOL_SERVICE_LOCAL_STR, HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0));
|
||||
protocolClientNoOp(client);
|
||||
protocolClientFree(client);
|
||||
}
|
||||
|
@ -281,20 +281,16 @@ testRun(void)
|
||||
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
|
||||
{
|
||||
// Start HTTP test server
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(
|
||||
ioFdReadNew(STRDEF("test server read"), HRN_FORK_CHILD_READ_FD(), 5000), hrnServerProtocolSocket),
|
||||
"http server run");
|
||||
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket), "http server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoWrite *http = hrnServerScriptBegin(
|
||||
ioFdWriteNew(STRDEF("test client write"), HRN_FORK_PARENT_WRITE_FD(0), 2000));
|
||||
IoWrite *http = hrnServerScriptBegin(HRN_FORK_PARENT_WRITE(0));
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("create client");
|
||||
|
@ -247,22 +247,21 @@ testRun(void)
|
||||
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
|
||||
{
|
||||
// Start server to test various certificate errors
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(
|
||||
ioFdReadNew(STRDEF("test server read"), HRN_FORK_CHILD_READ_FD(), 5000), hrnServerProtocolTls,
|
||||
HRN_FORK_CHILD_READ(), hrnServerProtocolTls,
|
||||
.certificate = STRDEF(HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "-alt-name.crt"),
|
||||
.key = STRDEF(HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX ".key")),
|
||||
"tls alt name server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
HRN_FORK_PARENT_BEGIN(.prefix = "test client", .timeout = 1000)
|
||||
{
|
||||
IoWrite *tls = hrnServerScriptBegin(
|
||||
ioFdWriteNew(STRDEF("test client write"), HRN_FORK_PARENT_WRITE_FD(0), 1000));
|
||||
IoWrite *tls = hrnServerScriptBegin(HRN_FORK_PARENT_WRITE(0));
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("certificate error on invalid ca path");
|
||||
@ -365,19 +364,15 @@ testRun(void)
|
||||
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
|
||||
{
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(
|
||||
ioFdReadNew(STRDEF("test server read"), HRN_FORK_CHILD_READ_FD(), 5000), hrnServerProtocolTls),
|
||||
"tls server run");
|
||||
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls), "tls server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
HRN_FORK_PARENT_BEGIN(.prefix = "test client", .timeout = 1000)
|
||||
{
|
||||
IoWrite *tls =
|
||||
hrnServerScriptBegin(ioFdWriteNew(STRDEF("test client write"), HRN_FORK_PARENT_WRITE_FD(0), 1000));
|
||||
IoWrite *tls = hrnServerScriptBegin(HRN_FORK_PARENT_WRITE(0));
|
||||
ioBufferSizeSet(12);
|
||||
|
||||
TEST_ASSIGN(
|
||||
|
@ -96,13 +96,20 @@ testRun(void)
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
TEST_RESULT_INT_NE(lockAcquireFile(backupLock, STRDEF("1-test"), 0, true), -1, "lock on fork");
|
||||
sleepMSec(500);
|
||||
|
||||
// Notify parent that lock has been acquired
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Wait for parent to allow release lock
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
sleepMSec(250);
|
||||
// Wait for child to acquire lock
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
|
||||
TEST_ERROR(
|
||||
lockAcquireFile(backupLock, STRDEF("2-test"), 0, true),
|
||||
LockAcquireError,
|
||||
@ -110,6 +117,9 @@ testRun(void)
|
||||
strNewFmt(
|
||||
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
||||
"HINT: is another pgBackRest process running?", strZ(backupLock))));
|
||||
|
||||
// Notify child to release lock
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
|
@ -32,8 +32,7 @@ testRun(void)
|
||||
HRN_CFG_LOAD(cfgCmdArchiveGet, argList);
|
||||
|
||||
ProtocolServer *server = protocolServerNew(
|
||||
STRDEF("test"), STRDEF("config"), ioFdReadNewOpen(STRDEF("client read"), HRN_FORK_CHILD_READ_FD(), 2000),
|
||||
ioFdWriteNewOpen(STRDEF("client write"), HRN_FORK_CHILD_WRITE_FD(), 2000));
|
||||
STRDEF("test"), STRDEF("config"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE());
|
||||
|
||||
static const ProtocolServerHandler commandHandler[] = {PROTOCOL_SERVER_HANDLER_OPTION_LIST};
|
||||
protocolServerProcess(server, NULL, commandHandler, PROTOCOL_SERVER_HANDLER_LIST_SIZE(commandHandler));
|
||||
@ -43,9 +42,7 @@ testRun(void)
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
ProtocolClient *client = protocolClientNew(
|
||||
STRDEF("test"), STRDEF("config"),
|
||||
ioFdReadNewOpen(STRDEF("server read"), HRN_FORK_PARENT_READ_FD(0), 2000),
|
||||
ioFdWriteNewOpen(STRDEF("server write"), HRN_FORK_PARENT_WRITE_FD(0), 2000));
|
||||
STRDEF("test"), STRDEF("config"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0));
|
||||
|
||||
VariantList *list = varLstNew();
|
||||
varLstAdd(list, varNewStr(STRDEF("repo1-host")));
|
||||
|
@ -96,10 +96,7 @@ testRun(void)
|
||||
|
||||
TEST_ASSIGN(
|
||||
server,
|
||||
protocolServerNew(
|
||||
STRDEF("db test server"), STRDEF("test"),
|
||||
ioFdReadNewOpen(STRDEF("client read"), HRN_FORK_CHILD_READ_FD(), 2000),
|
||||
ioFdWriteNewOpen(STRDEF("client write"), HRN_FORK_CHILD_WRITE_FD(), 2000)),
|
||||
protocolServerNew(STRDEF("db test server"), STRDEF("test"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE()),
|
||||
"create server");
|
||||
|
||||
static const ProtocolServerHandler commandHandler[] = {PROTOCOL_SERVER_HANDLER_DB_LIST};
|
||||
@ -119,10 +116,7 @@ testRun(void)
|
||||
|
||||
TEST_ASSIGN(
|
||||
client,
|
||||
protocolClientNew(
|
||||
STRDEF("db test client"), STRDEF("test"),
|
||||
ioFdReadNewOpen(STRDEF("server read"), HRN_FORK_PARENT_READ_FD(0), 2000),
|
||||
ioFdWriteNewOpen(STRDEF("server write"), HRN_FORK_PARENT_WRITE_FD(0), 2000)),
|
||||
protocolClientNew(STRDEF("db test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
"create client");
|
||||
|
||||
TRY_BEGIN()
|
||||
|
@ -147,7 +147,7 @@ testRun(void)
|
||||
CHECK(TEST_SCALE <= 2000);
|
||||
uint64_t fileTotal = (uint64_t)1000000 * TEST_SCALE;
|
||||
|
||||
HRN_FORK_BEGIN()
|
||||
HRN_FORK_BEGIN(.timeout = 60000)
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
@ -173,9 +173,7 @@ testRun(void)
|
||||
|
||||
// Setup handler for remote storage protocol
|
||||
ProtocolServer *server = protocolServerNew(
|
||||
STRDEF("storage test server"), STRDEF("test"),
|
||||
ioFdReadNewOpen(STRDEF("storage server read"), HRN_FORK_CHILD_READ_FD(), 60000),
|
||||
ioFdWriteNewOpen(STRDEF("storage server write"), HRN_FORK_CHILD_WRITE_FD(), 1000));
|
||||
STRDEF("storage test server"), STRDEF("test"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE());
|
||||
|
||||
static const ProtocolServerHandler commandHandler[] = {PROTOCOL_SERVER_HANDLER_STORAGE_REMOTE_LIST};
|
||||
protocolServerProcess(server, NULL, commandHandler, PROTOCOL_SERVER_HANDLER_LIST_SIZE(commandHandler));
|
||||
@ -187,9 +185,7 @@ testRun(void)
|
||||
{
|
||||
// Create client
|
||||
ProtocolClient *client = protocolClientNew(
|
||||
STRDEF("storage test client"), STRDEF("test"),
|
||||
ioFdReadNewOpen(STRDEF("storage client read"), HRN_FORK_PARENT_READ_FD(0), 60000),
|
||||
ioFdWriteNewOpen(STRDEF("storage client write"), HRN_FORK_PARENT_WRITE_FD(0), 1000));
|
||||
STRDEF("storage test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0));
|
||||
|
||||
// Create remote storage
|
||||
Storage *storageRemote = storageRemoteNew(
|
||||
|
@ -437,23 +437,21 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("server read"), HRN_FORK_CHILD_READ_FD(), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("server write"), HRN_FORK_CHILD_WRITE_FD(), 2000);
|
||||
|
||||
// Various bogus greetings
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
ioWriteStrLine(write, STRDEF("bogus greeting"));
|
||||
ioWriteFlush(write);
|
||||
ioWriteStrLine(write, STRDEF("{\"name\":999}"));
|
||||
ioWriteFlush(write);
|
||||
ioWriteStrLine(write, STRDEF("{\"name\":null}"));
|
||||
ioWriteFlush(write);
|
||||
ioWriteStrLine(write, STRDEF("{\"name\":\"bogus\"}"));
|
||||
ioWriteFlush(write);
|
||||
ioWriteStrLine(write, STRDEF("{\"name\":\"pgBackRest\",\"service\":\"bogus\"}"));
|
||||
ioWriteFlush(write);
|
||||
ioWriteStrLine(write, STRDEF("{\"name\":\"pgBackRest\",\"service\":\"test\",\"version\":\"bogus\"}"));
|
||||
ioWriteFlush(write);
|
||||
ioWriteStrLine(HRN_FORK_CHILD_WRITE(), STRDEF("bogus greeting"));
|
||||
ioWriteFlush(HRN_FORK_CHILD_WRITE());
|
||||
ioWriteStrLine(HRN_FORK_CHILD_WRITE(), STRDEF("{\"name\":999}"));
|
||||
ioWriteFlush(HRN_FORK_CHILD_WRITE());
|
||||
ioWriteStrLine(HRN_FORK_CHILD_WRITE(), STRDEF("{\"name\":null}"));
|
||||
ioWriteFlush(HRN_FORK_CHILD_WRITE());
|
||||
ioWriteStrLine(HRN_FORK_CHILD_WRITE(), STRDEF("{\"name\":\"bogus\"}"));
|
||||
ioWriteFlush(HRN_FORK_CHILD_WRITE());
|
||||
ioWriteStrLine(HRN_FORK_CHILD_WRITE(), STRDEF("{\"name\":\"pgBackRest\",\"service\":\"bogus\"}"));
|
||||
ioWriteFlush(HRN_FORK_CHILD_WRITE());
|
||||
ioWriteStrLine(
|
||||
HRN_FORK_CHILD_WRITE(), STRDEF("{\"name\":\"pgBackRest\",\"service\":\"test\",\"version\":\"bogus\"}"));
|
||||
ioWriteFlush(HRN_FORK_CHILD_WRITE());
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("server");
|
||||
@ -465,7 +463,8 @@ testRun(void)
|
||||
TEST_ASSIGN(
|
||||
server,
|
||||
protocolServerMove(
|
||||
protocolServerNew(STRDEF("test server"), STRDEF("test"), read, write), memContextPrior()),
|
||||
protocolServerNew(STRDEF("test server"), STRDEF("test"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE()),
|
||||
memContextPrior()),
|
||||
"new server");
|
||||
TEST_RESULT_VOID(protocolServerMove(NULL, memContextPrior()), "move null server");
|
||||
}
|
||||
@ -483,7 +482,8 @@ testRun(void)
|
||||
varLstAdd(retryList, varNewUInt64(0));
|
||||
|
||||
TEST_ASSIGN(
|
||||
server, protocolServerNew(STRDEF("test server"), STRDEF("test"), read, write), "new server");
|
||||
server, protocolServerNew(STRDEF("test server"), STRDEF("test"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE()),
|
||||
"new server");
|
||||
|
||||
// This cannot run in a TEST* macro because tests are run by the command handlers
|
||||
protocolServerProcess(server, retryList, commandHandler, PROTOCOL_SERVER_HANDLER_LIST_SIZE(commandHandler));
|
||||
@ -492,31 +492,31 @@ testRun(void)
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
IoRead *read = ioFdReadNewOpen(STRDEF("client read"), HRN_FORK_PARENT_READ_FD(0), 2000);
|
||||
IoWrite *write = ioFdWriteNewOpen(STRDEF("client write"), HRN_FORK_PARENT_WRITE_FD(0), 2000);
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("bogus greetings");
|
||||
|
||||
TEST_ERROR(
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), read, write), JsonFormatError,
|
||||
"expected '{' at 'bogus greeting'");
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
JsonFormatError, "expected '{' at 'bogus greeting'");
|
||||
TEST_ERROR(
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), read, write), ProtocolError,
|
||||
"greeting key 'name' must be string type");
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
ProtocolError, "greeting key 'name' must be string type");
|
||||
TEST_ERROR(
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), read, write), ProtocolError,
|
||||
"unable to find greeting key 'name'");
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
ProtocolError, "unable to find greeting key 'name'");
|
||||
TEST_ERROR(
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), read, write), ProtocolError,
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
ProtocolError,
|
||||
"expected value 'pgBackRest' for greeting key 'name' but got 'bogus'\n"
|
||||
"HINT: is the same version of " PROJECT_NAME " installed on the local and remote host?");
|
||||
TEST_ERROR(
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), read, write), ProtocolError,
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
ProtocolError,
|
||||
"expected value 'test' for greeting key 'service' but got 'bogus'\n"
|
||||
"HINT: is the same version of " PROJECT_NAME " installed on the local and remote host?");
|
||||
TEST_ERROR(
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), read, write), ProtocolError,
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
ProtocolError,
|
||||
"expected value '" PROJECT_VERSION "' for greeting key 'version' but got 'bogus'\n"
|
||||
"HINT: is the same version of " PROJECT_NAME " installed on the local and remote host?");
|
||||
|
||||
@ -530,7 +530,9 @@ testRun(void)
|
||||
TEST_ASSIGN(
|
||||
client,
|
||||
protocolClientMove(
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), read, write), memContextPrior()),
|
||||
protocolClientNew(
|
||||
STRDEF("test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
memContextPrior()),
|
||||
"new client");
|
||||
TEST_RESULT_VOID(protocolClientMove(NULL, memContextPrior()), "move null client");
|
||||
}
|
||||
@ -608,7 +610,10 @@ testRun(void)
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("new client with server retries");
|
||||
|
||||
TEST_ASSIGN(client, protocolClientNew(STRDEF("test client"), STRDEF("test"), read, write), "new client");
|
||||
TEST_ASSIGN(
|
||||
client,
|
||||
protocolClientNew(STRDEF("test client"), STRDEF("test"), HRN_FORK_PARENT_READ(0), HRN_FORK_PARENT_WRITE(0)),
|
||||
"new client");
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("command with retry");
|
||||
@ -656,18 +661,15 @@ testRun(void)
|
||||
TEST_RESULT_VOID(protocolParallelJobFree(job), "free job");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
HRN_FORK_BEGIN()
|
||||
HRN_FORK_BEGIN(.timeout = 5000)
|
||||
{
|
||||
// Local 1
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "local server")
|
||||
{
|
||||
ProtocolServer *server = NULL;
|
||||
TEST_ASSIGN(
|
||||
server,
|
||||
protocolServerNew(
|
||||
STRDEF("local server 1"), STRDEF("test"),
|
||||
ioFdReadNewOpen(STRDEF("local server 1 read"), HRN_FORK_CHILD_READ_FD(), 10000),
|
||||
ioFdWriteNewOpen(STRDEF("local server 1 write"), HRN_FORK_CHILD_WRITE_FD(), 2000)),
|
||||
protocolServerNew(STRDEF("local server 1"), STRDEF("test"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE()),
|
||||
"local server 1");
|
||||
|
||||
TEST_RESULT_UINT(protocolServerCommandGet(server).id, PROTOCOL_COMMAND_NOOP, "noop command get");
|
||||
@ -676,7 +678,8 @@ testRun(void)
|
||||
// Command with output
|
||||
TEST_RESULT_UINT(protocolServerCommandGet(server).id, strIdFromZ(stringIdBit5, "c-one"), "c-one command get");
|
||||
|
||||
sleepMSec(4000);
|
||||
// Wait for notify from parent
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
TEST_RESULT_VOID(protocolServerDataPut(server, pckWriteU32P(protocolPackNew(), 1)), "data end put");
|
||||
TEST_RESULT_VOID(protocolServerDataEndPut(server), "data end put");
|
||||
@ -687,15 +690,12 @@ testRun(void)
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
// Local 2
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "local server")
|
||||
{
|
||||
ProtocolServer *server = NULL;
|
||||
TEST_ASSIGN(
|
||||
server,
|
||||
protocolServerNew(
|
||||
STRDEF("local server 2"), STRDEF("test"),
|
||||
ioFdReadNewOpen(STRDEF("local server 2 read"), HRN_FORK_CHILD_READ_FD(), 10000),
|
||||
ioFdWriteNewOpen(STRDEF("local server 2 write"), HRN_FORK_CHILD_WRITE_FD(), 2000)),
|
||||
protocolServerNew(STRDEF("local server 2"), STRDEF("test"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE()),
|
||||
"local server 2");
|
||||
|
||||
TEST_RESULT_UINT(protocolServerCommandGet(server).id, PROTOCOL_COMMAND_NOOP, "noop command get");
|
||||
@ -704,7 +704,8 @@ testRun(void)
|
||||
// Command with output
|
||||
TEST_RESULT_UINT(protocolServerCommandGet(server).id, strIdFromZ(stringIdBit5, "c2"), "c2 command get");
|
||||
|
||||
sleepMSec(1000);
|
||||
// Wait for notify from parent
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
TEST_RESULT_VOID(protocolServerDataPut(server, pckWriteU32P(protocolPackNew(), 2)), "data end put");
|
||||
TEST_RESULT_VOID(protocolServerDataEndPut(server), "data end put");
|
||||
@ -718,7 +719,7 @@ testRun(void)
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
HRN_FORK_PARENT_BEGIN(.prefix = "local client")
|
||||
{
|
||||
TestParallelJobCallback data = {.jobList = lstNewP(sizeof(ProtocolParallelJob *))};
|
||||
ProtocolParallel *parallel = NULL;
|
||||
@ -726,19 +727,15 @@ testRun(void)
|
||||
TEST_RESULT_STR_Z(protocolParallelToLog(parallel), "{state: pending, clientTotal: 0, jobTotal: 0}", "check log");
|
||||
|
||||
// Add client
|
||||
unsigned int clientTotal = 2;
|
||||
ProtocolClient *client[HRN_FORK_CHILD_MAX];
|
||||
|
||||
for (unsigned int clientIdx = 0; clientIdx < clientTotal; clientIdx++)
|
||||
for (unsigned int clientIdx = 0; clientIdx < HRN_FORK_PROCESS_TOTAL(); clientIdx++)
|
||||
{
|
||||
TEST_ASSIGN(
|
||||
client[clientIdx],
|
||||
protocolClientNew(
|
||||
strNewFmt("local client %u", clientIdx), STRDEF("test"),
|
||||
ioFdReadNewOpen(
|
||||
strNewFmt("local client %u read", clientIdx), HRN_FORK_PARENT_READ_FD(clientIdx), 2000),
|
||||
ioFdWriteNewOpen(
|
||||
strNewFmt("local client %u write", clientIdx), HRN_FORK_PARENT_WRITE_FD(clientIdx), 2000)),
|
||||
strNewFmt("local client %u", clientIdx), STRDEF("test"), HRN_FORK_PARENT_READ(clientIdx),
|
||||
HRN_FORK_PARENT_WRITE(clientIdx)),
|
||||
strZ(strNewFmt("local client %u new", clientIdx)));
|
||||
TEST_RESULT_VOID(
|
||||
protocolParallelClientAdd(parallel, client[clientIdx]), strZ(strNewFmt("local client %u add", clientIdx)));
|
||||
@ -783,6 +780,9 @@ testRun(void)
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("result for job 2");
|
||||
|
||||
// Notify child to complete command
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(1);
|
||||
|
||||
TEST_RESULT_INT(protocolParallelProcess(parallel), 1, "process jobs");
|
||||
|
||||
TEST_ASSIGN(job, protocolParallelResult(parallel), "get result");
|
||||
@ -819,6 +819,9 @@ testRun(void)
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("result for job 1");
|
||||
|
||||
// Notify child to complete command
|
||||
HRN_FORK_PARENT_NOTIFY_PUT(0);
|
||||
|
||||
TEST_RESULT_INT(protocolParallelProcess(parallel), 1, "process jobs");
|
||||
|
||||
TEST_ASSIGN(job, protocolParallelResult(parallel), "get result");
|
||||
@ -845,7 +848,7 @@ testRun(void)
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("free clients");
|
||||
|
||||
for (unsigned int clientIdx = 0; clientIdx < clientTotal; clientIdx++)
|
||||
for (unsigned int clientIdx = 0; clientIdx < HRN_FORK_PROCESS_TOTAL(); clientIdx++)
|
||||
TEST_RESULT_VOID(protocolClientFree(client[clientIdx]), strZ(strNewFmt("free client %u", clientIdx)));
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
|
@ -267,18 +267,15 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "azure server", .timeout = 5000)
|
||||
{
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(ioFdReadNew(STRDEF("azure server read"), HRN_FORK_CHILD_READ_FD(), 5000), hrnServerProtocolTls),
|
||||
"azure server run");
|
||||
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls), "azure server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
HRN_FORK_PARENT_BEGIN(.prefix = "azure client")
|
||||
{
|
||||
IoWrite *service = hrnServerScriptBegin(
|
||||
ioFdWriteNew(STRDEF("azure client write"), HRN_FORK_PARENT_WRITE_FD(0), 2000));
|
||||
IoWrite *service = hrnServerScriptBegin(HRN_FORK_PARENT_WRITE(0));
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("test against local host");
|
||||
|
@ -279,44 +279,35 @@ testRun(void)
|
||||
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "gcs server", .timeout = 5000)
|
||||
{
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(
|
||||
ioFdReadNew(STRDEF("gcs server read"), HRN_FORK_CHILD_READ_FD(), 5000), hrnServerProtocolTls,
|
||||
.port = testPort),
|
||||
"gcs server run");
|
||||
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, .port = testPort), "gcs server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "auth server", .timeout = 5000)
|
||||
{
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(
|
||||
ioFdReadNew(STRDEF("auth server read"), HRN_FORK_CHILD_READ_FD(), 5000), hrnServerProtocolTls,
|
||||
.port = testPortAuth),
|
||||
"auth server run");
|
||||
hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, .port = testPortAuth), "auth server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "meta server", .timeout = 10000)
|
||||
{
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(
|
||||
ioFdReadNew(STRDEF("meta server read"), HRN_FORK_CHILD_READ_FD(), 10000), hrnServerProtocolSocket,
|
||||
.port = testPortMeta),
|
||||
"meta server run");
|
||||
hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket, .port = testPortMeta), "meta server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
// Do not use HRN_FORK_PARENT_WRITE() here so individual names can be assigned to help with debugging
|
||||
IoWrite *service = hrnServerScriptBegin(
|
||||
ioFdWriteNew(STRDEF("gcs client write"), HRN_FORK_PARENT_WRITE_FD(0), 2000));
|
||||
ioFdWriteNewOpen(STRDEF("gcs client write"), HRN_FORK_PARENT_WRITE_FD(0), 2000));
|
||||
IoWrite *auth = hrnServerScriptBegin(
|
||||
ioFdWriteNew(STRDEF("auth client write"), HRN_FORK_PARENT_WRITE_FD(1), 2000));
|
||||
ioFdWriteNewOpen(STRDEF("auth client write"), HRN_FORK_PARENT_WRITE_FD(1), 2000));
|
||||
IoWrite *meta = hrnServerScriptBegin(
|
||||
ioFdWriteNew(STRDEF("meta client write"), HRN_FORK_PARENT_WRITE_FD(2), 2000));
|
||||
ioFdWriteNewOpen(STRDEF("meta client write"), HRN_FORK_PARENT_WRITE_FD(2), 2000));
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("test service auth");
|
||||
|
@ -353,31 +353,26 @@ testRun(void)
|
||||
{
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "s3 server", .timeout = 5000)
|
||||
{
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(
|
||||
ioFdReadNew(STRDEF("s3 server read"), HRN_FORK_CHILD_READ_FD(), 5000), hrnServerProtocolTls, .port = port),
|
||||
"s3 server run");
|
||||
TEST_RESULT_VOID(hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolTls, .port = port), "s3 server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "auth server", .timeout = 5000)
|
||||
{
|
||||
TEST_RESULT_VOID(
|
||||
hrnServerRunP(
|
||||
ioFdReadNew(STRDEF("auth server read"), HRN_FORK_CHILD_READ_FD(), 5000), hrnServerProtocolSocket,
|
||||
.port = authPort),
|
||||
"auth server run");
|
||||
hrnServerRunP(HRN_FORK_CHILD_READ(), hrnServerProtocolSocket, .port = authPort), "auth server run");
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN()
|
||||
{
|
||||
// Do not use HRN_FORK_PARENT_WRITE() here so individual names can be assigned to help with debugging
|
||||
IoWrite *service = hrnServerScriptBegin(
|
||||
ioFdWriteNew(STRDEF("s3 client write"), HRN_FORK_PARENT_WRITE_FD(0), 2000));
|
||||
ioFdWriteNewOpen(STRDEF("s3 client write"), HRN_FORK_PARENT_WRITE_FD(0), 2000));
|
||||
IoWrite *auth = hrnServerScriptBegin(
|
||||
ioFdWriteNew(STRDEF("auth client write"), HRN_FORK_PARENT_WRITE_FD(1), 2000));
|
||||
ioFdWriteNewOpen(STRDEF("auth client write"), HRN_FORK_PARENT_WRITE_FD(1), 2000));
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("config with keys, token, and host with custom port");
|
||||
|
Loading…
Reference in New Issue
Block a user