EV-ClickHouse

 view release on metacpan or  search on metacpan

t/28_pass2_coverage.t  view on Meta::CPAN

#!/usr/bin/env perl
# Coverage for corner cases the earlier test files miss:
#   - on_query_complete (success + error path)
#   - HTTP keepalive PING does NOT fire on_query_complete (IS_KEEPALIVE_CB)
#   - query_log_comment is applied to INSERT and on HTTP
#   - DNS failure with pre-queued queries delivers errors
#   - Pool: cancel / skip_pending / reset broadcast
#   - Iterator timeout returns undef without setting error
#   - Streamer high_water fires when buffered count crosses watermark
use strict;
use warnings;
use Test::More;
use EV;
use EV::ClickHouse;
use IO::Socket::INET;

my $host  = $ENV{TEST_CLICKHOUSE_HOST}        || '127.0.0.1';
my $hport = $ENV{TEST_CLICKHOUSE_PORT}        || 8123;
my $nport = $ENV{TEST_CLICKHOUSE_NATIVE_PORT} || 9000;

plan skip_all => "ClickHouse not reachable"
    unless IO::Socket::INET->new(PeerAddr => $host, PeerPort => $nport, Timeout => 2);

plan tests => 30;

sub run_with_timeout { my $t = EV::timer($_[0], 0, sub { EV::break }); EV::run }

# 1. on_query_complete fires on success with non-zero duration
{
    my $completed;
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $nport, protocol => 'native',
        on_connect          => sub { $ch->query("select 1", sub { EV::break }) },
        on_query_complete   => sub { $completed = [@_] },
        on_error            => sub { diag "err: $_[0]"; EV::break },
    );
    EV::run;
    ok $completed, 'on_query_complete fired on success';
    cmp_ok $completed->[4], '>=', 0, '  duration_s is non-negative';
    is $completed->[5], undef, '  no error message on success';
    $ch->finish;
}

# 2. on_query_complete fires on server error with error_code + err set
{
    my $completed;
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $nport, protocol => 'native',
        on_connect          => sub {
            $ch->query("select * from no_such_table_$$", sub { EV::break });
        },
        on_query_complete   => sub { $completed = [@_] },
        on_error            => sub { },
    );
    EV::run;
    ok $completed && $completed->[5], 'on_query_complete fired with err msg on failure';
    cmp_ok $completed->[3], '>', 0, '  error_code populated';
    $ch->finish;
}

# 3. HTTP keepalive PING does not fire on_query_complete
SKIP: {
    skip 'HTTP not reachable', 1
        unless IO::Socket::INET->new(PeerAddr => $host, PeerPort => $hport, Timeout => 2);
    my $count = 0;
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $hport, protocol => 'http',
        keepalive => 0.2,
        on_connect          => sub { },
        on_query_complete   => sub { $count++ },
        on_error            => sub { },
    );
    # let two keepalive pings fly
    run_with_timeout(0.6);
    is $count, 0, 'HTTP keepalive PING did not fire on_query_complete';
    $ch->finish;
}

# 4. query_log_comment is applied to INSERT (and is well-formed enough that
#    the server accepts it). We can't read system.query_log on every test
#    setup, so we verify the insert succeeds with the comment in place.
{
    my $err;
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $nport, protocol => 'native',
        query_log_comment   => 'pass2-insert-test',
        on_connect          => sub {
            $ch->query("create temporary table _qlc28 (n UInt32) engine = Memory", sub {
                my (undef, $e) = @_; if ($e) { $err = $e; EV::break; return }
                $ch->insert('_qlc28', [[1],[2],[3]], sub {
                    (undef, $err) = @_;
                    EV::break;
                });
            });
        },
        on_error            => sub { $err = $_[0]; EV::break },
    );
    EV::run;
    is $err, undef, 'INSERT with query_log_comment succeeded (no SQL parse error)';
    $ch->finish;
}

# 5. query_log_comment via HTTP: select still works with prefix attached.
SKIP: {
    skip 'HTTP not reachable', 1
        unless IO::Socket::INET->new(PeerAddr => $host, PeerPort => $hport, Timeout => 2);
    my ($rows, $err);
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $hport, protocol => 'http',
        query_log_comment   => 'pass2-http-test',
        on_connect          => sub {
            $ch->query("select 7 format TabSeparated", sub {
                ($rows, $err) = @_;
                EV::break;
            });
        },
        on_error            => sub { $err = $_[0]; EV::break },
    );
    EV::run;
    is_deeply $rows, [[7]], 'HTTP select with query_log_comment returns the right rows';
    $ch->finish;
}

# 6. DNS failure with a pre-queued query delivers the error to the query cb.
SKIP: {
    skip 'EV::cares not installed', 1 unless eval { require EV::cares; 1 };
    my ($rows, $err, $oe);
    my $ch; $ch = EV::ClickHouse->new(
        host => 'no-such-host-' . time . '.invalid.',
        port => $nport, protocol => 'native',
        on_error => sub { $oe = $_[0]; EV::break },
    );
    # Queue a query before DNS resolves.
    $ch->query("select 1", sub {
        ($rows, $err) = @_;



( run in 0.512 second using v1.01-cache-2.11-cpan-f56aa216473 )