#!perl
use Cassandane::Tiny;

sub test_sigterm
    :needs_component_idled
    ($self)
{
    xlog $self, "Test that an imapd can be killed with SIGTERM";
    xlog $self, "while executing an IDLE command";

    $self->{instance}->{config}->set(imapidlepoll => '2');
    $self->{instance}->add_start(name => 'idled',
                                 argv => [ 'idled' ]);
    xlog $self, "Starting up the instance";
    $self->{instance}->start();

    my $svc = $self->{instance}->get_service('imap');

    my $store = $svc->create_store(folder => 'INBOX');
    my $talk = $store->get_client();

    $store->_select();

    xlog $self, "Sending the IDLE command";
    $store->idle_begin()
        or die "IDLE failed: $@";

    # procinfo: pid SP servicename SP host [SP user] [SP mailbox] [SP cmdname]
    my $procinfo = join '', $self->{instance}->run_cyr_info('proc');
    my ($imapd_pid, undef) =
        ($procinfo =~ m/^(\d+) imap (.+) cassandane user.cassandane Idle$/);
    $self->assert_not_null($imapd_pid);
    $imapd_pid = 0 + $imapd_pid;
    $self->assert($imapd_pid > 1);
    xlog $self, "PID of imapd process is $imapd_pid";

    xlog $self, "Poll for any unsolicited response - should be none";
    my $r = $store->idle_response({}, 0);
    $self->assert(!$r, "No unsolicted response");

    xlog $self, "sleeping for 3 seconds";
    sleep(3);

    xlog $self, "Poll for any unsolicited response - should be none";
    $r = $store->idle_response({}, 0);
    $self->assert(!$r, "No unsolicted response");

    $self->assert_null($talk->get_response_code('alert'));

    xlog $self, "Send SIGQUIT (or worse) to the imapd";
    $r = Cassandane::Instance::_stop_pid($imapd_pid);
    $self->assert($r == 1, "shutdown required brute force");

    xlog $self, "Check that the server disconnected";
    eval
    {
        # We use _send_cmd() and _next_atom() rather the normal path
        # through _imap_cmd() because the latter will warn() to stderr
        # about the exception we're about to generate, which is
        # downright untidy.
        $talk->_send_cmd('status', 'INBOX', '(messages unseen)');
        $talk->_parse_response({});
    };
    my $mm = $@;    # this doesn't survive unless we save it
    $self->assert_matches(qr/IMAP Connection closed by other end/, $mm);
}
