1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-09 00:45:49 +02:00

Allow I/O read interface to explicitly request blocking reads.

TlsClient introduced a non-blocking read which is required to read protocol messages that are linefeed-terminated rather than a known size. However, in many cases the expected number of bytes is known in advance so in that case it is more efficient to have tlsClientRead() block until all the bytes are read.

Add block parameter to all read functions and use it when a blocking read is required. For most read functions this is a noop, i.e. if the read function never blocks then it can ignore the parameter.

In passing, set the log level of storageNew*() functions to debug to expose more high-level I/O operations.
This commit is contained in:
David Steele
2018-11-23 12:01:36 -05:00
parent 256b727a3d
commit b5690e21a4
20 changed files with 111 additions and 65 deletions

View File

@ -31,6 +31,10 @@
<p>Add interface objects for <proper>libxml2</proper>.</p> <p>Add interface objects for <proper>libxml2</proper>.</p>
</release-item> </release-item>
<release-item>
<p>Allow I/O read interface to explicitly request blocking reads.</p>
</release-item>
<release-item> <release-item>
<p>Require <proper>S3</proper> key options except for <cmd>local</cmd>/<cmd>remote</cmd> commands.</p> <p>Require <proper>S3</proper> key options except for <cmd>local</cmd>/<cmd>remote</cmd> commands.</p>
</release-item> </release-item>

View File

@ -51,11 +51,12 @@ ioBufferReadNew(const Buffer *buffer)
Read data from the buffer Read data from the buffer
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t size_t
ioBufferRead(IoBufferRead *this, Buffer *buffer) ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_BUFFER_READ, this); FUNCTION_DEBUG_PARAM(IO_BUFFER_READ, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer); FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_PARAM(BOOL, block);
FUNCTION_DEBUG_ASSERT(this != NULL); FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(buffer != NULL); FUNCTION_DEBUG_ASSERT(buffer != NULL);

View File

@ -21,7 +21,7 @@ IoBufferRead *ioBufferReadNew(const Buffer *buffer);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Functions Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t ioBufferRead(IoBufferRead *this, Buffer *buffer); size_t ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block);
IoBufferRead *ioBufferReadMove(IoBufferRead *this, MemContext *parentNew); IoBufferRead *ioBufferReadMove(IoBufferRead *this, MemContext *parentNew);
/*********************************************************************************************************************************** /***********************************************************************************************************************************

View File

@ -59,11 +59,12 @@ struct HttpClient
Read content Read content
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
static size_t static size_t
httpClientRead(HttpClient *this, Buffer *buffer) httpClientRead(HttpClient *this, Buffer *buffer, bool block)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(HTTP_CLIENT, this); FUNCTION_DEBUG_PARAM(HTTP_CLIENT, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer); FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_PARAM(BOOL, block);
FUNCTION_TEST_ASSERT(this != NULL); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(buffer != NULL); FUNCTION_TEST_ASSERT(buffer != NULL);
@ -361,7 +362,7 @@ httpClientRequest(
do do
{ {
bufResize(result, bufSize(result) + ioBufferSize()); bufResize(result, bufSize(result) + ioBufferSize());
httpClientRead(this, result); httpClientRead(this, result, true);
} }
while (!httpClientEof(this)); while (!httpClientEof(this));
} }

View File

@ -113,12 +113,12 @@ ioReadEofDriver(const IoRead *this)
Read data from IO and process filters Read data from IO and process filters
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
static void static void
ioReadInternal(IoRead *this, Buffer *buffer, bool relaxed) ioReadInternal(IoRead *this, Buffer *buffer, bool block)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_READ, this); FUNCTION_DEBUG_PARAM(IO_READ, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer); FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_PARAM(BOOL, relaxed); FUNCTION_DEBUG_PARAM(BOOL, block);
FUNCTION_TEST_ASSERT(this != NULL); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(buffer != NULL); FUNCTION_TEST_ASSERT(buffer != NULL);
@ -142,7 +142,13 @@ ioReadInternal(IoRead *this, Buffer *buffer, bool relaxed)
if (!ioReadEofDriver(this)) if (!ioReadEofDriver(this))
{ {
bufUsedZero(this->input); bufUsedZero(this->input);
this->interface.read(this->driver, this->input);
// If blocking then limit the amount of data requested
if (block && bufRemains(this->input) > bufRemains(buffer))
bufLimitSet(this->input, bufRemains(buffer));
this->interface.read(this->driver, this->input, block);
bufLimitClear(this->input);
} }
// Set input to NULL and flush (no need to actually free the buffer here as it will be freed with the mem context) // Set input to NULL and flush (no need to actually free the buffer here as it will be freed with the mem context)
else else
@ -151,8 +157,8 @@ ioReadInternal(IoRead *this, Buffer *buffer, bool relaxed)
// Process the input buffer (or flush if NULL) // Process the input buffer (or flush if NULL)
ioFilterGroupProcess(this->filterGroup, this->input, buffer); ioFilterGroupProcess(this->filterGroup, this->input, buffer);
// Stop if relaxed read -- we don't need to fill the buffer as long as we got some data // Stop if not blocking -- we don't need to fill the buffer as long as we got some data
if (relaxed && bufUsed(buffer) > bufferUsedBegin) if (!block && bufUsed(buffer) > bufferUsedBegin)
break; break;
} }
@ -197,7 +203,7 @@ ioRead(IoRead *this, Buffer *buffer)
} }
// Read data // Read data
ioReadInternal(this, buffer, false); ioReadInternal(this, buffer, true);
FUNCTION_DEBUG_RESULT(SIZE, outputRemains - bufRemains(buffer)); FUNCTION_DEBUG_RESULT(SIZE, outputRemains - bufRemains(buffer));
} }
@ -263,7 +269,7 @@ ioReadLine(IoRead *this)
if (ioReadEof(this)) if (ioReadEof(this))
THROW(FileReadError, "unexpected eof while reading line"); THROW(FileReadError, "unexpected eof while reading line");
ioReadInternal(this, this->output, 1); ioReadInternal(this, this->output, false);
} }
} }
while (result == NULL); while (result == NULL);

View File

@ -12,7 +12,7 @@ Constructor
typedef bool (*IoReadInterfaceEof)(void *driver); typedef bool (*IoReadInterfaceEof)(void *driver);
typedef void (*IoReadInterfaceClose)(void *driver); typedef void (*IoReadInterfaceClose)(void *driver);
typedef bool (*IoReadInterfaceOpen)(void *driver); typedef bool (*IoReadInterfaceOpen)(void *driver);
typedef size_t (*IoReadInterfaceRead)(void *driver, Buffer *buffer); typedef size_t (*IoReadInterfaceRead)(void *driver, Buffer *buffer, bool block);
typedef struct IoReadInterface typedef struct IoReadInterface
{ {

View File

@ -377,11 +377,12 @@ tlsClientOpen(TlsClient *this)
Read from the TLS session Read from the TLS session
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t size_t
tlsClientRead(TlsClient *this, Buffer *buffer) tlsClientRead(TlsClient *this, Buffer *buffer, bool block)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(TLS_CLIENT, this); FUNCTION_DEBUG_PARAM(TLS_CLIENT, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer); FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_PARAM(BOOL, block);
FUNCTION_TEST_ASSERT(this != NULL); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(this->session != NULL); FUNCTION_TEST_ASSERT(this->session != NULL);
@ -391,6 +392,9 @@ tlsClientRead(TlsClient *this, Buffer *buffer)
ssize_t actualBytes = 0; ssize_t actualBytes = 0;
// If blocking read keep reading until buffer is full
do
{
// If no tls data pending then check the socket // If no tls data pending then check the socket
if (!SSL_pending(this->session)) if (!SSL_pending(this->session))
{ {
@ -430,7 +434,12 @@ tlsClientRead(TlsClient *this, Buffer *buffer)
// If zero bytes were returned then the connection was closed // If zero bytes were returned then the connection was closed
if (actualBytes == 0) if (actualBytes == 0)
{
tlsClientClose(this); tlsClientClose(this);
break;
}
}
while (block && bufRemains(buffer) > 0);
FUNCTION_DEBUG_RESULT(SIZE, (size_t)actualBytes); FUNCTION_DEBUG_RESULT(SIZE, (size_t)actualBytes);
} }

View File

@ -36,7 +36,7 @@ TlsClient *tlsClientNew(
Functions Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void tlsClientOpen(TlsClient *this); void tlsClientOpen(TlsClient *this);
size_t tlsClientRead(TlsClient *this, Buffer *buffer); size_t tlsClientRead(TlsClient *this, Buffer *buffer, bool block);
void tlsClientWrite(TlsClient *this, const Buffer *buffer); void tlsClientWrite(TlsClient *this, const Buffer *buffer);
void tlsClientClose(TlsClient *this); void tlsClientClose(TlsClient *this);

View File

@ -103,11 +103,12 @@ storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
Read from a file Read from a file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t size_t
storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer) storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this); FUNCTION_DEBUG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer); FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_PARAM(BOOL, block);
FUNCTION_DEBUG_ASSERT(this != NULL && this->handle != -1); FUNCTION_DEBUG_ASSERT(this != NULL && this->handle != -1);
FUNCTION_DEBUG_ASSERT(buffer != NULL && !bufFull(buffer)); FUNCTION_DEBUG_ASSERT(buffer != NULL && !bufFull(buffer));

View File

@ -23,7 +23,7 @@ StorageDriverPosixFileRead *storageDriverPosixFileReadNew(StorageDriverPosix *st
Functions Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this); bool storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this);
size_t storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer); size_t storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block);
void storageDriverPosixFileReadClose(StorageDriverPosixFileRead *this); void storageDriverPosixFileReadClose(StorageDriverPosixFileRead *this);
/*********************************************************************************************************************************** /***********************************************************************************************************************************

View File

@ -101,11 +101,12 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
Read from a file Read from a file
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
size_t size_t
storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer) storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_DRIVER_S3_FILE_READ, this); FUNCTION_DEBUG_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer); FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_PARAM(BOOL, block);
FUNCTION_DEBUG_ASSERT(this != NULL && this->httpClient != NULL); FUNCTION_DEBUG_ASSERT(this != NULL && this->httpClient != NULL);
FUNCTION_DEBUG_ASSERT(buffer != NULL && !bufFull(buffer)); FUNCTION_DEBUG_ASSERT(buffer != NULL && !bufFull(buffer));

View File

@ -23,7 +23,7 @@ StorageDriverS3FileRead *storageDriverS3FileReadNew(StorageDriverS3 *storage, co
Functions Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool storageDriverS3FileReadOpen(StorageDriverS3FileRead *this); bool storageDriverS3FileReadOpen(StorageDriverS3FileRead *this);
size_t storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer); size_t storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Getters Getters

View File

@ -330,7 +330,7 @@ Open a file for reading
StorageFileRead * StorageFileRead *
storageNewRead(const Storage *this, const String *fileExp, StorageNewReadParam param) storageNewRead(const Storage *this, const String *fileExp, StorageNewReadParam param)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace); FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this); FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, fileExp); FUNCTION_DEBUG_PARAM(STRING, fileExp);
FUNCTION_DEBUG_PARAM(BOOL, param.ignoreMissing); FUNCTION_DEBUG_PARAM(BOOL, param.ignoreMissing);
@ -361,7 +361,7 @@ Open a file for writing
StorageFileWrite * StorageFileWrite *
storageNewWrite(const Storage *this, const String *fileExp, StorageNewWriteParam param) storageNewWrite(const Storage *this, const String *fileExp, StorageNewWriteParam param)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace); FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this); FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, fileExp); FUNCTION_DEBUG_PARAM(STRING, fileExp);
FUNCTION_DEBUG_PARAM(MODE, param.modeFile); FUNCTION_DEBUG_PARAM(MODE, param.modeFile);

2
test/.gitignore vendored
View File

@ -1,6 +1,6 @@
.vagrant .vagrant
nytprof* nytprof*
scratch.txt scratch*
coverage* coverage*
ubuntu-bionic-18.04-cloudimg-console.log ubuntu-bionic-18.04-cloudimg-console.log
profile profile

View File

@ -126,6 +126,8 @@ P00 DEBUG: storage/storage::storageExists: => false
P00 DEBUG: command/control/control::lockStopTest: => void P00 DEBUG: command/control/control::lockStopTest: => void
P00 DEBUG: command/archive/get/file::archiveGetCheck: (archiveFile: {"700000007000000070000000"}) P00 DEBUG: command/archive/get/file::archiveGetCheck: (archiveFile: {"700000007000000070000000"})
P00 DEBUG: postgres/interface::pgControlFromFile: (pgPath: {"[TEST_PATH]/db-master/db/base"}) P00 DEBUG: postgres/interface::pgControlFromFile: (pgPath: {"[TEST_PATH]/db-master/db/base"})
P00 DEBUG: storage/storage::storageNewRead: (this: {type: posix, path: {"/"}, write: false}, fileExp: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, param.ignoreMissing: false, param.filterGroup: null)
P00 DEBUG: storage/storage::storageNewRead: => {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}
P00 DEBUG: storage/storage::storageGet: (file: {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}, param.exactSize: 512) P00 DEBUG: storage/storage::storageGet: (file: {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}, param.exactSize: 512)
P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: <off>} P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: <off>}
P00 DEBUG: postgres/interface::pgControlFromFile: => {version: 90400, systemId: 1000000000000000094, walSegmentSize: 16777216, pageChecksum: true} P00 DEBUG: postgres/interface::pgControlFromFile: => {version: 90400, systemId: 1000000000000000094, walSegmentSize: 16777216, pageChecksum: true}
@ -166,6 +168,8 @@ P00 DEBUG: storage/storage::storageExists: => false
P00 DEBUG: command/control/control::lockStopTest: => void P00 DEBUG: command/control/control::lockStopTest: => void
P00 DEBUG: command/archive/get/file::archiveGetCheck: (archiveFile: {"000000010000000100000001"}) P00 DEBUG: command/archive/get/file::archiveGetCheck: (archiveFile: {"000000010000000100000001"})
P00 DEBUG: postgres/interface::pgControlFromFile: (pgPath: {"[TEST_PATH]/db-master/db/base"}) P00 DEBUG: postgres/interface::pgControlFromFile: (pgPath: {"[TEST_PATH]/db-master/db/base"})
P00 DEBUG: storage/storage::storageNewRead: (this: {type: posix, path: {"/"}, write: false}, fileExp: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, param.ignoreMissing: false, param.filterGroup: null)
P00 DEBUG: storage/storage::storageNewRead: => {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}
P00 DEBUG: storage/storage::storageGet: (file: {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}, param.exactSize: 512) P00 DEBUG: storage/storage::storageGet: (file: {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}, param.exactSize: 512)
P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: <off>} P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: <off>}
P00 DEBUG: postgres/interface::pgControlFromFile: => {version: 90400, systemId: 1000000000000000094, walSegmentSize: 16777216, pageChecksum: true} P00 DEBUG: postgres/interface::pgControlFromFile: => {version: 90400, systemId: 1000000000000000094, walSegmentSize: 16777216, pageChecksum: true}
@ -184,8 +188,12 @@ P00 DEBUG: command/archive/common::walSegmentFind: => {"0000000100000001000
P00 DEBUG: command/archive/get/file::archiveGetCheck: => {"9.4-1/0000000100000001/000000010000000100000001-ceb021d9bb41f220511e413b095d2b0d89fec113.gz"} P00 DEBUG: command/archive/get/file::archiveGetCheck: => {"9.4-1/0000000100000001/000000010000000100000001-ceb021d9bb41f220511e413b095d2b0d89fec113.gz"}
P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: (path: {"/"}, modeFile: 0640, modePath: 0750, write: true, pathExpressionFunction: null) P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: (path: {"/"}, modeFile: 0640, modePath: 0750, write: true, pathExpressionFunction: null)
P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: => {StorageDriverPosix} P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: => {StorageDriverPosix}
P00 DEBUG: storage/storage::storageNewWrite: (this: {type: posix, path: {"/"}, write: true}, fileExp: {"[TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG"}, param.modeFile: 0000, param.modePath: 0000, param.noCreatePath: true, param.noSyncFile: true, param.noSyncPath: true, param.noAtomic: true, param.filterGroup: null)
P00 DEBUG: storage/storage::storageNewWrite: => {type: posix, name: {"[TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG"}, modeFile: 0640, modePath: 0750, createPath: false, syncFile: false, syncPath: false, atomic: false}
P00 DEBUG: common/io/filter/group::ioFilterGroupAdd: (this: {inputSame: false, done: true}, filter: {IoFilter}) P00 DEBUG: common/io/filter/group::ioFilterGroupAdd: (this: {inputSame: false, done: true}, filter: {IoFilter})
P00 DEBUG: common/io/filter/group::ioFilterGroupAdd: => void P00 DEBUG: common/io/filter/group::ioFilterGroupAdd: => void
P00 DEBUG: storage/storage::storageNewRead: (this: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileExp: {"<REPO:ARCHIVE>/9.4-1/0000000100000001/000000010000000100000001-ceb021d9bb41f220511e413b095d2b0d89fec113.gz"}, param.ignoreMissing: false, param.filterGroup: null)
P00 DEBUG: storage/storage::storageNewRead: => {type: posix, name: {"[TEST_PATH]/db-master/repo/archive/db/9.4-1/0000000100000001/000000010000000100000001-ceb021d9bb41f220511e413b095d2b0d89fec113.gz"}, ignoreMissing: false}
P00 DEBUG: storage/storage::storageCopy: (source: {type: posix, name: {"[TEST_PATH]/db-master/repo/archive/db/9.4-1/0000000100000001/000000010000000100000001-ceb021d9bb41f220511e413b095d2b0d89fec113.gz"}, ignoreMissing: false}, destination: {type: posix, name: {"[TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG"}, modeFile: 0640, modePath: 0750, createPath: false, syncFile: false, syncPath: false, atomic: false}) P00 DEBUG: storage/storage::storageCopy: (source: {type: posix, name: {"[TEST_PATH]/db-master/repo/archive/db/9.4-1/0000000100000001/000000010000000100000001-ceb021d9bb41f220511e413b095d2b0d89fec113.gz"}, ignoreMissing: false}, destination: {type: posix, name: {"[TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG"}, modeFile: 0640, modePath: 0750, createPath: false, syncFile: false, syncPath: false, atomic: false})
P00 DEBUG: storage/storage::storageCopy: => true P00 DEBUG: storage/storage::storageCopy: => true
P00 DEBUG: command/archive/get/file::archiveGetFile: => 0 P00 DEBUG: command/archive/get/file::archiveGetFile: => 0

View File

@ -543,6 +543,8 @@ P00 DEBUG: storage/storage::storageExists: => false
P00 DEBUG: command/control/control::lockStopTest: => void P00 DEBUG: command/control/control::lockStopTest: => void
P00 DEBUG: command/archive/get/file::archiveGetCheck: (archiveFile: {"000000010000000100000002"}) P00 DEBUG: command/archive/get/file::archiveGetCheck: (archiveFile: {"000000010000000100000002"})
P00 DEBUG: postgres/interface::pgControlFromFile: (pgPath: {"[TEST_PATH]/db-master/db/base"}) P00 DEBUG: postgres/interface::pgControlFromFile: (pgPath: {"[TEST_PATH]/db-master/db/base"})
P00 DEBUG: storage/storage::storageNewRead: (this: {type: posix, path: {"/"}, write: false}, fileExp: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, param.ignoreMissing: false, param.filterGroup: null)
P00 DEBUG: storage/storage::storageNewRead: => {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}
P00 DEBUG: storage/storage::storageGet: (file: {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}, param.exactSize: 512) P00 DEBUG: storage/storage::storageGet: (file: {type: posix, name: {"[TEST_PATH]/db-master/db/base/global/pg_control"}, ignoreMissing: false}, param.exactSize: 512)
P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: <off>} P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: <off>}
P00 DEBUG: postgres/interface::pgControlFromFile: => {version: 90300, systemId: 1000000000000000093, walSegmentSize: 16777216, pageChecksum: true} P00 DEBUG: postgres/interface::pgControlFromFile: => {version: 90300, systemId: 1000000000000000093, walSegmentSize: 16777216, pageChecksum: true}
@ -561,8 +563,12 @@ P00 DEBUG: command/archive/common::walSegmentFind: => {"0000000100000001000
P00 DEBUG: command/archive/get/file::archiveGetCheck: => {"9.3-1/0000000100000001/000000010000000100000002-488ba4b8b98acc510bce86b8f16e3c1ed9886a29.gz"} P00 DEBUG: command/archive/get/file::archiveGetCheck: => {"9.3-1/0000000100000001/000000010000000100000002-488ba4b8b98acc510bce86b8f16e3c1ed9886a29.gz"}
P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: (path: {"/"}, modeFile: 0640, modePath: 0750, write: true, pathExpressionFunction: null) P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: (path: {"/"}, modeFile: 0640, modePath: 0750, write: true, pathExpressionFunction: null)
P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: => {StorageDriverPosix} P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: => {StorageDriverPosix}
P00 DEBUG: storage/storage::storageNewWrite: (this: {type: posix, path: {"/"}, write: true}, fileExp: {"[TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG"}, param.modeFile: 0000, param.modePath: 0000, param.noCreatePath: true, param.noSyncFile: true, param.noSyncPath: true, param.noAtomic: true, param.filterGroup: null)
P00 DEBUG: storage/storage::storageNewWrite: => {type: posix, name: {"[TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG"}, modeFile: 0640, modePath: 0750, createPath: false, syncFile: false, syncPath: false, atomic: false}
P00 DEBUG: common/io/filter/group::ioFilterGroupAdd: (this: {inputSame: false, done: true}, filter: {IoFilter}) P00 DEBUG: common/io/filter/group::ioFilterGroupAdd: (this: {inputSame: false, done: true}, filter: {IoFilter})
P00 DEBUG: common/io/filter/group::ioFilterGroupAdd: => void P00 DEBUG: common/io/filter/group::ioFilterGroupAdd: => void
P00 DEBUG: storage/storage::storageNewRead: (this: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileExp: {"<REPO:ARCHIVE>/9.3-1/0000000100000001/000000010000000100000002-488ba4b8b98acc510bce86b8f16e3c1ed9886a29.gz"}, param.ignoreMissing: false, param.filterGroup: null)
P00 DEBUG: storage/storage::storageNewRead: => {type: posix, name: {"[TEST_PATH]/db-master/repo/archive/db/9.3-1/0000000100000001/000000010000000100000002-488ba4b8b98acc510bce86b8f16e3c1ed9886a29.gz"}, ignoreMissing: false}
P00 DEBUG: storage/storage::storageCopy: (source: {type: posix, name: {"[TEST_PATH]/db-master/repo/archive/db/9.3-1/0000000100000001/000000010000000100000002-488ba4b8b98acc510bce86b8f16e3c1ed9886a29.gz"}, ignoreMissing: false}, destination: {type: posix, name: {"[TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG"}, modeFile: 0640, modePath: 0750, createPath: false, syncFile: false, syncPath: false, atomic: false}) P00 DEBUG: storage/storage::storageCopy: (source: {type: posix, name: {"[TEST_PATH]/db-master/repo/archive/db/9.3-1/0000000100000001/000000010000000100000002-488ba4b8b98acc510bce86b8f16e3c1ed9886a29.gz"}, ignoreMissing: false}, destination: {type: posix, name: {"[TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG"}, modeFile: 0640, modePath: 0750, createPath: false, syncFile: false, syncPath: false, atomic: false})
P00 DEBUG: storage/storage::storageCopy: => true P00 DEBUG: storage/storage::storageCopy: => true
P00 DEBUG: command/archive/get/file::archiveGetFile: => 0 P00 DEBUG: command/archive/get/file::archiveGetFile: => 0

View File

@ -423,7 +423,7 @@ testRun(void)
strPtr(httpHeaderToLog(httpClientReponseHeader(client))), "{connection: 'close', content-length: '32'}", strPtr(httpHeaderToLog(httpClientReponseHeader(client))), "{connection: 'close', content-length: '32'}",
" check response headers"); " check response headers");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "01234567890123456789012345678901", " check response"); TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "01234567890123456789012345678901", " check response");
TEST_RESULT_UINT(httpClientRead(client, bufNew(1)), 0, " call internal read to check eof"); TEST_RESULT_UINT(httpClientRead(client, bufNew(1), true), 0, " call internal read to check eof");
// Request with content using chunked encoding // Request with content using chunked encoding
TEST_RESULT_VOID(httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, false), "request with chunked encoding"); TEST_RESULT_VOID(httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, false), "request with chunked encoding");

View File

@ -294,7 +294,7 @@ testRun(void)
TEST_RESULT_VOID(bufUsedZero(buffer), " zero buffer"); TEST_RESULT_VOID(bufUsedZero(buffer), " zero buffer");
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), true, " eof"); TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), true, " eof");
TEST_RESULT_BOOL(ioBufferRead(bufferRead, buffer), 0, " eof from driver"); TEST_RESULT_BOOL(ioBufferRead(bufferRead, buffer, true), 0, " eof from driver");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes"); TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes");
TEST_RESULT_VOID(ioReadClose(ioBufferReadIo(bufferRead)), " close buffer read object"); TEST_RESULT_VOID(ioReadClose(ioBufferReadIo(bufferRead)), " close buffer read object");

View File

@ -67,7 +67,13 @@ testTlsServer(void)
harnessTlsServerAccept(); harnessTlsServerAccept();
harnessTlsServerExpect("some protocol info"); harnessTlsServerExpect("some protocol info");
harnessTlsServerReply("something:0\nsome content"); harnessTlsServerReply("something:0\n");
sleepMSec(100);
harnessTlsServerReply("some ");
sleepMSec(100);
harnessTlsServerReply("contentAND MORE");
// This will cause the client to disconnect // This will cause the client to disconnect
sleepMSec(500); sleepMSec(500);
@ -180,16 +186,19 @@ testRun(void)
TEST_RESULT_VOID(ioWrite(tlsClientIoWrite(client), input), "write input"); TEST_RESULT_VOID(ioWrite(tlsClientIoWrite(client), input), "write input");
ioWriteFlush(tlsClientIoWrite(client)); ioWriteFlush(tlsClientIoWrite(client));
Buffer *output = bufNew(12); TEST_RESULT_STR(strPtr(ioReadLine(tlsClientIoRead(client))), "something:0", "read line");
TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 12, "read output");
TEST_RESULT_STR(strPtr(strNewBuf(output)), "something:0\n", " check output");
TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false"); TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false");
output = bufNew(12); Buffer *output = bufNew(12);
TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 12, "read output"); TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 12, "read output");
TEST_RESULT_STR(strPtr(strNewBuf(output)), "some content", " check output"); TEST_RESULT_STR(strPtr(strNewBuf(output)), "some content", " check output");
TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false"); TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false");
output = bufNew(8);
TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 8, "read output");
TEST_RESULT_STR(strPtr(strNewBuf(output)), "AND MORE", " check output");
TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false");
output = bufNew(12); output = bufNew(12);
TEST_ERROR( TEST_ERROR(
ioRead(tlsClientIoRead(client), output), FileReadError, ioRead(tlsClientIoRead(client), output), FileReadError,

View File

@ -749,7 +749,7 @@ testRun(void)
TEST_RESULT_INT(bufUsed(outBuffer), 0, " buffer is empty"); TEST_RESULT_INT(bufUsed(outBuffer), 0, " buffer is empty");
TEST_RESULT_VOID( TEST_RESULT_VOID(
storageDriverPosixFileRead(storageFileReadDriver(file), outBuffer), " no data to load from driver either"); storageDriverPosixFileRead(storageFileReadDriver(file), outBuffer, true), " no data to load from driver either");
TEST_RESULT_INT(bufUsed(outBuffer), 0, " buffer is empty"); TEST_RESULT_INT(bufUsed(outBuffer), 0, " buffer is empty");
TEST_RESULT_BOOL(bufEq(buffer, expectedBuffer), true, " check file contents (all loaded)"); TEST_RESULT_BOOL(bufEq(buffer, expectedBuffer), true, " check file contents (all loaded)");