test-imapc-client.c revision 204ee6ed414f5e4eeb6f6c10763b55daf56f11ac
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen#define IMAPC_COMMAND_STATE_INVALID (enum imapc_command_state)-1
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainentypedef void test_server_init_t(void);
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainentypedef void test_client_init_t(void);
09060303d565e15d54e42b4ef722f9d3c26f5336Timo Sirainenstatic enum imapc_command_state imapc_login_last_reply;
9224645cf699abae90fdd2cdf54247444f7acc18Timo Sirainenstatic ARRAY(enum imapc_command_state) imapc_cmd_last_replies;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct imapc_client_settings test_imapc_default_settings = {
3574bab52a67dfe1291f6306e707c6199e777043Timo Sirainenstatic int test_open_server_fd(in_port_t *bind_port)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen int fd = net_listen(&bind_ip, bind_port, 128);
5c8dec7f648cb0de2293a13265873baa640aa0cfTimo Sirainen i_debug("server listening on %u", *bind_port);
4bc4042782c465636eff2c713bc85f5a1d773d91Timo Sirainentest_server_wait_connection(struct test_server *server, bool send_banner)
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen server->fd = net_accept(server->fd_listen, NULL, NULL);
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);
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen "* OK [CAPABILITY IMAP4rev1 UNSELECT QUOTA] ready\r\n");
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_server_disconnect(struct test_server *server)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_server_disconnect_and_wait(bool send_banner)
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen test_server_wait_connection(&server, send_banner);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_server_kill(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("kill(%ld) failed: %m", (long)server.pid);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen i_fatal("waitpid(%ld) failed: %m", (long)server.pid);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct imapc_client_settings *client_set,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct imapc_client_settings client_set_copy = *client_set;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen server.fd_listen = test_open_server_fd(&server.port);
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);
d3ee83b4c24529fac4be5c1f30e254295e7addd9Timo Sirainen /* child: server */
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen /* wait for it to be killed; this way, valgrind will not
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen object to this process going away inelegantly. */
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen /* parent: client */
34115224152b94328ffe3ec4ff4f30927c8f9aa1Timo Sirainen usleep(100000); /* wait a little for server setup */
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen imapc_client = imapc_client_init(&client_set_copy);
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen test_assert(array_count(&imapc_cmd_last_replies) == 0);
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainen if (unlink_directory(client_set->temp_path_prefix,
8a513c80e95a51c29f5af5c702fbf71ecbad41f4Timo Sirainenstatic enum imapc_command_state test_imapc_cmd_last_reply_pop(void)
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen unsigned int count;
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen replies = array_get(&imapc_cmd_last_replies, &count);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic bool test_imapc_cmd_last_reply_expect(enum imapc_command_state state)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen if (array_count(&imapc_cmd_last_replies) == 0)
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen return test_imapc_cmd_last_reply_pop() == state;
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainenstatic bool test_imapc_server_expect(const char *expected_line)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen const char *line = i_stream_read_next_line(server.input);
6ccc7f584c832a3212d70952881cb0eb2d6e2cb9Timo Sirainen printf("imapc client disconnected unexpectedly: %s\n",
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen } else if (strcmp(line, expected_line) != 0) {
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainen printf("imapc client sent '%s' when expecting '%s'\n",
1ef9754a5169dc886d15089e59b45a7017d647d7Timo Sirainenstatic void imapc_login_callback(const struct imapc_command_reply *reply,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void imapc_command_callback(const struct imapc_command_reply *reply,
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen array_append(&imapc_cmd_last_replies, &reply->state, 1);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void imapc_reopen_callback(void *context)
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen cmd = imapc_client_mailbox_cmd(box, imapc_command_callback, NULL);
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_connect_failed_client(void)
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* connection refused & one reconnect */
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_DISCONNECTED);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_run_client_server(&set, test_imapc_connect_failed_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_banner_hangs_client(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_DISCONNECTED);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_banner_hangs_server(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct test_server server2 = { .fd_listen = server.fd_listen };
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(i_stream_read_next_line(server2.input) == NULL);
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_run_client_server(&set, test_imapc_banner_hangs_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_login_hangs_client(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_DISCONNECTED);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_login_hangs_server(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct test_server server2 = { .fd_listen = server.fd_listen };
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(i_stream_read_next_line(server2.input) == NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
6cb8e7d726a7e9d157e87fb379982d52100b283fTimo Sirainen test_run_client_server(&set, test_imapc_login_hangs_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* login to server */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_OK);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* disconnect */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_cmd_last_reply_pop() == IMAPC_COMMAND_STATE_DISCONNECTED);
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen /* we should be reconnected now. try a command. */
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
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 test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen o_stream_nsend_str(server.output, "1 OK \r\n");
67cb14c7fb54a031818228522dc7255d5cd00f0aTimo Sirainen test_assert(test_imapc_server_expect("2 DISCONNECT"));
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 test_assert(i_stream_read_next_line(server.input) == NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_run_client_server(&set, test_imapc_reconnect_client,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstatic void test_imapc_reconnect_resend_cmds_client(void)
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* login to server */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_OK);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
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 cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen /* disconnect & reconnect automatically */
98d5941dc28754f32432edc38578b946ba71dd0bTimo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
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 Sirainenstatic void test_imapc_reconnect_resend_cmds_server(void)
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 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"));
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 test_assert(i_stream_read_next_line(server.input) == NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_imapc_reconnect_resend_commands(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_begin("imapc reconnect resend commands");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_run_client_server(&set, test_imapc_reconnect_resend_cmds_client,
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainenstatic void test_imapc_reconnect_resend_cmds_failed_client(void)
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen /* login to server */
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_OK);
9054b5f92a7e5666c6beaa04916699a1408bf021Timo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
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 cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen /* disconnect & try to reconnect automatically */
5a530f778cc3eae05e70d13b8e5d7d501e7ba0b3Timo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_imapc_reconnect_resend_cmds_failed_server(void)
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 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"));
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstatic void test_imapc_reconnect_resend_commands_failed(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
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 Sirainenstatic void test_imapc_reconnect_mailbox_client(void)
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* login to server */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(imapc_login_last_reply == IMAPC_COMMAND_STATE_OK);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_login_last_reply = IMAPC_COMMAND_STATE_INVALID;
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 cmd = imapc_client_mailbox_cmd(box, imapc_command_callback, NULL);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_OK));
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 /* disconnect & reconnect automatically */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen cmd = imapc_client_cmd(imapc_client, imapc_command_callback, NULL);
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen test_assert(test_imapc_cmd_last_reply_expect(IMAPC_COMMAND_STATE_DISCONNECTED));
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));
68d87d8fb8f23ffed031ddfd9c410f3c929777faTimo Sirainenstatic void test_imapc_reconnect_mailbox_server(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_server_expect("1 LOGIN \"testuser\" \"testpass\""));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen o_stream_nsend_str(server.output, "1 OK \r\n");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_assert(test_imapc_server_expect("2 SELECT"));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen o_stream_nsend_str(server.output, "2 OK \r\n");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_server_expect("3 RETRY"));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_server_expect("4 DISCONNECT"));
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 test_assert(i_stream_read_next_line(server.input) == NULL);
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_run_client_server(&set, test_imapc_reconnect_mailbox_client,
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainenstatic void test_imapc_client_get_capabilities_client(void)
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_assert(imapc_client_get_capabilities(imapc_client, &capabilities) == 0);
c6a5305674d2aa59ee52dc101ef87bbcb04f04efTimo Sirainen test_assert(capabilities == (IMAPC_CAPABILITY_IMAP4REV1 |
79ee504bdf920f01e12e28f238799bf2616489dfTimo Sirainenstatic void test_imapc_client_get_capabilities_server(void)
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 test_assert(test_imapc_server_expect("2 LOGOUT"));
5c1733e9e572e242598b8b2f12a0068897caf5b7Timo Sirainen o_stream_nsend_str(server.output, "2 OK \r\n");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(i_stream_read_next_line(server.input) == NULL);
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainenstatic void test_imapc_client_get_capabilities(void)
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen test_begin("imapc_client_get_capabilities()");
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainen test_run_client_server(&set, test_imapc_client_get_capabilities_client,
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainenstatic void test_imapc_client_get_capabilities_reconnected_client(void)
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen test_assert(imapc_client_get_capabilities(imapc_client, &capabilities) == 0);
ade4a0e1a8f4bc3467f4fcff9c219558fe348abfTimo Sirainen test_assert(capabilities == (IMAPC_CAPABILITY_IMAP4REV1 |
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainenstatic void test_imapc_client_get_capabilities_reconnected_server(void)
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen test_assert(test_imapc_server_expect("2 LOGIN \"testuser\" \"testpass\""));
fb9dfa9ea15abdbf248021cfb7bf2846410116e6Timo Sirainen o_stream_nsend_str(server.output, "2 OK \r\n");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_assert(test_imapc_server_expect("3 LOGOUT"));
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen o_stream_nsend_str(server.output, "3 OK \r\n");
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen test_assert(i_stream_read_next_line(server.input) == NULL);
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainenstatic void test_imapc_client_get_capabilities_reconnected(void)
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_begin("imapc_client_get_capabilities() reconnected");
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_run_client_server(&set, test_imapc_client_get_capabilities_reconnected_client,
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen test_imapc_client_get_capabilities_reconnected_server);
4f2b533808371b3b8a8187819cd4c3d90e1ca8eeTimo Sirainenstatic void test_imapc_client_get_capabilities_disconnected_client(void)
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen test_assert(imapc_client_get_capabilities(imapc_client, &capabilities) < 0);
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainenstatic void test_imapc_client_get_capabilities_disconnected_server(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void test_imapc_client_get_capabilities_disconnected(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct imapc_client_settings set = test_imapc_default_settings;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_begin("imapc_client_get_capabilities() disconnected");
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 static void (*const test_functions[])(void) = {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_client_get_capabilities_reconnected,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen test_imapc_client_get_capabilities_disconnected,
8621be3846dc097420cce325ad36d1b646f72a09Timo Sirainen /* listen on localhost */