EV-Websockets

 view release on metacpan or  search on metacpan

t/16-edge-cases.t  view on Meta::CPAN


    my $t = EV::timer(0.1, 0, sub {
        $keep{c} = $ctx->connect(
            url => "ws://127.0.0.1:$port",
            on_connect => sub {
                my ($c) = @_;
                $c->close(1000);
                eval { $c->send("after close") };
                $send_after_close_err = $@;
            },
            on_close => sub {
                delete $keep{c};
                my $t; $t = EV::timer(0.3, 0, sub { undef $t; EV::break });
            },
            on_error => sub { delete $keep{c}; EV::break },
        );
    });

    my $to = EV::timer(10, 0, sub { EV::break });
    EV::run;

    like($send_after_close_err, qr/not open/, "send after close croaks");
}

# 5. peer_address and get_protocol on closed connection return undef
{
    my ($closed_peer, $closed_proto);
    my %keep;

    my $port = $ctx->listen(
        port => 0,
        on_connect => sub { $keep{s} = $_[0] },
        on_close => sub { delete $keep{s} },
    );

    my $t = EV::timer(0.1, 0, sub {
        $keep{c} = $ctx->connect(
            url => "ws://127.0.0.1:$port",
            on_connect => sub { $_[0]->close(1000) },
            on_close => sub {
                my ($c) = @_;
                $closed_peer = $c->peer_address;
                $closed_proto = $c->get_protocol;
                delete $keep{c};
                my $t; $t = EV::timer(0.3, 0, sub { undef $t; EV::break });
            },
            on_error => sub { delete $keep{c}; EV::break },
        );
    });

    my $to = EV::timer(10, 0, sub { EV::break });
    EV::run;

    ok(!defined $closed_peer, "peer_address returns undef on closed connection");
    ok(!defined $closed_proto, "get_protocol returns undef on closed connection");
}

# Drop the shared context before test 6
undef $ctx;

# 6. Context destroy from inside on_message (alive_flag test)
{
    my $ctx2 = EV::Websockets::Context->new();
    my ($msg_received, $destroyed_ok);
    my %keep;

    my $port = $ctx2->listen(
        port => 0,
        on_connect => sub { $keep{s} = $_[0] },
        on_message => sub { $_[0]->send("ack") },
        on_close => sub { delete $keep{s} },
    );

    my $t = EV::timer(0.1, 0, sub {
        $keep{c} = $ctx2->connect(
            url => "ws://127.0.0.1:$port",
            on_connect => sub { $_[0]->send("boom") },
            on_message => sub {
                $msg_received = 1;
                %keep = ();
                undef $ctx2;
                $destroyed_ok = 1;
                EV::break;
            },
            on_error => sub { %keep = (); EV::break },
        );
    });

    my $to = EV::timer(10, 0, sub { EV::break });
    EV::run;

    ok($msg_received, "message received before context destroy");
    ok($destroyed_ok, "context destroyed from inside on_message without crash");
}

done_testing;

# Avoid SEGV during global destruction
POSIX::_exit(Test::More->builder->is_passing ? 0 : 1);



( run in 0.636 second using v1.01-cache-2.11-cpan-14f38c9f855 )