ClickHouse-Encoder

 view release on metacpan or  search on metacpan

xt/fuzz.t  view on Meta::CPAN

my $seed = defined $ENV{FUZZ_SEED} ? $ENV{FUZZ_SEED} : time;
srand($seed);
diag("fuzz seed: $seed (set FUZZ_SEED=$seed to replay)");

for my $iter (1..$iters) {
    my $ncols = 1 + int(rand(4));
    my @cols  = map { ["c$_", random_type()] } 0..$ncols-1;
    my $nrows = 1 + int(rand(20));
    my @rows  = map {
        [map { random_value($_->[1]) } @cols]
    } 1..$nrows;

    my $enc = eval { ClickHouse::Encoder->new(columns => \@cols) };
    if (!$enc) {
        fail("iter $iter: encoder construction failed: $@");
        diag("schema: " . join(', ', map { "@$_" } @cols));
        next;
    }
    my $bin = eval { $enc->encode(\@rows) };
    if (!defined $bin) {
        fail("iter $iter: encode failed: $@");
        diag("schema: " . join(', ', map { "@$_" } @cols));
        next;
    }

    # Build schema and test against ClickHouse.
    my $col_defs = join(', ', map { "$_->[0] $_->[1]" } @cols);
    system("clickhouse-client --port $port --query 'drop table if exists fuzz_test' >/dev/null 2>&1");
    my $rc = system("clickhouse-client --port $port --query 'create table fuzz_test ($col_defs) engine = Memory' >/dev/null 2>&1");
    if ($rc != 0) {
        diag("iter $iter: skip (CH didn't accept schema): $col_defs");
        ok(1, "iter $iter: schema unsupported (skip)");
        next;
    }

    # List form so $port (an env var) isn't shell-interpreted; redirect
    # stderr in Perl rather than via the shell.
    my $err_fh;
    open $err_fh, '>', '/tmp/fuzz.err' or die "open /tmp/fuzz.err: $!";
    defined(my $pid = open my $fh, '|-') or die "fork: $!";
    if ($pid == 0) {
        open STDERR, '>&', $err_fh or die "redirect: $!";
        exec 'clickhouse-client', '--port', $port, '--query',
             "insert into fuzz_test format native";
        die "exec: $!";
    }
    close $err_fh;
    binmode $fh;
    print $fh $bin;
    close $fh;
    my $insert_ok = ($? == 0);

    open my $count_fh, '-|', 'clickhouse-client', '--port', $port,
        '--query', 'select count() from fuzz_test'
        or die "count query: $!";
    my $count = do { local $/; <$count_fh> };
    close $count_fh;
    chomp $count;

    if (!$insert_ok || $count != $nrows) {
        my $err = do { local (@ARGV, $/) = '/tmp/fuzz.err'; <> };
        fail("iter $iter: CH rejected our buffer (got $count rows, expected $nrows)");
        diag("schema: $col_defs");
        diag("error:  $err") if $err;
    } else {
        pass("iter $iter: $ncols cols × $nrows rows accepted");
    }
}

system("clickhouse-client --port $port --query 'drop table if exists fuzz_test' >/dev/null 2>&1");



( run in 1.257 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )