diff options
-rw-r--r-- | check/magma/magma_check.c | 1 | ||||
-rw-r--r-- | check/magma/magma_check.h | 1 | ||||
-rw-r--r-- | check/magma/servers/http/http_check.c | 24 | ||||
-rw-r--r-- | check/magma/servers/http/http_check.h | 1 | ||||
-rw-r--r-- | check/magma/servers/http/http_check_network.c | 70 | ||||
-rw-r--r-- | check/magma/servers/imap/imap_check_network.c | 462 | ||||
-rw-r--r-- | check/magma/servers/json/json_check.c | 36 | ||||
-rw-r--r-- | check/magma/servers/json/json_check.h | 13 | ||||
-rw-r--r-- | dev/scripts/test/.t.camel.sh.swp | bin | 0 -> 24576 bytes |
9 files changed, 288 insertions, 320 deletions
diff --git a/check/magma/magma_check.c b/check/magma/magma_check.c index 4b1b0922..c73e0965 100644 --- a/check/magma/magma_check.c +++ b/check/magma/magma_check.c @@ -283,6 +283,7 @@ int main(int argc, char *argv[]) { srunner_add_suite(sr, suite_check_pop()); srunner_add_suite(sr, suite_check_imap()); srunner_add_suite(sr, suite_check_http()); + srunner_add_suite(sr, suite_check_json()); srunner_add_suite(sr, suite_check_regression()); } diff --git a/check/magma/magma_check.h b/check/magma/magma_check.h index 4778af8e..ac59a406 100644 --- a/check/magma/magma_check.h +++ b/check/magma/magma_check.h @@ -35,6 +35,7 @@ #include "servers/pop/pop_check.h" #include "servers/imap/imap_check.h" #include "servers/http/http_check.h" +#include "servers/json/json_check.h" #include "regression/regression_check.h" #include "config/config_check.h" diff --git a/check/magma/servers/http/http_check.c b/check/magma/servers/http/http_check.c index 63aeba6f..e9df914c 100644 --- a/check/magma/servers/http/http_check.c +++ b/check/magma/servers/http/http_check.c @@ -53,12 +53,36 @@ START_TEST (check_http_network_basic_tls_s) { } END_TEST +START_TEST (check_http_network_options_s) { + + log_disable(); + bool_t outcome = true; + server_t *server = NULL; + stringer_t *errmsg = MANAGEDBUF(1024); + + if (!(server = servers_get_by_protocol(HTTP, true))) { + st_sprint(errmsg, "No HTTP servers were configured to support TCP connections."); + outcome = false; + } + else if (status() && !check_http_network_options_sthread(errmsg, server->network.port, true)) { + outcome = false; + } + else { + errmsg = NULL; + } + + log_test("HTTP / NETWORK / OPTIONS / SINGLE THREADED:", errmsg); + ck_assert_msg(outcome, st_char_get(errmsg)); +} +END_TEST + Suite * suite_check_http(void) { Suite *s = suite_create("\tHTTP"); suite_check_testcase(s, "HTTP", "HTTP Network Basic/ TCP/S", check_http_network_basic_tcp_s); suite_check_testcase(s, "HTTP", "HTTP Network Basic/ TLS/S", check_http_network_basic_tls_s); + suite_check_testcase(s, "HTTP", "HTTP Network Options/S", check_http_network_options_s); return s; } diff --git a/check/magma/servers/http/http_check.h b/check/magma/servers/http/http_check.h index e6eac8e7..261859d3 100644 --- a/check/magma/servers/http/http_check.h +++ b/check/magma/servers/http/http_check.h @@ -12,6 +12,7 @@ bool_t check_http_read_to_empty(client_t *client); uint32_t check_http_content_length_get(client_t *client, stringer_t *errmsg); bool_t check_http_content_length_test(client_t *client, uint32_t content_length, stringer_t *errmsg); bool_t check_http_network_basic_sthread(stringer_t *errmsg, uint32_t port, bool_t secure); +bool_t check_http_network_options_sthread(stringer_t *errmsg, uint32_t port, bool_t secure); Suite * suite_check_http(void); diff --git a/check/magma/servers/http/http_check_network.c b/check/magma/servers/http/http_check_network.c index 9ea10fc4..75e57153 100644 --- a/check/magma/servers/http/http_check_network.c +++ b/check/magma/servers/http/http_check_network.c @@ -73,6 +73,38 @@ bool_t check_http_content_length_test(client_t *client, uint32_t content_length, return (total == content_length); } +/** + * @brief Reads lines from the client, checking if each of the options are present. + * + * @param client A client_t* that should be connected to an HTTP server and has had the OPTIONS request + * submitted already. + * @param options An array of chr_t* containing the options that should be in the response. + * @return True if all of the options were present, false otherwise. + */ +bool_t check_http_options(client_t *client, chr_t *options[], stringer_t *errmsg) { + + bool_t opts_present[sizeof(options)/sizeof(chr_t*)] = { false }; + + while (st_cmp_ci_starts(&client->line, NULLER("\r\n")) != 0) { + for (size_t i = 0; i < (sizeof(options)/sizeof(chr_t*)); i++) { + if (st_cmp_cs_starts(&client->line, NULLER(options[i]))) { + opts_present[i] = true; + break; + } + } + client_read_line(client); + } + + for (size_t i = 0; i < (sizeof(opts_present)/sizeof(bool_t)); i++) { + if (!opts_present[i]) { + st_sprint(errmsg, "One of the HTTP options was not present in the response. { option = \"%s\" }", options[i]); + return false; + } + } + + return true; +} + bool_t check_http_network_basic_sthread(stringer_t *errmsg, uint32_t port, bool_t secure) { size_t content_length; @@ -87,16 +119,52 @@ bool_t check_http_network_basic_sthread(stringer_t *errmsg, uint32_t port, bool_ return false; } // Test submitting a GET request. - else if (client_print(client, "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n") != 35 || client_status(client) != 1 || + else if (client_print(client, "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n") != 37 || client_status(client) != 1 || !(content_length = check_http_content_length_get(client, errmsg))) { if (st_empty(errmsg)) st_sprint(errmsg, "Failed to return a valid GET response."); + client_close(client); return false; } // Test the response. else if (check_http_content_length_test(client, content_length, errmsg)) { if (st_empty(errmsg)) st_sprint(errmsg, "The content length and actual body length of the GET response did not match."); + client_close(client); + return false; + } + + client_close(client); + + return true; +} + +bool_t check_http_network_options_sthread(stringer_t *errmsg, uint32_t port, bool_t secure) { + + client_t *client = NULL; + chr_t *options[] = { + "Connection: close", + "Content-Length: 0", + "Content-Type: text/plain", + "Allow: GET, POST, OPTIONS", + "Access-Control-Max-Age: 86400", + "Access-Control-Allow-Origin: *", + "Access-Control-Allow-Credentials: true" + }; + + // Test the connection. + if (!(client = client_connect("localhost", port)) || (secure && (client_secure(client) == -1)) || + client_status(client) != 1) { + + st_sprint(errmsg, "Failed to connect with the HTTP server."); + client_close(client); + return false; + } + // Test OPTIONS + else if (client_print(client, "OPTIONS /portal/camel HTTP/1.1\r\n\r\n") != 34 || client_status(client) != 1 || + !check_http_options(client, options, errmsg)) { + + client_close(client); return false; } diff --git a/check/magma/servers/imap/imap_check_network.c b/check/magma/servers/imap/imap_check_network.c index d8137ee0..24a16215 100644 --- a/check/magma/servers/imap/imap_check_network.c +++ b/check/magma/servers/imap/imap_check_network.c @@ -64,7 +64,7 @@ bool_t check_imap_client_login(client_t *client, chr_t *user, chr_t *pass, chr_t } /** - * @brief Prints the SELECT command to the passed client using the passed parameter. + * @brief Prints the SELECT command to the passed client using the passed parameters. * * @param client The client_t* to print the command to. It should be connected to an IMAP server. * @param folder A chr_t* holding the name of the folder to select. @@ -85,24 +85,60 @@ bool_t check_imap_client_select(client_t *client, chr_t *folder, chr_t *tag, str return true; } -bool_t check_imap_client_close_logout(client_t *client, stringer_t *errmsg) { +/** + * @brief Prints the CLOSE and LOGOUT commands to the passed client using the passed tag. + * + * @param client The client_t* to print the commands to. It should be connected to an IMAP server. + * @param tag_num A uint32_t holding the sequence tag number from the last command. + * @param errmsg A stringer_t* into which the error message will be printed in the even of an error. + * @return True if the commands were successful, otherwise false. + */ +bool_t check_imap_client_close_logout(client_t *client, uint32_t tag_num, stringer_t *errmsg) { + + stringer_t *tag = NULL, *command = NULL, *success = NULL; + tag_num += 1; + + // Construct the tag, close_command, and success stringers for CLOSE. + if (!(tag = st_alloc_opts(MANAGED_T | CONTIGUOUS | HEAP, 1024)) || (st_sprint(tag, "A%u", tag_num) != uint32_digits(tag_num)+1) || + !(command = st_merge("sn", tag, " CLOSE\r\n")) || !(success = st_merge("sn", tag, " OK"))) { + + st_sprint(errmsg, "Failed to construct tag, command, or success strings for CLOSE."); + st_cleanup(tag, command, success); + return false; + } // Test the CLOSE command. - if (client_print(client, "A4 CLOSE\r\n") <= 0 || !check_imap_client_read_end(client, "A4") || - client_status(client) != 1 || st_cmp_cs_starts(&(client->line), NULLER("A4 OK"))) { + else if (client_print(client, st_char_get(command)) != st_length_get(command) || + !check_imap_client_read_end(client, st_char_get(tag)) || client_status(client) != 1 || + st_cmp_cs_starts(&(client->line), success)) { st_sprint(errmsg, "Failed to return a successful state after CLOSE."); + st_cleanup(tag, command, success); return false; } + //st_cleanup(tag, command, success); + tag_num += 1; + + // Construct the tag, close_command, and success stringers for LOGOUT. + if (!(tag = st_alloc_opts(MANAGED_T | CONTIGUOUS | HEAP, 1024)) || (st_sprint(tag, "A%u", tag_num) != uint32_digits(tag_num)+1) || + !(command = st_merge("sn", tag, " LOGOUT\r\n")) || !(success = st_merge("sn", tag, " OK"))) { + + st_sprint(errmsg, "Failed to construct tag, command, or success strings for LOGOUT."); + st_cleanup(tag, command, success); + return false; + } // Test the LOGOUT command. - else if (client_print(client, "A5 LOGOUT\r\n") <= 0 || !check_imap_client_read_end(client, "A5") || - client_status(client) != 1 || st_cmp_cs_starts(&(client->line), NULLER("A5 OK"))) { + else if (client_print(client, st_char_get(command)) != st_length_get(command) || + !check_imap_client_read_end(client, st_char_get(tag)) || client_status(client) != 1 || + st_cmp_cs_starts(&(client->line), success)) { st_sprint(errmsg, "Failed to return a successful state after LOGOUT."); + st_cleanup(tag, command, success); return false; } + st_cleanup(tag, command, success); return true; } @@ -170,10 +206,47 @@ bool_t check_imap_network_basic_sthread(stringer_t *errmsg, uint32_t port, bool_ return true; } - bool_t check_imap_network_search_sthread(stringer_t *errmsg, uint32_t port, bool_t secure) { + uint32_t tag_num = 0; client_t *client = NULL; + stringer_t *tag = NULL, *command = NULL, *success = NULL; + chr_t *commands[] = { + "SEARCH ALL\r\n", + "SEARCH ANSWERED\r\n", + "SEARCH BCC\r\n", + "SEARCH BEFORE 01-Apr-2017\r\n", + "SEARCH BODY Hello\r\n", + "SEARCH CC\r\n", + "SEARCH DELETED\r\n", + "SEARCH FLAGGED\r\n", + "SEARCH FROM ladar@lavabit.com\r\n", + "SEARCH HEADER lavabit\r\n", + "SEARCH KEYWORD Seen\r\n", + "SEARCH LARGER 1024\r\n", + "SEARCH NEW\r\n", + "SEARCH NOT Seen\r\n", + "SEARCH OLD\r\n", + "SEARCH ON 23-Mar-2017\r\n", + "SEARCH OR Seen Flagged\r\n", + "SEARCH RECENT\r\n", + "SEARCH SEEN\r\n", + "SEARCH SENTBEFORE 23-Mar-2017\r\n", + "SEARCH SENTON 23-Mar-2017\r\n", + "SEARCH SENTSINCE 01-Jan-2017\r\n", + "SEARCH SINCE 01-Jan-2017\r\n", + "SEARCH SMALLER 30960\r\n", + "SEARCH SUBJECT lavabit\r\n", + "SEARCH TEXT lavabit\r\n", + "SEARCH TO ladar@lavabit.com\r\n", + "SEARCH UID 1\r\n", + "SEARCH UNANSWERED\r\n", + "SEARCH UNDELETED\r\n", + "SEARCH UNDRAFT\r\n", + "SEARCH UNFLAGGED\r\n", + "SEARCH UNKEYWORD Seen\r\n", + "SEARCH UNSEEN\r\n" + }; // Check the initial response. if (!(client = client_connect("localhost", port)) || (secure && (client_secure(client) == -1)) || @@ -186,307 +259,69 @@ bool_t check_imap_network_search_sthread(stringer_t *errmsg, uint32_t port, bool } // Test the LOGIN command. else if (!check_imap_client_login(client, "princess", "password", "A0", errmsg)) { - return false; - } - // Test the SELECT command. - else if (!check_imap_client_select(client, "Inbox", "A1", errmsg)) { - return false; - } - // Test SEARCH ALL - else if (client_print(client, "A2 SEARCH ALL\r\n") <= 0 || !check_imap_client_read_end(client, "A2") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A2 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH ALL."); - client_close(client); - return false; - } - // Test SEARCH ANSWERED - else if (client_print(client, "A3 SEARCH ANSWERED\r\n") <= 0 || !check_imap_client_read_end(client, "A3") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A3 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH ANSWERED."); - client_close(client); - return false; - } - // Test SEARCH BCC <string> - else if (client_print(client, "A4 SEARCH BCC\r\n") <= 0 || !check_imap_client_read_end(client, "A4") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A4 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH BCC."); - client_close(client); - return false; - } - // Test SEARCH BEFORE <date> - // MID: replace the hard coded date with a dynamic one based on the current date. - else if (client_print(client, "A5 SEARCH BEFORE 01-Apr-2017\r\n") <= 0 || !check_imap_client_read_end(client, "A5") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A5 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH BEFORE."); - client_close(client); - return false; - } - // Test SEARCH BODY <string> - else if (client_print(client, "A6 SEARCH BODY Hello\r\n") <= 0 || !check_imap_client_read_end(client, "A6") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A6 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH BODY."); - client_close(client); - return false; - } - // Test SEARCH CC <string> - else if (client_print(client, "A7 SEARCH CC\r\n") <= 0 || !check_imap_client_read_end(client, "A7") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A7 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH CC."); - client_close(client); - return false; - } - // Test SEARCH DELETED - else if (client_print(client, "A8 SEARCH DELETED\r\n") <= 0 || !check_imap_client_read_end(client, "A8") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A8 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH DELETED."); - client_close(client); - return false; - } - // Test SEARCH DRAFT - else if (client_print(client, "A9 SEARCH DRAFT\r\n") <= 0 || !check_imap_client_read_end(client, "A9") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A9 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH DRAFT."); - client_close(client); - return false; - } - // Test SEARCH FLAGGED - else if (client_print(client, "A10 SEARCH FLAGGED\r\n") <= 0 || !check_imap_client_read_end(client, "A10") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A10 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH FLAGGED."); - client_close(client); - return false; - } - // Test SEARCH FROM <string> - else if (client_print(client, "A11 SEARCH FROM ladar@lavabit.com\r\n") <= 0 || !check_imap_client_read_end(client, "A11") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A11 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH FROM."); - client_close(client); - return false; - } - // Test SEARCH HEADER <field> <string> - else if (client_print(client, "A12 SEARCH HEADER lavabit\r\n") <= 0 || !check_imap_client_read_end(client, "A12") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A12 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH HEADER."); - client_close(client); - return false; - } - // Test SEARCH KEYWORD <flag> - else if (client_print(client, "A13 SEARCH KEYWORD Seen\r\n") <= 0 || !check_imap_client_read_end(client, "A13") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A13 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH KEYWORD."); - client_close(client); - return false; - } - // Test SEARCH LARGER <n> - else if (client_print(client, "A14 SEARCH LARGER 1024\r\n") <= 0 || !check_imap_client_read_end(client, "A14") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A14 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH LARGER."); - client_close(client); - return false; - } - // Test SEARCH NEW - else if (client_print(client, "A15 SEARCH NEW\r\n") <= 0 || !check_imap_client_read_end(client, "A15") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A15 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH NEW."); - client_close(client); - return false; - } - // Test SEARCH NOT <search-key> - else if (client_print(client, "A16 SEARCH NOT Seen\r\n") <= 0 || !check_imap_client_read_end(client, "A16") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A16 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH NOT."); - client_close(client); - return false; - } - // Test SEARCH OLD - else if (client_print(client, "A17 SEARCH OLD\r\n") <= 0 || !check_imap_client_read_end(client, "A17") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A17 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH OLD."); - client_close(client); - return false; - } - // Test SEARCH ON <date> - // MID: The hard coded date needs to be changed to a dynamic one based on the current date. - else if (client_print(client, "A18 SEARCH ON 23-Mar-2017\r\n") <= 0 || !check_imap_client_read_end(client, "A18") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A18 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH ON."); - client_close(client); - return false; - } - // Test SEARCH OR <search-key> <search-key> - else if (client_print(client, "A19 SEARCH OR Seen Flagged\r\n") <= 0 || !check_imap_client_read_end(client, "A19") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A19 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH OR."); - client_close(client); - return false; - } - // Test SEARCH RECENT - else if (client_print(client, "A20 SEARCH RECENT\r\n") <= 0 || !check_imap_client_read_end(client, "A20") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A20 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH RECENT."); - client_close(client); - return false; - } - // Test SEARCH SEEN - else if (client_print(client, "A21 SEARCH SEEN\r\n") <= 0 || !check_imap_client_read_end(client, "A21") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A21 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH SEEN."); - client_close(client); - return false; - } - // Test SEARCH SENTBEFORE <date> - else if (client_print(client, "A22 SEARCH SENTBEFORE 23-Mar-2017\r\n") <= 0 || !check_imap_client_read_end(client, "A22") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A22 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH SENTBEFORE."); - client_close(client); - return false; - } - // Test SEARCH SENTON <date> - else if (client_print(client, "A23 SEARCH 23-Mar-2017\r\n") <= 0 || !check_imap_client_read_end(client, "A23") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A23 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH SENTON."); - client_close(client); - return false; - } - // Test SEARCH SENTSINCE <date> - else if (client_print(client, "A24 SEARCH SENTSINCE 01-Jan-2017\r\n") <= 0 || !check_imap_client_read_end(client, "A24") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A24 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH SENTSINCE."); - client_close(client); - return false; - } - // Test SEARCH SINCE <date> - else if (client_print(client, "A25 SEARCH SINCE 01-Jan-2017\r\n") <= 0 || !check_imap_client_read_end(client, "A25") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A25 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH SINCE."); - client_close(client); - return false; - } - // Test SEARCH SMALLER <n> - else if (client_print(client, "A26 SEARCH SMALLER 30960\r\n") <= 0 || !check_imap_client_read_end(client, "A26") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A26 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH SMALLER."); - client_close(client); - return false; - } - // Test SEARCH SUBJECT <string> - else if (client_print(client, "A27 SEARCH SUBJECT lavabit\r\n") <= 0 || !check_imap_client_read_end(client, "A27") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A27 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH SUBJECT."); - client_close(client); - return false; - } - // Test SEARCH TEXT <string> - else if (client_print(client, "A28 SEARCH TEXT lavabit\r\n") <= 0 || !check_imap_client_read_end(client, "A28") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A28 OK Search complete.\r\n"))) { - - st_sprint(errmsg, "Failed to return a successful status after SEARCH TEXT."); - client_close(client); - return false; - } - // Test SEARCH TO <string> - else if (client_print(client, "A29 SEARCH TO ladar@lavabit.com\r\n") <= 0 || !check_imap_client_read_end(client, "A29") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A29 OK Search complete.\r\n"))) { - st_sprint(errmsg, "Failed to return a successful status after SEARCH TO."); client_close(client); return false; } - // Test SEARCH UID <sequence set> - else if (client_print(client, "A30 SEARCH UID 1\r\n") <= 0 || !check_imap_client_read_end(client, "A30") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A30 OK Search complete.\r\n"))) { + // Test the SELECT command. + else if (!check_imap_client_select(client, "Inbox", "A1", errmsg)) { - st_sprint(errmsg, "Failed to return a successful status after SEARCH UID."); client_close(client); return false; } - // Test SEARCH UNANSWERED - else if (client_print(client, "A31 SEARCH UNANSWERED\r\n") <= 0 || !check_imap_client_read_end(client, "A31") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A31 OK Search complete.\r\n"))) { - st_sprint(errmsg, "Failed to return a successful status after SEARCH UNANSWERED."); - client_close(client); - return false; - } - // Test SEARCH UNDELETED - else if (client_print(client, "A32 SEARCH UNDELETED\r\n") <= 0 || !check_imap_client_read_end(client, "A32") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A32 OK Search complete.\r\n"))) { + // Test each of the commands. + for (uint32_t i = 0; i < sizeof(commands)/sizeof(chr_t*); i++) { - st_sprint(errmsg, "Failed to return a successful status after SEARCH UNDELETED."); - client_close(client); - return false; - } - // Test SEARCH UNDRAFT - else if (client_print(client, "A33 SEARCH UNDRAFT\r\n") <= 0 || !check_imap_client_read_end(client, "A33") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A33 OK Search complete.\r\n"))) { + tag_num = i + 2; - st_sprint(errmsg, "Failed to return a successful status after SEARCH UNDRAFT."); - client_close(client); - return false; - } - // Test SEARCH UNFLAGGED - else if (client_print(client, "A34 SEARCH UNFLAGGED\r\n") <= 0 || !check_imap_client_read_end(client, "A34") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A34 OK Search complete.\r\n"))) { + if (!(tag = st_alloc_opts(MANAGED_T | CONTIGUOUS | HEAP, 1024)) ||//(uint32_digits(tag_num) +1))) || + (st_sprint(tag, "A%u", tag_num) != uint32_digits(tag_num)+1) || !(command = st_merge("snn", tag, " ", commands[i])) || + !(success = st_merge("sn", tag, " OK Search complete.\r\n"))) { - st_sprint(errmsg, "Failed to return a successful status after SEARCH UNFLAGGED."); - client_close(client); - return false; - } - // Test SEARCH UNKEYWORD <flag> - else if (client_print(client, "A35 SEARCH UNKEYWORD Seen\r\n") <= 0 || !check_imap_client_read_end(client, "A35") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A35 OK Search complete.\r\n"))) { + st_sprint(errmsg, "Failed to construct the command or success strings. { i = %d }", i); + st_cleanup(tag, command, success); + client_close(client); + return false; + } + else if (client_print(client, st_char_get(command)) <= 0 || !check_imap_client_read_end(client, st_char_get(tag)) || + client_status(client) != 1 || st_cmp_cs_eq(&(client->line), success)) { - st_sprint(errmsg, "Failed to return a successful status after SEARCH UNKEYWORD."); - client_close(client); - return false; - } - // Test SEARCH UNSEEN - else if (client_print(client, "A36 SEARCH UNSEEN\r\n") <= 0 || !check_imap_client_read_end(client, "A36") || - client_status(client) != 1 || st_cmp_cs_eq(&(client->line), NULLER("A36 OK Search complete.\r\n"))) { + st_sprint(errmsg, "Failed to return a successful status. { command = \"%s\" }", st_char_get(command)); + st_cleanup(tag, command, success); + client_close(client); + return false; + } - st_sprint(errmsg, "Failed to return a successful status after SEARCH UNSEEN."); - client_close(client); - return false; + st_cleanup(tag, command, success); } - else if (!check_imap_client_close_logout(client, errmsg)) { + // Test the CLOSE and LOGOUT commands; + if (!check_imap_client_close_logout(client, tag_num+1, errmsg)) { client_close(client); + st_cleanup(tag); return false; } + client_close(client); + st_cleanup(tag); return true; } bool_t check_imap_network_fetch_sthread(stringer_t *errmsg, uint32_t port, bool_t secure) { + uint32_t tag_num = 0; client_t *client = NULL; + stringer_t *tag = NULL, *command = NULL, *success = NULL; + chr_t *commands[] = { + "FETCH 1:* FLAGS\r\n", + "FETCH 1 (BODY [])\r\n", + "FETCH 1:* INTERNALDATE\r\n" + "FETCH 1 (BODY [HEADER])\r\n", + "FETCH 1 (BODY.PEEK[HEADER])\r\n", + "FETCH 1 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)])\r\n" + }; // Check the initial response. if (!(client = client_connect("localhost", port)) || (secure && (client_secure(client) == -1)) || @@ -499,62 +334,51 @@ bool_t check_imap_network_fetch_sthread(stringer_t *errmsg, uint32_t port, bool_ } // Test the LOGIN command. else if (!check_imap_client_login(client, "princess", "password", "A0", errmsg)) { + + client_close(client); return false; } // Test the SELECT command. else if (!check_imap_client_select(client, "Inbox", "A1", errmsg)) { - return false; - } - // Test FETCH 1 (BODY.PEEK[HEADER]) and make sure the message is not marked as seen - else if (client_print(client, "A2 FETCH 1 (BODY.PEEK[HEADER])\r\n") <= 0 || !check_imap_client_read_end(client, "A2") || - client_status(client) != 1 || st_cmp_cs_starts(&(client->line), NULLER("A2 OK"))) { - st_sprint(errmsg, "Failed to return a successful status after FETCH 1 (BODY.PEEK[HEADER])."); client_close(client); return false; } - // Test FETCH 1 (BODY [HEADER]) - else if (client_print(client, "A3 FETCH 1 (BODY [HEADER])\r\n") <= 0 || !check_imap_client_read_end(client, "A3") || - client_status(client) != 1 || st_cmp_cs_starts(&(client->line), NULLER("A3 OK"))) { + // Test each of the commands. + for (uint32_t i = 0; i < sizeof(commands)/sizeof(chr_t*); i++) { - st_sprint(errmsg, "Failed to return a successful status after FETCH 1 BODY [HEADER]."); - client_close(client); - return false; - } - // Test FETCH 1 (BODY[]) - else if (client_print(client, "A4 FETCH 1 (BODY [])\r\n") <= 0 || !check_imap_client_read_end(client, "A4") || - client_status(client) != 1 || st_cmp_cs_starts(&(client->line), NULLER("A4 OK"))) { + tag_num = i + 2; - st_sprint(errmsg, "Failed to return a successful status after FETCH 1 (BODY [])."); - client_close(client); - return false; - } - // Test FETCH 1 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)]) - else if (client_print(client, "A5 FETCH 1 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)])\r\n") <= 0 || - !check_imap_client_read_end(client, "A5") || client_status(client) != 1 || st_cmp_cs_starts(&(client->line), - NULLER("A5 OK"))) { + if (!(tag = st_alloc_opts(MANAGED_T | CONTIGUOUS | HEAP, 1024)) ||//(uint32_digits(tag_num) +1))) || + (st_sprint(tag, "A%u", tag_num) != uint32_digits(tag_num)+1) || !(command = st_merge("snn", tag, " ", commands[i])) || + !(success = st_merge("sn", tag, " OK"))) { - st_sprint(errmsg, "Failed to return a successful status after FETCH 1 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)])."); - client_close(client); - return false; - } - // Test FETCH 1:* FLAGS - else if (client_print(client, "A6 FETCH 1:* FLAGS\r\n") <= 0 || !check_imap_client_read_end(client, "A6") || - client_status(client) != 1 || st_cmp_cs_starts(&(client->line), NULLER("A6 OK"))) { + st_sprint(errmsg, "Failed to construct the command or success strings. { i = %d }", i); + st_cleanup(tag, command, success); + client_close(client); + return false; + } + else if (client_print(client, st_char_get(command)) <= 0 || !check_imap_client_read_end(client, st_char_get(tag)) || + client_status(client) != 1 || st_cmp_cs_starts(&(client->line), success)) { - st_sprint(errmsg, "Failed to return a successful status after FETCH 1 1:* FLAGS."); - client_close(client); - return false; + st_sprint(errmsg, "Failed to return a successful status. { command = \"%s\" }", st_char_get(command)); + st_cleanup(tag, command, success); + client_close(client); + return false; + } + + st_cleanup(tag, command, success); } - // Test FETCH 1:* INTERNALDATE - else if (client_print(client, "A7 FETCH 1:* INTERNALDATE\r\n") <= 0 || !check_imap_client_read_end(client, "A7") || - client_status(client) != 1 || st_cmp_cs_starts(&(client->line), NULLER("A7 OK"))) { + // Test the CLOSE and LOGOUT commands; + if (!check_imap_client_close_logout(client, tag_num+1, errmsg)) { - st_sprint(errmsg, "Failed to return a successful status after FETCH 1:* INTERNALDATE."); client_close(client); + st_cleanup(tag); return false; } + client_close(client); + st_cleanup(tag); return true; } diff --git a/check/magma/servers/json/json_check.c b/check/magma/servers/json/json_check.c new file mode 100644 index 00000000..a7c14d7f --- /dev/null +++ b/check/magma/servers/json/json_check.c @@ -0,0 +1,36 @@ +/** + * @file /check/magma/json/json_check.c + * + * @brief JSON Web API test functions. + */ + +#include "magma_check.h" + +START_TEST (check_json_network_basic_s) { + + log_disable(); + bool_t outcome = true; + client_t *client = NULL; + stringer_t *errmsg = MANAGEDBUF(1024); + if (status() && !(client = client_connect("localhost/json", 10000))) { + + st_sprint(errmsg, "Failed to connect to JSON Web API endpoint."); + outcome = false; + } + else { + errmsg = NULL; + } + + log_test("IMAP / NETWORK / FETCH / SINGLE THREADED:", errmsg); + ck_assert_msg(outcome, st_char_get(errmsg)); +} +END_TEST + +Suite * suite_check_json(void) { + + Suite *s = suite_create("\tJSON"); + + suite_check_testcase(s, "JSON", "JSON Network Basic/S", check_json_network_basic_s); + + return s; +} diff --git a/check/magma/servers/json/json_check.h b/check/magma/servers/json/json_check.h new file mode 100644 index 00000000..1271bbfd --- /dev/null +++ b/check/magma/servers/json/json_check.h @@ -0,0 +1,13 @@ +/* + * @file /check/magma/servers/json/json_check.h + * + * @brief JSON Web API test functions. + */ + +#ifndef JSON_CHECK_H +#define JSON_CHECK_H + +/// pop_check.c +Suite * suite_check_json(void); + +#endif diff --git a/dev/scripts/test/.t.camel.sh.swp b/dev/scripts/test/.t.camel.sh.swp Binary files differnew file mode 100644 index 00000000..cb7a3ba3 --- /dev/null +++ b/dev/scripts/test/.t.camel.sh.swp |