mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +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:
parent
256b727a3d
commit
b5690e21a4
@ -31,6 +31,10 @@
|
||||
<p>Add interface objects for <proper>libxml2</proper>.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Allow I/O read interface to explicitly request blocking reads.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Require <proper>S3</proper> key options except for <cmd>local</cmd>/<cmd>remote</cmd> commands.</p>
|
||||
</release-item>
|
||||
|
@ -51,11 +51,12 @@ ioBufferReadNew(const Buffer *buffer)
|
||||
Read data from the buffer
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
ioBufferRead(IoBufferRead *this, Buffer *buffer)
|
||||
ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block)
|
||||
{
|
||||
FUNCTION_DEBUG_BEGIN(logLevelTrace);
|
||||
FUNCTION_DEBUG_PARAM(IO_BUFFER_READ, this);
|
||||
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_DEBUG_PARAM(BOOL, block);
|
||||
|
||||
FUNCTION_DEBUG_ASSERT(this != NULL);
|
||||
FUNCTION_DEBUG_ASSERT(buffer != NULL);
|
||||
|
@ -21,7 +21,7 @@ IoBufferRead *ioBufferReadNew(const Buffer *buffer);
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
size_t ioBufferRead(IoBufferRead *this, Buffer *buffer);
|
||||
size_t ioBufferRead(IoBufferRead *this, Buffer *buffer, bool block);
|
||||
IoBufferRead *ioBufferReadMove(IoBufferRead *this, MemContext *parentNew);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -59,11 +59,12 @@ struct HttpClient
|
||||
Read content
|
||||
***********************************************************************************************************************************/
|
||||
static size_t
|
||||
httpClientRead(HttpClient *this, Buffer *buffer)
|
||||
httpClientRead(HttpClient *this, Buffer *buffer, bool block)
|
||||
{
|
||||
FUNCTION_DEBUG_BEGIN(logLevelTrace);
|
||||
FUNCTION_DEBUG_PARAM(HTTP_CLIENT, this);
|
||||
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_DEBUG_PARAM(BOOL, block);
|
||||
|
||||
FUNCTION_TEST_ASSERT(this != NULL);
|
||||
FUNCTION_TEST_ASSERT(buffer != NULL);
|
||||
@ -361,7 +362,7 @@ httpClientRequest(
|
||||
do
|
||||
{
|
||||
bufResize(result, bufSize(result) + ioBufferSize());
|
||||
httpClientRead(this, result);
|
||||
httpClientRead(this, result, true);
|
||||
}
|
||||
while (!httpClientEof(this));
|
||||
}
|
||||
|
@ -113,12 +113,12 @@ ioReadEofDriver(const IoRead *this)
|
||||
Read data from IO and process filters
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
ioReadInternal(IoRead *this, Buffer *buffer, bool relaxed)
|
||||
ioReadInternal(IoRead *this, Buffer *buffer, bool block)
|
||||
{
|
||||
FUNCTION_DEBUG_BEGIN(logLevelTrace);
|
||||
FUNCTION_DEBUG_PARAM(IO_READ, this);
|
||||
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_DEBUG_PARAM(BOOL, relaxed);
|
||||
FUNCTION_DEBUG_PARAM(BOOL, block);
|
||||
|
||||
FUNCTION_TEST_ASSERT(this != NULL);
|
||||
FUNCTION_TEST_ASSERT(buffer != NULL);
|
||||
@ -142,7 +142,13 @@ ioReadInternal(IoRead *this, Buffer *buffer, bool relaxed)
|
||||
if (!ioReadEofDriver(this))
|
||||
{
|
||||
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)
|
||||
else
|
||||
@ -151,8 +157,8 @@ ioReadInternal(IoRead *this, Buffer *buffer, bool relaxed)
|
||||
// Process the input buffer (or flush if NULL)
|
||||
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
|
||||
if (relaxed && bufUsed(buffer) > bufferUsedBegin)
|
||||
// Stop if not blocking -- we don't need to fill the buffer as long as we got some data
|
||||
if (!block && bufUsed(buffer) > bufferUsedBegin)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -197,7 +203,7 @@ ioRead(IoRead *this, Buffer *buffer)
|
||||
}
|
||||
|
||||
// Read data
|
||||
ioReadInternal(this, buffer, false);
|
||||
ioReadInternal(this, buffer, true);
|
||||
|
||||
FUNCTION_DEBUG_RESULT(SIZE, outputRemains - bufRemains(buffer));
|
||||
}
|
||||
@ -263,7 +269,7 @@ ioReadLine(IoRead *this)
|
||||
if (ioReadEof(this))
|
||||
THROW(FileReadError, "unexpected eof while reading line");
|
||||
|
||||
ioReadInternal(this, this->output, 1);
|
||||
ioReadInternal(this, this->output, false);
|
||||
}
|
||||
}
|
||||
while (result == NULL);
|
||||
|
@ -12,7 +12,7 @@ Constructor
|
||||
typedef bool (*IoReadInterfaceEof)(void *driver);
|
||||
typedef void (*IoReadInterfaceClose)(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
|
||||
{
|
||||
|
@ -377,11 +377,12 @@ tlsClientOpen(TlsClient *this)
|
||||
Read from the TLS session
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
tlsClientRead(TlsClient *this, Buffer *buffer)
|
||||
tlsClientRead(TlsClient *this, Buffer *buffer, bool block)
|
||||
{
|
||||
FUNCTION_DEBUG_BEGIN(logLevelTrace);
|
||||
FUNCTION_DEBUG_PARAM(TLS_CLIENT, this);
|
||||
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_DEBUG_PARAM(BOOL, block);
|
||||
|
||||
FUNCTION_TEST_ASSERT(this != NULL);
|
||||
FUNCTION_TEST_ASSERT(this->session != NULL);
|
||||
@ -391,46 +392,54 @@ tlsClientRead(TlsClient *this, Buffer *buffer)
|
||||
|
||||
ssize_t actualBytes = 0;
|
||||
|
||||
// If no tls data pending then check the socket
|
||||
if (!SSL_pending(this->session))
|
||||
// If blocking read keep reading until buffer is full
|
||||
do
|
||||
{
|
||||
// Initialize the file descriptor set used for select
|
||||
fd_set selectSet;
|
||||
FD_ZERO(&selectSet);
|
||||
|
||||
// We know the socket is not negative because it passed error handling, so it is safe to cast to unsigned
|
||||
FD_SET((unsigned int)this->socket, &selectSet);
|
||||
|
||||
// Initialize timeout struct used for select. Recreate this structure each time since Linux (at least) will modify it.
|
||||
struct timeval timeoutSelect;
|
||||
timeoutSelect.tv_sec = (time_t)(this->timeout / MSEC_PER_SEC);
|
||||
timeoutSelect.tv_usec = (time_t)(this->timeout % MSEC_PER_SEC * 1000);
|
||||
|
||||
// Determine if there is data to be read
|
||||
int result = select(this->socket + 1, &selectSet, NULL, NULL, &timeoutSelect);
|
||||
THROW_ON_SYS_ERROR_FMT(result == -1, AssertError, "unable to select from '%s:%u'", strPtr(this->host), this->port);
|
||||
|
||||
// If no data read after time allotted then error
|
||||
if (!result)
|
||||
// If no tls data pending then check the socket
|
||||
if (!SSL_pending(this->session))
|
||||
{
|
||||
THROW_FMT(
|
||||
FileReadError, "unable to read data from '%s:%u' after %" PRIu64 "ms",
|
||||
strPtr(this->host), this->port, this->timeout);
|
||||
// Initialize the file descriptor set used for select
|
||||
fd_set selectSet;
|
||||
FD_ZERO(&selectSet);
|
||||
|
||||
// We know the socket is not negative because it passed error handling, so it is safe to cast to unsigned
|
||||
FD_SET((unsigned int)this->socket, &selectSet);
|
||||
|
||||
// Initialize timeout struct used for select. Recreate this structure each time since Linux (at least) will modify it.
|
||||
struct timeval timeoutSelect;
|
||||
timeoutSelect.tv_sec = (time_t)(this->timeout / MSEC_PER_SEC);
|
||||
timeoutSelect.tv_usec = (time_t)(this->timeout % MSEC_PER_SEC * 1000);
|
||||
|
||||
// Determine if there is data to be read
|
||||
int result = select(this->socket + 1, &selectSet, NULL, NULL, &timeoutSelect);
|
||||
THROW_ON_SYS_ERROR_FMT(result == -1, AssertError, "unable to select from '%s:%u'", strPtr(this->host), this->port);
|
||||
|
||||
// If no data read after time allotted then error
|
||||
if (!result)
|
||||
{
|
||||
THROW_FMT(
|
||||
FileReadError, "unable to read data from '%s:%u' after %" PRIu64 "ms",
|
||||
strPtr(this->host), this->port, this->timeout);
|
||||
}
|
||||
}
|
||||
|
||||
// Read and handle errors
|
||||
size_t expectedBytes = bufRemains(buffer);
|
||||
actualBytes = SSL_read(this->session, bufRemainsPtr(buffer), (int)expectedBytes);
|
||||
|
||||
cryptoError(actualBytes < 0, "unable to read from TLS");
|
||||
|
||||
// Update amount of buffer used
|
||||
bufUsedInc(buffer, (size_t)actualBytes);
|
||||
|
||||
// If zero bytes were returned then the connection was closed
|
||||
if (actualBytes == 0)
|
||||
{
|
||||
tlsClientClose(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Read and handle errors
|
||||
size_t expectedBytes = bufRemains(buffer);
|
||||
actualBytes = SSL_read(this->session, bufRemainsPtr(buffer), (int)expectedBytes);
|
||||
|
||||
cryptoError(actualBytes < 0, "unable to read from TLS");
|
||||
|
||||
// Update amount of buffer used
|
||||
bufUsedInc(buffer, (size_t)actualBytes);
|
||||
|
||||
// If zero bytes were returned then the connection was closed
|
||||
if (actualBytes == 0)
|
||||
tlsClientClose(this);
|
||||
while (block && bufRemains(buffer) > 0);
|
||||
|
||||
FUNCTION_DEBUG_RESULT(SIZE, (size_t)actualBytes);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ TlsClient *tlsClientNew(
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
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 tlsClientClose(TlsClient *this);
|
||||
|
||||
|
@ -103,11 +103,12 @@ storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this)
|
||||
Read from a file
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer)
|
||||
storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block)
|
||||
{
|
||||
FUNCTION_DEBUG_BEGIN(logLevelTrace);
|
||||
FUNCTION_DEBUG_PARAM(STORAGE_DRIVER_POSIX_FILE_READ, this);
|
||||
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_DEBUG_PARAM(BOOL, block);
|
||||
|
||||
FUNCTION_DEBUG_ASSERT(this != NULL && this->handle != -1);
|
||||
FUNCTION_DEBUG_ASSERT(buffer != NULL && !bufFull(buffer));
|
||||
|
@ -23,7 +23,7 @@ StorageDriverPosixFileRead *storageDriverPosixFileReadNew(StorageDriverPosix *st
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverPosixFileReadOpen(StorageDriverPosixFileRead *this);
|
||||
size_t storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer);
|
||||
size_t storageDriverPosixFileRead(StorageDriverPosixFileRead *this, Buffer *buffer, bool block);
|
||||
void storageDriverPosixFileReadClose(StorageDriverPosixFileRead *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -101,11 +101,12 @@ storageDriverS3FileReadOpen(StorageDriverS3FileRead *this)
|
||||
Read from a file
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer)
|
||||
storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block)
|
||||
{
|
||||
FUNCTION_DEBUG_BEGIN(logLevelTrace);
|
||||
FUNCTION_DEBUG_PARAM(STORAGE_DRIVER_S3_FILE_READ, this);
|
||||
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
|
||||
FUNCTION_DEBUG_PARAM(BOOL, block);
|
||||
|
||||
FUNCTION_DEBUG_ASSERT(this != NULL && this->httpClient != NULL);
|
||||
FUNCTION_DEBUG_ASSERT(buffer != NULL && !bufFull(buffer));
|
||||
|
@ -23,7 +23,7 @@ StorageDriverS3FileRead *storageDriverS3FileReadNew(StorageDriverS3 *storage, co
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
bool storageDriverS3FileReadOpen(StorageDriverS3FileRead *this);
|
||||
size_t storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer);
|
||||
size_t storageDriverS3FileRead(StorageDriverS3FileRead *this, Buffer *buffer, bool block);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters
|
||||
|
@ -330,7 +330,7 @@ Open a file for reading
|
||||
StorageFileRead *
|
||||
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(STRING, fileExp);
|
||||
FUNCTION_DEBUG_PARAM(BOOL, param.ignoreMissing);
|
||||
@ -361,7 +361,7 @@ Open a file for writing
|
||||
StorageFileWrite *
|
||||
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(STRING, fileExp);
|
||||
FUNCTION_DEBUG_PARAM(MODE, param.modeFile);
|
||||
|
2
test/.gitignore
vendored
2
test/.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
.vagrant
|
||||
nytprof*
|
||||
scratch.txt
|
||||
scratch*
|
||||
coverage*
|
||||
ubuntu-bionic-18.04-cloudimg-console.log
|
||||
profile
|
||||
|
@ -126,6 +126,8 @@ P00 DEBUG: storage/storage::storageExists: => false
|
||||
P00 DEBUG: command/control/control::lockStopTest: => void
|
||||
P00 DEBUG: command/archive/get/file::archiveGetCheck: (archiveFile: {"700000007000000070000000"})
|
||||
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: => {used: 512, size: 512, limit: <off>}
|
||||
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/archive/get/file::archiveGetCheck: (archiveFile: {"000000010000000100000001"})
|
||||
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: => {used: 512, size: 512, limit: <off>}
|
||||
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: 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/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: => 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: => true
|
||||
P00 DEBUG: command/archive/get/file::archiveGetFile: => 0
|
||||
|
@ -543,6 +543,8 @@ P00 DEBUG: storage/storage::storageExists: => false
|
||||
P00 DEBUG: command/control/control::lockStopTest: => void
|
||||
P00 DEBUG: command/archive/get/file::archiveGetCheck: (archiveFile: {"000000010000000100000002"})
|
||||
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: => {used: 512, size: 512, limit: <off>}
|
||||
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: 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/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: => 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: => true
|
||||
P00 DEBUG: command/archive/get/file::archiveGetFile: => 0
|
||||
|
@ -423,7 +423,7 @@ testRun(void)
|
||||
strPtr(httpHeaderToLog(httpClientReponseHeader(client))), "{connection: 'close', content-length: '32'}",
|
||||
" check response headers");
|
||||
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
|
||||
TEST_RESULT_VOID(httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, false), "request with chunked encoding");
|
||||
|
@ -294,7 +294,7 @@ testRun(void)
|
||||
|
||||
TEST_RESULT_VOID(bufUsedZero(buffer), " zero buffer");
|
||||
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_VOID(ioReadClose(ioBufferReadIo(bufferRead)), " close buffer read object");
|
||||
|
||||
|
@ -67,7 +67,13 @@ testTlsServer(void)
|
||||
harnessTlsServerAccept();
|
||||
|
||||
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
|
||||
sleepMSec(500);
|
||||
@ -180,16 +186,19 @@ testRun(void)
|
||||
TEST_RESULT_VOID(ioWrite(tlsClientIoWrite(client), input), "write input");
|
||||
ioWriteFlush(tlsClientIoWrite(client));
|
||||
|
||||
Buffer *output = bufNew(12);
|
||||
TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 12, "read output");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(output)), "something:0\n", " check output");
|
||||
TEST_RESULT_STR(strPtr(ioReadLine(tlsClientIoRead(client))), "something:0", "read line");
|
||||
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_STR(strPtr(strNewBuf(output)), "some content", " check output");
|
||||
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);
|
||||
TEST_ERROR(
|
||||
ioRead(tlsClientIoRead(client), output), FileReadError,
|
||||
|
@ -749,7 +749,7 @@ testRun(void)
|
||||
TEST_RESULT_INT(bufUsed(outBuffer), 0, " buffer is empty");
|
||||
|
||||
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_BOOL(bufEq(buffer, expectedBuffer), true, " check file contents (all loaded)");
|
||||
|
Loading…
Reference in New Issue
Block a user