Test external mail response parsing
This commit is contained in:
@@ -32,3 +32,15 @@ target_link_libraries(bongocollector
|
||||
)
|
||||
|
||||
install(TARGETS bongocollector DESTINATION ${SBIN_INSTALL_DIR})
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_executable(collector-transport-test
|
||||
tests/external-transport-test.c
|
||||
external_transport.c
|
||||
)
|
||||
target_include_directories(collector-transport-test PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
target_link_libraries(collector-transport-test ${CURL_LIBRARIES})
|
||||
add_test(NAME collector-external-transport COMMAND collector-transport-test)
|
||||
endif()
|
||||
|
||||
@@ -97,12 +97,17 @@ AddId(CollectorRemoteIds *ids, const char *uid, size_t uid_length,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ParsePop3Ids(char *response, CollectorRemoteIds *ids)
|
||||
int
|
||||
CollectorRemoteParsePop3(const char *response, CollectorRemoteIds *ids)
|
||||
{
|
||||
char *copy;
|
||||
char *line;
|
||||
char *save = NULL;
|
||||
for (line = strtok_r(response, "\r\n", &save); line != NULL;
|
||||
int result = 0;
|
||||
if (response == NULL || ids == NULL) return -1;
|
||||
copy = strdup(response);
|
||||
if (copy == NULL) return -1;
|
||||
for (line = strtok_r(copy, "\r\n", &save); line != NULL;
|
||||
line = strtok_r(NULL, "\r\n", &save)) {
|
||||
char *number_end;
|
||||
char *uid;
|
||||
@@ -115,19 +120,26 @@ ParsePop3Ids(char *response, CollectorRemoteIds *ids)
|
||||
uid = number_end;
|
||||
while (isspace((unsigned char) *uid)) uid++;
|
||||
if (*uid != '\0' && AddId(ids, uid, strcspn(uid, " \t"),
|
||||
line, number_length) != 0) return -1;
|
||||
line, number_length) != 0) {
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
free(copy);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
ParseImapIds(char *response, CollectorRemoteIds *ids)
|
||||
int
|
||||
CollectorRemoteParseImap(const char *response, CollectorRemoteIds *ids)
|
||||
{
|
||||
char *search = strstr(response, "SEARCH");
|
||||
char *validity = strstr(response, "UIDVALIDITY");
|
||||
char *token;
|
||||
const char *search;
|
||||
const char *validity;
|
||||
const char *token;
|
||||
if (response == NULL || ids == NULL) return -1;
|
||||
search = strstr(response, "SEARCH");
|
||||
validity = strstr(response, "UIDVALIDITY");
|
||||
if (validity != NULL) {
|
||||
char *end;
|
||||
const char *end;
|
||||
validity += strlen("UIDVALIDITY");
|
||||
while (*validity != '\0' && !isdigit((unsigned char) *validity)) validity++;
|
||||
end = validity;
|
||||
@@ -140,7 +152,7 @@ ParseImapIds(char *response, CollectorRemoteIds *ids)
|
||||
if (search == NULL) return 0;
|
||||
token = search + strlen("SEARCH");
|
||||
while (*token != '\0' && *token != '\r' && *token != '\n') {
|
||||
char *end;
|
||||
const char *end;
|
||||
while (isspace((unsigned char) *token)) token++;
|
||||
if (!isdigit((unsigned char) *token)) break;
|
||||
end = token;
|
||||
@@ -425,7 +437,8 @@ CollectorRemoteList(const CollectorExternalAccount *account,
|
||||
if (response.data == NULL) goto done;
|
||||
}
|
||||
result = strcmp(account->inbound_protocol, "imap") == 0 ?
|
||||
ParseImapIds(response.data, ids) : ParsePop3Ids(response.data, ids);
|
||||
CollectorRemoteParseImap(response.data, ids) :
|
||||
CollectorRemoteParsePop3(response.data, ids);
|
||||
if (result != 0) {
|
||||
CollectorRemoteIdsFree(ids);
|
||||
SetError(error, error_size, "too many remote messages or insufficient memory");
|
||||
|
||||
@@ -29,4 +29,8 @@ int CollectorRemoteDelete(const CollectorExternalAccount *account,
|
||||
char *error, size_t error_size);
|
||||
void CollectorRemoteIdsFree(CollectorRemoteIds *ids);
|
||||
|
||||
/* Exposed for protocol parser tests and offline response validation. */
|
||||
int CollectorRemoteParsePop3(const char *response, CollectorRemoteIds *ids);
|
||||
int CollectorRemoteParseImap(const char *response, CollectorRemoteIds *ids);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "external_transport.h"
|
||||
|
||||
static int
|
||||
CheckPop3(void)
|
||||
{
|
||||
CollectorRemoteIds ids = {0};
|
||||
const char response[] = "+OK 2 messages\r\n1 alpha-uid\r\n2 beta-uid\r\n.\r\n";
|
||||
int failed = CollectorRemoteParsePop3(response, &ids) != 0 ||
|
||||
ids.count != 2 || strcmp(ids.items[0].locator, "1") != 0 ||
|
||||
strcmp(ids.items[0].uid, "alpha-uid") != 0 ||
|
||||
strcmp(ids.items[1].locator, "2") != 0 ||
|
||||
strcmp(ids.items[1].uid, "beta-uid") != 0;
|
||||
CollectorRemoteIdsFree(&ids);
|
||||
return failed;
|
||||
}
|
||||
|
||||
static int
|
||||
CheckImap(void)
|
||||
{
|
||||
CollectorRemoteIds ids = {0};
|
||||
const char response[] = "* OK [UIDVALIDITY 4242] valid\r\n* SEARCH 7 99 101\r\n";
|
||||
int failed = CollectorRemoteParseImap(response, &ids) != 0 ||
|
||||
strcmp(ids.uidvalidity, "4242") != 0 || ids.count != 3 ||
|
||||
strcmp(ids.items[0].uid, "7") != 0 ||
|
||||
strcmp(ids.items[1].uid, "99") != 0 ||
|
||||
strcmp(ids.items[2].locator, "101") != 0;
|
||||
CollectorRemoteIdsFree(&ids);
|
||||
return failed;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
if (CheckPop3() || CheckImap()) {
|
||||
fprintf(stderr, "external transport parser test failed\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user