diff --git a/test/define.yaml b/test/define.yaml index 40f3834a3..502d7394a 100644 --- a/test/define.yaml +++ b/test/define.yaml @@ -632,7 +632,7 @@ unit: # ---------------------------------------------------------------------------------------------------------------------------- - name: sftp - total: 20 + total: 14 harness: name: libSsh2 integration: false diff --git a/test/src/common/harnessLibSsh2.c b/test/src/common/harnessLibSsh2.c index 19d5c1559..2e149f2a8 100644 --- a/test/src/common/harnessLibSsh2.c +++ b/test/src/common/harnessLibSsh2.c @@ -11,6 +11,7 @@ libssh2 Test Harness #include "common/type/json.h" #include "common/type/string.h" #include "common/type/variantList.h" +#include "common/user.h" #include "common/harnessLibSsh2.h" #include "common/harnessTest.h" @@ -20,12 +21,19 @@ libssh2 shim error prefix ***********************************************************************************************************************************/ #define LIBSSH2_ERROR_PREFIX "LIBSSH2 SHIM ERROR" +/*********************************************************************************************************************************** +Standard stat attribute flags reported when a scripted response omits .flags +***********************************************************************************************************************************/ +#define HRN_LIBSSH2_ATTR_DEFAULT \ + (LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID) + /*********************************************************************************************************************************** Script that defines how shim functions operate ***********************************************************************************************************************************/ static HrnLibSsh2 hrnLibSsh2Script[1024]; static bool hrnLibSsh2ScriptDone = true; static unsigned int hrnLibSsh2ScriptIdx; +static unsigned int hrnLibSsh2ScriptSize; // If there is a script failure change the behavior of cleanup functions to return immediately so the real error will be reported // rather than a bogus scripting error during cleanup @@ -36,24 +44,19 @@ static char hrnLibSsh2ScriptError[4096]; Set libssh2 script ***********************************************************************************************************************************/ void -hrnLibSsh2ScriptSet(HrnLibSsh2 *hrnLibSsh2ScriptParam) +hrnLibSsh2ScriptSet(const HrnLibSsh2 *const script, const unsigned int scriptSize) { if (!hrnLibSsh2ScriptDone) THROW(AssertError, "previous libssh2 script has not yet completed"); - if (hrnLibSsh2ScriptParam[0].function == NULL) + if (scriptSize == 0) THROW(AssertError, "libssh2 script must have entries"); // Copy records into local storage - unsigned int copyIdx = 0; + for (unsigned int copyIdx = 0; copyIdx < scriptSize; copyIdx++) + hrnLibSsh2Script[copyIdx] = script[copyIdx]; - while (hrnLibSsh2ScriptParam[copyIdx].function != NULL) - { - hrnLibSsh2Script[copyIdx] = hrnLibSsh2ScriptParam[copyIdx]; - copyIdx++; - } - - hrnLibSsh2Script[copyIdx].function = NULL; + hrnLibSsh2ScriptSize = scriptSize; hrnLibSsh2ScriptDone = false; hrnLibSsh2ScriptIdx = 0; } @@ -146,7 +149,7 @@ hrnLibSsh2ScriptRun(const char *const function, const VariantList *const param, hrnLibSsh2ScriptIdx++; - if (hrnLibSsh2Script[hrnLibSsh2ScriptIdx].function == NULL) + if (hrnLibSsh2ScriptIdx >= hrnLibSsh2ScriptSize) hrnLibSsh2ScriptDone = true; strFree(paramStr); @@ -333,10 +336,11 @@ libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type) { HrnLibSsh2 *hrnLibSsh2 = hrnLibSsh2ScriptRun(HRNLIBSSH2_SESSION_HOSTKEY, NULL, (HrnLibSsh2 *)session); - *len = (size_t)hrnLibSsh2->len; - *type = (int)hrnLibSsh2->type; + // Default the host key length (20), type (RSA), and value (HOSTKEY) when omitted + *len = hrnLibSsh2->len == 0 ? 20 : (size_t)hrnLibSsh2->len; + *type = hrnLibSsh2->type == 0 ? LIBSSH2_HOSTKEY_TYPE_RSA : (int)hrnLibSsh2->type; - return hrnLibSsh2->resultNull ? NULL : (const char *)hrnLibSsh2->resultZ; + return hrnLibSsh2->resultNull ? NULL : (const char *)(hrnLibSsh2->resultZ != NULL ? hrnLibSsh2->resultZ : HOSTKEY); } /*********************************************************************************************************************************** @@ -557,27 +561,45 @@ libssh2_sftp_stat_ex( MEM_CONTEXT_TEMP_BEGIN() { hrnLibSsh2 = hrnLibSsh2ScriptRun( - HRNLIBSSH2_SFTP_STAT_EX, - varLstAdd( - varLstAdd( - varLstNew(), varNewStrZ(path)), - varNewInt(stat_type)), - (HrnLibSsh2 *)sftp); + HRNLIBSSH2_SFTP_STAT_EX, varLstAdd(varLstNew(), varNewStrZ(path)), (HrnLibSsh2 *)sftp); } MEM_CONTEXT_TEMP_END(); + // When the scripted response follows symlinks, verify the production code requested LIBSSH2_SFTP_STAT (otherwise stat_type is + // not checked, since it only affects the result for symlinks) + if (hrnLibSsh2->follow && stat_type != LIBSSH2_SFTP_STAT) + THROW_FMT(AssertError, "libssh2_sftp_stat_ex expected stat_type LIBSSH2_SFTP_STAT but got %d", stat_type); + if (attrs == NULL) THROW(AssertError, "attrs is NULL"); - attrs->flags = 0; - attrs->flags |= (unsigned long)hrnLibSsh2->flags; + // An omitted (0) attr defaults to a regular file with mode 0640 + attrs->permissions = + hrnLibSsh2->attr == 0 ? (unsigned long)(LIBSSH2_SFTP_S_IFREG | 0640) : (unsigned long)hrnLibSsh2->attr; - attrs->permissions = 0; - attrs->permissions |= (unsigned long)hrnLibSsh2->attrPerms; + // Default the response flags: omitted (0) reports the standard attribute set, plus LIBSSH2_SFTP_ATTR_SIZE for a regular file + // (which reports a size); HRN_LIBSSH2_ATTR_EXISTENCE reports none (the path exists but provides no attributes) + uint64_t flags = hrnLibSsh2->flags; + + if (flags == 0) + { + flags = HRN_LIBSSH2_ATTR_DEFAULT; + + if (LIBSSH2_SFTP_S_ISREG(attrs->permissions)) + flags |= LIBSSH2_SFTP_ATTR_SIZE; + } + else if (flags == HRN_LIBSSH2_ATTR_EXISTENCE) + flags = 0; + + attrs->flags = (unsigned long)flags; attrs->mtime = (unsigned long)hrnLibSsh2->mtime; - attrs->uid = (unsigned long)hrnLibSsh2->uid; - attrs->gid = (unsigned long)hrnLibSsh2->gid; + + // An omitted (0) uid/gid defaults to the test user/group; HRN_LIBSSH2_OWNER_ROOT selects root (0) + attrs->uid = + hrnLibSsh2->uid == HRN_LIBSSH2_OWNER_ROOT ? 0 : hrnLibSsh2->uid == 0 ? (unsigned long)userId() : (unsigned long)hrnLibSsh2->uid; + attrs->gid = + hrnLibSsh2->gid == HRN_LIBSSH2_OWNER_ROOT ? 0 : hrnLibSsh2->gid == 0 ? (unsigned long)groupId() : (unsigned long)hrnLibSsh2->gid; attrs->filesize = hrnLibSsh2->filesize; return hrnLibSsh2->resultInt; @@ -626,15 +648,15 @@ libssh2_sftp_symlink_ex( { case LIBSSH2_SFTP_READLINK: case LIBSSH2_SFTP_REALPATH: - if (hrnLibSsh2->symlinkExTarget != NULL) + if (hrnLibSsh2->target != NULL) { - if (strSize(hrnLibSsh2->symlinkExTarget) < PATH_MAX) - strncpy(target, strZ(hrnLibSsh2->symlinkExTarget), strSize(hrnLibSsh2->symlinkExTarget)); + if (strSize(hrnLibSsh2->target) < PATH_MAX) + strncpy(target, strZ(hrnLibSsh2->target), strSize(hrnLibSsh2->target)); else - THROW_FMT(AssertError, "symlinkExTarget too large for target buffer"); + THROW_FMT(AssertError, "link target too large for buffer"); } - rc = hrnLibSsh2->resultInt != 0 ? hrnLibSsh2->resultInt : (int)strSize(hrnLibSsh2->symlinkExTarget); + rc = hrnLibSsh2->resultInt != 0 ? hrnLibSsh2->resultInt : (int)strSize(hrnLibSsh2->target); break; default: @@ -665,15 +687,21 @@ libssh2_sftp_open_ex( varLstAdd( varLstAdd( varLstAdd( - varLstAdd( - varLstNew(), varNewStrZ(filename)), - varNewUInt64(flags)), - varNewInt64(mode)), + varLstNew(), varNewStrZ(filename)), + varNewUInt64(flags)), varNewInt(open_type)), (HrnLibSsh2 *)sftp); } MEM_CONTEXT_TEMP_END(); + // Verify the open mode. It is not part of the scripted param so it can be defaulted: a write open with an omitted (0) mode + // expects 0640, while other opens expect mode 0. + long modeExpected = + hrnLibSsh2->mode != 0 ? (long)hrnLibSsh2->mode : ((flags & LIBSSH2_FXF_WRITE) != 0 ? 0640 : 0); + + if (mode != modeExpected) + THROW_FMT(AssertError, "libssh2_sftp_open_ex expected mode %ld but got %ld", modeExpected, mode); + return hrnLibSsh2->resultNull ? NULL : (LIBSSH2_SFTP_HANDLE *)hrnLibSsh2; } @@ -697,9 +725,7 @@ libssh2_sftp_readdir_ex( varLstAdd( varLstAdd( varLstAdd( - varLstAdd( - varLstNew(), varNewStrZ(buffer)), - varNewUInt64(buffer_maxlen)), + varLstNew(), varNewUInt64(buffer_maxlen)), varNewStrZ(longentry)), varNewUInt64(longentry_maxlen)), (HrnLibSsh2 *)handle); @@ -709,7 +735,10 @@ libssh2_sftp_readdir_ex( if (hrnLibSsh2->fileName != NULL) strncpy(buffer, strZ(hrnLibSsh2->fileName), buffer_maxlen); - return hrnLibSsh2->resultInt; + // libssh2_sftp_readdir_ex() returns the number of bytes in the entry name (0 at end of directory). Derive it from the scripted + // file name so tests need not specify it; a negative resultInt (e.g. EAGAIN) is returned as-is. + return hrnLibSsh2->resultInt < 0 ? + hrnLibSsh2->resultInt : hrnLibSsh2->fileName != NULL ? (int)strSize(hrnLibSsh2->fileName) : 0; } /*********************************************************************************************************************************** @@ -745,15 +774,16 @@ libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_le MEM_CONTEXT_TEMP_BEGIN() { hrnLibSsh2 = hrnLibSsh2ScriptRun( - HRNLIBSSH2_SFTP_MKDIR_EX, - varLstAdd( - varLstAdd( - varLstNew(), varNewStrZ(path)), - varNewInt64(mode)), - (HrnLibSsh2 *)sftp); + HRNLIBSSH2_SFTP_MKDIR_EX, varLstAdd(varLstNew(), varNewStrZ(path)), (HrnLibSsh2 *)sftp); } MEM_CONTEXT_TEMP_END(); + // Verify the mode. It is not part of the scripted param so it can be defaulted: an omitted (0) mode expects 0750. + long modeExpected = hrnLibSsh2->mode != 0 ? (long)hrnLibSsh2->mode : 0750; + + if (mode != modeExpected) + THROW_FMT(AssertError, "libssh2_sftp_mkdir_ex expected mode %ld but got %ld", modeExpected, mode); + return hrnLibSsh2->resultInt; } @@ -781,8 +811,9 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxle if (hrnLibSsh2->readBuffer != NULL) strncpy(buffer, strZ(hrnLibSsh2->readBuffer), strSize(hrnLibSsh2->readBuffer)); - // number of bytes populated - return hrnLibSsh2->resultInt; + // Return the number of bytes read, defaulting an omitted (0) result to the read buffer size (0 when there is no read buffer) + return hrnLibSsh2->resultInt != 0 ? + hrnLibSsh2->resultInt : (hrnLibSsh2->readBuffer != NULL ? (ssize_t)strSize(hrnLibSsh2->readBuffer) : 0); } /*********************************************************************************************************************************** @@ -908,8 +939,8 @@ libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count } MEM_CONTEXT_TEMP_END(); - // Return number of bytes written - return hrnLibSsh2->resultInt; + // Return the number of bytes written, defaulting an omitted (0) result to the full count + return hrnLibSsh2->resultInt != 0 ? hrnLibSsh2->resultInt : (ssize_t)count; } #endif // HAVE_LIBSSH2 diff --git a/test/src/common/harnessLibSsh2.h b/test/src/common/harnessLibSsh2.h index 973354313..28b4a3c45 100644 --- a/test/src/common/harnessLibSsh2.h +++ b/test/src/common/harnessLibSsh2.h @@ -12,7 +12,9 @@ Scripted testing for libssh2 so exact results can be returned for unit testing. #include #include +#include #include +#include #include "common/macro.h" #include "common/time.h" @@ -31,6 +33,10 @@ libssh2 authorization constants #define ETC_KNOWNHOSTS2_FILE_CSTR "/etc/ssh/ssh_known_hosts2" #define HOSTKEY "12345678901234567890" +// Sentinel .uid/.gid for scripted stat responses selecting root (0). An omitted (0) .uid/.gid instead defaults to the test +// user/group, so use HRN_LIBSSH2_OWNER_ROOT when a response must report ownership by root. +#define HRN_LIBSSH2_OWNER_ROOT UINT_MAX + /*********************************************************************************************************************************** Function constants ***********************************************************************************************************************************/ @@ -68,40 +74,6 @@ Function constants #define HRNLIBSSH2_SFTP_WRITE "libssh2_sftp_write" #define HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX "libssh2_userauth_publickey_fromfile_ex" -/*********************************************************************************************************************************** -Macros for defining groups of functions that implement commands -***********************************************************************************************************************************/ -// Set of functions mimicking libssh2 initialization and authorization -#define HRNLIBSSH2_MACRO_STARTUP() \ - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = 0}, \ - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, \ - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = 0}, \ - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, \ - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, \ - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, \ - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", \ - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, \ - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, \ - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", \ - .resultInt = 0}, \ - {.function = HRNLIBSSH2_SFTP_INIT} - -// Set of functions mimicking libssh2 shutdown and disconnect -#define HRNLIBSSH2_MACRO_SHUTDOWN() \ - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = 0}, \ - {.function = HRNLIBSSH2_SESSION_DISCONNECT_EX, .param ="[11,\"pgBackRest instance shutdown\",\"\"]", .resultInt = 0}, \ - {.function = HRNLIBSSH2_SESSION_FREE, .resultInt = 0}, \ - {.function = NULL} \ - -// Older systems do not support LIBSSH2_HOSTKEY_HASH_SHA256 -#ifdef LIBSSH2_HOSTKEY_HASH_SHA256 -#define HOSTKEY_HASH_ENTRY() \ - {.function = HRNLIBSSH2_HOSTKEY_HASH, .param = "[3]", .resultZ = "12345678910123456789"} -#else -#define HOSTKEY_HASH_ENTRY() \ - {.function = HRNLIBSSH2_HOSTKEY_HASH, .param = "[2]", .resultZ = "12345678910123456789"} -#endif - /*********************************************************************************************************************************** Structure for scripting libssh2 responses ***********************************************************************************************************************************/ @@ -115,12 +87,14 @@ typedef struct HrnLibSsh2 const char *resultZ; // Zero-terminated result value bool resultNull; // Return null from function that normally returns a struct ptr uint64_t flags; // libssh2 flags - uint64_t attrPerms; // libssh2 attr perms + uint64_t attr; // libssh2 attributes (file type and mode bits) + uint64_t mode; // libssh2_sftp_open_ex file mode (write open defaults to 0640) + bool follow; // stat_ex follows symlinks (LIBSSH2_SFTP_STAT vs LSTAT) uint64_t atime, mtime; // libssh2 timestamps uint64_t uid, gid; // libssh2 uid/gid uint64_t filesize; // libssh2 filesize uint64_t offset; // libssh2 seek offset - const String *symlinkExTarget; // libssh2_sftp_symlink_ex target + const String *target; // libssh2_sftp_symlink_ex target const String *fileName; // libssh2_readdir* libssh2_stat* filename const String *readBuffer; // what to copy into read buffer TimeMSec sleep; // Sleep specified milliseconds before returning from function @@ -129,10 +103,221 @@ typedef struct HrnLibSsh2 const char *errMsg; // libssh2_session_last_error error msg } HrnLibSsh2; +/*********************************************************************************************************************************** +Older systems do not support LIBSSH2_HOSTKEY_HASH_SHA256 +***********************************************************************************************************************************/ +#ifdef LIBSSH2_HOSTKEY_HASH_SHA256 +#define HOSTKEY_HASH_ENTRY() HRN_LIBSSH2_HOSTKEY_HASH(3, .resultZ = "12345678910123456789") +#else +#define HOSTKEY_HASH_ENTRY() HRN_LIBSSH2_HOSTKEY_HASH(2, .resultZ = "12345678910123456789") +#endif + +/*********************************************************************************************************************************** +Scripted response macros, one per libssh2 shim function + +Each expands to an HrnLibSsh2 script entry that names the function, bakes its fixed parameters, and defaults the common result, so a +test supplies only the values that vary as trailing designated initializers (e.g. .resultInt, .resultNull). The associated helper +macros build the values those entries take (.attr, .flags, ...). +***********************************************************************************************************************************/ +// Sentinel .flags reporting a path that exists but carries no attributes (the harness maps it to libssh2 flags 0). Uses a value +// that cannot collide with a real LIBSSH2_SFTP_ATTR_* combination. +#define HRN_LIBSSH2_ATTR_EXISTENCE UINT64_MAX + +// .attr shorthand: file type OR'd with an octal mode (the LIBSSH2_SFTP_S_I* permission bits are the octal mode bits) +#define HRN_LIBSSH2_DIR(mode) (LIBSSH2_SFTP_S_IFDIR | (mode)) +#define HRN_LIBSSH2_FILE(mode) (LIBSSH2_SFTP_S_IFREG | (mode)) +#define HRN_LIBSSH2_LINK(mode) (LIBSSH2_SFTP_S_IFLNK | (mode)) +#define HRN_LIBSSH2_FIFO(mode) (LIBSSH2_SFTP_S_IFIFO | (mode)) + +// libssh2_sftp_readdir_ex() response returning a directory entry (an empty name signals end of directory) +#define HRN_LIBSSH2_READDIR(name, ...) \ + {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[4095,null,0]", .fileName = STRDEF(name), __VA_ARGS__} + +// libssh2_sftp_stat_ex() response. The path is the full server path (e.g. TEST_PATH "/sub"). Attributes are trailing arguments +// (.attr, .flags, .mtime, .uid, .gid, .filesize, ...); the harness defaults omitted ones: .attr (0) to a regular file (set it with +// the HRN_LIBSSH2_DIR/FILE/LINK/FIFO() helpers), .uid/.gid (0) to the test user/group (HRN_LIBSSH2_OWNER_ROOT for root), and +// .flags (0) to the standard attribute set (permissions, times, owner) plus a size for a regular file. Reports success +// (LIBSSH2_ERROR_NONE) by default; set .resultInt for a failure. Set .follow = true to require LIBSSH2_SFTP_STAT. +#define HRN_LIBSSH2_STAT(path, ...) \ + {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" path "\"]", __VA_ARGS__} + +// libssh2_sftp_close_handle() response. Reports success (LIBSSH2_ERROR_NONE) by default; set .resultInt for a failure. +#define HRN_LIBSSH2_CLOSE(...) {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, __VA_ARGS__} + +// libssh2_sftp_fsync() response. Reports success (LIBSSH2_ERROR_NONE) by default; set .resultInt for a failure. +#define HRN_LIBSSH2_FSYNC(...) {.function = HRNLIBSSH2_SFTP_FSYNC, __VA_ARGS__} + +// libssh2_session_block_directions() response. Reports no blocked direction (SSH2_NO_BLOCK_READING_WRITING) by default; set +// .resultInt to an SSH2_BLOCK_* direction to make the production code wait. +#define HRN_LIBSSH2_BLOCK(...) {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, __VA_ARGS__} + +// libssh2_session_last_errno() response returning the given libssh2 error +#define HRN_LIBSSH2_ERRNO(error, ...) \ + {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = (error), __VA_ARGS__} + +// libssh2_sftp_last_error() response returning the given SFTP status (LIBSSH2_FX_*) +#define HRN_LIBSSH2_SFTP_ERROR(code, ...) \ + {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = (code), __VA_ARGS__} + +// libssh2_session_last_error() response returning the given libssh2 error and, via .errMsg, the message string +#define HRN_LIBSSH2_SESSION_ERROR(error, ...) \ + {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = (error), __VA_ARGS__} + +// libssh2_init() response (always called with flags 0). Reports success (LIBSSH2_ERROR_NONE) by default; set .resultInt for a +// failure. +#define HRN_LIBSSH2_INIT(...) \ + {.function = HRNLIBSSH2_INIT, .param = "[0]", __VA_ARGS__} + +// libssh2_session_init_ex() response (the production code always passes NULL allocators). Returns a session by default; set +// .resultNull = true for a failure. +#define HRN_LIBSSH2_SESSION_INIT(...) \ + {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]", __VA_ARGS__} + +// libssh2_session_handshake() response. Reports success (LIBSSH2_ERROR_NONE) by default; set .resultInt for a failure. +#define HRN_LIBSSH2_HANDSHAKE(...) \ + {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, __VA_ARGS__} + +// libssh2_session_hostkey() response. The harness defaults the host key length (20), type (LIBSSH2_HOSTKEY_TYPE_RSA), and +// value (HOSTKEY); set .type for another key type or .resultNull = true for a failure. +#define HRN_LIBSSH2_HOSTKEY(...) \ + {.function = HRNLIBSSH2_SESSION_HOSTKEY, __VA_ARGS__} + +// libssh2_hostkey_hash() response for the given hash type. Set .resultZ to the hash, or .resultNull = true for a failure. +#define HRN_LIBSSH2_HOSTKEY_HASH(hashType, ...) \ + {.function = HRNLIBSSH2_HOSTKEY_HASH, .param = "[" #hashType "]", __VA_ARGS__} + +// libssh2_knownhost_init() response. Returns a known-hosts collection by default; set .resultNull = true for a failure. +#define HRN_LIBSSH2_KNOWNHOST_INIT(...) \ + {.function = HRNLIBSSH2_KNOWNHOST_INIT, __VA_ARGS__} + +// libssh2_knownhost_readfile() response for the given file (LIBSSH2_KNOWNHOST_FILE_OPENSSH). Reports 0 hosts read by default; set +// .resultInt to the host count or a failure. +#define HRN_LIBSSH2_KNOWNHOST_READFILE(file, ...) \ + {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" file "\",1]", __VA_ARGS__} + +// libssh2_knownhost_writefile() response for the given file (LIBSSH2_KNOWNHOST_FILE_OPENSSH). Reports success (LIBSSH2_ERROR_NONE) +// by default; set .resultInt for a failure. +#define HRN_LIBSSH2_KNOWNHOST_WRITEFILE(file, ...) \ + {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" file "\",1]", __VA_ARGS__} + +// libssh2_knownhost_checkp() response for localhost returning the given LIBSSH2_KNOWNHOST_CHECK_* result +#define HRN_LIBSSH2_KNOWNHOST_CHECK(result) \ + {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", .resultInt = (result)} + +// libssh2_knownhost_addc() response adding localhost with the given type mask. Reports success by default; set .resultInt for a +// failure. +#define HRN_LIBSSH2_KNOWNHOST_ADD(typeMask, ...) \ + {.function = HRNLIBSSH2_KNOWNHOST_ADDC, \ + .param = "[\"localhost\",null,\"" HOSTKEY "\",20,\"Generated from pgBackRest\",25," #typeMask "]", __VA_ARGS__} + +// libssh2_userauth_publickey_fromfile_ex() response for the standard public-key login (TEST_USER with KEYPUB_CSTR / KEYPRIV_CSTR +// and no passphrase). Reports success (LIBSSH2_ERROR_NONE) by default; set .resultInt for a failure. A login that omits the public +// key or supplies a passphrase is scripted longhand. +#define HRN_LIBSSH2_USERAUTH(...) \ + {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, \ + .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", __VA_ARGS__} + +// libssh2_sftp_init() response. Returns an SFTP session by default; set .resultNull = true for a failure. +#define HRN_LIBSSH2_SFTP_INIT(...) \ + {.function = HRNLIBSSH2_SFTP_INIT, __VA_ARGS__} + +// libssh2_sftp_shutdown() response. Reports success (LIBSSH2_ERROR_NONE) by default; set .resultInt for a failure. +#define HRN_LIBSSH2_SHUTDOWN(...) {.function = HRNLIBSSH2_SFTP_SHUTDOWN, __VA_ARGS__} + +// libssh2_session_disconnect_ex() response (the production code always passes the standard shutdown reason). Reports success +// (LIBSSH2_ERROR_NONE) by default; set .resultInt for a failure. +#define HRN_LIBSSH2_DISCONNECT(...) \ + {.function = HRNLIBSSH2_SESSION_DISCONNECT_EX, .param = "[11,\"pgBackRest instance shutdown\",\"\"]", __VA_ARGS__} + +// libssh2_session_free() response. Reports success (LIBSSH2_ERROR_NONE) by default; set .resultInt for a failure. +#define HRN_LIBSSH2_SESSION_FREE(...) {.function = HRNLIBSSH2_SESSION_FREE, __VA_ARGS__} + +// libssh2_sftp_seek64() expectation verifying the production code seeks to the given byte offset (the function returns void) +#define HRN_LIBSSH2_SEEK(offset, ...) \ + {.function = HRNLIBSSH2_SFTP_SEEK64, .param = "[" #offset "]", __VA_ARGS__} + +// libssh2_sftp_read() response (size is the production buffer_maxlen). Set .readBuffer to the bytes returned; the result +// (bytes read) defaults to the read buffer size, so set .resultInt only for a short read or a failure. +#define HRN_LIBSSH2_READ(size, ...) \ + {.function = HRNLIBSSH2_SFTP_READ, .param = "[" #size "]", __VA_ARGS__} + +// libssh2_sftp_write() response (size is the production byte size). The result (bytes written) defaults to the full size, so set +// .resultInt only for a short write or a failure. +#define HRN_LIBSSH2_WRITE(size, ...) \ + {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[" #size "]", __VA_ARGS__} + +// libssh2_sftp_open_ex() responses, one per production open path (param is ["path",flags,open_type]): a directory (flags 0, +// LIBSSH2_SFTP_OPENDIR), a file for reading (LIBSSH2_FXF_READ, LIBSSH2_SFTP_OPENFILE), or a file for writing +// (LIBSSH2_FXF_CREAT | LIBSSH2_FXF_WRITE | LIBSSH2_FXF_TRUNC = 26, LIBSSH2_SFTP_OPENFILE). The path is the full server path (e.g. +// TEST_PATH "/sub"). The harness verifies the open mode separately; a write open defaults to 0640, so set .mode only when it +// differs. Pass .resultNull = true (optionally with .resultInt) for a failed open. +#define HRN_LIBSSH2_OPENDIR(path, ...) \ + {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" path "\",0,1]", __VA_ARGS__} +#define HRN_LIBSSH2_OPEN_READ(path, ...) \ + {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" path "\",1,0]", __VA_ARGS__} +#define HRN_LIBSSH2_OPEN_WRITE(path, ...) \ + {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" path "\",26,0]", __VA_ARGS__} + +// libssh2_sftp_symlink_ex() response reading a link destination (param is ["path","",LIBSSH2_SFTP_READLINK]; the empty target is +// the production output buffer). The path is the full server path (e.g. TEST_PATH "/sub"). Reports success by default; set .target +// to the destination, or .resultInt for a failure. +#define HRN_LIBSSH2_READLINK(path, ...) \ + {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" path "\",\"\",1]", __VA_ARGS__} + +// libssh2_sftp_unlink_ex() response. The path is the full server path (e.g. TEST_PATH "/sub"). Reports success (LIBSSH2_ERROR_NONE) +// by default; set .resultInt for a failure. +#define HRN_LIBSSH2_UNLINK(path, ...) \ + {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" path "\"]", __VA_ARGS__} + +// libssh2_sftp_mkdir_ex() response. The path is the full server path (e.g. TEST_PATH "/sub"). The harness verifies the mode +// separately and defaults an omitted .mode to 0750. Reports success by default; set .resultInt for a failure. +#define HRN_LIBSSH2_MKDIR(path, ...) \ + {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" path "\"]", __VA_ARGS__} + +// libssh2_sftp_rmdir_ex() response. The path is the full server path (e.g. TEST_PATH "/sub"). Reports success by default; set +// .resultInt for a failure. +#define HRN_LIBSSH2_RMDIR(path, ...) \ + {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" path "\"]", __VA_ARGS__} + +// libssh2_sftp_rename_ex() response (flags 7 = LIBSSH2_SFTP_RENAME_OVERWRITE | _ATOMIC | _NATIVE, as the production code always +// passes). Both paths are full server paths (e.g. TEST_PATH "/sub"). Reports success by default; set .resultInt for a failure. +#define HRN_LIBSSH2_RENAME(source, dest, ...) \ + {.function = HRNLIBSSH2_SFTP_RENAME_EX, .param = "[\"" source "\",\"" dest "\",7]", __VA_ARGS__} + +/*********************************************************************************************************************************** +Macros for defining groups of functions that implement commands +***********************************************************************************************************************************/ +// Set of functions mimicking libssh2 initialization and authorization +#define HRNLIBSSH2_MACRO_STARTUP() \ + HRN_LIBSSH2_INIT(), \ + HRN_LIBSSH2_SESSION_INIT(), \ + HRN_LIBSSH2_HANDSHAKE(), \ + HRN_LIBSSH2_KNOWNHOST_INIT(), \ + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), \ + HRN_LIBSSH2_HOSTKEY(), \ + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), \ + HRN_LIBSSH2_USERAUTH(), \ + HRN_LIBSSH2_SFTP_INIT() + +// Set of functions mimicking libssh2 shutdown and disconnect +#define HRNLIBSSH2_MACRO_SHUTDOWN() \ + HRN_LIBSSH2_SHUTDOWN(), \ + HRN_LIBSSH2_DISCONNECT(), \ + HRN_LIBSSH2_SESSION_FREE() + /*********************************************************************************************************************************** Functions ***********************************************************************************************************************************/ -void hrnLibSsh2ScriptSet(HrnLibSsh2 *hrnLibSsh2ScriptParam); +// Set a libssh2 script. The prior script must have completed. The script length is computed, so no terminator entry is needed. +#define HRN_LIBSSH2_SCRIPT_SET(...) \ + do \ + { \ + const HrnLibSsh2 script[] = {__VA_ARGS__}; \ + hrnLibSsh2ScriptSet(script, LENGTH_OF(script)); \ + } \ + while (0) + +void hrnLibSsh2ScriptSet(const HrnLibSsh2 *script, unsigned int scriptSize); #endif // HARNESS_LIBSSH2_REAL diff --git a/test/src/module/storage/sftpTest.c b/test/src/module/storage/sftpTest.c index a3bce4df6..6c0c68080 100644 --- a/test/src/module/storage/sftpTest.c +++ b/test/src/module/storage/sftpTest.c @@ -27,31 +27,6 @@ Constants #define SSH2_BLOCK_WRITING 2 #define SSH2_BLOCK_READING_WRITING 3 -/*********************************************************************************************************************************** -Test function for path expression -***********************************************************************************************************************************/ -#ifdef HAVE_LIBSSH2 - -static String * -storageTestPathExpression(const String *expression, const String *path) -{ - String *result = NULL; - - if (strcmp(strZ(expression), "") == 0) - { - result = strCatZ(strNew(), "test"); - - if (path != NULL) - strCatFmt(result, "/%s", strZ(path)); - } - else if (strcmp(strZ(expression), "") != 0) - THROW_FMT(AssertError, "invalid expression '%s'", strZ(expression)); - - return result; -} - -#endif // HAVE_LIBSSH2 - /*********************************************************************************************************************************** Test Run ***********************************************************************************************************************************/ @@ -61,8 +36,13 @@ testRun(void) FUNCTION_HARNESS_VOID(); #ifdef HAVE_LIBSSH2 + // Set storage helper + static const StorageHelper storageHelperList[] = {STORAGE_SFTP_HELPER, STORAGE_END_HELPER}; + storageHelperInit(storageHelperList); + // Install shim to return defined fd hrnSckClientOpenShimInstall(); + // Install shim to manage true/false return for fdReady hrnFdReadyShimInstall(); @@ -70,10 +50,17 @@ testRun(void) const String *fileNoPerm = STRDEF(TEST_PATH "/noperm/noperm"); String *pathNoPerm = strPath(fileNoPerm); - // Write file for testing if storage is read-only - const String *writeFile = STRDEF(TEST_PATH "/writefile"); - - unsigned int repoIdx = 0; + // Common argument list + StringList *const argCommonList = strLstNew(); + hrnCfgArgRawZ(argCommonList, cfgOptStanza, "test"); + hrnCfgArgRawZ(argCommonList, cfgOptPgPath, "/path/to/pg"); + hrnCfgArgRawZ(argCommonList, cfgOptRepoSftpHostUser, TEST_USER); + hrnCfgArgRawZ(argCommonList, cfgOptRepoType, "sftp"); + hrnCfgArgRawZ(argCommonList, cfgOptRepoSftpHost, "localhost"); + hrnCfgArgRawZ(argCommonList, cfgOptRepoSftpHostKeyHashType, "sha1"); + hrnCfgArgRawZ(argCommonList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); + hrnCfgArgRawZ(argCommonList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); + hrnCfgArgRawZ(argCommonList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); #endif // HAVE_LIBSSH2 // ***************************************************************************************************************************** @@ -83,11 +70,7 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("ssh2 init failure"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = -1}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET(HRN_LIBSSH2_INIT(.resultInt = -1)); TEST_ERROR( storageSftpNewP( @@ -98,12 +81,9 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("driver session failure"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]", .resultNull = true}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(.resultNull = true)); TEST_ERROR( storageSftpNewP( @@ -114,16 +94,13 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("handshake failure"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_WRITING}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_BAD_SOCKET}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_BAD_SOCKET, .errMsg = "Bad socket provided"}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_WRITING), + HRN_LIBSSH2_HANDSHAKE(.resultInt = LIBSSH2_ERROR_BAD_SOCKET), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_BAD_SOCKET, .errMsg = "Bad socket provided")); TEST_ERROR( storageSftpNewP( @@ -134,16 +111,13 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("handshake failure - timeout during libssh2 handshake"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_HANDSHAKE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); TEST_ERROR( storageSftpNewP( @@ -154,15 +128,12 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("hostkey hash fail"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_HOSTKEY_HASH, .param = "[2]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_HOSTKEY_HASH(2, .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND)); TEST_ERROR( storageSftpNewP( @@ -174,13 +145,10 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("invalid hostkey hash"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = 0}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = 0}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE()); TEST_ERROR( storageSftpNewP( @@ -191,23 +159,16 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("public key from file auth failure leading - tilde key paths"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_HOSTKEY_HASH, .param = "[2]", .resultZ = "12345678909876543210"}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", .resultInt = -16}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_HOSTKEY_HASH(2, .resultZ = "12345678909876543210"), + HRN_LIBSSH2_USERAUTH(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_USERAUTH(.resultInt = -16), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK)); - // Load configuration StringList *argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); @@ -224,17 +185,7 @@ testRun(void) HRN_CFG_LOAD(cfgCmdArchiveGet, argList); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, + storageRepo(), ServiceError, "public key authentication failed: libssh2 error [-16]\n" "HINT: libssh2 compiled against non-openssl libraries requires --repo-sftp-private-key-file and" " --repo-sftp-public-key-file to be provided\n" @@ -245,14 +196,11 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("fingerprint mismatch"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_HOSTKEY_HASH, .param = "[2]", .resultZ = "12345678909876543210"}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_HOSTKEY_HASH(2, .resultZ = "12345678909876543210")); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -270,217 +218,111 @@ testRun(void) HRN_CFG_LOAD(cfgCmdArchiveGet, argList); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, + storageRepo(), ServiceError, "host [3132333435363738393039383736353433323130] and configured fingerprint (repo-sftp-host-fingerprint)" " [9132333435363738393039383736353433323130] do not match"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("known host init failure"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT, .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_ALLOC}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_ALLOC, - .errMsg = "Unable to allocate memory for known-hosts collection"}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(.resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_ALLOC), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_ALLOC, .errMsg = "Unable to allocate memory for known-hosts collection")); - // Load configuration - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, + storageRepo(), ServiceError, "failure during libssh2_knownhost_init: libssh2 errno [-6] Unable to allocate memory for known-hosts collection"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("libssh2_session_hostkey fail - return NULL - hostKeyCheckType = yes"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(.resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND)); - // Load configuration - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, - "libssh2_session_hostkey failed to get hostkey: libssh2 error [-7]"); + TEST_ERROR(storageRepo(), ServiceError, "libssh2_session_hostkey failed to get hostkey: libssh2 error [-7]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_checkp failure LIBSSH2_KNOWNHOST_CHECK_MISMATCH"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MISMATCH}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MISMATCH)); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, - "known hosts failure: 'localhost' mismatch in known hosts files: LIBSSH2_KNOWNHOST_CHECK_MISMATCH [1]: check type " - "[strict]"); + storageRepo(), ServiceError, + "known hosts failure: 'localhost' mismatch in known hosts files: LIBSSH2_KNOWNHOST_CHECK_MISMATCH [1]: check type" + " [strict]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_checkp failure LIBSSH2_KNOWNHOST_CHECK_FAILURE"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_FAILURE}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_FAILURE)); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, "known hosts failure: 'localhost' LIBSSH2_KNOWNHOST_CHECK_FAILURE [3]: check type [strict]"); + storageRepo(), ServiceError, + "known hosts failure: 'localhost' LIBSSH2_KNOWNHOST_CHECK_FAILURE [3]: check type [strict]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_checkp failure LIBSSH2_KNOWNHOST_CHECK_NOTFOUND"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND)); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, + storageRepo(), ServiceError, "known hosts failure: 'localhost' not found in known hosts files: LIBSSH2_KNOWNHOST_CHECK_NOTFOUND [2]: check type" " [strict]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("read known_hosts file failure - empty files - log INFO on empty known_hosts files"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 0}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", .resultInt = 0}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 0}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", .resultInt = 0}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND)); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -495,35 +337,21 @@ testRun(void) HRN_CFG_LOAD(cfgCmdArchiveGet, argList); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, + storageRepo(), ServiceError, "known hosts failure: 'localhost' not found in known hosts files: LIBSSH2_KNOWNHOST_CHECK_NOTFOUND [2]: check type" " [strict]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_checkp unknown failure type"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = 5}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(5)); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -538,50 +366,25 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, "known hosts failure: 'localhost' unknown failure [5]: check type [strict]"); + TEST_ERROR(storageRepo(), ServiceError, "known hosts failure: 'localhost' unknown failure [5]: check type [strict]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("public key from file auth failure, no public key"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",null,\"" KEYPRIV_CSTR "\",null]", .resultInt = -16}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK}, - {.function = NULL} - }); + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK)); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, + storageRepo(), ServiceError, "public key authentication failed: libssh2 error [-16]\n" "HINT: libssh2 compiled against non-openssl libraries requires --repo-sftp-private-key-file and" " --repo-sftp-public-key-file to be provided\n" @@ -594,211 +397,107 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("public key from file LIBSSH2_ERROR_EAGAIN, failure"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, - "timeout during public key authentication"); + TEST_ERROR(storageRepo(), ServiceError, "timeout during public key authentication"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init failure ssh2 error"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT, .resultNull = true}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(.resultNull = true), // storageSftpWaitFd returns false - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - {.function = NULL} - }); + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); - TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, - "unable to init libssh2_sftp session"); + TEST_ERROR(storageRepo(), ServiceError, "unable to init libssh2_sftp session"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("sftp session init fail && timeout"); + TEST_TITLE("sftp session init fail and timeout"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT, .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(.resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), // fdReady shim returns false --> storageSftpWaitFd returns false - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = NULL} - }); + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN)); - TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, - "timeout during init of libssh2_sftp session"); + TEST_ERROR(storageRepo(), ServiceError, "timeout during init of libssh2_sftp session"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init fail no timeout"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT, .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(.resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), // fdReady shim returns true --> storageSftpWaitFd returns true - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING}, - {.function = HRNLIBSSH2_SFTP_INIT, .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - {.function = NULL} - }); + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING), + HRN_LIBSSH2_SFTP_INIT(.resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); - TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, - "unable to init libssh2_sftp session"); + TEST_ERROR(storageRepo(), ServiceError, "unable to init libssh2_sftp session"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init success"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRNLIBSSH2_MACRO_SHUTDOWN()); - Storage *storageTest = NULL; + TEST_RESULT_VOID(storageRepo(), "new storage"); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); - TEST_RESULT_BOOL(storageTest->write, false, "check write"); - - // Free context, otherwise callbacks to storageSftpLibSsh2SessionFreeResource() accumulate - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_init WARN host key checking disabled, insecure connections, hostKeyCheckType = no"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -814,146 +513,67 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "none"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - storageTest = NULL; + TEST_RESULT_VOID(storageRepo(), "new storage"); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); - - // Free context, otherwise callbacks to storageSftpLibSsh2SessionFreeResource() accumulate - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_init WARN init fail for user's known_hosts file for update, hostKeyCheckType = accept-new"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT, .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_ALLOC}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_ALLOC, - .errMsg = "Unable to allocate memory for known-hosts collection"}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(.resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_ALLOC), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_ALLOC, .errMsg = "Unable to allocate memory for known-hosts collection"), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "accept-new"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: libssh2_knownhost_init failed for '/home/" TEST_USER "/.ssh/known_hosts' for update: libssh2 errno [-6] " "Unable to allocate memory for known-hosts collection"); - // Free context, otherwise callbacks to storageSftpLibSsh2SessionFreeResource() accumulate - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_init WARN missing user's known_host file for update - hostKeyCheckType = accept-new"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .errMsg = "Failed to open file", .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_FILE, .errMsg = "Failed to open file"), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "accept-new"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" @@ -961,7 +581,7 @@ testRun(void) "to open file\n" " HINT: does '/home/" TEST_USER "/.ssh/known_hosts' exist with proper permissions?"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_init WARN unable to read user's known_host file for update - hostKeyCheckType = accept-new"); @@ -969,45 +589,23 @@ testRun(void) // Create known_hosts file so it can be found by storageExistsP(), i.e. file exists but is unreadable HRN_SYSTEM_FMT("touch %s", strZ(strNewFmt("%s/.ssh/known_hosts", strZ(userHome())))); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .errMsg = "Failed to open file", .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_FILE, .errMsg = "Failed to open file"), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" @@ -1018,49 +616,27 @@ testRun(void) // Remove known_hosts file HRN_SYSTEM_FMT("rm %s", strZ(strNewFmt("%s/.ssh/known_hosts", strZ(userHome())))); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_init WARN fail to load user's known_host file with error other than LIBSSH2_ERROR_FILE"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_KNOWN_HOSTS}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .errMsg = "Failed to parse known hosts file", - .resultInt = LIBSSH2_ERROR_KNOWN_HOSTS}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = LIBSSH2_ERROR_KNOWN_HOSTS), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_KNOWN_HOSTS, .errMsg = "Failed to parse known hosts file"), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" @@ -1068,44 +644,32 @@ testRun(void) "parse known hosts file\n" " HINT: does '/home/" TEST_USER "/.ssh/known_hosts' exist with proper permissions?"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init success - hostKeyCheckType = accept-new - add host to user's known_hosts file RSA"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .errMsg = "Failed to open file", .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .errMsg = "Failed to open file", .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,589825]"}, - {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR, .resultInt = LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_FILE, .errMsg = "Failed to open file"), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR, .resultInt = LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_FILE, .errMsg = "Failed to open file"), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR, .resultInt = LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_SESSION_ERROR(LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(589825), + HRN_LIBSSH2_KNOWNHOST_WRITEFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -1121,22 +685,9 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "accept-new"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - storageTest = NULL; - harnessLogLevelSet(logLevelDetail); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 DETAIL: libssh2 '/home/" TEST_USER "/.ssh/known_hosts' file is empty\n" "P00 DETAIL: libssh2 read '/home/" TEST_USER "/.ssh/known_hosts2' failed: libssh2 errno [-16] Failed to open file\n" @@ -1148,474 +699,264 @@ testRun(void) "P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'"); harnessLogLevelReset(); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init success - hostKeyCheckType = accept-new - add host to user's known_hosts file DSS"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_DSS, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,851969]"}, - {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(.type = LIBSSH2_HOSTKEY_TYPE_DSS), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(851969), + HRN_LIBSSH2_KNOWNHOST_WRITEFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); -#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256 // ------------------------------------------------------------------------------------------------------------------------- +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256 TEST_TITLE("sftp session init success - hostKeyCheckType = accept-new - add host to user's known_hosts ECDSA_256"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_ECDSA_256, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,1114113]"}, - {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(.type = LIBSSH2_HOSTKEY_TYPE_ECDSA_256), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(1114113), + HRN_LIBSSH2_KNOWNHOST_WRITEFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #endif -#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384 // ------------------------------------------------------------------------------------------------------------------------- +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384 TEST_TITLE("sftp session init success - hostKeyCheckType = accept-new - add host to user's known_hosts ECDSA_384"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_ECDSA_384, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,1376257]"}, - {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(.type = LIBSSH2_HOSTKEY_TYPE_ECDSA_384), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(1376257), + HRN_LIBSSH2_KNOWNHOST_WRITEFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #endif -#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521 // ------------------------------------------------------------------------------------------------------------------------- +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521 TEST_TITLE("sftp session init success - hostKeyCheckType = accept-new - add host to user's known_hosts ECDSA_521"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_ECDSA_521, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,1638401]"}, - {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(.type = LIBSSH2_HOSTKEY_TYPE_ECDSA_521), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(1638401), + HRN_LIBSSH2_KNOWNHOST_WRITEFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #endif -#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519 // ------------------------------------------------------------------------------------------------------------------------- +#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519 TEST_TITLE("sftp session init success - hostKeyCheckType = accept-new - add host to user's known_hosts ED25519"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_ED25519, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,1900545]"}, - {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(.type = LIBSSH2_HOSTKEY_TYPE_ED25519), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(1900545), + HRN_LIBSSH2_KNOWNHOST_WRITEFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #endif // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init WARN - hostKeyCheckType = accept-new - fail to write user's known_hosts file"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,589825]"}, - {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_FILE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(589825), + HRN_LIBSSH2_KNOWNHOST_WRITEFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = LIBSSH2_ERROR_FILE), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: pgBackRest unable to write '/home/" TEST_USER "/.ssh/known_hosts' for update"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init WARN - hostKeyCheckType = accept-new, add to user's known_hosts - unknown key type"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = 9, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(.type = 9), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: unsupported key type [9], unable to update knownhosts for 'localhost'"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init WARN - hostKeyCheckType = accept-new - add host to user's known_hosts failure"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, .resultInt = LIBSSH2_ERROR_KNOWN_HOSTS, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,589825]"}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(589825, .resultInt = LIBSSH2_ERROR_KNOWN_HOSTS), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: pgBackRest failed to add 'localhost' to known_hosts internal list"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_checkp failure LIBSSH2_KNOWNHOST_CHECK_FAILURE hostKeyCheckType = accept-new"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_FAILURE}, - {.function = NULL}, - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_FAILURE)); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -1632,117 +973,86 @@ testRun(void) HRN_CFG_LOAD(cfgCmdArchiveGet, argList); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, "known hosts failure: 'localhost': LIBSSH2_KNOWNHOST_CHECK_FAILURE [3]: check type [accept-new]"); + storageRepo(), ServiceError, + "known hosts failure: 'localhost': LIBSSH2_KNOWNHOST_CHECK_FAILURE [3]: check type [accept-new]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("knownhost_checkp failure LIBSSH2_KNOWNHOST_CHECK_MISMATCH hostKeyCheckType = accept-new"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MISMATCH}, - {.function = NULL}, - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MISMATCH)); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, + storageRepo(), ServiceError, "known hosts failure: 'localhost': mismatch in known hosts files: LIBSSH2_KNOWNHOST_CHECK_MISMATCH [1]: check type" " [accept-new]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init success LIBSSH2_KNOWNHOST_CHECK_MISMATCH hostKeyCheckType = accept-new"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",null,\"" KEYPRIV_CSTR "\",null]", .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); + + Storage *storageTest; TEST_ASSIGN( storageTest, storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + cfgOptionIdxStr(cfgOptRepoPath, 0), cfgOptionIdxStr(cfgOptRepoSftpHost, 0), + cfgOptionIdxUInt(cfgOptRepoSftpHostPort, 0), cfgOptionIdxStr(cfgOptRepoSftpHostUser, 0), + cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, 0), + cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, 0), .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, 0), + .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, 0), + .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, 0), + .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, 0), + .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, 0)), .write = true, + .pathExpressionFunction = storageRepoPathExpression), + "new storage"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + TEST_RESULT_UINT(storageTest->modeFile, 0640, "check file mode"); + TEST_RESULT_UINT(storageTest->modePath, 0750, "check path mode"); + TEST_RESULT_PTR(storageTest->pathExpressionFunction, storageRepoPathExpression, "check expression"); + TEST_RESULT_BOOL(storageTest->write, true, "check write"); + + objFree(storageTest); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init WARN - hostKeyCheckType = accept-new - add host to user's known_hosts"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_ADDC, - .param = "[\"localhost\",null,\"12345678901234567890\",20,\"Generated from pgBackRest\",25,589825]"}, - {.function = HRNLIBSSH2_KNOWNHOST_WRITEFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_READFILE(ETC_KNOWNHOSTS2_FILE_CSTR), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_NOTFOUND), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_KNOWNHOST_ADD(589825), + HRN_LIBSSH2_KNOWNHOST_WRITEFILE(KNOWNHOSTS_FILE_CSTR), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -1758,144 +1068,72 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "accept-new"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - storageTest = NULL; - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), - .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_LOG( "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "'/home/" TEST_USER "/.ssh/known_hosts'\n" "P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session failure - libssh2_session_hostkey fail - hostKeyCheckType = accept-new"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(.resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND)); - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "accept-new"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - ServiceError, - "libssh2_session_hostkey failed to get hostkey: libssh2 error [-7]"); + TEST_ERROR(storageRepo(), ServiceError, "libssh2_session_hostkey failed to get hostkey: libssh2 error [-7]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("sftp session init success timeout"); // Shim sets FD for tests. - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT, .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "accept-new"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); - TEST_RESULT_BOOL(storageTest->write, false, "check write"); + TEST_RESULT_VOID(storageRepo(), "new storage"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("create new storage with defaults && a single known_hosts file with leading tilde"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"/home/" TEST_USER "/.ssh/pgbackrest_known_hosts\",1]", - .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT, .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE("/home/" TEST_USER "/.ssh/pgbackrest_known_hosts", .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), + HRNLIBSSH2_MACRO_SHUTDOWN()); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -1912,38 +1150,19 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "strict"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (defaults)"); - TEST_RESULT_STR_Z(storageTest->path, "/tmp", "check path"); - TEST_RESULT_INT(storageTest->modeFile, 0640, "check file mode"); - TEST_RESULT_INT(storageTest->modePath, 0750, "check path mode"); - TEST_RESULT_BOOL(storageTest->write, false, "check write"); + TEST_RESULT_VOID(storageRepo(), "new storage"); TEST_RESULT_STR_Z( strLstGet(strLstNewVarLst(cfgOptionLst(cfgOptRepoSftpKnownHost)), 0), "~/.ssh/pgbackrest_known_hosts", "check known hosts path"); - TEST_RESULT_BOOL(storageTest->pathExpressionFunction == NULL, true, "check expression function is not set"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("create new storage - override defaults"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRNLIBSSH2_MACRO_SHUTDOWN()); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -1960,78 +1179,33 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "accept-new"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = 0600, - .modePath = 0700, .write = true, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage (non-default)"); - TEST_RESULT_STR_Z(storageTest->path, "/path/to", "check path"); - TEST_RESULT_INT(storageTest->modeFile, 0600, "check file mode"); - TEST_RESULT_INT(storageTest->modePath, 0700, "check path mode"); - TEST_RESULT_BOOL(storageTest->write, true, "check write"); - TEST_RESULT_BOOL(storageTest->pathExpressionFunction == NULL, true, "check expression function is empty"); + TEST_RESULT_VOID(storageRepoWrite(), "new storage"); - TEST_RESULT_PTR(storageInterface(storageTest).info, storageTest->pub.interface.info, "check interface"); - TEST_RESULT_PTR(storageDriver(storageTest), storageTest->pub.driver, "check driver"); - TEST_RESULT_UINT(storageType(storageTest), storageTest->pub.type, "check type"); - TEST_RESULT_BOOL(storageFeature(storageTest, storageFeaturePath), true, "check path feature"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("public key from file auth failure, key passphrase"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",\"keyPassphrase\"]", .resultInt = -16}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK}, - {.function = NULL} - }); + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK)); - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); hrnCfgEnvKeyRawZ(cfgOptRepoSftpPrivateKeyPassphrase, 1, "keyPassphrase"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); TEST_ERROR( - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), + storageRepo(), ServiceError, "public key authentication failed: libssh2 error [-16]\n" "HINT: libssh2 compiled against non-openssl libraries requires --repo-sftp-private-key-file and" @@ -2051,152 +1225,104 @@ testRun(void) if (testBegin("storageExists() and storagePathExists()")) { #ifdef HAVE_LIBSSH2 - // Mimic creation of /noperm/noperm for permission denied - // drwx------ 2 root root 3 Dec 5 15:30 noperm - // noperm/: - // total 1 - // -rw------- 1 root root 0 Dec 5 15:30 noperm - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // File missing - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/missing\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/missing\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE, .sleep = 100}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/missing\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/missing\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/missing\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Path missing - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "\",0]", - .attrPerms = LIBSSH2_SFTP_S_IFDIR, .resultInt = LIBSSH2_ERROR_NONE}, - // Permission denied - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // File and path - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]", - .attrPerms = LIBSSH2_SFTP_S_IFREG, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pathExists\",0]", - .attrPerms = LIBSSH2_SFTP_S_IFDIR, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]", - .attrPerms = LIBSSH2_SFTP_S_IFREG, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pathExists\",0]", - .attrPerms = LIBSSH2_SFTP_S_IFDIR, .resultInt = LIBSSH2_ERROR_NONE}, - // File exists after wait - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]", - .attrPerms = LIBSSH2_SFTP_S_IFREG, .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + StringList *argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "strict"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - Storage *storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + const Storage *storageTest = storageRepoWrite(); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("file"); + TEST_TITLE("file missing"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); TEST_RESULT_BOOL(storageExistsP(storageTest, STRDEF("missing")), false, "file does not exist"); - TEST_RESULT_BOOL(storageExistsP(storageTest, STRDEF("missing"), .timeout = 100), false, "file does not exist"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path"); + TEST_TITLE("file missing with timeout"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE, .sleep = 100), + HRN_LIBSSH2_STAT(TEST_PATH "/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_STAT(TEST_PATH "/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + + TEST_RESULT_BOOL(storageExistsP(storageTest, STRDEF("missing"), .timeout = 100), false, "file does not exist with timeout"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("path missing"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE),); TEST_RESULT_BOOL(storagePathExistsP(storageTest, STRDEF("missing")), false, "path does not exist"); - TEST_RESULT_BOOL(storagePathExistsP(storageTest, NULL), true, "test path exists"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("permission denied"); - TEST_ERROR_FMT( - storageExistsP(storageTest, fileNoPerm), - FileOpenError, - STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm)); + HRN_LIBSSH2_SCRIPT_SET( + // Permission denied + HRN_LIBSSH2_STAT(TEST_PATH "/noperm/noperm", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); + TEST_ERROR_FMT( storagePathExistsP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm)); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("file and path"); + TEST_TITLE("file exists"); - const String *fileExists = STRDEF(TEST_PATH "/exists"); - const String *pathExists = STRDEF(TEST_PATH "/pathExists"); + HRN_LIBSSH2_SCRIPT_SET(HRN_LIBSSH2_STAT(TEST_PATH "/exists", .flags = HRN_LIBSSH2_ATTR_EXISTENCE)); - 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_BOOL(storagePathExistsP(storageTest, pathExists), true, "path exists"); + TEST_RESULT_BOOL(storageExistsP(storageTest, STRDEF(TEST_PATH "/exists")), true, "file exists"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("file after wait"); + TEST_TITLE("path exists"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/pathExists", .attr = HRN_LIBSSH2_DIR(0), .flags = HRN_LIBSSH2_ATTR_EXISTENCE)); + + TEST_RESULT_BOOL(storagePathExistsP(storageTest, STRDEF(TEST_PATH "/pathExists")), true, "path exists"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("file exists after wait"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/exists", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_STAT(TEST_PATH "/exists", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_STAT(TEST_PATH "/exists", .flags = HRN_LIBSSH2_ATTR_EXISTENCE), + HRNLIBSSH2_MACRO_SHUTDOWN()); HRN_FORK_BEGIN() { HRN_FORK_CHILD_BEGIN() { sleepMSec(250); - - // Mimic HRN_SYSTEM_FMT("touch %s", strZ(fileExists)); } HRN_FORK_CHILD_END(); HRN_FORK_PARENT_BEGIN() { - TEST_RESULT_BOOL(storageExistsP(storageTest, fileExists, .timeout = 1000), true, "file exists after wait"); + TEST_RESULT_BOOL( + storageExistsP(storageTest, STRDEF(TEST_PATH "/exists"), .timeout = 1000), true, "file exists after wait"); } HRN_FORK_PARENT_END(); } HRN_FORK_END(); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 @@ -2207,259 +1333,44 @@ testRun(void) { #ifdef HAVE_LIBSSH2 // File open error via permission denied sftp error - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",1]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_STAT(TEST_PATH "/noperm/noperm", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); // Create storage object for testing - Storage *storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + Storage *storageTest = storageSftpHelper(0, true, storageRepoPathExpression); TEST_ERROR_FMT( storageInfoP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // File open error via ssh error - covers storageSftpLibSsh2FxNoSuchFile where rc != LIBSSH2_ERROR_SFTP_PROTOCOL - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",1]", .resultInt = LIBSSH2_ERROR_INVAL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/noperm/noperm", .resultInt = LIBSSH2_ERROR_INVAL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); TEST_ERROR_FMT( storageInfoP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-34]", strZ(fileNoPerm)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("info for / exists"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"/\",1]", .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); - hrnCfgArgRawZ(argList, cfgOptRepoPath, strZ(FSLASH_STR)); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "strict"); - HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - - // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_RESULT_BOOL(storageInfoP(storageTest, NULL).exists, true, "info for /"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("info for / does not exist with no path feature"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - Storage *storageRootNoPath = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - storageRootNoPath->pub.interface.feature ^= 1 << storageFeaturePath; - - TEST_RESULT_BOOL(storageInfoP(storageRootNoPath, NULL, .ignoreMissing = true).exists, false, "no info for /"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageRootNoPath))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("directory does not exist"); - - const String *fileName = STRDEF(TEST_PATH "/fileinfo"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // File does not exist - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/fileinfo\",1]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/fileinfo\",1]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Info out of base path - first test libssh2_sftp_stat_ex throws error before reaching libssh2 code second test - // libssh2_sftp_stat_stat_ex reaches libssh2 code - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"/etc\",1]", .resultInt = LIBSSH2_ERROR_NONE}, - // Info - path - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // Info - path exists only - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // Info basic - path - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // Info - file - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/fileinfo\",1]", - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1555155555, .uid = 99999, .gid = 99999, .filesize = 8}, - // Info - link - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testlink\",1]", - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG | LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/testlink\",\"\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .symlinkExTarget = STRDEF("/tmp")}, - // Info - link .followLink = true - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testlink\",0]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testlink\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG | LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .uid = 0, .gid = 0}, - // Info - link .followLink = true, timeout EAGAIN in followLink - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testlink\",0]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - // Info - link .followLink = false, timeout EAGAIN - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testlink\",1]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - // Info - link .followLink = false, libssh2_sftp_symlink_ex link destination size timeout - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testlink\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG | LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/testlink\",\"\",1]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - // Info - link .followLink = false, libssh2_sftp_symlink_ex link destination size fail - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testlink\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG | LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/testlink\",\"\",1]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/testlink\",\"\",1]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_LINK_LOOP}, - // Info - pipe - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testpipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP | LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IWOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); - hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "strict"); - HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - - // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR_FMT(storageInfoP(storageTest, fileName), FileOpenError, STORAGE_ERROR_INFO_MISSING, strZ(fileName)); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("file does not exist"); - StorageInfo info = {0}; - TEST_ASSIGN(info, storageInfoP(storageTest, fileName, .ignoreMissing = true), "get file info (missing)"); - TEST_RESULT_BOOL(info.exists, false, "check not exists"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/fileinfo", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + + TEST_RESULT_BOOL( + storageInfoP( + storageTest, STRDEF(TEST_PATH "/fileinfo"), .ignoreMissing = true).exists, false, "get file info (missing)"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("info outside of base path"); - TEST_ERROR( - storageInfoP(storageTest, STRDEF("/etc"), .ignoreMissing = true), AssertError, - "absolute path '/etc' is not in base path '" TEST_PATH "'"); + HRN_LIBSSH2_SCRIPT_SET(HRN_LIBSSH2_STAT("/etc", .flags = HRN_LIBSSH2_ATTR_EXISTENCE)); + TEST_RESULT_BOOL( storageInfoP(storageTest, STRDEF("/etc"), .ignoreMissing = true, .noPathEnforce = true).exists, true, "path not enforced"); @@ -2467,7 +1378,9 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("info - path"); - HRN_STORAGE_TIME(storageTest, TEST_PATH, 1555160000); + HRN_LIBSSH2_SCRIPT_SET(HRN_LIBSSH2_STAT(TEST_PATH, .attr = HRN_LIBSSH2_DIR(0770), .mtime = 1555160000)); + + StorageInfo info; TEST_ASSIGN(info, storageInfoP(storageTest, TEST_PATH_STR), "get path info"); TEST_RESULT_STR(info.name, NULL, "name is not set"); @@ -2485,36 +1398,22 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("info - path existence only"); + HRN_LIBSSH2_SCRIPT_SET(HRN_LIBSSH2_STAT(TEST_PATH, .attr = HRN_LIBSSH2_DIR(0770), .mtime = 1555160000)); + TEST_ASSIGN(info, storageInfoP(storageTest, TEST_PATH_STR, .level = storageInfoLevelExists), "path exists"); TEST_RESULT_BOOL(info.exists, true, "check exists"); TEST_RESULT_UINT(info.size, 0, "check exists"); TEST_RESULT_INT(info.timeModified, 0, "check time"); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("info basic - path"); - - storageTest->pub.interface.feature ^= 1 << storageFeatureInfoDetail; - - TEST_ASSIGN(info, storageInfoP(storageTest, TEST_PATH_STR), "get path info"); - TEST_RESULT_STR(info.name, NULL, "name is not set"); - TEST_RESULT_BOOL(info.exists, true, "check exists"); - TEST_RESULT_INT(info.type, storageTypePath, "check type"); - TEST_RESULT_UINT(info.size, 0, "check size"); - TEST_RESULT_INT(info.mode, 0, "check mode"); - TEST_RESULT_INT(info.timeModified, 1555160000, "check mod time"); - TEST_RESULT_STR(info.linkDestination, NULL, "no link destination"); - TEST_RESULT_UINT(info.userId, 0, "check user id"); - TEST_RESULT_STR(info.user, NULL, "check user"); - TEST_RESULT_UINT(info.groupId, 0, "check group id"); - TEST_RESULT_STR(info.group, NULL, "check group"); - - storageTest->pub.interface.feature ^= 1 << storageFeatureInfoDetail; - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("info - file"); - // Mimic file chown'd 99999:99999, timestamp 1555155555, containing "TESTFILE" - TEST_ASSIGN(info, storageInfoP(storageTest, fileName), "get file info"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT( + TEST_PATH "/fileinfo", .attr = HRN_LIBSSH2_FILE(0640), .mtime = 1555155555, .uid = 99999, .gid = 99999, + .filesize = 8)); + + TEST_ASSIGN(info, storageInfoP(storageTest, STRDEF(TEST_PATH "/fileinfo")), "get file info"); TEST_RESULT_STR(info.name, NULL, "name is not set"); TEST_RESULT_BOOL(info.exists, true, "check exists"); TEST_RESULT_INT(info.type, storageTypeFile, "check type"); @@ -2528,9 +1427,12 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("info - link"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/testlink", .attr = HRN_LIBSSH2_LINK(0777)), + HRN_LIBSSH2_READLINK(TEST_PATH "/testlink", .target = STRDEF("/tmp"))); + const String *linkName = STRDEF(TEST_PATH "/testlink"); - // Mimic link testlink to /tmp TEST_ASSIGN(info, storageInfoP(storageTest, linkName), "get link info"); TEST_RESULT_STR(info.name, NULL, "name is not set"); TEST_RESULT_BOOL(info.exists, true, "check exists"); @@ -2541,6 +1443,16 @@ testRun(void) TEST_RESULT_STR(info.user, NULL, "check user"); TEST_RESULT_STR(info.group, NULL, "check group"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("info - link, followLink = true"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/testlink", .resultInt = LIBSSH2_ERROR_EAGAIN, .follow = true), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_STAT( + TEST_PATH "/testlink", .follow = true, .attr = HRN_LIBSSH2_DIR(0777), .uid = HRN_LIBSSH2_OWNER_ROOT, + .gid = HRN_LIBSSH2_OWNER_ROOT)); + TEST_ASSIGN(info, storageInfoP(storageTest, linkName, .followLink = true), "get info from path pointed to by link"); TEST_RESULT_STR(info.name, NULL, "name is not set"); TEST_RESULT_BOOL(info.exists, true, "check exists"); @@ -2551,21 +1463,38 @@ testRun(void) TEST_RESULT_STR_Z(info.user, NULL, "check user"); TEST_RESULT_STR_Z(info.group, NULL, "check group"); - // Exercise paths/branches - // libssh2_sftp_stat_ex timeout EAGAIN followLink true - TEST_ERROR_FMT( - storageInfoP(storageTest, linkName, .followLink = true), FileOpenError, "timeout opening '" TEST_PATH "/testlink'"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("info - link, followLink = false, stat timeout EAGAIN"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/testlink", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); - // libssh2_sftp_stat_ex timeout EAGAIN followLink false TEST_ERROR_FMT( storageInfoP(storageTest, linkName, .followLink = false), FileOpenError, "timeout opening '" TEST_PATH "/testlink'"); - // libssh2_sftp_symlink_ex link destination timeout EAGAIN followLink false + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("info - link, followLink = false, symlink destination timeout EAGAIN"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/testlink", .attr = HRN_LIBSSH2_LINK(0777)), + HRN_LIBSSH2_READLINK(TEST_PATH "/testlink", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + TEST_ERROR_FMT( storageInfoP(storageTest, linkName, .followLink = false), FileReadError, "timeout getting destination for link '" TEST_PATH "/testlink'"); - // libssh2_sftp_symlink_ex fail link destination followLink false + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("info - link, followLink = false, symlink destination fail (link loop)"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/testlink", .attr = HRN_LIBSSH2_LINK(0777)), + HRN_LIBSSH2_READLINK(TEST_PATH "/testlink", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_READLINK(TEST_PATH "/testlink", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_LINK_LOOP)); + TEST_ERROR_FMT( storageInfoP(storageTest, linkName, .followLink = false), FileReadError, "unable to get destination for link '" TEST_PATH "/testlink': libssh2 error [-31]: sftp error [21] link loop"); @@ -2573,10 +1502,11 @@ testRun(void) // -------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("info - pipe"); - const String *pipeName = STRDEF(TEST_PATH "/testpipe"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/testpipe", .attr = HRN_LIBSSH2_FIFO(0666)), + HRNLIBSSH2_MACRO_SHUTDOWN()); - // Mimic pipe "/testpipe" with mode 0666 - TEST_ASSIGN(info, storageInfoP(storageTest, pipeName), "get info from pipe (special file)"); + TEST_ASSIGN(info, storageInfoP(storageTest, STRDEF(TEST_PATH "/testpipe")), "get info from pipe (special file)"); TEST_RESULT_STR(info.name, NULL, "name is not set"); TEST_RESULT_BOOL(info.exists, true, "check exists"); TEST_RESULT_INT(info.type, storageTypeSpecial, "check type"); @@ -2586,7 +1516,7 @@ testRun(void) TEST_RESULT_STR(info.user, NULL, "check user"); TEST_RESULT_STR(info.group, NULL, "check group"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + objFree(storageTest); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 @@ -2596,206 +1526,79 @@ testRun(void) if (testBegin("storageNewItrP()")) { #ifdef HAVE_LIBSSH2 - // Mimic creation of /noperm/noperm - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Path missing errorOnMissing true - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Ignore missing dir - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Path no perm - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // Path no perm ignore missing - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // Helper function storageSftpListEntry() - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"pg/missing\",1]", .resultNull = true}, - // Path with only dot - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IWOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IWOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // Path with file, link, pipe, dot dotdot - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IWOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg\",0,0,1]"}, - // readdir returns . - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // readdir returns .. - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".\",4095,null,0]", .fileName = STRDEF(".."), - .resultInt = 8, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // readdir returns .include - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"..\",4095,null,0]", .fileName = STRDEF(".include"), - .resultInt = 8, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/.include\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".include\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, - // readdir returns link - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF("link"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/pg/link\",\"\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .symlinkExTarget = STRDEF("../file")}, - // readdir returns pipe - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"link\",4095,null,0]", .fileName = STRDEF("pipe"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/pipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"pipe\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/.include\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IWOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/pg/link\",\"\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .symlinkExTarget = STRDEF("../file")}, - // Helper function - storageSftpListEntry() info doesn't exist - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"pg/missing\",1]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"pg/missing\",1]", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + StringList *argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "strict"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - // Create storage object for testing - Storage *storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))); + Storage *storageTest = storageSftpHelper(0, false, storageRepoPathExpression); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path missing"); + TEST_TITLE("path missing, errorOnMissing"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/BOGUS", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/BOGUS", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_NONE), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); TEST_ERROR_FMT( storageNewItrP(storageTest, STRDEF(BOGUS_STR), .errorOnMissing = true), PathMissingError, STORAGE_ERROR_LIST_INFO_MISSING, TEST_PATH "/BOGUS"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("path missing, ignore missing dir"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/BOGUS", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_NONE), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + TEST_RESULT_PTR(storageNewItrP(storageTest, STRDEF(BOGUS_STR), .nullOnMissing = true), NULL, "ignore missing dir"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("path no perm"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/noperm", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); + TEST_ERROR_FMT( storageNewItrP(storageTest, pathNoPerm, .errorOnMissing = true), PathOpenError, STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathNoPerm)); - // Should still error even when ignore missing + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("path no perm, ignore missing"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/noperm", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); + TEST_ERROR_FMT( storageNewItrP(storageTest, pathNoPerm), PathOpenError, STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathNoPerm)); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("helper function - storageSftpListEntry()"); - - TEST_RESULT_VOID( - storageSftpListEntry( - (StorageSftp *)storageDriver(storageTest), storageLstNew(storageInfoLevelBasic), STRDEF("pg"), "missing", - storageInfoLevelBasic), - "missing path"); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path with only dot"); - // Mimic creation of TEST_PATH "/pg" mode 0766 + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0766), .mtime = 1555160000), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0766), .mtime = 1555160000)); // NOTE: if operating against an actual sftp server, a neutral umask is required to get the proper permissions. // Without the neutral umask, permissions were 0764. @@ -2807,10 +1610,40 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path with file, link, pipe"); - // Mimic creation of TEST_PATH "/pg/.include" mode 0755 chown'd 77777:77777 - // Mimic creation of TEST_PATH "pg/file" mode 0660 timemodified 1656433838 containing "TESTDATA" - // Mimic creation of TEST_PATH "/pg/link" linked to "../file" - // Mimic creation of TEST_PATH "/pg/pipe" mode 777 + HRN_LIBSSH2_SCRIPT_SET( + // Path with file, link, pipe, dot dotdot + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0766), .mtime = 1555160000), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg"), + // readdir returns . + HRN_LIBSSH2_READDIR("."), + // readdir returns .. + HRN_LIBSSH2_READDIR(".."), + // readdir returns .include + HRN_LIBSSH2_READDIR(".include"), + HRN_LIBSSH2_STAT( + TEST_PATH "/pg/.include", .attr = HRN_LIBSSH2_DIR(0755), .mtime = 1555160000, .uid = 77777, .gid = 77777), + // readdir returns file + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656433838, .filesize = 8), + // readdir returns link + HRN_LIBSSH2_READDIR("link"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), + HRN_LIBSSH2_READLINK(TEST_PATH "/pg/link", .target = STRDEF("../file")), + // readdir returns pipe + HRN_LIBSSH2_READDIR("pipe"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/pipe", .attr = HRN_LIBSSH2_FIFO(0764), .mtime = 1656433838), + // readdir returns empty + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + // readdir returns empty + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/.include"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + // link stat + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0766), .mtime = 1555160000), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), + HRN_LIBSSH2_READLINK(TEST_PATH "/pg/link", .target = STRDEF("../file"))); + TEST_STORAGE_LIST( storageTest, "pg", "./ {u=" TEST_USER_ID_Z ", g=" TEST_GROUP_ID_Z ", m=0766}\n" @@ -2823,205 +1656,81 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("helper function - storageSftpListEntry() info doesn't exist"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT("pg/missing", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_STAT("pg/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + TEST_RESULT_VOID( storageSftpListEntry( (StorageSftp *)storageDriver(storageTest), storageLstNew(storageInfoLevelBasic), STRDEF("pg"), "missing", storageInfoLevelBasic), "missing path"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageItrMore() twice in a row"); StorageIterator *storageItr = NULL; - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".\",4095,null,0]", .fileName = STRDEF(".include"), - .resultInt = 8, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/.include\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg"), + HRN_LIBSSH2_READDIR("."), + HRN_LIBSSH2_READDIR(".include"), + HRN_LIBSSH2_STAT( + TEST_PATH "/pg/.include", .attr = HRN_LIBSSH2_DIR(0755), .mtime = 1555160000, .uid = 77777, .gid = 77777), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".include\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656433838, .filesize = 8), // readdir returns link - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF("link"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/pg/link\",\"\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .symlinkExTarget = STRDEF("../file")}, + HRN_LIBSSH2_READDIR("link"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), + HRN_LIBSSH2_READLINK(TEST_PATH "/pg/link", .target = STRDEF("../file")), // readdir returns pipe - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"link\",4095,null,0]", .fileName = STRDEF("pipe"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/pipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("pipe"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/pipe", .attr = HRN_LIBSSH2_FIFO(0764), .mtime = 1656433838), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"pipe\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE()); // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))); - TEST_ASSIGN(storageItr, storageNewItrP(storageTest, STRDEF("pg")), "new iterator"); TEST_RESULT_BOOL(storageItrMore(storageItr), true, "check more"); TEST_RESULT_BOOL(storageItrMore(storageItr), true, "check more again"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path - recurse desc"); - // Mimic creation of "pg/path" mode 0700 - // Mimic creation of "pg/path/file" mode 0600 timemodified 1656434296 containing "TESTDATA" - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".\",4095,null,0]", .fileName = STRDEF("path"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1555160000), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg"), + HRN_LIBSSH2_READDIR("."), + HRN_LIBSSH2_READDIR("path"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/path", .attr = HRN_LIBSSH2_DIR(0755), .mtime = 1555160000, .uid = 77777, .gid = 77777), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"path\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656433838, .filesize = 8), // readdir returns link - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF("link"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, + HRN_LIBSSH2_READDIR("link"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), // readdir returns pipe - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"link\",4095,null,0]", .fileName = STRDEF("pipe"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/pipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("pipe"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/pipe", .attr = HRN_LIBSSH2_FIFO(0764), .mtime = 1656433838), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"pipe\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse readdir path - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/path\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/path"), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/path/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656434296, .filesize = 8), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/pg/link\",\"\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .symlinkExTarget = STRDEF("../file")}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))); + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + // link stat + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1555160000), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), + HRN_LIBSSH2_READLINK(TEST_PATH "/pg/link", .target = STRDEF("../file"))); TEST_STORAGE_LIST( storageTest, "pg", @@ -3033,156 +1742,61 @@ testRun(void) "./\n", .level = storageInfoLevelBasic, .includeDot = true, .sortOrder = sortOrderDesc); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path - recurse asc"); // Create a path with a subpath that will always be last to make sure lists are not freed too early in the iterator // Mimic creation of "pg/zzz/yyy" mode 0700 - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg\",0,0,1]"}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1555160000), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg"), // readdir returns dot - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("."), // readdir returns path - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".\",4095,null,0]", .fileName = STRDEF("path"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, + HRN_LIBSSH2_READDIR("path"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/path", .attr = HRN_LIBSSH2_DIR(0755), .mtime = 1555160000, .uid = 77777, .gid = 77777), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"path\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656433838, .filesize = 8), // readdir returns link - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF("link"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, + HRN_LIBSSH2_READDIR("link"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), // readdir returns pipe - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"link\",4095,null,0]", .fileName = STRDEF("pipe"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/pipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("pipe"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/pipe", .attr = HRN_LIBSSH2_FIFO(0764), .mtime = 1656433838), // readdir returns zzz - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"pipe\",4095,null,0]", .fileName = STRDEF("zzz"), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/zzz\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("zzz"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/zzz", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1656433838), // readdir return empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"zzz\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse readdir path - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/path\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/path"), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/path/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656434296, .filesize = 8), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse zzz - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/zzz\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/zzz"), // readdir returns yyy - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("yyy"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/zzz/yyy\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("yyy"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/zzz/yyy", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1656433838), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"yyy\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse yyy - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/zzz/yyy\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/zzz/yyy"), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/pg/link\",\"\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .symlinkExTarget = STRDEF("../file")}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + // link stat + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1555160000), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), + HRN_LIBSSH2_READLINK(TEST_PATH "/pg/link", .target = STRDEF("../file"))); // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))); - TEST_STORAGE_LIST( storageTest, "pg", "./\n" @@ -3195,465 +1809,118 @@ testRun(void) "zzz/yyy/\n", .level = storageInfoLevelBasic, .includeDot = true); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path basic info - recurse"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg\",0,0,1]"}, - // readdir returns dot - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // readdir returns path - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".\",4095,null,0]", .fileName = STRDEF("path"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"path\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, - // readdir returns link - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF("link"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, - // readdir returns pipe - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"link\",4095,null,0]", .fileName = STRDEF("pipe"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/pipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // readdir returns zzz - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"pipe\",4095,null,0]", .fileName = STRDEF("zzz"), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/zzz\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // readdir return empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"zzz\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - // Recurse zzz - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/zzz\",0,0,1]"}, - // readdir returns yyy - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("yyy"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/zzz/yyy\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"yyy\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - // Recurse yyy - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/zzz/yyy\",0,0,1]"}, - // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - // Recurse path - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/path\",0,0,1]"}, - // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, - // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, - {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/pg/link\",\"\",1]", - .resultInt = LIBSSH2_ERROR_NONE, .symlinkExTarget = STRDEF("../file")}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))); - - storageTest->pub.interface.feature ^= 1 << storageFeatureInfoDetail; - - TEST_STORAGE_LIST( - storageTest, "pg", - "zzz/yyy/\n" - "zzz/\n" - "pipe*\n" - "path/file {s=8, t=1656434296}\n" - "path/\n" - "link> {d=../file}\n" - "file {s=8, t=1656433838}\n" - "./\n", - .levelForce = true, .includeDot = true, .sortOrder = sortOrderDesc); - - storageTest->pub.interface.feature ^= 1 << storageFeatureInfoDetail; - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("empty path - filter"); // Mimic "pg/empty" mode 0700 - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg\",0,0,1]"}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1555160000), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg"), // readdir returns dot - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("."), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".\",4095,null,0]", .fileName = STRDEF("empty"), - .resultInt = 5, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/empty\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, + HRN_LIBSSH2_READDIR("empty"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/empty", .attr = HRN_LIBSSH2_DIR(0755), .mtime = 1555160000, .uid = 77777, .gid = 77777), // readdir returns path - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"empty\",4095,null,0]", .fileName = STRDEF("path"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, + HRN_LIBSSH2_READDIR("path"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/path", .attr = HRN_LIBSSH2_DIR(0755), .mtime = 1555160000, .uid = 77777, .gid = 77777), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"path\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656433838, .filesize = 8), // readdir returns link - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF("link"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, + HRN_LIBSSH2_READDIR("link"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), // readdir returns pipe - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"link\",4095,null,0]", .fileName = STRDEF("pipe"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/pipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("pipe"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/pipe", .attr = HRN_LIBSSH2_FIFO(0764), .mtime = 1656433838), // readdir returns zzz - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"pipe\",4095,null,0]", .fileName = STRDEF("zzz"), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/zzz\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("zzz"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/zzz", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1656433838), // readdir return empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"zzz\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse empty - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/empty\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/empty"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse path - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/path\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/path"), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/path/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656434296, .filesize = 8), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse zzz - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/zzz\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/zzz"), // readdir returns yyy - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("yyy"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/zzz/yyy\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("yyy"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/zzz/yyy", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1656433838), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"yyy\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse yyy - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/zzz/yyy\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/zzz/yyy"), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE()); // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))); - TEST_STORAGE_LIST( storageTest, "pg", "empty/\n", .level = storageInfoLevelType, .expression = "^empty"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("filter in subpath during recursion"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg\",0,0,1]"}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_STAT(TEST_PATH "/pg", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1555160000), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg"), // readdir returns dot - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("."), // readdir returns path - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".\",4095,null,0]", .fileName = STRDEF("path"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP | - LIBSSH2_SFTP_S_IROTH | LIBSSH2_SFTP_S_IXOTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = 77777, .gid = 77777}, + HRN_LIBSSH2_READDIR("path"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/path", .attr = HRN_LIBSSH2_DIR(0755), .mtime = 1555160000, .uid = 77777, .gid = 77777), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"path\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656433838, .filesize = 8), // readdir returns link - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF("link"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/link\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFLNK | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .symlinkExTarget = STRDEF("../file")}, + HRN_LIBSSH2_READDIR("link"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/link", .attr = HRN_LIBSSH2_LINK(0764), .mtime = 1656433838), // readdir returns pipe - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"link\",4095,null,0]", .fileName = STRDEF("pipe"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/pipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("pipe"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/pipe", .attr = HRN_LIBSSH2_FIFO(0764), .mtime = 1656433838), // readdir returns zzz - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"pipe\",4095,null,0]", .fileName = STRDEF("zzz"), - .resultInt = 3, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/zzz\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("zzz"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/zzz", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1656433838), // readdir return empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"zzz\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse path - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/path\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/path"), // readdir returns file - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("file"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/path/file\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IWGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID, .filesize = 8}, + HRN_LIBSSH2_READDIR("file"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/path/file", .attr = HRN_LIBSSH2_FILE(0660), .mtime = 1656434296, .filesize = 8), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"file\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse zzz - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/zzz\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/zzz"), // readdir returns yyy - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("yyy"), - .resultInt = 4, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/pg/zzz/yyy\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IWGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_READDIR("yyy"), + HRN_LIBSSH2_STAT(TEST_PATH "/pg/zzz/yyy", .attr = HRN_LIBSSH2_DIR(0764), .mtime = 1656433838), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"yyy\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656433838, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), // Recurse yyy - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/pg/zzz/yyy\",0,0,1]"}, + HRN_LIBSSH2_OPENDIR(TEST_PATH "/pg/zzz/yyy"), // readdir returns empty - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRNLIBSSH2_MACRO_SHUTDOWN()); // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))); - TEST_STORAGE_LIST( storageTest, "pg", "path/file {s=8, t=1656434296}\n", @@ -3670,179 +1937,93 @@ testRun(void) { #ifdef HAVE_LIBSSH2 // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path missing"); + TEST_TITLE("path missing, errorOnMissing"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Empty list - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Timeout on sftp_open_ex - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",0,0,1]", .resultNull = true, - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",0,0,1]", .resultNull = true, - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - // Error on missing, regardless of errorOnMissing setting - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // Ignore missing - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - // Create storage object for testing - Storage *storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))); + const Storage *storageTest = storageRepoWrite(); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/BOGUS", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_NONE), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); TEST_ERROR_FMT( storageListP(storageTest, STRDEF(BOGUS_STR), .errorOnMissing = true), PathMissingError, STORAGE_ERROR_LIST_INFO_MISSING, TEST_PATH "/BOGUS"); - TEST_RESULT_PTR(storageListP(storageTest, STRDEF(BOGUS_STR), .nullOnMissing = true), NULL, "null for missing dir"); - TEST_RESULT_UINT(strLstSize(storageListP(storageTest, STRDEF(BOGUS_STR))), 0, "empty list for missing dir"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("path missing, timeout on sftp_open_ex"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/BOGUS", .resultNull = true, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/BOGUS", .resultNull = true, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN)); - // Timeout on sftp_open_ex TEST_ERROR_FMT( storageListP(storageTest, STRDEF(BOGUS_STR), .errorOnMissing = true), FileReadError, "timeout opening directory '" TEST_PATH "/BOGUS'"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("error on missing, regardless of errorOnMissing setting"); + TEST_TITLE("error on missing, ignore missing"); - TEST_ERROR_FMT( - storageListP(storageTest, pathNoPerm, .errorOnMissing = true), PathOpenError, - STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathNoPerm)); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/noperm", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); // Should still error even when ignore missing TEST_ERROR_FMT( storageListP(storageTest, pathNoPerm), PathOpenError, STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathNoPerm)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("list - path with files"); ioBufferSizeSet(65536); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // storagePutP(storageNewWriteP()) - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/.aaa.txt.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[14]", .resultInt = 14}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, .resultInt = LIBSSH2_ERROR_EAGAIN, - .param = "[\"" TEST_PATH "/.aaa.txt.pgbackrest.tmp\",\"" TEST_PATH "/.aaa.txt\",7]"}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL, - .param = "[\"" TEST_PATH "/.aaa.txt.pgbackrest.tmp\",\"" TEST_PATH "/.aaa.txt\",7]"}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/.aaa.txt\"]", .resultUInt = LIBSSH2_FX_OK}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, .resultInt = LIBSSH2_ERROR_NONE, - .param = "[\"" TEST_PATH "/.aaa.txt.pgbackrest.tmp\",\"" TEST_PATH "/.aaa.txt\",7]"}, - // strListSort(storageListP()) - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(".aaa.txt"), - .resultInt = 8, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\".aaa.txt\",4095,null,0]", .fileName = STRDEF("noperm"), - .resultInt = 6, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"noperm\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - // bbb.txt - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/bbb.txt.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[7]", .resultInt = 7}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/bbb.txt.pgbackrest.tmp\",\"" TEST_PATH "/bbb.txt\",7]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("bbb.txt"), - .resultInt = 7, .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"bbb.txt\",4095,null,0]", .fileName = STRDEF("noperm"), - .resultInt = 6, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"noperm\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - // Path with only dot, readdir timeout EAGAIN - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .resultInt = LIBSSH2_ERROR_EAGAIN, .param = "[\"\",4095,null,0]"}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .resultInt = LIBSSH2_ERROR_EAGAIN, .param = "[\"\",4095,null,0]"}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - // Fail to close path after listing timeout EAGAIN - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - // Fail to close path after listing - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("."), - .resultInt = LIBSSH2_ERROR_NONE, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_SOCKET_RECV}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - // Create storage object for testing - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + HRN_LIBSSH2_SCRIPT_SET( + // Write aaa.txt + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/.aaa.txt.pgbackrest.tmp"), + HRN_LIBSSH2_WRITE(14), + HRN_LIBSSH2_FSYNC(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME(TEST_PATH "/.aaa.txt.pgbackrest.tmp", TEST_PATH "/.aaa.txt", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/.aaa.txt.pgbackrest.tmp", TEST_PATH "/.aaa.txt", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_UNLINK(TEST_PATH "/.aaa.txt"), + HRN_LIBSSH2_RENAME(TEST_PATH "/.aaa.txt.pgbackrest.tmp", TEST_PATH "/.aaa.txt"), + // read dir + HRN_LIBSSH2_OPENDIR(TEST_PATH), + HRN_LIBSSH2_READDIR(".aaa.txt"), + HRN_LIBSSH2_READDIR("noperm"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + // write bbb.txt + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/bbb.txt.pgbackrest.tmp"), + HRN_LIBSSH2_WRITE(7), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME(TEST_PATH "/bbb.txt.pgbackrest.tmp", TEST_PATH "/bbb.txt"), + // read dir + HRN_LIBSSH2_OPENDIR(TEST_PATH), + HRN_LIBSSH2_READDIR("bbb.txt"), + HRN_LIBSSH2_READDIR("noperm"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_CLOSE()); TEST_RESULT_VOID( storagePutP(storageNewWriteP(storageTest, STRDEF(".aaa.txt")), BUFSTRDEF("aaaaaaaaaaaaaa")), "write aaa.text"); @@ -3854,11 +2035,25 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpList() readdir EAGAIN timeout"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH), + HRN_LIBSSH2_READDIR("", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_READDIR("", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRN_LIBSSH2_CLOSE()); + TEST_RESULT_VOID(storageListP(storageTest, NULL, .errorOnMissing = true), "storageSftpList readdir EAGAIN timeout"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpList() fail to close path after listing EAGAIN timeout"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + TEST_ERROR_FMT( storageListP(storageTest, NULL, .errorOnMissing = true), PathCloseError, "timeout closing path '" TEST_PATH "' after listing"); @@ -3866,134 +2061,18 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpList() fail to close path after listing"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_SOCKET_RECV), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE), + HRNLIBSSH2_MACRO_SHUTDOWN()); + TEST_ERROR_FMT( storageListP(storageTest, NULL, .errorOnMissing = true), PathCloseError, "unable to close path '" TEST_PATH "' after listing: libssh2 error [-43]"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); -#else - TEST_LOG(PROJECT_NAME " not built with sftp support"); -#endif // HAVE_LIBSSH2 - } - - // ***************************************************************************************************************************** - if (testBegin("storagePath()")) - { -#ifdef HAVE_LIBSSH2 - Storage *storageTest = NULL; - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path - root path"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); - hrnCfgArgRawZ(argList, cfgOptRepoPath, strZ(FSLASH_STR)); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "strict"); - HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), - "new storage /"); - TEST_RESULT_STR_Z(storagePathP(storageTest, NULL), "/", "root dir"); - TEST_RESULT_STR_Z(storagePathP(storageTest, STRDEF("/")), "/", "same as root dir"); - TEST_RESULT_STR_Z(storagePathP(storageTest, STRDEF("subdir")), "/subdir", "simple subdir"); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path - expressions"); - - TEST_ERROR( - storagePathP(storageTest, STRDEF("")), AssertError, "expression '' not valid without callback function"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); - hrnCfgArgRawZ(argList, cfgOptRepoPath, "/path/to"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "strict"); - HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), - .pathExpressionFunction = storageTestPathExpression), - "new storage /path/to"); - TEST_RESULT_STR_Z(storagePathP(storageTest, NULL), "/path/to", "root dir"); - TEST_RESULT_STR_Z(storagePathP(storageTest, STRDEF("/path/to")), "/path/to", "absolute root dir"); - TEST_RESULT_STR_Z(storagePathP(storageTest, STRDEF("is/a/subdir")), "/path/to/is/a/subdir", "subdir"); - - TEST_ERROR( - storagePathP(storageTest, STRDEF("/bogus")), AssertError, "absolute path '/bogus' is not in base path '/path/to'"); - TEST_ERROR( - storagePathP(storageTest, STRDEF("/path/toot")), AssertError, - "absolute path '/path/toot' is not in base path '/path/to'"); - - // Path enforcement disabled for a single call - TEST_RESULT_STR_Z(storagePathP(storageTest, STRDEF("/bogus"), .noEnforce = true), "/bogus", "path enforce disabled"); - - TEST_ERROR(storagePathP(storageTest, STRDEF(" not found in path expression '" BOGUS_STR)), AssertError, - "'/' should separate expression and path 'BOGUS'"); - - TEST_RESULT_STR_Z(storagePathP(storageTest, STRDEF("")), "/path/to/test", "expression"); - TEST_ERROR(strZ(storagePathP(storageTest, STRDEF("/"))), AssertError, "path '/' should not end in '/'"); - - TEST_RESULT_STR_Z( - storagePathP(storageTest, STRDEF("/something")), "/path/to/test/something", "expression with path"); - - TEST_ERROR(storagePathP(storageTest, STRDEF("")), AssertError, "evaluated path '' cannot be null"); - - TEST_ERROR(storagePathP(storageTest, STRDEF("")), AssertError, "invalid expression ''"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 @@ -4003,196 +2082,170 @@ testRun(void) if (testBegin("storagePathCreate()")) { #ifdef HAVE_LIBSSH2 - Storage *storageTest = NULL; + const Storage *storageTest; - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Create /sub1 - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub1\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // create /sub1 again fails mkdir_ex ssh error - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", - .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - // create /sub1 again no error on file already exists, file already exists - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub1\",0]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub1\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // create /sub1 again fails stat_ex, file doesn't already exist - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub1\",0]", .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - // create /sub1 again fail timeout EAGAIN on stat_ex - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub1\",0]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - // create /sub1 again fail with .errorOnExists, file already exists - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub1\",0]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - // sub2 custom mode - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub2\",511]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub2\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG | LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // sub3/sub4 .noParentCreate fail - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub3/sub4\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // sub3/sub4 success - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub3/sub4\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub3\",488]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub3/sub4\",488]", - .resultInt = LIBSSH2_ERROR_NONE}, - // subfail EAGAIN timeout - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/subfail\",488]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/subfail\",488]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + StringList *argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage /"); + TEST_ASSIGN(storageTest, storageRepoWrite(), "new storage /"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("create /sub1"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_STAT(TEST_PATH "/sub1", .attr = HRN_LIBSSH2_DIR(0750), .mtime = 1656434296)); + TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1"); TEST_RESULT_INT(storageInfoP(storageTest, STRDEF("sub1")).mode, 0750, "check sub1 dir mode"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("create /sub1 again fails mkdir_ex ssh error"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1", .resultInt = LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); + TEST_ERROR( storagePathCreateP(storageTest, STRDEF("sub1")), PathCreateError, "ssh2 error [-7] unable to create path '" TEST_PATH "/sub1': libssh2 error [-7]"); - TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1 again no .errorOnExists fail EAGAIN"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("create /sub1 again no error on path already exists"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_STAT(TEST_PATH "/sub1", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_STAT(TEST_PATH "/sub1", .attr = HRN_LIBSSH2_DIR(0750), .mtime = 1656434296)); + + TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1 again"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("create /sub1 again fails stat_ex, path doesn't already exist"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_STAT(TEST_PATH "/sub1", .resultInt = LIBSSH2_ERROR_SOCKET_SEND)); + TEST_RESULT_VOID( - storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1 again no .errorOnExists fail other than EAGAIN"); + storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1 again"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("create /sub1 again fail timeout EAGAIN on stat_ex"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_STAT(TEST_PATH "/sub1", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + TEST_ERROR(storagePathCreateP(storageTest, STRDEF("sub1")), PathCreateError, "timeout stat'ing path '" TEST_PATH "/sub1'"); - TEST_ERROR( - storagePathCreateP(storageTest, STRDEF("sub1"), .errorOnExists = true), PathCreateError, - "sftp error unable to create path '" TEST_PATH "/sub1': path already exists"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("sub2 custom mode"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub2", .mode = 0777), + HRN_LIBSSH2_STAT(TEST_PATH "/sub2", .attr = HRN_LIBSSH2_DIR(0777), .mtime = 1656434296)); // NOTE: if operating against an actual sftp server, a neutral umask is required to get the proper permissions. // Without the neutral umask, permissions were 0775. TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub2"), .mode = 0777), "create sub2 with custom mode"); TEST_RESULT_INT(storageInfoP(storageTest, STRDEF("sub2")).mode, 0777, "check sub2 dir mode"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("sub3/sub4 .noParentCreate fail"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub3/sub4", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + TEST_ERROR( storagePathCreateP(storageTest, STRDEF("sub3/sub4"), .noParentCreate = true), PathCreateError, "sftp error unable to create path '" TEST_PATH "/sub3/sub4': libssh2 error [-31]: sftp error [2] no such file"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("sub3/sub4 success"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub3/sub4", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub3"), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub3/sub4")); + TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub3/sub4")), "create sub3/sub4"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("subfail EAGAIN timeout"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/subfail", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_MKDIR(TEST_PATH "/subfail", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + // LIBSSH2_ERROR_EAGAIN timeout fail TEST_ERROR( storagePathCreateP(storageTest, STRDEF("subfail")), PathCreateError, "timeout creating path '" TEST_PATH "/subfail'"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path create, timeout success on stat"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), + HRN_LIBSSH2_SCRIPT_SET( // Timeout success - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/subfail\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/subfail\",0]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/subfail\",0]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/subfail\",0]", .resultInt = LIBSSH2_ERROR_NONE}, - // Error other than no such file && no parent create LIBSSH2_FX_PERMISSION_DENIED} - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/subfail\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // No error on already exists - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/subfail\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FILE_ALREADY_EXISTS}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/subfail\",0]", .resultInt = LIBSSH2_ERROR_NONE}, - // Error on already exists - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/subfail\",488]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FILE_ALREADY_EXISTS}, - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/subfail\",0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FILE_ALREADY_EXISTS}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_MKDIR(TEST_PATH "/subfail", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_STAT(TEST_PATH "/subfail", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_STAT(TEST_PATH "/subfail", .flags = HRN_LIBSSH2_ATTR_EXISTENCE)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage /"); TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("subfail")), "timeout success"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("error other than no such file, no parent create"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/subfail", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); + TEST_ERROR( storagePathCreateP(storageTest, STRDEF("subfail"), .noParentCreate = true), PathCreateError, "sftp error unable to create path '" TEST_PATH "/subfail': libssh2 error [-31]: sftp error [3] permission denied"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("no error on already exists"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/subfail", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FILE_ALREADY_EXISTS), + HRN_LIBSSH2_STAT(TEST_PATH "/subfail", .flags = HRN_LIBSSH2_ATTR_EXISTENCE)); + TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("subfail")), "do not throw error on already exists"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("error on already exists"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_MKDIR(TEST_PATH "/subfail", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FILE_ALREADY_EXISTS), + HRN_LIBSSH2_STAT(TEST_PATH "/subfail", .flags = HRN_LIBSSH2_ATTR_EXISTENCE), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FILE_ALREADY_EXISTS), + HRNLIBSSH2_MACRO_SHUTDOWN()); + TEST_ERROR( storagePathCreateP(storageTest, STRDEF("subfail"), .errorOnExists = true), PathCreateError, "sftp error unable to create path '" TEST_PATH "/subfail': path already exists"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 @@ -4202,207 +2255,56 @@ testRun(void) if (testBegin("storagePathRemove()")) { #ifdef HAVE_LIBSSH2 - Storage *storageTest = NULL; + const Storage *storageTest = NULL; - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Path remove missing errorOnMissing - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Recurse - ignore missing path - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Recurse parent/subpath permission denied - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // Recurse subpath permission denied - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1/remove2\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1/remove2\",0,0,1]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // Path remove - file in subpath, permission denied - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("remove2"), - .resultInt = 7, .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove2\",4095,null,0]", .fileName = STRDEF("remove.txt"), - .resultInt = 10, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove.txt\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1/remove2\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("remove.txt"), - .resultInt = 10, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG | LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove.txt\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2/remove.txt\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1/remove2/remove.txt\",0,0,1]", - .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1/remove2/remove.txt\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // Path remove - path with subpath and file removed - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("remove2"), .resultInt = 7, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG| LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove2\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1/remove2\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("remove.txt"), - .resultInt = 10, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG | LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove.txt\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2/remove.txt\"]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", .resultInt = LIBSSH2_ERROR_NONE}, - // Path remove - path with subpath ssh fail on libssh2_sftp_unlink_ex - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("remove2"), .resultInt = 7, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG| LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove2\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - // unlink SFTP failure other than LIBSSH2_FX_FAILURE / LIBSSH2_FX_PERMISSION_DENIED - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("remove2"), .resultInt = 7, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG| LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove2\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST}, + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + StringList *argList = strLstDup(argCommonList); + hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); + HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage /"); + TEST_ASSIGN(storageTest, storageRepoWrite(), "new storage /"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path remove - missing"); + TEST_TITLE("path remove - missing, errorOnMissing"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); const String *pathRemove1 = STRDEF(TEST_PATH "/remove1"); TEST_ERROR_FMT( storagePathRemoveP(storageTest, pathRemove1, .errorOnMissing = true), PathRemoveError, STORAGE_ERROR_PATH_REMOVE_MISSING, strZ(pathRemove1)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("path remove - missing, recurse ignores missing"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + TEST_RESULT_VOID(storagePathRemoveP(storageTest, pathRemove1, .recurse = true), "ignore missing path"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path remove - parent/subpath permission denied"); + TEST_TITLE("path remove - recurse subpath permission denied"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1/remove2", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); String *pathRemove2 = strNewFmt("%s/remove2", strZ(pathRemove1)); - // Mimic creation of pathRemove2 mode 700 - TEST_ERROR_FMT( - storagePathRemoveP(storageTest, pathRemove2), PathRemoveError, - STORAGE_ERROR_PATH_REMOVE " sftp error [3] permission denied", strZ(pathRemove2)); - TEST_ERROR_FMT( - storagePathRemoveP(storageTest, pathRemove2, .recurse = true), PathOpenError, - STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathRemove2)); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path remove - subpath permission denied"); - - // Mimic chmod 777 pathRemove1 TEST_ERROR_FMT( storagePathRemoveP(storageTest, pathRemove2, .recurse = true), PathOpenError, STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathRemove2)); @@ -4410,9 +2312,33 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path remove - file in subpath, permission denied"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1"), + HRN_LIBSSH2_READDIR("remove2"), + HRN_LIBSSH2_READDIR("remove.txt"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1/remove2"), + HRN_LIBSSH2_READDIR("remove.txt"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2/remove.txt", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1/remove2/remove.txt", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1/remove2/remove.txt", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1/remove2", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); + String *fileRemove = strNewFmt("%s/remove.txt", strZ(pathRemove2)); - // Mimic "sudo chmod 755 %s && sudo touch %s && sudo chmod 777 %s", strZ(pathRemove2), strZ(fileRemove), strZ(fileRemove)); TEST_ERROR_FMT( storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError, STORAGE_ERROR_PATH_REMOVE " sftp error [3] permission denied", strZ(pathRemove2)); @@ -4420,12 +2346,37 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path remove - path with subpath and file removed"); - // Mimic chmod 777 pathRemove2 + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1"), + HRN_LIBSSH2_READDIR("remove2"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1/remove2"), + HRN_LIBSSH2_READDIR("remove.txt"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2/remove.txt"), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1/remove2", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1/remove2"), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1")); + TEST_RESULT_VOID(storagePathRemoveP(storageTest, pathRemove1, .recurse = true), "remove path"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path remove - path with subpath ssh fail on unlink"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1"), + HRN_LIBSSH2_READDIR("remove2"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2", .resultInt = LIBSSH2_ERROR_SOCKET_SEND)); + TEST_ERROR_FMT( storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError, STORAGE_ERROR_PATH_REMOVE_FILE " libssh ssh [-7]", strZ(pathRemove2)); @@ -4433,2047 +2384,71 @@ testRun(void) // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path remove - other than LIBSSH2_FX_FAILURE/LIBSSH2_FX_PERMISSION_DENIED"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1"), + HRN_LIBSSH2_READDIR("remove2"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_CONNECTION_LOST)); + TEST_ERROR_FMT( storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError, STORAGE_ERROR_PATH_REMOVE_FILE " libssh sftp [7] connection lost", strZ(pathRemove2)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path remove - unlink LIBSSH2_ERROR_EAGAIN timeout"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("remove2"), .resultInt = 7, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG| LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove2\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1/remove2\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF("remove.txt"), - .resultInt = 10, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG | LIBSSH2_SFTP_S_IRWXO, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"remove.txt\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | - LIBSSH2_SFTP_S_IROTH, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = 0, .gid = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2/remove.txt\"]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove1/remove2/remove.txt\"]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1"), + HRN_LIBSSH2_READDIR("remove2"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1/remove2"), + HRN_LIBSSH2_READDIR("remove.txt"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2/remove.txt", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove1/remove2/remove.txt", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage /"); TEST_ERROR_FMT( storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError, "timeout removing file '%s'", strZ(fileRemove)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path remove - rmdir LIBSSH2_ERROR_EAGAIN timeout"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage /"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + TEST_ERROR_FMT( storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError, "timeout removing path '%s'", strZ(pathRemove1)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("path remove - rmdir ssh error"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/remove1\",0,0,1]"}, - {.function = HRNLIBSSH2_SFTP_READDIR_EX, .param = "[\"\",4095,null,0]", .fileName = STRDEF(""), - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage /"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPENDIR(TEST_PATH "/remove1"), + HRN_LIBSSH2_READDIR(""), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RMDIR(TEST_PATH "/remove1", .resultInt = LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE), + HRNLIBSSH2_MACRO_SHUTDOWN()); + TEST_ERROR_FMT( storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError, "unable to remove path '%s': libssh2 error [-7]", strZ(pathRemove1)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); -#else - TEST_LOG(PROJECT_NAME " not built with sftp support"); -#endif // HAVE_LIBSSH2 - } - - // ***************************************************************************************************************************** - if (testBegin("storageNewRead()")) - { -#ifdef HAVE_LIBSSH2 - Storage *storageTest = NULL; - StorageRead *file = NULL; - const String *fileName = STRDEF(TEST_PATH "/readtest.txt"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Missing sftp error no such file - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Timeout EAGAIN - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_WRITING}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - // Error not sftp, not EAGAIN - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_METHOD_NOT_SUPPORTED}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_METHOD_NOT_SUPPORTED}, - // Read success - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage /"); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("read missing"); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - - // Missing no such file - TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(fileName)); - - // Missing EAGAIN timeout - TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN ": libssh2 error [-37]", strZ(fileName)); - - // Missing not sftp, not EAGAIN - TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(fileName)); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("read success"); - - // Mimic creation of TEST_PATH "/readtest.txt" - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - TEST_RESULT_INT(ioReadFd(storageReadIo(file)), -1, "check read fd"); - TEST_RESULT_VOID(ioReadClose(storageReadIo(file)), "close file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); -#else - TEST_LOG(PROJECT_NAME " not built with sftp support"); -#endif // HAVE_LIBSSH2 - } - - // ***************************************************************************************************************************** - if (testBegin("storageReadClose()")) - { -#ifdef HAVE_LIBSSH2 - // ------------------------------------------------------------------------------------------------------------------------ - TEST_TITLE("close success via storageReadSftpClose()"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // storageReadSftpClose - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - // close(ioSessionFd()...) - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - Storage *storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - StorageRead *file = NULL; - const String *fileName = STRDEF(TEST_PATH "/readtest.txt"); - - // Mimic creation of fileName - Buffer *outBuffer = bufNew(2); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - TEST_RESULT_VOID(storageReadSftpClose((StorageReadSftp *)file->driver), "close file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------ - TEST_TITLE("close success via close()"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // close(ioSessionFd()...) - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - close(ioSessionFd(((StorageReadSftp *)file->driver)->storage->ioSession)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------ - TEST_TITLE("close, null sftpHandle"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // storageReadSftpClose null sftpHandle - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - ((StorageReadSftp *)file->driver)->sftpHandle = NULL; - TEST_RESULT_VOID(storageReadSftpClose(file->driver), "close file null sftpHandle"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------ - TEST_TITLE("close fail via storageReadSftpClose() EAGAIN"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // storageReadSftpClose - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - // close(ioSessionFd()...) - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - TEST_ERROR( - storageReadSftpClose(file->driver), FileCloseError, - "timeout closing file '" TEST_PATH "/readtest.txt': libssh2 error [-37]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------ - TEST_TITLE("close fail via storageReadSftpClose() sftp error"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // storageReadSftpClose - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - TEST_ERROR( - storageReadSftpClose(file->driver), FileCloseError, - "unable to close file '" TEST_PATH "/readtest.txt' after read: libssh2 errno [-31]: sftp errno [4]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------ - TEST_TITLE("close fail via storageReadSftpClose() ssh error"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // storageReadSftpClose - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_ZLIB}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - TEST_ERROR( - storageReadSftpClose(file->driver), FileCloseError, - "unable to close file '" TEST_PATH "/readtest.txt' after read: libssh2 errno [-29]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------ - TEST_TITLE("storageReadSftp() sftp error"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // storageReadSftpClose - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - TEST_ERROR( - storageReadSftp(file->driver, outBuffer, false), FileReadError, - "unable to read '" TEST_PATH "/readtest.txt': sftp errno [4]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------ - TEST_TITLE("storageReadSftp() ssh error"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // storageReadSftpClose - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_ZLIB}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); - TEST_ERROR( - storageReadSftp(file->driver, outBuffer, false), FileReadError, - "unable to read '" TEST_PATH "/readtest.txt': libssh2 error [-29]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); -#else - TEST_LOG(PROJECT_NAME " not built with sftp support"); -#endif // HAVE_LIBSSH2 - } - - // ***************************************************************************************************************************** - if (testBegin("storageNewWrite()")) - { -#ifdef HAVE_LIBSSH2 - const String *fileName = STRDEF(TEST_PATH "/sub1/testfile"); - StorageWrite *file = NULL; - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("permission denied"); - - // Mimic creation of /noperm/noperm - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Permission denied - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",26,416,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",26,416,0]", .resultNull = true, - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - Storage *storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true, .noCreatePath = false), "new write file"); - TEST_ERROR_FMT( - ioWriteOpen(storageWriteIo(file)), FileOpenError, - STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("timeout"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Timeout - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",26,416,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",26,416,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true, .noCreatePath = false), "new write file"); - TEST_ERROR_FMT(ioWriteOpen(storageWriteIo(file)), FileOpenError, "timeout while opening file '%s'", strZ(fileNoPerm)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("missing"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Missing - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/missing\",26,416,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "\",488]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/missing\",26,416,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN( - file, storageNewWriteP(storageTest, STRDEF("missing"), .noAtomic = true, .noCreatePath = false), "new write file"); - TEST_ERROR_FMT(ioWriteOpen(storageWriteIo(file)), FileMissingError, STORAGE_ERROR_WRITE_MISSING, TEST_PATH "/missing"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("write file - defaults"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",\"" TEST_PATH "/sub1/testfile\",7]", - .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageWriteSftpClose timeout on fsync"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - const String *fileNameTmp = STRDEF(TEST_PATH "/sub1/testfile.pgbackrest.tmp"); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_ERROR_FMT(ioWriteClose(storageWriteIo(file)), FileSyncError, "timeout syncing file '%s'", strZ(fileNameTmp)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageWriteSftpClose error on fsync"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - fileNameTmp = STRDEF(TEST_PATH "/sub1/testfile.pgbackrest.tmp"); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_ERROR_FMT( - ioWriteClose(storageWriteIo(file)), - FileSyncError, "unable to sync file '%s' after write: libssh2 error [-7]", strZ(fileNameTmp)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageWriteSftpClose error on close"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_ERROR_FMT( - ioWriteClose(storageWriteIo(file)), FileCloseError, - "unable to close file '%s' after write: libssh2 error [-7]", strZ(fileNameTmp)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("timeout on rename"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",\"" TEST_PATH "/sub1/testfile\",7]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_ERROR_FMT(ioWriteClose(storageWriteIo(file)), FileCloseError, "timeout renaming file '%s'", strZ(fileNameTmp)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("sftp error on rename, other than LIBSSH2_FX_FAILURE"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",\"" TEST_PATH "/sub1/testfile\",7]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_ERROR_FMT( - ioWriteClose(storageWriteIo(file)), FileCloseError, - "unable to move '%s' to '%s': libssh2 error [-31]: sftp error [7] connection lost", strZ(fileNameTmp), - strZ(fileName)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("sftp remove existing file on rename - LIBSSH2_FX_FILE_ALREADY_EXISTS"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",\"" TEST_PATH "/sub1/testfile\",7]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FILE_ALREADY_EXISTS}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/sub1/testfile\"]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",\"" TEST_PATH "/sub1/testfile\",7]", - .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("ssh error on rename"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",\"" TEST_PATH "/sub1/testfile\",7]", - .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_ERROR_FMT( - ioWriteClose(storageWriteIo(file)), FileCloseError, - "unable to move '%s' to '%s': libssh2 error [-7]", strZ(fileNameTmp), strZ(fileName)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageWriteSftpClose() timeout EAGAIN on libssh2_sftp_close"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_ERROR_FMT(ioWriteClose(storageWriteIo(file)), FileCloseError, "timeout closing file '%s'", strZ(fileNameTmp)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("write file - noAtomic = true"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noAtomic = true), "new write file (defaults)"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageWriteSftpClose() - null sftpHandle"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, .param = "[\"" TEST_PATH "/sub1/testfile\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile\",26,416,0]"}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noAtomic = true, .noSyncPath = false), "new write file"); - TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); - TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); - - // Make sftpHandle NULL - ((StorageWriteSftp *)file->driver)->sftpHandle = NULL; - - TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); -#else - TEST_LOG(PROJECT_NAME " not built with sftp support"); -#endif // HAVE_LIBSSH2 - } - - // ***************************************************************************************************************************** - if (testBegin("storagePut() and storageGet()")) - { -#ifdef HAVE_LIBSSH2 - ioBufferSizeSet(65536); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[65536]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[65536]", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - Storage *storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("get error - attempt to get directory"); - - TEST_ERROR( - storageGetP(storageNewReadP(storageTest, TEST_PATH_STR, .ignoreMissing = false)), FileReadError, - "unable to read '" TEST_PATH "': sftp errno [4]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("put - empty file"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - const String *emptyFile = STRDEF(TEST_PATH "/test.empty"); - TEST_RESULT_VOID(storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), "put empty file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("put - empty file, already exists"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = 99}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileRemoveError, - "unable to remove existing '" TEST_PATH "/test.empty': libssh2 error [-31]: sftp error [99] unknown error"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("put - empty file, remove already existing file, storageWriteSftpRename timeout EAGAIN"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileWriteError, - "timeout moving '" TEST_PATH "/test.empty.pgbackrest.tmp' to '" TEST_PATH "/test.empty'"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("put - empty file, remove already existing file, storageWriteSftpRename ssh error"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileRemoveError, - "unable to move '" TEST_PATH "/test.empty.pgbackrest.tmp' to '" TEST_PATH "/test.empty': libssh2 error [-7]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("put - empty file, EAGAIN fail on remove already existing file"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.empty.pgbackrest.tmp\",\"" TEST_PATH "/test.empty\",7]", - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_FAILURE}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileWriteError, - "timeout unlinking '" TEST_PATH "/test.empty'"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("put - file with contents - timeout EAGAIN libssh2_sftp_write"); - - ioBufferSizeSet(2); - - const Buffer *failBuffer = BUFSTRDEF("FAIL\n"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storagePutP(storageNewWriteP(storageTest, STRDEF(TEST_PATH "/test.txt")), failBuffer), FileWriteError, - "timeout writing '" TEST_PATH "/test.txt.pgbackrest.tmp'"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("put - file with contents - error other than EAGAIN libssh2_sftp_write"); - - failBuffer = BUFSTRDEF("FAIL\n"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storagePutP(storageNewWriteP(storageTest, STRDEF(TEST_PATH "/test.txt")), failBuffer), FileWriteError, - "unable to write '" TEST_PATH "/test.txt.pgbackrest.tmp': libssh2 error [-7]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("put - file with contents"); - - const Buffer *buffer = BUFSTRDEF("TESTFILE\n"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt.pgbackrest.tmp\",26,416,0]"}, - // Not passing buffer param, see shim function, initial passed buffer contains random data - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = 2}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = 2}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = 2}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = 1}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[1]", .resultInt = 1}, - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[1]", .resultInt = 1}, - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/test.txt.pgbackrest.tmp\",\"" TEST_PATH "/test.txt\",7]", - .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_RESULT_VOID(storagePutP(storageNewWriteP(storageTest, STRDEF(TEST_PATH "/test.txt")), buffer), "put test file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("get - ignore missing"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/BOGUS\",1,0,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_RESULT_PTR( - storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/" BOGUS_STR), .ignoreMissing = true)), NULL, - "get missing file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("get - empty file"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.empty\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.empty"))), "get empty"); - TEST_RESULT_UINT(bufSize(buffer), 0, "size is 0"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("get - file with contents"); - - const Buffer *outBuffer = bufNew(2); - - ioBufferSizeSet(65536); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - // Not passing buffer param, see shim function, initial passed buffer contains random data - {.function = HRNLIBSSH2_SFTP_READ, .param = "[65536]", .resultInt = 9, .readBuffer = STRDEF("TESTFILE\n")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[65527]", .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(outBuffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"))), "get text"); - TEST_RESULT_UINT(bufSize(outBuffer), 9, "check size"); - TEST_RESULT_BOOL(memcmp(bufPtrConst(outBuffer), "TESTFILE\n", bufSize(outBuffer)) == 0, true, "check content"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("get - exact size smaller"); - - ioBufferSizeSet(2); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("TE")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("ST")}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt")), .exactSize = 4), "get exact"); - TEST_RESULT_UINT(bufSize(buffer), 4, "check size"); - TEST_RESULT_BOOL(memcmp(bufPtrConst(buffer), "TEST", bufSize(buffer)) == 0, true, "check content"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("get - exact size larger"); - - ioBufferSizeSet(4); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[4]", .resultInt = 4, .readBuffer = STRDEF("TEST")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[4]", .resultInt = 4, .readBuffer = STRDEF("FILE")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[4]", .resultInt = 1, .readBuffer = STRDEF("\n")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[3]", .resultInt = 0}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt")), .exactSize = 64), FileReadError, - "unable to read 64 byte(s) from '" TEST_PATH "/test.txt'"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("get - smaller buffer size"); - - ioBufferSizeSet(2); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("TE")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("ST")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("FI")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("LE")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 1, .readBuffer = STRDEF("\n")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[1]", .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"))), "get text"); - TEST_RESULT_UINT(bufSize(buffer), 9, "check size"); - TEST_RESULT_BOOL(memcmp(bufPtrConst(buffer), "TESTFILE\n", bufSize(buffer)) == 0, true, "check content"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("error on invalid read offset bytes"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_SEEK64, .param = "[18446744073709551615]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_BAD_MESSAGE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"), .offset = UINT64_MAX)), FileOpenError, - "unable to seek to 18446744073709551615 in file '" TEST_PATH "/test.txt'"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("error on invalid read"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_BAD_MESSAGE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"))), FileReadError, - "unable to read '" TEST_PATH "/test.txt': sftp errno [5]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("read limited bytes"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("TE")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("ST")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("FI")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[1]", .resultInt = 1, .readBuffer = STRDEF("LE")}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"), .limit = VARUINT64(7))), "get"); - TEST_RESULT_UINT(bufSize(buffer), 7, "check size"); - TEST_RESULT_BOOL(memcmp(bufPtrConst(buffer), "TESTFIL", bufSize(buffer)) == 0, true, "check content"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("read offset bytes"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_SEEK64, .param = "[4]"}, - // Simulate seeking offset 4 - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("FI")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 2, .readBuffer = STRDEF("LE")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = 1, .readBuffer = STRDEF("\n")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[1]", .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"), .offset = 4)), "get"); - TEST_RESULT_UINT(bufSize(buffer), 5, "check size"); - TEST_RESULT_BOOL(memcmp(bufPtrConst(buffer), "FILE\n", bufSize(buffer)) == 0, true, "check content"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("get - read timeout EAGAIN"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt\",1,0,0]"}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"))), FileReadError, - "timeout reading '" TEST_PATH "/test.txt'"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); -#else - TEST_LOG(PROJECT_NAME " not built with sftp support"); -#endif // HAVE_LIBSSH2 - } - - // ***************************************************************************************************************************** - if (testBegin("storageRemove()")) - { -#ifdef HAVE_LIBSSH2 - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("remove - file missing"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); - hrnCfgArgRawZ(argList, cfgOptRepoPath, strZ(FSLASH_STR)); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); - HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - - Storage *storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_RESULT_VOID(storageRemoveP(storageTest, STRDEF("missing")), "remove missing file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("remove - file missing, .errorOnMissing = true, sftp error LIBSSH2_FX_NO_SUCH_FILE"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError, - "unable to remove '/missing': libssh2 error [-31]: sftp error [2] no such file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("remove - file missing, sftp error other than LIBSSH2_FX_NO_SUCH_FILE"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing")), FileRemoveError, - "unable to remove '/missing': libssh2 error [-31]: sftp error [7] connection lost"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("remove - file missing, ssh error, .errorOnMissing = true"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_BAD_SOCKET}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError, - "unable to remove '/missing': libssh2 error [-45]"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("remove - file missing, timeout EAGAIN, .errorOnMissing = true"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ERROR( - storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError, "timeout removing '/missing'"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("remove - LIBSSH2_ERROR_SOCKET_SEND"); - - const String *fileRemove1 = STRDEF(TEST_PATH "/remove.txt"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/remove.txt\"]", - .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage /"); - TEST_RESULT_VOID(storageRemoveP(storageTest, fileRemove1), "remove file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageWriteSftpOpen libssh2_sftp_open_ex timeout EAGAIN"); - - StorageWrite *file = NULL; - const String *fileName = STRDEF(TEST_PATH "/sub1/testfile"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, .resultInt = LIBSSH2_ERROR_EAGAIN, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, .resultInt = LIBSSH2_ERROR_EAGAIN, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen timeout EAGAIN"); - TEST_ERROR_FMT(ioWriteOpen(storageWriteIo(file)), FileOpenError, "timeout while opening file '%s'", strZ(fileName)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageWriteSftpOpen libssh2_sftp_open_ex sftp error"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen sftp error"); - TEST_ERROR_FMT( - ioWriteOpen(storageWriteIo(file)), FileOpenError, - STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileName)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageWriteSftpOpen libssh2_sftp_open_ex ssh error"); - - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, - .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen ssh error"); - TEST_ERROR_FMT( - ioWriteOpen(storageWriteIo(file)), FileOpenError, STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-7]", strZ(fileName)); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 @@ -6483,136 +2458,184 @@ testRun(void) if (testBegin("StorageRead")) { #ifdef HAVE_LIBSSH2 - Storage *storageTest = NULL; StorageRead *file = NULL; + const String *fileName = STRDEF(TEST_PATH "/readtest.txt"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Ignore missing - file with no permission to read - // New read file, check ignore missing, check name require no libssh2 calls - // Permission denied - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",1,0,0]", .resultNull = true, - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - // File missing - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.file\",1,0,0]", .resultNull = true, - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - // Ignore missing - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.file\",1,0,0]", .resultNull = true, - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + StringList *argList = strLstDup(argCommonList); + hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); + HRN_CFG_LOAD(cfgCmdArchiveGet, argList); + + const Storage *storageTest = storageRepo(); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("ignore missing - file with no permission to read"); + TEST_TITLE("read missing - no such file"); - // Mimic creation of /noperm/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"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("permission denied"); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileNoPerm), "new no perm read file"); - TEST_ERROR_FMT( - ioReadOpen(storageReadIo(file)), - FileOpenError, - STORAGE_ERROR_READ_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm)); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("file missing"); - - const String *fileName = STRDEF(TEST_PATH "/test.file"); - - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new missing read file"); + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(fileName)); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("ignore missing"); + TEST_TITLE("read missing - EAGAIN timeout"); - TEST_ASSIGN(file, storageNewReadP(storageTest, fileName, .ignoreMissing = true), "new missing read file"); - TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), false, "missing file ignored"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_WRITING), + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + TEST_ERROR_FMT( + ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN ": libssh2 error [-37]", strZ(fileName)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("read missing - not sftp, not EAGAIN"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_METHOD_NOT_SUPPORTED), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_METHOD_NOT_SUPPORTED)); + + TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(fileName)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("read success"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt"), + HRN_LIBSSH2_CLOSE()); + + TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); + TEST_RESULT_INT(ioReadFd(storageReadIo(file)), -1, "check read fd"); + TEST_RESULT_VOID(ioReadClose(storageReadIo(file)), "close file"); + + // ------------------------------------------------------------------------------------------------------------------------ + TEST_TITLE("close success via storageReadSftpClose()"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt"), + HRN_LIBSSH2_CLOSE()); + + Buffer *outBuffer = bufNew(2); + + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); + TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); + TEST_RESULT_VOID(storageReadSftpClose((StorageReadSftp *)file->driver), "close file"); + + // ------------------------------------------------------------------------------------------------------------------------ + TEST_TITLE("close, null sftpHandle"); + + HRN_LIBSSH2_SCRIPT_SET(HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt")); + + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); + TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); + ((StorageReadSftp *)file->driver)->sftpHandle = NULL; + TEST_RESULT_VOID(storageReadSftpClose(file->driver), "close file null sftpHandle"); + + // ------------------------------------------------------------------------------------------------------------------------ + TEST_TITLE("close fail via storageReadSftpClose() EAGAIN"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt"), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); + + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); + TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); + TEST_ERROR( + storageReadSftpClose(file->driver), FileCloseError, + "timeout closing file '" TEST_PATH "/readtest.txt': libssh2 error [-37]"); + + // ------------------------------------------------------------------------------------------------------------------------ + TEST_TITLE("close fail via storageReadSftpClose() sftp error"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt"), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE)); + + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); + TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); + TEST_ERROR( + storageReadSftpClose(file->driver), FileCloseError, + "unable to close file '" TEST_PATH "/readtest.txt' after read: libssh2 errno [-31]: sftp errno [4]"); + + // ------------------------------------------------------------------------------------------------------------------------ + TEST_TITLE("close fail via storageReadSftpClose() ssh error"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt"), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_ZLIB)); + + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); + TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); + TEST_ERROR( + storageReadSftpClose(file->driver), FileCloseError, + "unable to close file '" TEST_PATH "/readtest.txt' after read: libssh2 errno [-29]"); + + // ------------------------------------------------------------------------------------------------------------------------ + TEST_TITLE("storageReadSftp() sftp error"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt"), + HRN_LIBSSH2_READ(2, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE)); + + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); + TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); + TEST_ERROR( + storageReadSftp(file->driver, outBuffer, false), FileReadError, + "unable to read '" TEST_PATH "/readtest.txt': sftp errno [4]"); + + // ------------------------------------------------------------------------------------------------------------------------ + TEST_TITLE("storageReadSftp() ssh error"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt"), + HRN_LIBSSH2_READ(2, .resultInt = LIBSSH2_ERROR_ZLIB), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); + + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName), "new read file (defaults)"); + TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); + TEST_ERROR( + storageReadSftp(file->driver, outBuffer, false), FileReadError, + "unable to read '" TEST_PATH "/readtest.txt': libssh2 error [-29]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("incremental load, storageReadSftp(), storageReadSftpEof()"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - // Open file - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.file\",1,0,0]", - .resultInt = LIBSSH2_ERROR_NONE}, - // Check file name, check file type, check offset, check limit require no libssh2 calls - {.function = HRNLIBSSH2_SFTP_READ, .param = "[44]", .resultInt = 2, .readBuffer = STRDEF("TE")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[42]", .resultInt = 2, .readBuffer = STRDEF("ST")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[40]", .resultInt = 2, .readBuffer = STRDEF("FI")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[38]", .resultInt = 2, .readBuffer = STRDEF("LE")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[36]", .resultInt = 1, .readBuffer = STRDEF("\n")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[35]", .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); - hrnCfgArgRawZ(argList, cfgOptRepoPath, strZ(FSLASH_STR)); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); - HRN_CFG_LOAD(cfgCmdArchiveGet, argList); + fileName = STRDEF(TEST_PATH "/test.file"); - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.file"), + HRN_LIBSSH2_READ(44, .readBuffer = STRDEF("TE")), + HRN_LIBSSH2_READ(42, .readBuffer = STRDEF("ST")), + HRN_LIBSSH2_READ(40, .readBuffer = STRDEF("FI")), + HRN_LIBSSH2_READ(38, .readBuffer = STRDEF("LE")), + HRN_LIBSSH2_READ(36, .readBuffer = STRDEF("\n")), + HRN_LIBSSH2_READ(35), + HRN_LIBSSH2_CLOSE(), + HRNLIBSSH2_MACRO_SHUTDOWN()); Buffer *buffer = bufNew(0); - Buffer *outBuffer = bufNew(2); - const Buffer *expectedBuffer = BUFSTRDEF("TESTFILE\n"); + outBuffer = bufNew(2); - MEM_CONTEXT_TEMP_BEGIN() - { - TEST_ASSIGN( - file, - storageReadMove(storageNewReadP(storageTest, fileName, .limit = VARUINT64(44)), memContextPrior()), - "new read file"); - } - MEM_CONTEXT_TEMP_END(); + TEST_ASSIGN(file, storageNewReadP(storageTest, fileName, .limit = VARUINT64(44)), "new read file"); TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); TEST_RESULT_STR(storageReadName(file), fileName, "check file name"); @@ -6632,8 +2655,6 @@ testRun(void) TEST_RESULT_VOID(ioRead(storageReadIo(file), outBuffer), "load data"); bufCat(buffer, outBuffer); bufUsedZero(outBuffer); - TEST_RESULT_BOOL(bufEq(buffer, expectedBuffer), false, "check file contents (not all loaded yet)"); - TEST_RESULT_VOID(ioRead(storageReadIo(file), outBuffer), "load data"); bufCat(buffer, outBuffer); bufUsedZero(outBuffer); @@ -6644,7 +2665,7 @@ testRun(void) TEST_RESULT_VOID(storageReadSftp(file->driver, outBuffer, true), "no data to load from driver either"); TEST_RESULT_UINT(bufUsed(outBuffer), 0, "buffer is empty"); - TEST_RESULT_BOOL(bufEq(buffer, expectedBuffer), true, "check file contents (all loaded)"); + TEST_RESULT_BOOL(bufEq(buffer, BUFSTRDEF("TESTFILE\n")), true, "check file contents (all loaded)"); TEST_RESULT_BOOL(ioReadEof(storageReadIo(file)), true, "eof"); TEST_RESULT_BOOL(ioReadEof(storageReadIo(file)), true, "still eof"); @@ -6654,9 +2675,7 @@ testRun(void) TEST_RESULT_VOID(storageReadFree(storageNewReadP(storageTest, fileName)), "free file"); - TEST_RESULT_VOID(storageReadMove(NULL, memContextTop()), "move null file"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 @@ -6666,89 +2685,386 @@ testRun(void) if (testBegin("StorageWrite")) { #ifdef HAVE_LIBSSH2 - Storage *storageTest = NULL; + const String *fileName = STRDEF(TEST_PATH "/sub1/testfile"); StorageWrite *file = NULL; - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("check getters"); + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - // mimic creation of /noperm/noperm - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + StringList *argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); - - TEST_ASSIGN( - file, - storageNewWriteP( - storageTest, fileNoPerm, .modeFile = 0444, .modePath = 0555, .noSyncFile = true, .noSyncPath = true, - .noAtomic = true), - "new write file"); - TEST_RESULT_BOOL(storageWriteAtomic(file), false, "check atomic"); - TEST_RESULT_BOOL(storageWriteCreatePath(file), true, "check create path"); - TEST_RESULT_INT(storageWriteModeFile(file), 0444, "check mode file"); - TEST_RESULT_INT(storageWriteModePath(file), 0555, "check mode path"); - TEST_RESULT_STR(storageWriteName(file), fileNoPerm, "check name"); - TEST_RESULT_BOOL(storageWriteSyncPath(file), false, "check sync path"); - TEST_RESULT_BOOL(storageWriteSyncFile(file), false, "check sync file"); - TEST_RESULT_BOOL(storageWriteTruncate(file), true, "file will be truncated"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + const Storage *storageTest = storageRepoWrite(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("permission denied"); - // mimic creation of /noperm/noperm - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = 0}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = 0}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/noperm/noperm", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/noperm/noperm", .resultNull = true, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true, .noCreatePath = false), "new write file"); + TEST_ERROR_FMT( + ioWriteOpen(storageWriteIo(file)), FileOpenError, + STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("timeout"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/noperm/noperm", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/noperm/noperm", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true, .noCreatePath = false), "new write file"); + TEST_ERROR_FMT(ioWriteOpen(storageWriteIo(file)), FileOpenError, "timeout while opening file '%s'", strZ(fileNoPerm)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("missing"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/missing", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/missing", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + + TEST_ASSIGN( + file, storageNewWriteP(storageTest, STRDEF("missing"), .noAtomic = true, .noCreatePath = false), "new write file"); + TEST_ERROR_FMT(ioWriteOpen(storageWriteIo(file)), FileMissingError, STORAGE_ERROR_WRITE_MISSING, TEST_PATH "/missing"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("write file - defaults"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME(TEST_PATH "/sub1/testfile.pgbackrest.tmp", TEST_PATH "/sub1/testfile")); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("storageWriteSftpClose timeout on fsync"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + + const String *fileNameTmp = STRDEF(TEST_PATH "/sub1/testfile.pgbackrest.tmp"); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_ERROR_FMT(ioWriteClose(storageWriteIo(file)), FileSyncError, "timeout syncing file '%s'", strZ(fileNameTmp)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("storageWriteSftpClose error on fsync"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(.resultInt = LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_ERROR_FMT( + ioWriteClose(storageWriteIo(file)), + FileSyncError, "unable to sync file '%s' after write: libssh2 error [-7]", strZ(fileNameTmp)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("storageWriteSftpClose error on close"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_ERROR_FMT( + ioWriteClose(storageWriteIo(file)), FileCloseError, + "unable to close file '%s' after write: libssh2 error [-7]", strZ(fileNameTmp)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("timeout on rename"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/sub1/testfile.pgbackrest.tmp", TEST_PATH "/sub1/testfile", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_ERROR_FMT(ioWriteClose(storageWriteIo(file)), FileCloseError, "timeout renaming file '%s'", strZ(fileNameTmp)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("sftp error on rename, other than LIBSSH2_FX_FAILURE"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/sub1/testfile.pgbackrest.tmp", TEST_PATH "/sub1/testfile", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_CONNECTION_LOST)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_ERROR_FMT( + ioWriteClose(storageWriteIo(file)), FileCloseError, + "unable to move '%s' to '%s': libssh2 error [-31]: sftp error [7] connection lost", strZ(fileNameTmp), + strZ(fileName)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("sftp remove existing file on rename - LIBSSH2_FX_FILE_ALREADY_EXISTS"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/sub1/testfile.pgbackrest.tmp", TEST_PATH "/sub1/testfile", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FILE_ALREADY_EXISTS), + HRN_LIBSSH2_UNLINK(TEST_PATH "/sub1/testfile"), + HRN_LIBSSH2_RENAME(TEST_PATH "/sub1/testfile.pgbackrest.tmp", TEST_PATH "/sub1/testfile")); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("ssh error on rename"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/sub1/testfile.pgbackrest.tmp", TEST_PATH "/sub1/testfile", .resultInt = LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_ERROR_FMT( + ioWriteClose(storageWriteIo(file)), FileCloseError, + "unable to move '%s' to '%s': libssh2 error [-7]", strZ(fileNameTmp), strZ(fileName)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("storageWriteSftpClose() timeout EAGAIN on libssh2_sftp_close"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_ERROR_FMT(ioWriteClose(storageWriteIo(file)), FileCloseError, "timeout closing file '%s'", strZ(fileNameTmp)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("write file - no atomic"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE()); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noAtomic = true), "new write file (defaults)"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("open libssh2_sftp_open_ex timeout EAGAIN"); + + fileName = STRDEF(TEST_PATH "/sub1/testfile"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE( + TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING), + HRN_LIBSSH2_OPEN_WRITE( + TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen timeout EAGAIN"); + TEST_ERROR_FMT(ioWriteOpen(storageWriteIo(file)), FileOpenError, "timeout while opening file '%s'", strZ(fileName)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("open libssh2_sftp_open_ex sftp error"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE( + TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen sftp error"); + TEST_ERROR_FMT( + ioWriteOpen(storageWriteIo(file)), FileOpenError, + STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileName)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("open libssh2_sftp_open_ex ssh error"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile.pgbackrest.tmp", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen ssh error"); + TEST_ERROR_FMT( + ioWriteOpen(storageWriteIo(file)), FileOpenError, STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-7]", strZ(fileName)); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("storageWriteSftpClose() - null sftpHandle"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/testfile"), + HRNLIBSSH2_MACRO_SHUTDOWN()); + + TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noAtomic = true, .noSyncPath = false), "new write file"); + TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); + TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); + + ((StorageWriteSftp *)file->driver)->sftpHandle = NULL; + + TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); + + storageHelperFree(); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("permission denied"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), // Permission denied - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",26,416,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/noperm/noperm", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED), + HRNLIBSSH2_MACRO_SHUTDOWN()); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -6768,16 +3084,7 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + storageTest = storageRepoWrite(); TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true), "new write file"); TEST_ERROR_FMT( @@ -6785,44 +3092,38 @@ testRun(void) FileOpenError, STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("file missing"); - const String *fileName = STRDEF(TEST_PATH "/sub1/test.file"); + fileName = STRDEF(TEST_PATH "/sub1/test.file"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = 0}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = 0}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), // Missing - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/test.file\",26,416,0]", .resultNull = true}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/test.file\",26,416,0]", .resultNull = true, - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/test.file\",26,416,0]", .resultNull = true, - .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_NO_SUCH_FILE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/test.file", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/test.file", .resultNull = true, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRN_LIBSSH2_MKDIR(TEST_PATH "/sub1"), + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/test.file", .resultNull = true, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE), + HRNLIBSSH2_MACRO_SHUTDOWN()); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); @@ -6843,80 +3144,54 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, "/home/" TEST_USER "/.ssh/known_hosts2"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + storageTest = storageRepoWrite(); TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noAtomic = true), "new write file"); TEST_ERROR_FMT(ioWriteOpen(storageWriteIo(file)), FileMissingError, STORAGE_ERROR_WRITE_MISSING, strZ(fileName)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("write file success"); const Buffer *buffer = BUFSTRDEF("TESTFILE\n"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = 0}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = 0}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), // Open file - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/test.file.pgbackrest.tmp\",26,416,0]"}, - // Write null and zero size buffers are noops + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub1/test.file.pgbackrest.tmp"), // Write filled buffer to file - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[9]", .resultInt = 9}, + HRN_LIBSSH2_WRITE(9), // Close file - {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_RENAME_EX, - .param = "[\"" TEST_PATH "/sub1/test.file.pgbackrest.tmp\",\"" TEST_PATH "/sub1/test.file\",7]", - .resultInt = LIBSSH2_ERROR_NONE}, - // Move context + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME(TEST_PATH "/sub1/test.file.pgbackrest.tmp", TEST_PATH "/sub1/test.file"), // Open file - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/test.file\",1,0,0]"}, + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/sub1/test.file"), // Read file - {.function = HRNLIBSSH2_SFTP_READ, .param = "[65536]", .resultInt = 9, .readBuffer = STRDEF("TESTFILE\n")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[65527]", .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, + HRN_LIBSSH2_READ(65536, .readBuffer = STRDEF("TESTFILE\n")), + HRN_LIBSSH2_READ(65527), + HRN_LIBSSH2_CLOSE(), // Check path mode - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub1\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IXGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_STAT(TEST_PATH "/sub1", .attr = HRN_LIBSSH2_DIR(0750), .mtime = 1656434296), // Check file mode - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub1/test.file\",1]", - .fileName = STRDEF("test.file"), .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, + HRN_LIBSSH2_STAT(TEST_PATH "/sub1/test.file", .attr = HRN_LIBSSH2_FILE(0640), .mtime = 1656434296), // Remove filename - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/sub1/test.file\"]", - .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_UNLINK(TEST_PATH "/sub1/test.file"), + HRNLIBSSH2_MACRO_SHUTDOWN()); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "test"); hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); + hrnCfgArgRawZ(argList, cfgOptBufferSize, "64KiB"); hrnCfgArgRawZ(argList, cfgOptRepo, "1"); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); @@ -6928,18 +3203,7 @@ testRun(void) hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - ioBufferSizeSet(65536); - - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + storageTest = storageRepoWrite(); MEM_CONTEXT_TEMP_BEGIN() { @@ -6962,83 +3226,46 @@ testRun(void) storageRemoveP(storageTest, fileName, .errorOnMissing = true); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("write subpath and file success"); fileName = STRDEF(TEST_PATH "/sub2/test.file"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = 0}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = 0}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS2_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_INIT}, + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_INIT(), + HRN_LIBSSH2_SESSION_INIT(), + HRN_LIBSSH2_HANDSHAKE(), + HRN_LIBSSH2_KNOWNHOST_INIT(), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_KNOWNHOST_READFILE(KNOWNHOSTS2_FILE_CSTR, .resultInt = 5), + HRN_LIBSSH2_HOSTKEY(), + HRN_LIBSSH2_KNOWNHOST_CHECK(LIBSSH2_KNOWNHOST_CHECK_MATCH), + HRN_LIBSSH2_USERAUTH(), + HRN_LIBSSH2_SFTP_INIT(), // Open file - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub2/test.file\",26,384,0]"}, + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/sub2/test.file", .mode = 0600), // Write filled buffer to file - {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[9]", .resultInt = 9}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - // Open file - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub2/test.file\",1,0,0]"}, - // Read file - {.function = HRNLIBSSH2_SFTP_READ, .param = "[65536]", .resultInt = 9, .readBuffer = STRDEF("TESTFILE\n")}, - {.function = HRNLIBSSH2_SFTP_READ, .param = "[65527]", .resultInt = 0}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - // Check path mode - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub2\",1]", .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFDIR | LIBSSH2_SFTP_S_IRWXU, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | - LIBSSH2_SFTP_ATTR_SIZE, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // Check file mode - {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub2/test.file\",1]", - .fileName = STRDEF("test.file"), .resultInt = LIBSSH2_ERROR_NONE, - .attrPerms = LIBSSH2_SFTP_S_IFREG | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR, - .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, - .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, - // Remove filename - {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/sub2/test.file\"]", - .resultInt = LIBSSH2_ERROR_NONE}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepo, "1"); + HRN_LIBSSH2_WRITE(9), + HRN_LIBSSH2_CLOSE(), + HRNLIBSSH2_MACRO_SHUTDOWN()); + + argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, "/home/" TEST_USER "/.ssh/known_hosts "); hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, " /home/" TEST_USER "/.ssh/known_hosts2"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - ioBufferSizeSet(65536); + storageTest = storageRepoWrite(); - storageTest = storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); + TEST_RESULT_STR_Z( + strLstGet(strLstNewVarLst(cfgOptionLst(cfgOptRepoSftpKnownHost)), 1), "/home/" TEST_USER "/.ssh/known_hosts ", + "check known hosts path trailing spaces"); + TEST_RESULT_STR_Z( + strLstGet(strLstNewVarLst(cfgOptionLst(cfgOptRepoSftpKnownHost)), 2), " /home/" TEST_USER "/.ssh/known_hosts2", + "check known hosts path leading spaces"); TEST_ASSIGN( file, @@ -7050,245 +3277,436 @@ testRun(void) TEST_RESULT_VOID(ioWrite(storageWriteIo(file), buffer), "write to file"); TEST_RESULT_VOID(ioWriteClose(storageWriteIo(file)), "close file"); - expectedBuffer = storageGetP(storageNewReadP(storageTest, fileName)); - TEST_RESULT_BOOL(bufEq(buffer, expectedBuffer), true, "check file contents"); - TEST_RESULT_INT(storageInfoP(storageTest, strPath(fileName)).mode, 0700, "check path mode"); - TEST_RESULT_INT(storageInfoP(storageTest, fileName).mode, 0600, "check file mode"); - TEST_RESULT_STR_Z( - strLstGet(strLstNewVarLst(cfgOptionLst(cfgOptRepoSftpKnownHost)), 0), "/home/" TEST_USER "/.ssh/known_hosts ", - "check known hosts path trailing spaces"); - TEST_RESULT_STR_Z( - strLstGet(strLstNewVarLst(cfgOptionLst(cfgOptRepoSftpKnownHost)), 1), " /home/" TEST_USER "/.ssh/known_hosts2", - "check known hosts path leading spaces"); - - storageRemoveP(storageTest, fileName, .errorOnMissing = true); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + storageHelperFree(); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 } // ***************************************************************************************************************************** - if (testBegin("storageRepo*()")) + if (testBegin("storagePut() and storageGet()")) { #ifdef HAVE_LIBSSH2 - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - // Load configuration to set repo-path and stanza - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "db"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyCheckType, "accept-new"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, " ~/.ssh/id_rsa"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, " ~/.ssh/id_rsa.pub"); + StringList *argList = strLstDup(argCommonList); + hrnCfgArgRawZ(argList, cfgOptRepoPath, strZ(FSLASH_STR)); + hrnCfgArgRawZ(argList, cfgOptBufferSize, "64KiB"); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - const Storage *storage = NULL; + const Storage *storageTest = storageRepoWrite(); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageRepo() - cached/not cached"); + TEST_TITLE("get error - attempt to get directory"); - // Set storage helper - static const StorageHelper storageHelperList[] = {STORAGE_SFTP_HELPER, STORAGE_END_HELPER}; - storageHelperInit(storageHelperList); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH), + HRN_LIBSSH2_READ(65536, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_READ(65536, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE)); - TEST_RESULT_PTR(storageHelper.storageRepo, NULL, "repo storage not cached"); - TEST_ASSIGN(storage, storageRepo(), "new storage"); - TEST_RESULT_PTR(storageHelper.storageRepo[0], storage, "repo storage cached"); - TEST_RESULT_PTR(storageRepo(), storage, "get cached storage"); + TEST_ERROR( + storageGetP(storageNewReadP(storageTest, TEST_PATH_STR, .ignoreMissing = false)), FileReadError, + "unable to read '" TEST_PATH "': sftp errno [4]"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageRepo() - confirm settings"); + TEST_TITLE("put - empty file"); - TEST_ERROR(storagePathP(storage, STRDEF("/path")), AssertError, "invalid expression ''"); - TEST_ERROR(storageNewWriteP(storage, writeFile), AssertError, "assertion 'this->write' failed"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/test.empty.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME(TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty")); - TEST_RESULT_STR_Z(storagePathP(storage, NULL), TEST_PATH, "check base path"); - TEST_RESULT_STR_Z( - storagePathP(storage, STORAGE_REPO_ARCHIVE_STR), TEST_PATH "/archive/db", "check archive path"); - TEST_RESULT_STR_Z( - storagePathP(storage, STRDEF(STORAGE_REPO_ARCHIVE "/simple")), TEST_PATH "/archive/db/simple", - "check simple path"); - TEST_RESULT_STR_Z( - storagePathP(storage, STRDEF(STORAGE_REPO_ARCHIVE "/17-1/700000007000000070000000")), - TEST_PATH "/archive/db/17-1/7000000070000000/700000007000000070000000", "check segment path"); - TEST_RESULT_STR_Z( - storagePathP(storage, STRDEF(STORAGE_REPO_ARCHIVE "/17-1/00000008.history")), - TEST_PATH "/archive/db/17-1/00000008.history", "check history path"); - TEST_RESULT_STR_Z( - storagePathP(storage, STRDEF(STORAGE_REPO_ARCHIVE "/17-1/000000010000014C0000001A.00000028.backup")), - TEST_PATH "/archive/db/17-1/000000010000014C/000000010000014C0000001A.00000028.backup", - "check archive backup path"); - TEST_RESULT_STR_Z(storagePathP(storage, STORAGE_REPO_BACKUP_STR), TEST_PATH "/backup/db", "check backup path"); + const String *emptyFile = STRDEF(TEST_PATH "/test.empty"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storage))); + TEST_RESULT_VOID(storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), "put empty file"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageRepo() - helper does not fail when stanza option not set"); + TEST_TITLE("put - empty file, already exists"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/test.empty.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_UNLINK(TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(99)); - // Change the stanza to NULL with the stanzaInit flag still true, make sure helper does not fail when stanza option not set - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, "/home/" TEST_USER "/.ssh/known_hosts"); - HRN_CFG_LOAD(cfgCmdInfo, argList); - - TEST_ASSIGN(storage, storageRepo(), "new repo storage no stanza"); - TEST_RESULT_STR(storageHelper.stanza, NULL, "stanza NULL"); - - TEST_RESULT_STR_Z( - storagePathP(storage, STORAGE_REPO_ARCHIVE_STR), TEST_PATH "/archive", "check archive path - NULL stanza"); - TEST_RESULT_STR_Z( - storagePathP(storage, STRDEF(STORAGE_REPO_ARCHIVE "/simple")), TEST_PATH "/archive/simple", - "check simple archive path - NULL stanza"); - TEST_RESULT_STR_Z(storagePathP(storage, STORAGE_REPO_BACKUP_STR), TEST_PATH "/backup", "check backup path - NULL stanza"); - TEST_RESULT_STR_Z( - storagePathP(storage, STRDEF(STORAGE_REPO_BACKUP "/simple")), TEST_PATH "/backup/simple", - "check simple backup path - NULL stanza"); - - memContextFree(objMemContext((StorageSftp *)storageDriver(storage))); + TEST_ERROR( + storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileRemoveError, + "unable to remove existing '" TEST_PATH "/test.empty': libssh2 error [-31]: sftp error [99] unknown error"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storageRepoWrite() - confirm write enabled"); + TEST_TITLE("put - empty file, remove already existing file, storageWriteSftpRename timeout EAGAIN"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/test.empty.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_UNLINK(TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/test.empty"), + HRN_LIBSSH2_RENAME(TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_RENAME(TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); - TEST_RESULT_PTR(storageHelper.storageRepoWrite, NULL, "repo write storage not cached"); - TEST_ASSIGN(storage, storageRepoWrite(), "new write storage"); - TEST_RESULT_PTR(storageHelper.storageRepoWrite[0], storage, "repo write storage cached"); - TEST_RESULT_PTR(storageRepoWrite(), storage, "get cached storage"); + TEST_ERROR( + storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileWriteError, + "timeout moving '" TEST_PATH "/test.empty.pgbackrest.tmp' to '" TEST_PATH "/test.empty'"); - TEST_RESULT_BOOL(storage->write, true, "get write enabled"); - TEST_RESULT_UINT(storageType(storage), storage->pub.type, "check type"); - TEST_RESULT_STR_Z(strNewStrId(storageType(storage)), "sftp", "storage type is sftp"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("put - empty file, remove already existing file, storageWriteSftpRename ssh error"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storage))); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/test.empty.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_UNLINK(TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/test.empty"), + HRN_LIBSSH2_RENAME(TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK)); + + TEST_ERROR( + storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileRemoveError, + "unable to move '" TEST_PATH "/test.empty.pgbackrest.tmp' to '" TEST_PATH "/test.empty': libssh2 error [-7]"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("put - empty file, EAGAIN fail on remove already existing file"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/test.empty.pgbackrest.tmp"), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME( + TEST_PATH "/test.empty.pgbackrest.tmp", TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_FAILURE), + HRN_LIBSSH2_UNLINK(TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK(TEST_PATH "/test.empty", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + + TEST_ERROR( + storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileWriteError, + "timeout unlinking '" TEST_PATH "/test.empty'"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("put - file with contents - timeout EAGAIN libssh2_sftp_write"); + + ioBufferSizeSet(2); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/test.txt.pgbackrest.tmp"), + HRN_LIBSSH2_WRITE(2, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_WRITE(2, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + + TEST_ERROR( + storagePutP(storageNewWriteP(storageTest, STRDEF(TEST_PATH "/test.txt")), BUFSTRDEF("FAIL\n")), FileWriteError, + "timeout writing '" TEST_PATH "/test.txt.pgbackrest.tmp'"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("put - file with contents - error other than EAGAIN libssh2_sftp_write"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/test.txt.pgbackrest.tmp"), + HRN_LIBSSH2_WRITE(2, .resultInt = LIBSSH2_ERROR_SOCKET_SEND), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); + + TEST_ERROR( + storagePutP(storageNewWriteP(storageTest, STRDEF(TEST_PATH "/test.txt")), BUFSTRDEF("FAIL\n")), FileWriteError, + "unable to write '" TEST_PATH "/test.txt.pgbackrest.tmp': libssh2 error [-7]"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("put - file with contents"); + + const Buffer *buffer = BUFSTRDEF("TESTFILE\n"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_WRITE(TEST_PATH "/test.txt.pgbackrest.tmp"), + HRN_LIBSSH2_WRITE(2, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_WRITE(2, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_WRITE(2), + HRN_LIBSSH2_WRITE(2), + HRN_LIBSSH2_WRITE(2), + HRN_LIBSSH2_WRITE(2, .resultInt = 1), + HRN_LIBSSH2_WRITE(1), + HRN_LIBSSH2_WRITE(1), + HRN_LIBSSH2_FSYNC(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_RENAME(TEST_PATH "/test.txt.pgbackrest.tmp", TEST_PATH "/test.txt")); + + TEST_RESULT_VOID(storagePutP(storageNewWriteP(storageTest, STRDEF(TEST_PATH "/test.txt")), buffer), "put test file"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("get - ignore missing"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/BOGUS", .resultNull = true), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + + TEST_RESULT_PTR( + storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/" BOGUS_STR), .ignoreMissing = true)), NULL, + "get missing file"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("get - empty file"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.empty"), + HRN_LIBSSH2_READ(2), + HRN_LIBSSH2_CLOSE()); + + TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.empty"))), "get empty"); + TEST_RESULT_UINT(bufSize(buffer), 0, "size is 0"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("get - file with contents"); + + const Buffer *outBuffer = bufNew(2); + + ioBufferSizeSet(65536); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_READ(65536, .readBuffer = STRDEF("TESTFILE\n")), + HRN_LIBSSH2_READ(65527), + HRN_LIBSSH2_CLOSE()); + + TEST_ASSIGN(outBuffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"))), "get text"); + TEST_RESULT_UINT(bufSize(outBuffer), 9, "check size"); + TEST_RESULT_BOOL(memcmp(bufPtrConst(outBuffer), "TESTFILE\n", bufSize(outBuffer)) == 0, true, "check content"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("get - exact size smaller"); + + ioBufferSizeSet(2); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("TE")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("ST")), + HRN_LIBSSH2_CLOSE()); + + TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt")), .exactSize = 4), "get exact"); + TEST_RESULT_UINT(bufSize(buffer), 4, "check size"); + TEST_RESULT_BOOL(memcmp(bufPtrConst(buffer), "TEST", bufSize(buffer)) == 0, true, "check content"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("get - exact size larger"); + + ioBufferSizeSet(4); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_READ(4, .readBuffer = STRDEF("TEST")), + HRN_LIBSSH2_READ(4, .readBuffer = STRDEF("FILE")), + HRN_LIBSSH2_READ(4, .readBuffer = STRDEF("\n")), + HRN_LIBSSH2_READ(3)); + + TEST_ERROR( + storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt")), .exactSize = 64), FileReadError, + "unable to read 64 byte(s) from '" TEST_PATH "/test.txt'"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("get - smaller buffer size"); + + ioBufferSizeSet(2); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("TE")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("ST")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("FI")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("LE")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("\n")), + HRN_LIBSSH2_READ(1), + HRN_LIBSSH2_CLOSE()); + + TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"))), "get text"); + TEST_RESULT_UINT(bufSize(buffer), 9, "check size"); + TEST_RESULT_BOOL(memcmp(bufPtrConst(buffer), "TESTFILE\n", bufSize(buffer)) == 0, true, "check content"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("error on invalid read offset bytes"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_SEEK(18446744073709551615), + HRN_LIBSSH2_READ(2, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_BAD_MESSAGE)); + + TEST_ERROR( + storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"), .offset = UINT64_MAX)), FileOpenError, + "unable to seek to 18446744073709551615 in file '" TEST_PATH "/test.txt'"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("error on invalid read"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_READ(2, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_BAD_MESSAGE)); + + TEST_ERROR( + storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"))), FileReadError, + "unable to read '" TEST_PATH "/test.txt': sftp errno [5]"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("read limited bytes"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("TE")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("ST")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("FI")), + HRN_LIBSSH2_READ(1, .readBuffer = STRDEF("LE"), .resultInt = 1), + HRN_LIBSSH2_CLOSE()); + + TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"), .limit = VARUINT64(7))), "get"); + TEST_RESULT_UINT(bufSize(buffer), 7, "check size"); + TEST_RESULT_BOOL(memcmp(bufPtrConst(buffer), "TESTFIL", bufSize(buffer)) == 0, true, "check content"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("read offset bytes"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_SEEK(4), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("FI")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("LE")), + HRN_LIBSSH2_READ(2, .readBuffer = STRDEF("\n")), + HRN_LIBSSH2_READ(1), + HRN_LIBSSH2_CLOSE()); + + TEST_ASSIGN(buffer, storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"), .offset = 4)), "get"); + TEST_RESULT_UINT(bufSize(buffer), 5, "check size"); + TEST_RESULT_BOOL(memcmp(bufPtrConst(buffer), "FILE\n", bufSize(buffer)) == 0, true, "check content"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("get - read timeout EAGAIN"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_OPEN_READ(TEST_PATH "/test.txt"), + HRN_LIBSSH2_READ(2, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_READ(2, .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING), + HRNLIBSSH2_MACRO_SHUTDOWN()); + + TEST_ERROR( + storageGetP(storageNewReadP(storageTest, STRDEF(TEST_PATH "/test.txt"))), FileReadError, + "timeout reading '" TEST_PATH "/test.txt'"); + + storageHelperFree(); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 } // ***************************************************************************************************************************** - if (testBegin("storageRepoGet() and StorageDriverCifs")) + if (testBegin("storageRemove()")) { #ifdef HAVE_LIBSSH2 - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - {.function = HRNLIBSSH2_INIT, .param = "[0]", .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, - {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_KNOWNHOST_INIT}, - {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" KNOWNHOSTS_FILE_CSTR "\",1]", .resultInt = 5}, - {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, - {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", - .resultInt = LIBSSH2_KNOWNHOST_CHECK_MATCH}, - {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, - .param = "[\"" TEST_USER "\"," TEST_USER_LEN ",\"" KEYPUB_CSTR "\",\"" KEYPRIV_CSTR "\",null]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_INIT}, - HRNLIBSSH2_MACRO_SHUTDOWN() - }); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("remove - file missing"); - // Load configuration - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); - hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); + HRN_LIBSSH2_SCRIPT_SET( + HRNLIBSSH2_MACRO_STARTUP(), + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); + + StringList *argList = strLstDup(argCommonList); + hrnCfgArgRawZ(argList, cfgOptRepoPath, strZ(FSLASH_STR)); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("error on invalid storage type"); + const Storage *storageTest = storageRepoWrite(); - static const StorageHelper storageHelperListError[] = {{.type = STORAGE_CIFS_TYPE}, STORAGE_END_HELPER}; - storageHelperInit(storageHelperListError); - - TEST_ERROR(storageRepoGet(0, true), AssertError, "invalid storage type"); + TEST_RESULT_VOID(storageRemoveP(storageTest, STRDEF("missing")), "remove missing file"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("storage configuration"); + TEST_TITLE("remove - file missing, .errorOnMissing = true, sftp error LIBSSH2_FX_NO_SUCH_FILE"); - // Set storage helper - static const StorageHelper storageHelperList[] = {STORAGE_SFTP_HELPER, STORAGE_END_HELPER}; - storageHelperInit(storageHelperList); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_NO_SUCH_FILE)); - const Storage *storage = NULL; - TEST_ASSIGN(storage, storageRepoGet(0, true), "get sftp repo storage"); - TEST_RESULT_UINT(storageType(storage), STORAGE_SFTP_TYPE, "check storage type"); - TEST_RESULT_BOOL(storageFeature(storage, storageFeaturePath), true, "check path feature"); + TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError, + "unable to remove '/missing': libssh2 error [-31]: sftp error [2] no such file"); // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("path sync result is noop"); + TEST_TITLE("remove - file missing, sftp error other than LIBSSH2_FX_NO_SUCH_FILE"); - // Test the path sync function -- pass a bogus path to ensure that this is a noop - TEST_RESULT_VOID(storagePathSyncP(storage, STRDEF(BOGUS_STR)), "path sync is a noop"); + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_CONNECTION_LOST), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_CONNECTION_LOST)); - memContextFree(objMemContext((StorageSftp *)storageDriver(storage))); + TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing")), FileRemoveError, + "unable to remove '/missing': libssh2 error [-31]: sftp error [7] connection lost"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("remove - file missing, ssh error, .errorOnMissing = true"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_BAD_SOCKET), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE)); + + TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError, + "unable to remove '/missing': libssh2 error [-45]"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("remove - file missing, timeout EAGAIN, .errorOnMissing = true"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_UNLINK("/missing", .resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); + + TEST_ERROR( + storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError, "timeout removing '/missing'"); + + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("remove - LIBSSH2_ERROR_SOCKET_SEND"); + + const String *fileRemove1 = STRDEF(TEST_PATH "/remove.txt"); + + HRN_LIBSSH2_SCRIPT_SET( + HRN_LIBSSH2_UNLINK(TEST_PATH "/remove.txt", .resultInt = LIBSSH2_ERROR_SOCKET_SEND), + HRNLIBSSH2_MACRO_SHUTDOWN()); + + TEST_RESULT_VOID(storageRemoveP(storageTest, fileRemove1), "remove file"); + + storageHelperFree(); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2 @@ -7298,417 +3716,204 @@ testRun(void) if (testBegin("storageSftpLibSsh2SessionFreeResource()")) { #ifdef HAVE_LIBSSH2 - Storage *storageTest = NULL; - StorageSftp *storageSftp = NULL; - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftpHandle, sftpSession, session not NULL, branch tests, EAGAIN"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,0,1]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, + {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,1]"}, + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_CLOSE(), + HRN_LIBSSH2_SHUTDOWN(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_DISCONNECT_EX, .param = "[11,\"pgBackRest instance shutdown\",\"\"]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_DISCONNECT_EX, .param = "[11,\"pgBackRest instance shutdown\",\"\"]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_FREE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, - {.function = HRNLIBSSH2_SESSION_FREE, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE}, - HRNLIBSSH2_MACRO_SHUTDOWN(), - }); + HRN_LIBSSH2_SHUTDOWN(), + HRN_LIBSSH2_DISCONNECT(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_DISCONNECT(), + HRN_LIBSSH2_SESSION_FREE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(), + HRN_LIBSSH2_SESSION_FREE(), + HRN_LIBSSH2_CLOSE(), + HRNLIBSSH2_MACRO_SHUTDOWN(),); - StringList *argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "test"); - hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg"); + Storage *storageTest = NULL; + StorageSftp *storageSftp = NULL; + + StringList *argList = strLstDup(argCommonList); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostUser, TEST_USER); - hrnCfgArgRawZ(argList, cfgOptRepoType, "sftp"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHost, "localhost"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpHostKeyHashType, "sha1"); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPrivateKeyFile, KEYPRIV_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpPublicKeyFile, KEYPUB_CSTR); - hrnCfgArgRawZ(argList, cfgOptRepoSftpKnownHost, KNOWNHOSTS_FILE_CSTR); HRN_CFG_LOAD(cfgCmdArchiveGet, argList); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, storageRepoPathExpression), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); // Populate sftpHandle, NULL sftpSession and session storageSftp->sftpHandle = libssh2_sftp_open_ex(storageSftp->sftpSession, TEST_PATH, 25, 1, 0, 1); TEST_RESULT_VOID(storageSftpLibSsh2SessionFreeResource(storageSftp), "freeResource not NULL sftpHandle"); - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); + objFree(storageTest); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftpHandle, sftpSession, session all NULL"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { - HRNLIBSSH2_MACRO_STARTUP(), - {.function = NULL} - }); + HRN_LIBSSH2_SCRIPT_SET(HRNLIBSSH2_MACRO_STARTUP()); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); // NULL out sftpSession and session storageSftp->sftpSession = NULL; storageSftp->session = NULL; - TEST_RESULT_VOID(memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), "free resource all NULL"); + TEST_RESULT_VOID(objFree(storageTest), "free resource all NULL"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftp close handle failure, sftpHandle not NULL, libssh2 error"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,0,1]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = NULL} - }); + {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,1]"}, + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_SOCKET_SEND)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); // Populate sftpHandle, NULL out sftpSession and session storageSftp->sftpHandle = libssh2_sftp_open_ex(storageSftp->sftpSession, TEST_PATH, 25, 1, 0, 1); storageSftp->sftpSession = NULL; storageSftp->session = NULL; - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), - ServiceError, "failed to close sftpHandle: libssh2 errno [-7]"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "failed to close sftpHandle: libssh2 errno [-7]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftp close handle failure, sftpHandle not NULL, EAGAIN"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,0,1]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = NULL} - }); + {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,1]"}, + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); // Populate sftpHandle, NULL out sftpSession and session storageSftp->sftpHandle = libssh2_sftp_open_ex(storageSftp->sftpSession, TEST_PATH, 25, 1, 0, 1); storageSftp->sftpSession = NULL; storageSftp->session = NULL; - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), - ServiceError, "timeout closing sftpHandle: libssh2 errno [-37]"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "timeout closing sftpHandle: libssh2 errno [-37]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftp close handle failure, sftpHandle not NULL, libssh2 sftp error"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,0,1]"}, - {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST}, - {.function = NULL} - }); + {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "\",1,1]"}, + HRN_LIBSSH2_CLOSE(.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_CONNECTION_LOST)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); // Populate sftpHandle, NULL out sftpSession and session storageSftp->sftpHandle = libssh2_sftp_open_ex(storageSftp->sftpSession, TEST_PATH, 25, 1, 0, 1); storageSftp->sftpSession = NULL; storageSftp->session = NULL; - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), - ServiceError, "failed to close sftpHandle: libssh2 errno [-31]: sftp errno [7]"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "failed to close sftpHandle: libssh2 errno [-31]: sftp errno [7]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftp shutdown failure libssh2 error"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, - {.function = NULL}, - }); + HRN_LIBSSH2_SHUTDOWN(.resultInt = LIBSSH2_ERROR_SOCKET_SEND)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), ServiceError, - "failed to shutdown sftpSession: libssh2 errno [-7]"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "failed to shutdown sftpSession: libssh2 errno [-7]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftp shutdown failure libssh2 sftp error"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST}, - {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST}, - {.function = NULL}, - }); + HRN_LIBSSH2_SHUTDOWN(.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_CONNECTION_LOST), + HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_CONNECTION_LOST)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), ServiceError, + objFree(storageTest), ServiceError, "failed to shutdown sftpSession: libssh2 errno [-31]: sftp errno [7] connection lost"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftp shutdown failure EAGAIN"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = NULL}, - }); + HRN_LIBSSH2_SHUTDOWN(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), ServiceError, - "timeout shutting down sftpSession: libssh2 errno [-37]"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "timeout shutting down sftpSession: libssh2 errno [-37]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() session disconnect failure"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_DISCONNECT_EX, .param = "[11,\"pgBackRest instance shutdown\",\"\"]", - .resultInt = LIBSSH2_ERROR_SOCKET_DISCONNECT}, - {.function = NULL}, - }); + HRN_LIBSSH2_SHUTDOWN(), + HRN_LIBSSH2_DISCONNECT(.resultInt = LIBSSH2_ERROR_SOCKET_DISCONNECT)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), - ServiceError, "failed to disconnect libssh2 session: libssh2 errno [-13]"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "failed to disconnect libssh2 session: libssh2 errno [-13]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() session disconnect failure EAGAIN"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_DISCONNECT_EX, .param = "[11,\"pgBackRest instance shutdown\",\"\"]", - .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = NULL}, - }); + HRN_LIBSSH2_SHUTDOWN(), + HRN_LIBSSH2_DISCONNECT(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), - ServiceError, "timeout disconnecting libssh2 session: libssh2 errno [-37]"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "timeout disconnecting libssh2 session: libssh2 errno [-37]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() session free failure"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_DISCONNECT_EX, .param = "[11,\"pgBackRest instance shutdown\",\"\"]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_FREE, .resultInt = LIBSSH2_ERROR_SOCKET_DISCONNECT}, - {.function = NULL}, - }); + HRN_LIBSSH2_SHUTDOWN(), + HRN_LIBSSH2_DISCONNECT(), + HRN_LIBSSH2_SESSION_FREE(.resultInt = LIBSSH2_ERROR_SOCKET_DISCONNECT)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), ServiceError, - "failed to free libssh2 session: libssh2 errno [-13]"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "failed to free libssh2 session: libssh2 errno [-13]"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("storageSftpLibSsh2SessionFreeResource() session free failure EAGAIN"); - hrnLibSsh2ScriptSet((HrnLibSsh2 []) - { + HRN_LIBSSH2_SCRIPT_SET( HRNLIBSSH2_MACRO_STARTUP(), - {.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_DISCONNECT_EX, .param = "[11,\"pgBackRest instance shutdown\",\"\"]", - .resultInt = LIBSSH2_ERROR_NONE}, - {.function = HRNLIBSSH2_SESSION_FREE, .resultInt = LIBSSH2_ERROR_EAGAIN}, - {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, - {.function = NULL}, - }); + HRN_LIBSSH2_SHUTDOWN(), + HRN_LIBSSH2_DISCONNECT(), + HRN_LIBSSH2_SESSION_FREE(.resultInt = LIBSSH2_ERROR_EAGAIN), + HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING)); - TEST_ASSIGN( - storageTest, - storageSftpNewP( - cfgOptionIdxStr(cfgOptRepoPath, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHost, repoIdx), - cfgOptionIdxUInt(cfgOptRepoSftpHostPort, repoIdx), cfgOptionIdxStr(cfgOptRepoSftpHostUser, repoIdx), - cfgOptionUInt64(cfgOptIoTimeout), cfgOptionIdxStr(cfgOptRepoSftpPrivateKeyFile, repoIdx), - cfgOptionIdxStrId(cfgOptRepoSftpHostKeyHashType, repoIdx), .modeFile = STORAGE_MODE_FILE_DEFAULT, - .modePath = STORAGE_MODE_PATH_DEFAULT, .keyPub = cfgOptionIdxStrNull(cfgOptRepoSftpPublicKeyFile, repoIdx), - .keyPassphrase = cfgOptionIdxStrNull(cfgOptRepoSftpPrivateKeyPassphrase, repoIdx), - .hostFingerprint = cfgOptionIdxStrNull(cfgOptRepoSftpHostFingerprint, repoIdx), - .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), - .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), - "new storage (defaults)"); - TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage"); - TEST_ERROR_FMT( - memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), ServiceError, - "timeout freeing libssh2 session: libssh2 errno [-37]"); + TEST_ASSIGN(storageTest, storageSftpHelper(0, true, NULL), "new storage"); + TEST_ASSIGN(storageSftp, storageDriver(storageTest), "storage driver"); + TEST_ERROR_FMT(objFree(storageTest), ServiceError, "timeout freeing libssh2 session: libssh2 errno [-37]"); #else TEST_LOG(PROJECT_NAME " not built with sftp support"); #endif // HAVE_LIBSSH2