|
Packit |
4e8bc4 |
#!/usr/bin/perl
|
|
Packit |
4e8bc4 |
# Networked logging tests.
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
use strict;
|
|
Packit |
4e8bc4 |
use warnings;
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
use Test::More;
|
|
Packit |
4e8bc4 |
use FindBin qw($Bin);
|
|
Packit |
4e8bc4 |
use lib "$Bin/lib";
|
|
Packit |
4e8bc4 |
use MemcachedTest;
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
my $ext_path;
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
if (!supports_extstore()) {
|
|
Packit |
4e8bc4 |
plan skip_all => 'extstore not enabled';
|
|
Packit |
4e8bc4 |
exit 0;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
$ext_path = "/tmp/extstore.$$";
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
my $server = new_memcached("-m 64 -U 0 -o ext_page_size=8,ext_wbuf_size=2,ext_threads=1,ext_io_depth=2,ext_item_size=512,ext_item_age=2,ext_recache_rate=10000,ext_max_frag=0.9,ext_path=$ext_path:64m,slab_chunk_max=16384,slab_automove=0,ext_compact_under=1");
|
|
Packit |
4e8bc4 |
my $sock = $server->sock;
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
# Wait until all items have flushed
|
|
Packit |
4e8bc4 |
sub wait_for_ext {
|
|
Packit |
4e8bc4 |
my $sum = 1;
|
|
Packit |
4e8bc4 |
while ($sum != 0) {
|
|
Packit |
4e8bc4 |
my $s = mem_stats($sock, "items");
|
|
Packit |
4e8bc4 |
$sum = 0;
|
|
Packit |
4e8bc4 |
for my $key (keys %$s) {
|
|
Packit |
4e8bc4 |
if ($key =~ m/items:(\d+):number/) {
|
|
Packit |
4e8bc4 |
# Ignore classes which can contain extstore items
|
|
Packit |
4e8bc4 |
next if $1 < 3;
|
|
Packit |
4e8bc4 |
$sum += $s->{$key};
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
sleep 1 if $sum != 0;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
# We're testing to ensure item chaining doesn't corrupt or poorly overlap
|
|
Packit |
4e8bc4 |
# data, so create a non-repeating pattern.
|
|
Packit |
4e8bc4 |
my @parts = ();
|
|
Packit |
4e8bc4 |
for (1 .. 8000) {
|
|
Packit |
4e8bc4 |
push(@parts, $_);
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
my $pattern = join(':', @parts);
|
|
Packit |
4e8bc4 |
my $plen = length($pattern);
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
print $sock "set pattern 0 0 $plen\r\n$pattern\r\n";
|
|
Packit |
4e8bc4 |
is(scalar <$sock>, "STORED\r\n", "stored pattern successfully");
|
|
Packit |
4e8bc4 |
# Stash two more for later test
|
|
Packit |
4e8bc4 |
print $sock "set pattern2 0 0 $plen noreply\r\n$pattern\r\n";
|
|
Packit |
4e8bc4 |
print $sock "set pattern3 0 0 $plen noreply\r\n$pattern\r\n";
|
|
Packit |
4e8bc4 |
sleep 4;
|
|
Packit |
4e8bc4 |
mem_get_is($sock, "pattern", $pattern);
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
for (1..5) {
|
|
Packit |
4e8bc4 |
my $size = 400 * 1024;
|
|
Packit |
4e8bc4 |
my $data = "x" x $size;
|
|
Packit |
4e8bc4 |
print $sock "set foo$_ 0 0 $size\r\n$data\r\n";
|
|
Packit |
4e8bc4 |
my $res = <$sock>;
|
|
Packit |
4e8bc4 |
is($res, "STORED\r\n", "stored some big items");
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
{
|
|
Packit |
4e8bc4 |
my $max = 1024 * 1024;
|
|
Packit |
4e8bc4 |
my $big = "a big value that's > .5M and < 1M. ";
|
|
Packit |
4e8bc4 |
while (length($big) * 2 < $max) {
|
|
Packit |
4e8bc4 |
$big = $big . $big;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
my $biglen = length($big);
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
for (1..40) {
|
|
Packit |
4e8bc4 |
print $sock "set toast$_ 0 0 $biglen\r\n$big\r\n";
|
|
Packit |
4e8bc4 |
is(scalar <$sock>, "STORED\r\n", "stored big");
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
wait_for_ext();
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
for (1..40) {
|
|
Packit |
4e8bc4 |
mem_get_is($sock, "toast$_", $big);
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
my $stats = mem_stats($sock);
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_page_allocs}, '>', 0, 'at least one page allocated');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_objects_written}, '>', 25, 'some objects written');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_bytes_written}, '>', $max * 2, 'some bytes written');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{get_extstore}, '>', 5, 'multiple objects fetched');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_objects_read}, '>', 0, 'one object read');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_bytes_read}, '>', $max * 2, 'some bytes read');
|
|
Packit |
4e8bc4 |
is($stats->{badcrc_from_extstore}, 0, 'CRC checks successful');
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
# fill to eviction
|
|
Packit |
4e8bc4 |
{
|
|
Packit |
4e8bc4 |
my $keycount = 1250;
|
|
Packit |
4e8bc4 |
for (1 .. $keycount) {
|
|
Packit |
4e8bc4 |
print $sock "set mfoo$_ 0 0 $plen noreply\r\n$pattern\r\n";
|
|
Packit |
4e8bc4 |
wait_for_ext() if $_ % 500 == 0;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
# because item_age is set to 2s.
|
|
Packit |
4e8bc4 |
wait_for_ext();
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
my $stats = mem_stats($sock);
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_page_evictions}, '>', 0, 'at least one page evicted');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_objects_evicted}, '>', 0, 'at least one object evicted');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_bytes_evicted}, '>', 0, 'some bytes evicted');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_pages_free}, '<', 2, 'most pages are used');
|
|
Packit |
4e8bc4 |
is($stats->{miss_from_extstore}, 0, 'no misses');
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
# original "pattern" key should be gone.
|
|
Packit |
4e8bc4 |
mem_get_is($sock, "pattern", undef, "original pattern key is gone");
|
|
Packit |
4e8bc4 |
$stats = mem_stats($sock);
|
|
Packit |
4e8bc4 |
is($stats->{miss_from_extstore}, 1, 'one extstore miss');
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
print $sock "get pattern2 pattern3\r\n";
|
|
Packit |
4e8bc4 |
is(scalar <$sock>, "END\r\n", "multiget double miss");
|
|
Packit |
4e8bc4 |
$stats = mem_stats($sock);
|
|
Packit |
4e8bc4 |
is($stats->{miss_from_extstore}, 3, 'three extstore misses');
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
# Let compaction run.
|
|
Packit |
4e8bc4 |
{
|
|
Packit |
4e8bc4 |
for (1..40) {
|
|
Packit |
4e8bc4 |
print $sock "delete toast$_ noreply\r\n" if $_ % 2 == 0;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
for (1..1250) {
|
|
Packit |
4e8bc4 |
# Force a read so objects don't get skipped.
|
|
Packit |
4e8bc4 |
print $sock "add mfoo$_ 0 0 1 noreply\r\n1\r\n" if $_ % 2 == 1;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
for (1..1250) {
|
|
Packit |
4e8bc4 |
# Delete lots of objects to trigger compaction.
|
|
Packit |
4e8bc4 |
print $sock "delete mfoo$_ noreply\r\n" if $_ % 2 == 0;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
print $sock "extstore compact_under 4\r\n";
|
|
Packit |
4e8bc4 |
my $res = <$sock>;
|
|
Packit |
4e8bc4 |
print $sock "extstore drop_under 3\r\n";
|
|
Packit |
4e8bc4 |
$res = <$sock>;
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
sleep 4;
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
my $stats = mem_stats($sock);
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_pages_free}, '>', 2, 'some pages now free');
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{extstore_compact_rescues}, '>', 0, 'some compaction rescues happened');
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
# Some of the early items got evicted
|
|
Packit |
4e8bc4 |
for (750..1250) {
|
|
Packit |
4e8bc4 |
# everything should validate properly.
|
|
Packit |
4e8bc4 |
mem_get_is($sock, "mfoo$_", $pattern) if $_ % 2 == 1;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
# test recache
|
|
Packit |
4e8bc4 |
{
|
|
Packit |
4e8bc4 |
print $sock "extstore recache_rate 1\r\n";
|
|
Packit |
4e8bc4 |
is(scalar <$sock>, "OK\r\n", "upped recache rate");
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
for (1150..1250) {
|
|
Packit |
4e8bc4 |
mem_get_is($sock, "mfoo$_", $pattern) if $_ % 2 == 1;
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
my $stats = mem_stats($sock);
|
|
Packit |
4e8bc4 |
cmp_ok($stats->{recache_from_extstore}, '>', 25, 'recaching happening');
|
|
Packit |
4e8bc4 |
}
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
done_testing();
|
|
Packit |
4e8bc4 |
|
|
Packit |
4e8bc4 |
END {
|
|
Packit |
4e8bc4 |
unlink $ext_path if $ext_path;
|
|
Packit |
4e8bc4 |
}
|