test-imapc-client.c revision 204ee6ed414f5e4eeb6f6c10763b55daf56f11ac
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include "lib.h"
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include "array.h"
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include "hostpid.h"
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include "net.h"
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include "fd-set-nonblock.h"
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include "istream.h"
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include "ostream.h"
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen#include "ioloop.h"
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include "unlink-directory.h"
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen#include "test-common.h"
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen#include "imapc-client-private.h"
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include <stdio.h>
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include <unistd.h>
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include <signal.h>
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include <sys/stat.h>
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#include <sys/wait.h>
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#define IMAPC_COMMAND_STATE_INVALID (enum imapc_command_state)-1
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainentypedef void test_server_init_t(void);
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainentypedef void test_client_init_t(void);
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstruct test_server {
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen in_port_t port;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen pid_t pid;
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen int fd_listen, fd;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct istream *input;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ostream *output;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen};
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct ip_addr bind_ip;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct test_server server;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct imapc_client *imapc_client;
09060303d565e15d54e42b4ef722f9d3c26f5336Timo Sirainenstatic enum imapc_command_state imapc_login_last_reply;
9224645cf699abae90fdd2cdf54247444f7acc18Timo Sirainenstatic ARRAY(enum imapc_command_state) imapc_cmd_last_replies;
9522aa5f33cc37fe8ccd0d647cc51dd3ba6a9b55Timo Sirainenstatic bool debug = FALSE;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct imapc_client_settings test_imapc_default_settings = {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen .host = "127.0.0.1",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen .username = "testuser",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen .password = "testpass",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen .dns_client_socket_path = "",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen .temp_path_prefix = ".test-tmp/",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen .rawlog_dir = "",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen .connect_timeout_msecs = 500,
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen .connect_retry_count = 3,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen .connect_retry_interval_msecs = 10,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
fe7f9298fb789717d26dc4cb6317a9d376acd8fcTimo Sirainen .max_idle_time = 10000,
3574bab52a67dfe1291f6306e707c6199e777043Timo Sirainen};
3574bab52a67dfe1291f6306e707c6199e777043Timo Sirainen
3574bab52a67dfe1291f6306e707c6199e777043Timo Sirainenstatic int test_open_server_fd(in_port_t *bind_port)
5a5b39ce7c6ba6d6ff2218ae1679e0485bf43b47Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen int fd = net_listen(&bind_ip, bind_port, 128);
5c8dec7f648cb0de2293a13265873baa640aa0cfTimo Sirainen if (debug)
5c8dec7f648cb0de2293a13265873baa640aa0cfTimo Sirainen i_debug("server listening on %u", *bind_port);
5c8dec7f648cb0de2293a13265873baa640aa0cfTimo Sirainen if (fd == -1) {
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen i_fatal("listen(%s:%u) failed: %m",
fe7f9298fb789717d26dc4cb6317a9d376acd8fcTimo Sirainen net_ip2addr(&bind_ip), *bind_port);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen }
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen fd_set_nonblock(fd, FALSE);
03fa2d644be0a9274e7e94fb4835cc374c539264Timo Sirainen return fd;
03fa2d644be0a9274e7e94fb4835cc374c539264Timo Sirainen}
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainenstatic void
4bc4042782c465636eff2c713bc85f5a1d773d91Timo Sirainentest_server_wait_connection(struct test_server *server, bool send_banner)
4bc4042782c465636eff2c713bc85f5a1d773d91Timo Sirainen{
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen server->fd = net_accept(server->fd_listen, NULL, NULL);
d8a93844f0b25be82da9c0ab79c321c110f5fb5fTimo Sirainen i_assert(server->fd >= 0);
9a656df90290a5fef45b3a1191ae75864f17602dTimo Sirainen
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen fd_set_nonblock(server->fd, FALSE);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen server->input = i_stream_create_fd(server->fd, (size_t)-1);
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainen server->output = o_stream_create_fd(server->fd, (size_t)-1);
dfbd56c81cb8fb7fe70393c4682cc99e68fe06b6Timo Sirainen o_stream_set_no_error_handling(server->output, TRUE);
dfbd56c81cb8fb7fe70393c4682cc99e68fe06b6Timo Sirainen
dfbd56c81cb8fb7fe70393c4682cc99e68fe06b6Timo Sirainen if (send_banner) {
dfbd56c81cb8fb7fe70393c4682cc99e68fe06b6Timo Sirainen o_stream_nsend_str(server->output,
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen "* OK [CAPABILITY IMAP4rev1 UNSELECT QUOTA] ready\r\n");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_server_disconnect(struct test_server *server)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen i_stream_unref(&server->input);
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen o_stream_unref(&server->output);
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen i_close_fd(&server->fd);
eb209d12e3b1cfed564c35cf19fdb1bf7fcc6811Timo Sirainen}
eb209d12e3b1cfed564c35cf19fdb1bf7fcc6811Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_server_disconnect_and_wait(bool send_banner)
312213260e384239ac93c77951c2f1f5f3d3611eTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_server_disconnect(&server);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen test_server_wait_connection(&server, send_banner);
7fd22d5521c8ecf84c40fbef553e70bf2553a663Timo Sirainen}
ee3362f3b78827a2c9a7e9ddee83f5a429c06213Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_server_kill(void)
9224645cf699abae90fdd2cdf54247444f7acc18Timo Sirainen{
9224645cf699abae90fdd2cdf54247444f7acc18Timo Sirainen if (server.pid != (pid_t)-1) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (kill(server.pid, SIGKILL) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("kill(%ld) failed: %m", (long)server.pid);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (waitpid(server.pid, NULL, 0) < 0)
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen i_fatal("waitpid(%ld) failed: %m", (long)server.pid);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen server.pid = -1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_run_client_server(
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct imapc_client_settings *client_set,
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen test_client_init_t *client_test,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_server_init_t *server_test)
1f7f4294207557edf83171642ef62ce4922ffc9dTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct imapc_client_settings client_set_copy = *client_set;
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen struct ioloop *ioloop;
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen const char *error;
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen imapc_client_cmd_tag_counter = 0;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen t_array_init(&imapc_cmd_last_replies, 4);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen i_zero(&server);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen server.pid = (pid_t)-1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen server.fd = -1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen server.fd_listen = test_open_server_fd(&server.port);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen client_set_copy.port = server.port;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen if (server_test == NULL)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen i_close_fd(&server.fd_listen);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (mkdir(client_set->temp_path_prefix, 0700) < 0 && errno != EEXIST)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("mkdir(%s) failed: %m", client_set->temp_path_prefix);
312213260e384239ac93c77951c2f1f5f3d3611eTimo Sirainen
a9ade104616bbb81c34cc6f8bfde5dab0571afacTimo Sirainen if ((server.pid = fork()) == (pid_t)-1)
d3ee83b4c24529fac4be5c1f30e254295e7addd9Timo Sirainen i_fatal("fork() failed: %m");
d3ee83b4c24529fac4be5c1f30e254295e7addd9Timo Sirainen if (server.pid == 0) {
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen server.pid = (pid_t)-1;
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen hostpid_init();
06fc82430569125dccb8cd20e122e77b44698c7eTimo Sirainen if (debug)
d3ee83b4c24529fac4be5c1f30e254295e7addd9Timo Sirainen i_debug("server: PID=%s", my_pid);
d3ee83b4c24529fac4be5c1f30e254295e7addd9Timo Sirainen /* child: server */
eb209d12e3b1cfed564c35cf19fdb1bf7fcc6811Timo Sirainen ioloop = io_loop_create();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (server_test != NULL)
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen server_test();
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen test_server_disconnect(&server);
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen io_loop_destroy(&ioloop);
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen /* wait for it to be killed; this way, valgrind will not
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen object to this process going away inelegantly. */
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen sleep(60);
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen exit(1);
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen }
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen /* parent: client */
4847d74a7442a3efabe76a8ad18dd464082d6581Timo Sirainen
34115224152b94328ffe3ec4ff4f30927c8f9aa1Timo Sirainen usleep(100000); /* wait a little for server setup */
34115224152b94328ffe3ec4ff4f30927c8f9aa1Timo Sirainen
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen ioloop = io_loop_create();
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen imapc_client = imapc_client_init(&client_set_copy);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen client_test();
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen test_assert(array_count(&imapc_cmd_last_replies) == 0);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen if (imapc_client != NULL)
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen imapc_client_deinit(&imapc_client);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen io_loop_destroy(&ioloop);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen i_close_fd(&server.fd_listen);
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen test_server_kill();
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen if (unlink_directory(client_set->temp_path_prefix,
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen UNLINK_DIRECTORY_FLAG_RMDIR, &error) < 0)
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen i_fatal("%s", error);
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen}
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainenstatic enum imapc_command_state test_imapc_cmd_last_reply_pop(void)
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen{
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen const enum imapc_command_state *replies;
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen enum imapc_command_state reply;
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen unsigned int count;
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen replies = array_get(&imapc_cmd_last_replies, &count);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen if (count == 0)
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen return IMAPC_COMMAND_STATE_INVALID;
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen reply = replies[0];
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen array_delete(&imapc_cmd_last_replies, 0, 1);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen return reply;
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen}
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic bool test_imapc_cmd_last_reply_expect(enum imapc_command_state state)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen if (array_count(&imapc_cmd_last_replies) == 0)
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen imapc_client_run(imapc_client);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen return test_imapc_cmd_last_reply_pop() == state;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainenstatic bool test_imapc_server_expect(const char *expected_line)
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen const char *line = i_stream_read_next_line(server.input);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen if (line == NULL) {
6ccc7f584c832a3212d70952881cb0eb2d6e2cb9Timo Sirainen printf("imapc client disconnected unexpectedly: %s\n",
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen i_stream_get_error(server.input));
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen return FALSE;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen } else if (strcmp(line, expected_line) != 0) {
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen printf("imapc client sent '%s' when expecting '%s'\n",
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen line, expected_line);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen return FALSE;
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen } else {
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen return TRUE;
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen }
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen}
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainenstatic void imapc_login_callback(const struct imapc_command_reply *reply,
d3ee83b4c24529fac4be5c1f30e254295e7addd9Timo Sirainen void *context ATTR_UNUSED)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen if (debug) {
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen i_debug("Login reply: %s %s",
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_command_state_names[reply->state],
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen reply->text_full);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen }
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_last_reply = reply->state;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_stop(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void imapc_command_callback(const struct imapc_command_reply *reply,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen void *context ATTR_UNUSED)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen if (debug) {
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen i_debug("Command reply: %s %s",
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen imapc_command_state_names[reply->state],
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen reply->text_full);
d3ee83b4c24529fac4be5c1f30e254295e7addd9Timo Sirainen }
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen array_append(&imapc_cmd_last_replies, &reply->state, 1);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen imapc_client_stop(imapc_client);
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen}
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void imapc_reopen_callback(void *context)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_mailbox *box = context;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_command *cmd;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen cmd = imapc_client_mailbox_cmd(box, imapc_command_callback, NULL);
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT);
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen imapc_command_send(cmd, "SELECT");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_connect_failed_client(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen imapc_client_set_login_callback(imapc_client,
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen imapc_login_callback, NULL);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen imapc_client_login(imapc_client);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* connection refused & one reconnect */
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen test_expect_errors(2);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen imapc_client_run(imapc_client);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen test_expect_no_more_errors();
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_DISCONNECTED);
9a656df90290a5fef45b3a1191ae75864f17602dTimo Sirainen}
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_connect_failed(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_begin("imapc connect failed");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_run_client_server(&set, test_imapc_connect_failed_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_end();
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_banner_hangs_client(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainen imapc_client_set_login_callback(imapc_client,
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainen imapc_login_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_login(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_expect_errors(2);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_run(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_expect_no_more_errors();
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_DISCONNECTED);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_banner_hangs_server(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct test_server server2 = { .fd_listen = server.fd_listen };
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_server_wait_connection(&server, FALSE);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_server_wait_connection(&server2, FALSE);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(i_stream_read_next_line(server2.input) == NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_server_disconnect(&server2);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_banner_hangs(void)
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen{
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen test_begin("imapc banner hangs");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_run_client_server(&set, test_imapc_banner_hangs_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_imapc_banner_hangs_server);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_end();
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_login_hangs_client(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_set_login_callback(imapc_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_login(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_expect_errors(2);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_run(imapc_client);
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen test_expect_no_more_errors();
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_DISCONNECTED);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_login_hangs_server(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct test_server server2 = { .fd_listen = server.fd_listen };
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_server_wait_connection(&server, TRUE);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_server_wait_connection(&server2, TRUE);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(i_stream_read_next_line(server2.input) == NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_server_disconnect(&server2);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_login_hangs(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_begin("imapc login hangs");
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen test_run_client_server(&set, test_imapc_login_hangs_client,
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen test_imapc_login_hangs_server);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_end();
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainenstatic void test_imapc_reconnect_client(void)
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_command *cmd;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* login to server */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_set_login_callback(imapc_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_login(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_run(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_OK);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* disconnect */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen imapc_command_send(cmd, "DISCONNECT");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_expect_error_string("reconnecting");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_run(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_expect_no_more_errors();
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_cmd_last_reply_pop() == IMAPC_COMMAND_STATE_DISCONNECTED);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen /* we should be reconnected now. try a command. */
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen imapc_command_send(cmd, "NOOP");
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen imapc_client_run(imapc_client);
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_INVALID);
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen test_assert(test_imapc_cmd_last_reply_pop() == IMAPC_COMMAND_STATE_OK);
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen}
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainenstatic void test_imapc_reconnect_server(void)
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen{
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen test_server_wait_connection(&server, TRUE);
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen o_stream_nsend_str(server.output, "1 OK \r\n");
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen test_assert(test_imapc_server_expect("2 DISCONNECT"));
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen test_server_disconnect_and_wait(TRUE);
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen test_assert(test_imapc_server_expect("4 LOGIN \"testuser\" \"testpass\""));
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen o_stream_nsend_str(server.output, "4 OK \r\n");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_server_expect("3 NOOP"));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen o_stream_nsend_str(server.output, "3 OK \r\n");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(i_stream_read_next_line(server.input) == NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_reconnect(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_begin("imapc reconnect");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_run_client_server(&set, test_imapc_reconnect_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_imapc_reconnect_server);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_end();
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_reconnect_resend_cmds_client(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen struct imapc_command *cmd;
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* login to server */
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen imapc_client_set_login_callback(imapc_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_login(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_run(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_OK);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* send two commands */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen imapc_command_send(cmd, "RETRY1");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
009217abb57a24a4076092e8e4e165545747839eStephan Bosch imapc_command_send(cmd, "RETRY2");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen /* disconnect & reconnect automatically */
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen imapc_command_send(cmd, "DISCONNECT");
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen test_expect_error_string("reconnecting");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen imapc_client_run(imapc_client);
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen test_expect_no_more_errors();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
009217abb57a24a4076092e8e4e165545747839eStephan Bosch /* continue reconnection */
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_OK));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_OK));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_imapc_reconnect_resend_cmds_server(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_server_wait_connection(&server, TRUE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen o_stream_nsend_str(server.output, "1 OK \r\n");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_server_expect("2 RETRY1"));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_server_expect("3 RETRY2"));
009217abb57a24a4076092e8e4e165545747839eStephan Bosch test_assert(test_imapc_server_expect("4 DISCONNECT"));
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen test_server_disconnect_and_wait(TRUE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_server_expect("5 LOGIN \"testuser\" \"testpass\""));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen o_stream_nsend_str(server.output, "5 OK \r\n");
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen test_assert(test_imapc_server_expect("2 RETRY1"));
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen o_stream_nsend_str(server.output, "2 OK \r\n");
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen test_assert(test_imapc_server_expect("3 RETRY2"));
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen o_stream_nsend_str(server.output, "3 OK \r\n");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(i_stream_read_next_line(server.input) == NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_imapc_reconnect_resend_commands(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_begin("imapc reconnect resend commands");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_run_client_server(&set, test_imapc_reconnect_resend_cmds_client,
7fd22d5521c8ecf84c40fbef553e70bf2553a663Timo Sirainen test_imapc_reconnect_resend_cmds_server);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_end();
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen}
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainenstatic void test_imapc_reconnect_resend_cmds_failed_client(void)
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen{
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen struct imapc_command *cmd;
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen /* login to server */
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen imapc_client_set_login_callback(imapc_client,
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen imapc_login_callback, NULL);
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen imapc_client_login(imapc_client);
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen imapc_client_run(imapc_client);
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_OK);
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen /* send two commands */
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen imapc_command_send(cmd, "RETRY1");
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen imapc_command_send(cmd, "RETRY2");
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen /* disconnect & try to reconnect automatically */
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_command_send(cmd, "DISCONNECT");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_expect_error_string("reconnecting");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen imapc_client_run(imapc_client);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_expect_no_more_errors();
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen test_expect_error_string("timed out");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_expect_no_more_errors();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen}
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_imapc_reconnect_resend_cmds_failed_server(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_server_wait_connection(&server, TRUE);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen o_stream_nsend_str(server.output, "1 OK \r\n");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_server_expect("2 RETRY1"));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_server_expect("3 RETRY2"));
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen test_assert(test_imapc_server_expect("4 DISCONNECT"));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_server_disconnect(&server);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen}
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstatic void test_imapc_reconnect_resend_commands_failed(void)
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen{
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_begin("imapc reconnect resend commands failed");
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen test_run_client_server(&set, test_imapc_reconnect_resend_cmds_failed_client,
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen test_imapc_reconnect_resend_cmds_failed_server);
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen test_end();
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen}
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainenstatic void test_imapc_reconnect_mailbox_client(void)
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen{
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen struct imapc_command *cmd;
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen struct imapc_client_mailbox *box;
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* login to server */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_set_login_callback(imapc_client,
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen imapc_login_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_login(imapc_client);
e2fdcdb4ee53ab769123e27997713aaea34910e1Timo Sirainen imapc_client_run(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_OK);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* select a mailbox */
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen box = imapc_client_mailbox_open(imapc_client, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_mailbox_set_reopen_cb(box, imapc_reopen_callback, box);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen cmd = imapc_client_mailbox_cmd(box, imapc_command_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_command_send(cmd, "SELECT");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_client_run(imapc_client);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_OK));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* send a command */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen cmd = imapc_client_mailbox_cmd(box, imapc_command_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen imapc_command_send(cmd, "RETRY");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* disconnect & reconnect automatically */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen imapc_command_send(cmd, "DISCONNECT");
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen test_expect_error_string("reconnecting");
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen imapc_client_run(imapc_client);
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen test_expect_no_more_errors();
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen /* continue reconnection */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_OK));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_OK));
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen imapc_client_mailbox_close(&box);
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen}
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen
68d87d8fb8f23ffed031ddfd9c410f3c929777faTimo Sirainenstatic void test_imapc_reconnect_mailbox_server(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
68d87d8fb8f23ffed031ddfd9c410f3c929777faTimo Sirainen test_server_wait_connection(&server, TRUE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen o_stream_nsend_str(server.output, "1 OK \r\n");
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_server_expect("2 SELECT"));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen o_stream_nsend_str(server.output, "2 OK \r\n");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_server_expect("3 RETRY"));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_server_expect("4 DISCONNECT"));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_server_disconnect_and_wait(TRUE);
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen test_assert(test_imapc_server_expect("5 LOGIN \"testuser\" \"testpass\""));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen o_stream_nsend_str(server.output, "5 OK \r\n");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_server_expect("6 SELECT"));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen o_stream_nsend_str(server.output, "6 OK \r\n");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_server_expect("3 RETRY"));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen o_stream_nsend_str(server.output, "3 OK \r\n");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(i_stream_read_next_line(server.input) == NULL);
68d87d8fb8f23ffed031ddfd9c410f3c929777faTimo Sirainen}
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen
1df39b899804fd1dbc560f75382364822935c857Timo Sirainenstatic void test_imapc_reconnect_mailbox(void)
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen{
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_begin("imapc reconnect mailbox");
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_run_client_server(&set, test_imapc_reconnect_mailbox_client,
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_imapc_reconnect_mailbox_server);
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_end();
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen}
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainenstatic void test_imapc_client_get_capabilities_client(void)
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen{
68d87d8fb8f23ffed031ddfd9c410f3c929777faTimo Sirainen enum imapc_capability capabilities;
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_assert(imapc_client_get_capabilities(imapc_client, &capabilities) == 0);
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_assert(capabilities == (IMAPC_CAPABILITY_IMAP4REV1 |
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen IMAPC_CAPABILITY_UNSELECT |
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen IMAPC_CAPABILITY_QUOTA));
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen}
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen
79ee504bdf920f01e12e28f238799bf2616489dfTimo Sirainenstatic void test_imapc_client_get_capabilities_server(void)
5c1733e9e572e242598b8b2f12a0068897caf5b7Timo Sirainen{
5c1733e9e572e242598b8b2f12a0068897caf5b7Timo Sirainen test_server_wait_connection(&server, TRUE);
5c1733e9e572e242598b8b2f12a0068897caf5b7Timo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
5c1733e9e572e242598b8b2f12a0068897caf5b7Timo Sirainen o_stream_nsend_str(server.output, "1 OK \r\n");
5c1733e9e572e242598b8b2f12a0068897caf5b7Timo Sirainen
5c1733e9e572e242598b8b2f12a0068897caf5b7Timo Sirainen test_assert(test_imapc_server_expect("2 LOGOUT"));
5c1733e9e572e242598b8b2f12a0068897caf5b7Timo Sirainen o_stream_nsend_str(server.output, "2 OK \r\n");
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(i_stream_read_next_line(server.input) == NULL);
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen}
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainenstatic void test_imapc_client_get_capabilities(void)
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen{
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen test_begin("imapc_client_get_capabilities()");
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen test_run_client_server(&set, test_imapc_client_get_capabilities_client,
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen test_imapc_client_get_capabilities_server);
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen test_end();
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen}
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainenstatic void test_imapc_client_get_capabilities_reconnected_client(void)
79ee504bdf920f01e12e28f238799bf2616489dfTimo Sirainen{
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen enum imapc_capability capabilities;
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen
ade4a0e1a8f4bc3467f4fcff9c219558fe348abfTimo Sirainen test_expect_errors(2);
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen test_assert(imapc_client_get_capabilities(imapc_client, &capabilities) == 0);
ade4a0e1a8f4bc3467f4fcff9c219558fe348abfTimo Sirainen test_assert(capabilities == (IMAPC_CAPABILITY_IMAP4REV1 |
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen IMAPC_CAPABILITY_UNSELECT |
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen IMAPC_CAPABILITY_QUOTA));
36a687c1ed3ce55520bdf28cd2fa1f653360068dTimo Sirainen test_expect_no_more_errors();
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen}
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainenstatic void test_imapc_client_get_capabilities_reconnected_server(void)
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen{
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen test_server_wait_connection(&server, TRUE);
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen test_server_disconnect_and_wait(TRUE);
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen test_assert(test_imapc_server_expect("2 LOGIN \"testuser\" \"testpass\""));
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen o_stream_nsend_str(server.output, "2 OK \r\n");
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_server_expect("3 LOGOUT"));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen o_stream_nsend_str(server.output, "3 OK \r\n");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen test_assert(i_stream_read_next_line(server.input) == NULL);
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainen}
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainen
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainenstatic void test_imapc_client_get_capabilities_reconnected(void)
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainen{
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_begin("imapc_client_get_capabilities() reconnected");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_run_client_server(&set, test_imapc_client_get_capabilities_reconnected_client,
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_imapc_client_get_capabilities_reconnected_server);
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_end();
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen}
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainenstatic void test_imapc_client_get_capabilities_disconnected_client(void)
68d87d8fb8f23ffed031ddfd9c410f3c929777faTimo Sirainen{
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen enum imapc_capability capabilities;
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen test_expect_errors(4);
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen test_assert(imapc_client_get_capabilities(imapc_client, &capabilities) < 0);
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_expect_no_more_errors();
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen}
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainenstatic void test_imapc_client_get_capabilities_disconnected_server(void)
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen{
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_server_wait_connection(&server, TRUE);
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_server_disconnect_and_wait(TRUE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_imapc_client_get_capabilities_disconnected(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_begin("imapc_client_get_capabilities() disconnected");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_run_client_server(&set, test_imapc_client_get_capabilities_disconnected_client,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_client_get_capabilities_disconnected_server);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_end();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenint main(int argc ATTR_UNUSED, char *argv[])
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen static void (*const test_functions[])(void) = {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_connect_failed,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_banner_hangs,
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen test_imapc_login_hangs,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_reconnect,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_reconnect_resend_commands,
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_imapc_reconnect_resend_commands_failed,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_reconnect_mailbox,
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen test_imapc_client_get_capabilities,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_client_get_capabilities_reconnected,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_client_get_capabilities_disconnected,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen NULL
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen };
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen debug = null_strcmp(argv[1], "-D") == 0;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen test_imapc_default_settings.debug = debug;
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen
8621be3846dc097420cce325ad36d1b646f72a09Timo Sirainen /* listen on localhost */
8621be3846dc097420cce325ad36d1b646f72a09Timo Sirainen i_zero(&bind_ip);
8621be3846dc097420cce325ad36d1b646f72a09Timo Sirainen bind_ip.family = AF_INET;
8621be3846dc097420cce325ad36d1b646f72a09Timo Sirainen bind_ip.u.ip4.s_addr = htonl(INADDR_LOOPBACK);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return test_run(test_functions);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen