You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-09-16 09:06:18 +02:00
Allow more tests to run outside of containers.
These tests required sudo to achieve complete coverage. Add a new coverage exception, vm_covered, that applies to code that can only be covered in a container. When the test is run outside of a container code sections that require a container will be excluded with TEST_CONTAINER_REQUIRED and the coverage exception will be added to prevent a coverage error. This does require marking up the core code with vm_covered, which in some modules (e.g. common/io/tls/client) can be extensive. It's possible that some of these tests can be rewritten to be less dependent on sudo but no attempt was made to do that here. Only allow coverage summaries in a vm since coverage summaries outside a vm will not be complete, which was true even before this commit.
This commit is contained in:
@@ -607,11 +607,11 @@ restoreManifestOwner(Manifest *manifest)
|
||||
StorageInfo pathInfo = storageInfoP(storagePg(), manifestTargetBase(manifest)->path);
|
||||
|
||||
// If user/group is null then set it to root
|
||||
if (pathInfo.user == NULL)
|
||||
pathInfo.user = userName();
|
||||
if (pathInfo.user == NULL) // {vm_covered}
|
||||
pathInfo.user = userName(); // {vm_covered}
|
||||
|
||||
if (pathInfo.group == NULL)
|
||||
pathInfo.group = groupName();
|
||||
if (pathInfo.group == NULL) // {vm_covered}
|
||||
pathInfo.group = groupName(); // {vm_covered}
|
||||
|
||||
if (userNull || groupNull)
|
||||
{
|
||||
|
@@ -101,11 +101,11 @@ tlsClientNew(SocketClient *socket, TimeMSec timeout, bool verifyPeer, const Stri
|
||||
if (this->verifyPeer)
|
||||
{
|
||||
// If the user specified a location
|
||||
if (caFile != NULL || caPath != NULL)
|
||||
if (caFile != NULL || caPath != NULL) // {vm_covered}
|
||||
{
|
||||
cryptoError(
|
||||
SSL_CTX_load_verify_locations(this->context, strPtr(caFile), strPtr(caPath)) != 1,
|
||||
"unable to set user-defined CA certificate location");
|
||||
cryptoError( // {vm_covered}
|
||||
SSL_CTX_load_verify_locations(this->context, strPtr(caFile), strPtr(caPath)) != 1, // {vm_covered}
|
||||
"unable to set user-defined CA certificate location"); // {vm_covered}
|
||||
}
|
||||
// Else use the defaults
|
||||
else
|
||||
@@ -130,10 +130,10 @@ asn1ToStr(ASN1_STRING *nameAsn1)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
// The name should not be null
|
||||
if (nameAsn1 == NULL)
|
||||
if (nameAsn1 == NULL) // {vm_covered}
|
||||
THROW(CryptoError, "TLS certificate name entry is missing");
|
||||
|
||||
FUNCTION_TEST_RETURN(
|
||||
FUNCTION_TEST_RETURN( // {vm_covered}
|
||||
strNewN(
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
(const char *)ASN1_STRING_data(nameAsn1),
|
||||
@@ -166,9 +166,9 @@ tlsClientHostVerifyName(const String *host, const String *name)
|
||||
bool result = false;
|
||||
|
||||
// Try an exact match
|
||||
if (strcasecmp(strPtr(name), strPtr(host)) == 0)
|
||||
if (strcasecmp(strPtr(name), strPtr(host)) == 0) // {vm_covered}
|
||||
{
|
||||
result = true;
|
||||
result = true; // {vm_covered}
|
||||
}
|
||||
// Else check if a wildcard certificate matches the host name
|
||||
//
|
||||
@@ -180,11 +180,12 @@ tlsClientHostVerifyName(const String *host, const String *name)
|
||||
//
|
||||
// This is roughly in line with RFC2818, but contrary to what most browsers appear to be implementing (point 3 being the
|
||||
// difference)
|
||||
else if (strPtr(name)[0] == '*' && strPtr(name)[1] == '.' && strSize(name) > 2 && strSize(name) < strSize(host) &&
|
||||
strcasecmp(strPtr(name) + 1, strPtr(host) + strSize(host) - strSize(name) + 1) == 0 &&
|
||||
strChr(host, '.') >= (int)(strSize(host) - strSize(name)))
|
||||
else if (strPtr(name)[0] == '*' && strPtr(name)[1] == '.' && strSize(name) > 2 && // {vm_covered}
|
||||
strSize(name) < strSize(host) && // {vm_covered}
|
||||
strcasecmp(strPtr(name) + 1, strPtr(host) + strSize(host) - strSize(name) + 1) == 0 && // {vm_covered}
|
||||
strChr(host, '.') >= (int)(strSize(host) - strSize(name))) // {vm_covered}
|
||||
{
|
||||
result = true;
|
||||
result = true; // {vm_covered}
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN(BOOL, result);
|
||||
@@ -208,50 +209,51 @@ tlsClientHostVerify(const String *host, X509 *certificate)
|
||||
bool result = false;
|
||||
|
||||
// Error if the certificate is NULL
|
||||
if (certificate == NULL)
|
||||
THROW(CryptoError, "No certificate presented by the TLS server");
|
||||
if (certificate == NULL) // {vm_covered}
|
||||
THROW(CryptoError, "No certificate presented by the TLS server"); // {vm_covered}
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
MEM_CONTEXT_TEMP_BEGIN() // {vm_covered}
|
||||
{
|
||||
// First get the subject alternative names from the certificate and compare them against the hostname
|
||||
STACK_OF(GENERAL_NAME) *altNameStack = (STACK_OF(GENERAL_NAME) *)X509_get_ext_d2i(
|
||||
certificate, NID_subject_alt_name, NULL, NULL);
|
||||
bool altNameFound = false;
|
||||
STACK_OF(GENERAL_NAME) *altNameStack = (STACK_OF(GENERAL_NAME) *)X509_get_ext_d2i( // {vm_covered}
|
||||
certificate, NID_subject_alt_name, NULL, NULL); // {vm_covered}
|
||||
bool altNameFound = false; // {vm_covered}
|
||||
|
||||
if (altNameStack)
|
||||
if (altNameStack) // {vm_covered}
|
||||
{
|
||||
for (int altNameIdx = 0; altNameIdx < sk_GENERAL_NAME_num(altNameStack); altNameIdx++)
|
||||
for (int altNameIdx = 0; altNameIdx < sk_GENERAL_NAME_num(altNameStack); altNameIdx++) // {vm_covered}
|
||||
{
|
||||
const GENERAL_NAME *name = sk_GENERAL_NAME_value(altNameStack, altNameIdx);
|
||||
altNameFound = true;
|
||||
const GENERAL_NAME *name = sk_GENERAL_NAME_value(altNameStack, altNameIdx); // {vm_covered}
|
||||
altNameFound = true; // {vm_covered}
|
||||
|
||||
if (name->type == GEN_DNS)
|
||||
result = tlsClientHostVerifyName(host, asn1ToStr(name->d.dNSName));
|
||||
if (name->type == GEN_DNS) // {vm_covered}
|
||||
result = tlsClientHostVerifyName(host, asn1ToStr(name->d.dNSName)); // {vm_covered}
|
||||
|
||||
if (result != false)
|
||||
break;
|
||||
if (result != false) // {vm_covered}
|
||||
break; // {vm_covered}
|
||||
}
|
||||
|
||||
sk_GENERAL_NAME_pop_free(altNameStack, GENERAL_NAME_free);
|
||||
sk_GENERAL_NAME_pop_free(altNameStack, GENERAL_NAME_free); // {vm_covered}
|
||||
}
|
||||
|
||||
// If no subject alternative name was found then check the common name. Per RFC 2818 and RFC 6125, if the subjectAltName
|
||||
// extension of type dNSName is present the CN must be ignored.
|
||||
if (!altNameFound)
|
||||
if (!altNameFound) // {vm_covered}
|
||||
{
|
||||
X509_NAME *subjectName = X509_get_subject_name(certificate);
|
||||
CHECK(subjectName != NULL);
|
||||
X509_NAME *subjectName = X509_get_subject_name(certificate); // {vm_covered}
|
||||
CHECK(subjectName != NULL); // {vm_covered}
|
||||
|
||||
int commonNameIndex = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1);
|
||||
CHECK(commonNameIndex >= 0);
|
||||
int commonNameIndex = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1); // {vm_covered}
|
||||
CHECK(commonNameIndex >= 0); // {vm_covered}
|
||||
|
||||
result = tlsClientHostVerifyName(
|
||||
host, asn1ToStr(X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subjectName, commonNameIndex))));
|
||||
result = tlsClientHostVerifyName( // {vm_covered}
|
||||
host, // {vm_covered}
|
||||
asn1ToStr(X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subjectName, commonNameIndex)))); // {vm_covered}
|
||||
}
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
MEM_CONTEXT_TEMP_END(); // {vm_covered}
|
||||
|
||||
FUNCTION_LOG_RETURN(BOOL, result);
|
||||
FUNCTION_LOG_RETURN(BOOL, result); // {vm_covered}
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@@ -322,30 +324,30 @@ tlsClientOpen(TlsClient *this)
|
||||
tlsClientStatLocal.session++;
|
||||
|
||||
// Verify that the certificate presented by the server is valid
|
||||
if (this->verifyPeer)
|
||||
if (this->verifyPeer) // {vm_covered}
|
||||
{
|
||||
// Verify that the chain of trust leads to a valid CA
|
||||
long int verifyResult = SSL_get_verify_result(session);
|
||||
long int verifyResult = SSL_get_verify_result(session); // {vm_covered}
|
||||
|
||||
if (verifyResult != X509_V_OK)
|
||||
if (verifyResult != X509_V_OK) // {vm_covered}
|
||||
{
|
||||
THROW_FMT(
|
||||
CryptoError, "unable to verify certificate presented by '%s:%u': [%ld] %s",
|
||||
strPtr(sckClientHost(this->socketClient)), sckClientPort(this->socketClient), verifyResult,
|
||||
X509_verify_cert_error_string(verifyResult));
|
||||
THROW_FMT( // {vm_covered}
|
||||
CryptoError, "unable to verify certificate presented by '%s:%u': [%ld] %s", // {vm_covered}
|
||||
strPtr(sckClientHost(this->socketClient)), sckClientPort(this->socketClient), verifyResult, // {vm_covered}
|
||||
X509_verify_cert_error_string(verifyResult)); // {vm_covered}
|
||||
}
|
||||
|
||||
// Verify that the hostname appears in the certificate
|
||||
X509 *certificate = SSL_get_peer_certificate(session);
|
||||
bool nameResult = tlsClientHostVerify(sckClientHost(this->socketClient), certificate);
|
||||
X509_free(certificate);
|
||||
X509 *certificate = SSL_get_peer_certificate(session); // {vm_covered}
|
||||
bool nameResult = tlsClientHostVerify(sckClientHost(this->socketClient), certificate); // {vm_covered}
|
||||
X509_free(certificate); // {vm_covered}
|
||||
|
||||
if (!nameResult)
|
||||
if (!nameResult) // {vm_covered}
|
||||
{
|
||||
THROW_FMT(
|
||||
CryptoError,
|
||||
"unable to find hostname '%s' in certificate common name or subject alternative names",
|
||||
strPtr(sckClientHost(this->socketClient)));
|
||||
THROW_FMT( // {vm_covered}
|
||||
CryptoError, // {vm_covered}
|
||||
"unable to find hostname '%s' in certificate common name or subject alternative names", // {vm_covered}
|
||||
strPtr(sckClientHost(this->socketClient))); // {vm_covered}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -74,13 +74,13 @@ storageReadPosixOpen(THIS_VOID)
|
||||
// Handle errors
|
||||
if (this->handle == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
if (errno == ENOENT) // {vm_covered}
|
||||
{
|
||||
if (!this->interface.ignoreMissing)
|
||||
THROW_FMT(FileMissingError, STORAGE_ERROR_READ_MISSING, strPtr(this->interface.name));
|
||||
}
|
||||
else
|
||||
THROW_SYS_ERROR_FMT(FileOpenError, STORAGE_ERROR_READ_OPEN, strPtr(this->interface.name));
|
||||
THROW_SYS_ERROR_FMT(FileOpenError, STORAGE_ERROR_READ_OPEN, strPtr(this->interface.name)); // {vm_covered}
|
||||
}
|
||||
// On success set free callback to ensure file handle is freed
|
||||
if (this->handle != -1)
|
||||
|
@@ -65,8 +65,8 @@ storagePosixInfo(THIS_VOID, const String *file, StorageInfoLevel level, StorageI
|
||||
|
||||
if ((param.followLink ? stat(strPtr(file), &statFile) : lstat(strPtr(file), &statFile)) == -1)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
THROW_SYS_ERROR_FMT(FileOpenError, STORAGE_ERROR_INFO, strPtr(file));
|
||||
if (errno != ENOENT) // {vm_covered}
|
||||
THROW_SYS_ERROR_FMT(FileOpenError, STORAGE_ERROR_INFO, strPtr(file)); // {vm_covered}
|
||||
}
|
||||
// On success the file exists
|
||||
else
|
||||
@@ -180,8 +180,8 @@ storagePosixInfoList(
|
||||
// If the directory could not be opened process errors and report missing directories
|
||||
if (dir == NULL)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
THROW_SYS_ERROR_FMT(PathOpenError, STORAGE_ERROR_LIST_INFO, strPtr(path));
|
||||
if (errno != ENOENT) // {vm_covered}
|
||||
THROW_SYS_ERROR_FMT(PathOpenError, STORAGE_ERROR_LIST_INFO, strPtr(path)); // {vm_covered}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -277,12 +277,15 @@ storagePosixMove(THIS_VOID, StorageRead *source, StorageWrite *destination, Stor
|
||||
result = storageInterfaceMoveP(this, source, destination);
|
||||
}
|
||||
// Else the destination is on a different device so a copy will be needed
|
||||
else if (errno == EXDEV)
|
||||
else if (errno == EXDEV) // {vm_covered}
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
THROW_SYS_ERROR_FMT(FileMoveError, "unable to move '%s' to '%s'", strPtr(sourceFile), strPtr(destinationFile));
|
||||
{
|
||||
THROW_SYS_ERROR_FMT( // {vm_covered}
|
||||
FileMoveError, "unable to move '%s' to '%s'", strPtr(sourceFile), strPtr(destinationFile)); // {vm_covered}
|
||||
}
|
||||
}
|
||||
// Sync paths on success
|
||||
else
|
||||
@@ -411,7 +414,7 @@ storagePosixPathRemoveCallback(void *callbackData, const StorageInfo *info)
|
||||
String *file = strNewFmt("%s/%s", strPtr(data->path), strPtr(info->name));
|
||||
|
||||
// Rather than stat the file to discover what type it is, just try to unlink it and see what happens
|
||||
if (unlink(strPtr(file)) == -1)
|
||||
if (unlink(strPtr(file)) == -1) // {vm_covered}
|
||||
{
|
||||
// These errors indicate that the entry is actually a path so we'll try to delete it that way
|
||||
if (errno == EPERM || errno == EISDIR) // {uncovered_branch - no EPERM on tested systems}
|
||||
@@ -420,7 +423,7 @@ storagePosixPathRemoveCallback(void *callbackData, const StorageInfo *info)
|
||||
}
|
||||
// Else error
|
||||
else
|
||||
THROW_SYS_ERROR_FMT(PathRemoveError, STORAGE_ERROR_PATH_REMOVE_FILE, strPtr(file));
|
||||
THROW_SYS_ERROR_FMT(PathRemoveError, STORAGE_ERROR_PATH_REMOVE_FILE, strPtr(file)); // {vm_covered}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,8 +465,8 @@ storagePosixPathRemove(THIS_VOID, const String *path, bool recurse, StorageInter
|
||||
// Delete the path
|
||||
if (rmdir(strPtr(path)) == -1)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
THROW_SYS_ERROR_FMT(PathRemoveError, STORAGE_ERROR_PATH_REMOVE, strPtr(path));
|
||||
if (errno != ENOENT) // {vm_covered}
|
||||
THROW_SYS_ERROR_FMT(PathRemoveError, STORAGE_ERROR_PATH_REMOVE, strPtr(path)); // {vm_covered}
|
||||
|
||||
// Path does not exist
|
||||
result = false;
|
||||
@@ -495,10 +498,10 @@ storagePosixPathSync(THIS_VOID, const String *path, StorageInterfacePathSyncPara
|
||||
// Handle errors
|
||||
if (handle == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
if (errno == ENOENT) // {vm_covered}
|
||||
THROW_FMT(PathMissingError, STORAGE_ERROR_PATH_SYNC_MISSING, strPtr(path));
|
||||
else
|
||||
THROW_SYS_ERROR_FMT(PathOpenError, STORAGE_ERROR_PATH_SYNC_OPEN, strPtr(path));
|
||||
THROW_SYS_ERROR_FMT(PathOpenError, STORAGE_ERROR_PATH_SYNC_OPEN, strPtr(path)); // {vm_covered}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -537,8 +540,8 @@ storagePosixRemove(THIS_VOID, const String *file, StorageInterfaceRemoveParam pa
|
||||
// Attempt to unlink the file
|
||||
if (unlink(strPtr(file)) == -1)
|
||||
{
|
||||
if (param.errorOnMissing || errno != ENOENT)
|
||||
THROW_SYS_ERROR_FMT(FileRemoveError, "unable to remove '%s'", strPtr(file));
|
||||
if (param.errorOnMissing || errno != ENOENT) // {vm_covered}
|
||||
THROW_SYS_ERROR_FMT(FileRemoveError, "unable to remove '%s'", strPtr(file)); // {vm_covered}
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
|
@@ -78,8 +78,8 @@ storageWritePosixOpen(THIS_VOID)
|
||||
// Open the file
|
||||
this->handle = open(strPtr(this->nameTmp), FILE_OPEN_FLAGS, this->interface.modeFile);
|
||||
|
||||
// Attempt the create the path if it is missing
|
||||
if (this->handle == -1 && errno == ENOENT && this->interface.createPath)
|
||||
// Attempt to create the path if it is missing
|
||||
if (this->handle == -1 && errno == ENOENT && this->interface.createPath) // {vm_covered}
|
||||
{
|
||||
// Create the path
|
||||
storageInterfacePathCreateP(this->storage, this->path, false, false, this->interface.modePath);
|
||||
@@ -91,10 +91,10 @@ storageWritePosixOpen(THIS_VOID)
|
||||
// Handle errors
|
||||
if (this->handle == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
if (errno == ENOENT) // {vm_covered}
|
||||
THROW_FMT(FileMissingError, STORAGE_ERROR_WRITE_MISSING, strPtr(this->interface.name));
|
||||
else
|
||||
THROW_SYS_ERROR_FMT(FileOpenError, STORAGE_ERROR_WRITE_OPEN, strPtr(this->interface.name));
|
||||
THROW_SYS_ERROR_FMT(FileOpenError, STORAGE_ERROR_WRITE_OPEN, strPtr(this->interface.name)); // {vm_covered}
|
||||
}
|
||||
|
||||
// Set free callback to ensure file handle is freed
|
||||
|
@@ -240,7 +240,6 @@ unit:
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: io-tls
|
||||
total: 5
|
||||
containerReq: true
|
||||
|
||||
coverage:
|
||||
common/io/tls/client: full
|
||||
@@ -411,7 +410,6 @@ unit:
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: posix
|
||||
total: 21
|
||||
containerReq: true
|
||||
|
||||
coverage:
|
||||
storage/posix/read: full
|
||||
@@ -652,7 +650,6 @@ unit:
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: restore
|
||||
total: 12
|
||||
containerReq: true
|
||||
binReq: true
|
||||
|
||||
coverage:
|
||||
|
@@ -35,12 +35,14 @@ sub coverageLCovConfigGenerate
|
||||
{
|
||||
my $oStorage = shift;
|
||||
my $strOutFile = shift;
|
||||
my $bContainer = shift;
|
||||
my $bCoverageSummary = shift;
|
||||
|
||||
my $strBranchFilter =
|
||||
'OBJECT_DEFINE_[A-Z0-9_]+\(|\s{4}[A-Z][A-Z0-9_]+\([^\?]*\)|\s{4}(ASSERT|assert|switch\s)\(|\{\+{0,1}' .
|
||||
($bCoverageSummary ? 'uncoverable_branch' : 'uncover(ed|able)_branch');
|
||||
my $strLineFilter = '\{\+{0,1}uncover' . ($bCoverageSummary ? 'able' : '(ed|able)') . '[^_]';
|
||||
my $strLineFilter =
|
||||
'\{\+{0,1}' . ($bCoverageSummary ? 'uncoverable' : '(uncover(ed|able)' . ($bContainer ? '' : '|vm_covered') . ')') . '[^_]';
|
||||
|
||||
my $strConfig =
|
||||
"# LCOV Settings\n" .
|
||||
@@ -80,6 +82,7 @@ sub coverageExtract
|
||||
my $oStorage = shift;
|
||||
my $strModule = shift;
|
||||
my $strTest = shift;
|
||||
my $bContainer = shift;
|
||||
my $bSummary = shift;
|
||||
my $strContainerImage = shift;
|
||||
my $strWorkPath = shift;
|
||||
@@ -87,6 +90,12 @@ sub coverageExtract
|
||||
my $strWorkUnitPath = shift;
|
||||
my $strTestResultCoveragePath = shift . '/coverage';
|
||||
|
||||
# Coverage summary must be run in a container
|
||||
if ($bSummary && !$bContainer)
|
||||
{
|
||||
confess &log(ERROR, "coverage summary must be run on containers for full coverage");
|
||||
}
|
||||
|
||||
# Generate a list of files to cover
|
||||
my $hTestCoverage = (testDefModuleTest($strModule, $strTest))->{&TESTDEF_COVERAGE};
|
||||
|
||||
@@ -101,7 +110,7 @@ sub coverageExtract
|
||||
|
||||
# Generate coverage reports for the modules
|
||||
my $strLCovConf = "${strTestResultCoveragePath}/raw/lcov.conf";
|
||||
coverageLCovConfigGenerate($oStorage, $strLCovConf, $bSummary);
|
||||
coverageLCovConfigGenerate($oStorage, $strLCovConf, $bContainer, $bSummary);
|
||||
|
||||
my $strLCovExe = "lcov --config-file=${strLCovConf}";
|
||||
my $strLCovOut = "${strWorkUnitPath}/test.lcov";
|
||||
|
@@ -501,6 +501,7 @@ sub run
|
||||
(($self->{bOptimize} && ($self->{bProfile} || $bPerformance)) ? '-O2' : $strNoOptimizeFlags) .
|
||||
(!$self->{bDebugTestTrace} && $self->{bDebug} ? ' -DDEBUG_TEST_TRACE' : '') .
|
||||
(vmCoverageC($self->{oTest}->{&TEST_VM}) && $self->{bCoverageUnit} ? ' -fprofile-arcs -ftest-coverage' : '') .
|
||||
($self->{oTest}->{&TEST_VM} eq VM_NONE ? '' : " -DTEST_CONTAINER_REQUIRED") .
|
||||
($self->{oTest}->{&TEST_CTESTDEF} ? " $self->{oTest}->{&TEST_CTESTDEF}" : '');
|
||||
|
||||
buildPutDiffers(
|
||||
@@ -638,7 +639,8 @@ sub end
|
||||
if ($iExitStatus == 0 && $self->{oTest}->{&TEST_C} && vmCoverageC($self->{oTest}->{&TEST_VM}) && $self->{bCoverageUnit})
|
||||
{
|
||||
coverageExtract(
|
||||
$self->{oStorageTest}, $self->{oTest}->{&TEST_MODULE}, $self->{oTest}->{&TEST_NAME}, $self->{bCoverageSummary},
|
||||
$self->{oStorageTest}, $self->{oTest}->{&TEST_MODULE}, $self->{oTest}->{&TEST_NAME},
|
||||
$self->{oTest}->{&TEST_VM} ne VM_NONE, $self->{bCoverageSummary},
|
||||
$self->{oTest}->{&TEST_VM} eq VM_NONE ? undef : $strImage, $self->{strTestPath}, "$self->{strTestPath}/temp",
|
||||
$self->{strGCovPath}, $self->{strBackRestBase} . '/test/result');
|
||||
}
|
||||
|
@@ -919,24 +919,23 @@ testRun(void)
|
||||
TEST_RESULT_LOG("P00 WARN: unknown user in backup manifest mapped to '{[user]}'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
if (testContainer())
|
||||
{
|
||||
TEST_TITLE("owner is root and ownership of pg_data is bad");
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_TITLE("owner is root and ownership of pg_data is bad");
|
||||
|
||||
manifestPathAdd(manifest, &path);
|
||||
manifestFileAdd(manifest, &file);
|
||||
manifestPathAdd(manifest, &path);
|
||||
manifestFileAdd(manifest, &file);
|
||||
|
||||
TEST_SYSTEM_FMT("sudo chown 77777:77777 %s", strPtr(pgPath));
|
||||
TEST_SYSTEM_FMT("sudo chown 77777:77777 %s", strPtr(pgPath));
|
||||
|
||||
userLocalData.userName = STRDEF("root");
|
||||
userLocalData.groupName = STRDEF("root");
|
||||
userLocalData.userName = STRDEF("root");
|
||||
userLocalData.groupName = STRDEF("root");
|
||||
|
||||
TEST_RESULT_VOID(restoreManifestOwner(manifest), "check ownership");
|
||||
TEST_RESULT_VOID(restoreManifestOwner(manifest), "check ownership");
|
||||
|
||||
TEST_RESULT_LOG(
|
||||
"P00 WARN: unknown user in backup manifest mapped to 'root'\n"
|
||||
"P00 WARN: unknown group in backup manifest mapped to 'root'");
|
||||
}
|
||||
TEST_RESULT_LOG(
|
||||
"P00 WARN: unknown user in backup manifest mapped to 'root'\n"
|
||||
"P00 WARN: unknown group in backup manifest mapped to 'root'");
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
|
@@ -12,6 +12,8 @@ Test Tls Client
|
||||
/***********************************************************************************************************************************
|
||||
Test server with subject alternate names
|
||||
***********************************************************************************************************************************/
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
|
||||
static void
|
||||
testTlsServerAltName(void)
|
||||
{
|
||||
@@ -26,20 +28,17 @@ testTlsServerAltName(void)
|
||||
harnessTlsServerAccept();
|
||||
harnessTlsServerClose();
|
||||
|
||||
if (testContainer())
|
||||
{
|
||||
// Success on valid ca file and match common name
|
||||
harnessTlsServerAccept();
|
||||
harnessTlsServerClose();
|
||||
// Success on valid ca file and match common name
|
||||
harnessTlsServerAccept();
|
||||
harnessTlsServerClose();
|
||||
|
||||
// Success on valid ca file and match alt name
|
||||
harnessTlsServerAccept();
|
||||
harnessTlsServerClose();
|
||||
// Success on valid ca file and match alt name
|
||||
harnessTlsServerAccept();
|
||||
harnessTlsServerClose();
|
||||
|
||||
// Unable to find matching hostname in certificate
|
||||
harnessTlsServerAccept();
|
||||
harnessTlsServerClose();
|
||||
}
|
||||
// Unable to find matching hostname in certificate
|
||||
harnessTlsServerAccept();
|
||||
harnessTlsServerClose();
|
||||
|
||||
// Certificate error
|
||||
harnessTlsServerAccept();
|
||||
@@ -52,6 +51,8 @@ testTlsServerAltName(void)
|
||||
FUNCTION_HARNESS_RESULT_VOID();
|
||||
}
|
||||
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test server
|
||||
***********************************************************************************************************************************/
|
||||
@@ -226,10 +227,12 @@ testRun(void)
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("unable to connect to blocking socket");
|
||||
|
||||
SocketClient *socketClient = sckClientNew(STR(hostLocal), 7777, 0);
|
||||
TEST_RESULT_UINT(sckClientPort(socketClient), 7777, " check port");
|
||||
|
||||
socketLocal.block = true;
|
||||
TEST_ERROR(
|
||||
sckClientOpen(sckClientNew(STR(hostLocal), 7777, 0)), HostConnectError,
|
||||
"unable to connect to '127.0.0.1:7777': [111] Connection refused");
|
||||
sckClientOpen(socketClient), HostConnectError, "unable to connect to '127.0.0.1:7777': [111] Connection refused");
|
||||
socketLocal.block = false;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
@@ -304,14 +307,12 @@ testRun(void)
|
||||
// Certificate location and validation errors
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
// Add test hosts
|
||||
if (testContainer())
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
if (system( // {uncoverable_branch}
|
||||
"echo \"127.0.0.1 test.pgbackrest.org host.test2.pgbackrest.org test3.pgbackrest.org\" |"
|
||||
" sudo tee -a /etc/hosts > /dev/null") != 0)
|
||||
{
|
||||
if (system( // {uncoverable_branch}
|
||||
"echo \"127.0.0.1 test.pgbackrest.org host.test2.pgbackrest.org test3.pgbackrest.org\" |"
|
||||
" sudo tee -a /etc/hosts > /dev/null") != 0)
|
||||
{
|
||||
THROW(AssertError, "unable to add test hosts to /etc/hosts"); // {uncovered+}
|
||||
}
|
||||
THROW(AssertError, "unable to add test hosts to /etc/hosts"); // {uncovered+}
|
||||
}
|
||||
|
||||
HARNESS_FORK_BEGIN()
|
||||
@@ -331,6 +332,7 @@ testRun(void)
|
||||
sckClientNew(strNew("localhost"), harnessTlsTestPort(), 5000), 0, true, strNew("bogus.crt"),
|
||||
strNew("/bogus"))),
|
||||
CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory");
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
tlsClientOpen(
|
||||
tlsClientNew(
|
||||
@@ -339,28 +341,25 @@ testRun(void)
|
||||
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
|
||||
harnessTlsTestPort());
|
||||
|
||||
if (testContainer())
|
||||
{
|
||||
TEST_RESULT_VOID(
|
||||
tlsClientOpen(
|
||||
tlsClientNew(
|
||||
sckClientNew(strNew("test.pgbackrest.org"), harnessTlsTestPort(), 5000), 0, true,
|
||||
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
|
||||
"success on valid ca file and match common name");
|
||||
TEST_RESULT_VOID(
|
||||
tlsClientOpen(
|
||||
tlsClientNew(
|
||||
sckClientNew(strNew("host.test2.pgbackrest.org"), harnessTlsTestPort(), 5000), 0, true,
|
||||
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
|
||||
"success on valid ca file and match alt name");
|
||||
TEST_ERROR(
|
||||
tlsClientOpen(
|
||||
tlsClientNew(
|
||||
sckClientNew(strNew("test3.pgbackrest.org"), harnessTlsTestPort(), 5000), 0, true,
|
||||
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
|
||||
CryptoError,
|
||||
"unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names");
|
||||
}
|
||||
TEST_RESULT_VOID(
|
||||
tlsClientOpen(
|
||||
tlsClientNew(
|
||||
sckClientNew(strNew("test.pgbackrest.org"), harnessTlsTestPort(), 5000), 0, true,
|
||||
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
|
||||
"success on valid ca file and match common name");
|
||||
TEST_RESULT_VOID(
|
||||
tlsClientOpen(
|
||||
tlsClientNew(
|
||||
sckClientNew(strNew("host.test2.pgbackrest.org"), harnessTlsTestPort(), 5000), 0, true,
|
||||
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
|
||||
"success on valid ca file and match alt name");
|
||||
TEST_ERROR(
|
||||
tlsClientOpen(
|
||||
tlsClientNew(
|
||||
sckClientNew(strNew("test3.pgbackrest.org"), harnessTlsTestPort(), 5000), 0, true,
|
||||
strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)),
|
||||
CryptoError,
|
||||
"unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names");
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
tlsClientOpen(
|
||||
@@ -380,6 +379,7 @@ testRun(void)
|
||||
HARNESS_FORK_PARENT_END();
|
||||
}
|
||||
HARNESS_FORK_END();
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
|
@@ -53,8 +53,10 @@ testRun(void)
|
||||
ioBufferSizeSet(2);
|
||||
|
||||
// Directory and file that cannot be accessed to test permissions errors
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
String *fileNoPerm = strNewFmt("%s/noperm/noperm", testPath());
|
||||
String *pathNoPerm = strPath(fileNoPerm);
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// Write file for testing if storage is read-only
|
||||
String *writeFile = strNewFmt("%s/writefile", testPath());
|
||||
@@ -115,7 +117,9 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageExists() and storagePathExists()"))
|
||||
{
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_BOOL(storageExistsP(storageTest, strNew("missing")), false, "file does not exist");
|
||||
@@ -126,12 +130,14 @@ testRun(void)
|
||||
TEST_RESULT_BOOL(storagePathExistsP(storageTest, NULL), true, "test path exists");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_ERROR_FMT(
|
||||
storageExistsP(storageTest, fileNoPerm), FileOpenError,
|
||||
"unable to get info for path/file '%s': [13] Permission denied", strPtr(fileNoPerm));
|
||||
TEST_ERROR_FMT(
|
||||
storagePathExistsP(storageTest, fileNoPerm), FileOpenError,
|
||||
"unable to get info for path/file '%s': [13] Permission denied", strPtr(fileNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
String *fileExists = strNewFmt("%s/exists", testPath());
|
||||
@@ -142,7 +148,7 @@ testRun(void)
|
||||
TEST_RESULT_BOOL(storageExistsP(storageTest, fileExists), true, "file exists");
|
||||
TEST_RESULT_BOOL(storageExistsP(storageTest, pathExists), false, "not a file");
|
||||
TEST_RESULT_BOOL(storagePathExistsP(storageTest, fileExists), false, "not a path");
|
||||
TEST_RESULT_INT(system(strPtr(strNewFmt("sudo rm %s", strPtr(fileExists)))), 0, "remove exists file");
|
||||
TEST_RESULT_INT(system(strPtr(strNewFmt("rm %s", strPtr(fileExists)))), 0, "remove exists file");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
HARNESS_FORK_BEGIN()
|
||||
@@ -162,17 +168,19 @@ testRun(void)
|
||||
}
|
||||
HARNESS_FORK_END();
|
||||
|
||||
TEST_RESULT_INT(system(strPtr(strNewFmt("sudo rm %s", strPtr(fileExists)))), 0, "remove exists file");
|
||||
TEST_RESULT_INT(system(strPtr(strNewFmt("rm %s", strPtr(fileExists)))), 0, "remove exists file");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageInfo()"))
|
||||
{
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
storageInfoP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO ": [13] Permission denied",
|
||||
strPtr(fileNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
String *fileName = strNewFmt("%s/fileinfo", testPath());
|
||||
@@ -220,7 +228,9 @@ testRun(void)
|
||||
utimeTest.modtime = 1555155555;
|
||||
THROW_ON_SYS_ERROR_FMT(utime(strPtr(fileName), &utimeTest) != 0, FileWriteError, "unable to set time for '%s'", testPath());
|
||||
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_RESULT_INT(system(strPtr(strNewFmt("sudo chown 99999:99999 %s", strPtr(fileName)))), 0, "set invalid user/group");
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
TEST_ASSIGN(info, storageInfoP(storageTest, fileName), "get file info");
|
||||
TEST_RESULT_PTR(info.name, NULL, " name is not set");
|
||||
@@ -230,8 +240,10 @@ testRun(void)
|
||||
TEST_RESULT_INT(info.mode, 0640, " check mode");
|
||||
TEST_RESULT_INT(info.timeModified, 1555155555, " check mod time");
|
||||
TEST_RESULT_PTR(info.linkDestination, NULL, " no link destination");
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_RESULT_STR(info.user, NULL, " check user");
|
||||
TEST_RESULT_STR(info.group, NULL, " check group");
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
storageRemoveP(storageTest, fileName, .errorOnMissing = true);
|
||||
|
||||
@@ -281,7 +293,9 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageInfoList()"))
|
||||
{
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR_FMT(
|
||||
@@ -291,6 +305,7 @@ testRun(void)
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoListP(storageTest, strNew(BOGUS_STR), (StorageInfoListCallback)1, NULL), false, "ignore missing dir");
|
||||
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_ERROR_FMT(
|
||||
storageInfoListP(storageTest, pathNoPerm, (StorageInfoListCallback)1, NULL), PathOpenError,
|
||||
STORAGE_ERROR_LIST_INFO ": [13] Permission denied", strPtr(pathNoPerm));
|
||||
@@ -299,6 +314,7 @@ testRun(void)
|
||||
TEST_ERROR_FMT(
|
||||
storageInfoListP(storageTest, pathNoPerm, (StorageInfoListCallback)1, NULL), PathOpenError,
|
||||
STORAGE_ERROR_LIST_INFO ": [13] Permission denied", strPtr(pathNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
HarnessStorageInfoListCallbackData callbackData =
|
||||
@@ -326,8 +342,10 @@ testRun(void)
|
||||
" check content");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
storagePathCreateP(storageTest, strNew("pg/.include"), .mode = 0755);
|
||||
ASSERT(system(strPtr(strNewFmt("sudo chown 77777:77777 %s/pg/.include", testPath()))) == 0);
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
storagePutP(storageNewWriteP(storageTest, strNew("pg/file"), .modeFile = 0660), BUFSTRDEF("TESTDATA"));
|
||||
|
||||
@@ -351,14 +369,19 @@ testRun(void)
|
||||
TEST_RESULT_STR_Z(
|
||||
callbackData.content,
|
||||
". {path}\n"
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
".include {path, m=0755, u=77777, g=77777}\n"
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
"file {file, s=8, m=0660}\n"
|
||||
"link {link, d=../file}\n"
|
||||
"pipe {special}\n",
|
||||
" check content");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
ASSERT(system(strPtr(strNewFmt("sudo rmdir %s/pg/.include", testPath()))) == 0);
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
storagePathCreateP(storageTest, strNew("pg/path"), .mode = 0700);
|
||||
storagePutP(storageNewWriteP(storageTest, strNew("pg/path/file"), .modeFile = 0600), BUFSTRDEF("TESTDATA"));
|
||||
|
||||
@@ -395,7 +418,9 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageList()"))
|
||||
{
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR_FMT(
|
||||
@@ -406,6 +431,7 @@ testRun(void)
|
||||
TEST_RESULT_UINT(strLstSize(storageListP(storageTest, strNew(BOGUS_STR))), 0, "empty list for missing dir");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_ERROR_FMT(
|
||||
storageListP(storageTest, pathNoPerm), PathOpenError,
|
||||
STORAGE_ERROR_LIST_INFO ": [13] Permission denied", strPtr(pathNoPerm));
|
||||
@@ -414,12 +440,18 @@ testRun(void)
|
||||
TEST_ERROR_FMT(
|
||||
storageListP(storageTest, pathNoPerm), PathOpenError,
|
||||
STORAGE_ERROR_LIST_INFO ": [13] Permission denied", strPtr(pathNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_VOID(
|
||||
storagePutP(storageNewWriteP(storageTest, strNew(".aaa.txt")), BUFSTRDEF("aaa")), "write aaa.text");
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(strLstSort(storageListP(storageTest, NULL), sortOrderAsc), ", "), ".aaa.txt, noperm", "dir list");
|
||||
strLstJoin(strLstSort(storageListP(storageTest, NULL), sortOrderAsc), ", "),
|
||||
".aaa.txt"
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
", noperm"
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
, "dir list");
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
storagePutP(storageNewWriteP(storageTest, strNew("bbb.txt")), BUFSTRDEF("bbb")), "write bbb.text");
|
||||
@@ -458,7 +490,9 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageMove()"))
|
||||
{
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
String *sourceFile = strNewFmt("%s/source.txt", testPath());
|
||||
String *destinationFile = strNewFmt("%s/sub/destination.txt", testPath());
|
||||
@@ -471,11 +505,13 @@ testRun(void)
|
||||
"unable to move missing source '%s': [2] No such file or directory", strPtr(sourceFile));
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
source = storageNewReadP(storageTest, fileNoPerm);
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
storageMoveP(storageTest, source, destination), FileMoveError,
|
||||
"unable to move '%s' to '%s': [13] Permission denied", strPtr(fileNoPerm), strPtr(destinationFile));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
const Buffer *buffer = BUFSTRDEF("TESTFILE");
|
||||
@@ -620,6 +656,8 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
String *pathRemove2 = strNewFmt("%s/remove2", strPtr(pathRemove1));
|
||||
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
|
||||
TEST_RESULT_INT(system(strPtr(strNewFmt("sudo mkdir -p -m 700 %s", strPtr(pathRemove2)))), 0, "create noperm paths");
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
@@ -656,6 +694,7 @@ testRun(void)
|
||||
storagePathRemoveP(storageTest, pathRemove1, .recurse = true), "remove path");
|
||||
TEST_RESULT_BOOL(
|
||||
storageExistsP(storageTest, pathRemove1), false, "path is removed");
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_INT(system(strPtr(strNewFmt("mkdir -p %s", strPtr(pathRemove2)))), 0, "create subpaths");
|
||||
@@ -669,11 +708,13 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storagePathSync()"))
|
||||
{
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
storagePathSyncP(storageTest, fileNoPerm), PathOpenError, STORAGE_ERROR_PATH_SYNC_OPEN ": [13] Permission denied",
|
||||
strPtr(fileNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
String *pathName = strNewFmt("%s/testpath", testPath());
|
||||
@@ -713,14 +754,16 @@ testRun(void)
|
||||
if (testBegin("storageNewWrite()"))
|
||||
{
|
||||
String *fileName = strNewFmt("%s/sub1/testfile", testPath());
|
||||
|
||||
TEST_CREATE_NOPERM();
|
||||
StorageWrite *file = NULL;
|
||||
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
|
||||
TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true), "new write file (defaults)");
|
||||
TEST_ERROR_FMT(
|
||||
ioWriteOpen(storageWriteIo(file)), FileOpenError, STORAGE_ERROR_WRITE_OPEN ": [13] Permission denied",
|
||||
strPtr(fileNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ASSIGN(
|
||||
@@ -829,7 +872,9 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageRemove()"))
|
||||
{
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_VOID(storageRemoveP(storageTest, strNew("missing")), "remove missing file");
|
||||
@@ -844,26 +889,32 @@ testRun(void)
|
||||
TEST_RESULT_VOID(storageRemoveP(storageTest, fileExists), "remove exists file");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_ERROR_FMT(
|
||||
storageRemoveP(storageTest, fileNoPerm), FileRemoveError,
|
||||
"unable to remove '%s': [13] Permission denied", strPtr(fileNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("StorageRead"))
|
||||
{
|
||||
TEST_CREATE_NOPERM();
|
||||
StorageRead *file = NULL;
|
||||
|
||||
TEST_ASSIGN(file, storageNewReadP(storageTest, fileNoPerm, .ignoreMissing = true, .limit = VARUINT64(44)), "new read file");
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
|
||||
TEST_ASSIGN(file, storageNewReadP(storageTest, fileNoPerm, .ignoreMissing = true), "new read file");
|
||||
TEST_RESULT_BOOL(storageReadIgnoreMissing(file), true, " check ignore missing");
|
||||
TEST_RESULT_STR(storageReadName(file), fileNoPerm, " check name");
|
||||
TEST_RESULT_UINT(varUInt64(storageReadLimit(file)), 44, " check limit");
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_ASSIGN(file, storageNewReadP(storageTest, fileNoPerm), "new no perm read file");
|
||||
TEST_ERROR_FMT(
|
||||
ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN ": [13] Permission denied", strPtr(fileNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
String *fileName = strNewFmt("%s/test.file", testPath());
|
||||
@@ -898,13 +949,16 @@ testRun(void)
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
TEST_ASSIGN(file, storageReadMove(storageNewReadP(storageTest, fileName), memContextPrior()), "new read file");
|
||||
TEST_ASSIGN(
|
||||
file, storageReadMove(storageNewReadP(storageTest, fileName, .limit = VARUINT64(44)), memContextPrior()),
|
||||
"new read file");
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, " open file");
|
||||
TEST_RESULT_STR(storageReadName(file), fileName, " check file name");
|
||||
TEST_RESULT_STR_Z(storageReadType(file), "posix", " check file type");
|
||||
TEST_RESULT_UINT(varUInt64(storageReadLimit(file)), 44, " check limit");
|
||||
|
||||
TEST_RESULT_VOID(ioRead(storageReadIo(file), outBuffer), " load data");
|
||||
bufCat(buffer, outBuffer);
|
||||
@@ -945,9 +999,11 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("StorageWrite"))
|
||||
{
|
||||
TEST_CREATE_NOPERM();
|
||||
StorageWrite *file = NULL;
|
||||
|
||||
#ifdef TEST_CONTAINER_REQUIRED
|
||||
TEST_CREATE_NOPERM();
|
||||
|
||||
TEST_ASSIGN(
|
||||
file,
|
||||
storageNewWriteP(
|
||||
@@ -968,6 +1024,7 @@ testRun(void)
|
||||
TEST_ERROR_FMT(
|
||||
ioWriteOpen(storageWriteIo(file)), FileOpenError, STORAGE_ERROR_WRITE_OPEN ": [13] Permission denied",
|
||||
strPtr(fileNoPerm));
|
||||
#endif // TEST_CONTAINER_REQUIRED
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
String *fileName = strNewFmt("%s/sub1/test.file", testPath());
|
||||
|
Reference in New Issue
Block a user