This repository has been archived by the owner. It is now read-only.
Permalink
Fetching contributors…
Cannot retrieve contributors at this time
294 lines (280 sloc) 8.69 KB
use Mojo::Base -strict;
use Test::More;
plan skip_all => 'set TEST_ONLINE to enable this test'
unless $ENV{TEST_ONLINE};
use Mango;
use Mango::BSON 'bson_oid';
use Mojo::IOLoop;
# Clean up before start
my $mango = Mango->new($ENV{TEST_ONLINE});
my $gridfs = $mango->db->gridfs;
$gridfs->$_->remove for qw(files chunks);
# Blocking roundtrip
my $writer = $gridfs->writer;
$writer->filename('foo.txt')->content_type('text/plain')
->metadata({foo => 'bar'});
ok !$writer->is_closed, 'file has not been closed';
my $oid = $writer->write('hello ')->write('world!')->close;
ok $writer->is_closed, 'file has been closed';
my $reader = $gridfs->reader;
is $reader->tell, 0, 'right position';
$reader->open($oid);
is $reader->filename, 'foo.txt', 'right filename';
is $reader->content_type, 'text/plain', 'right content type';
is $reader->md5, 'fc3ff98e8c6a0d3087d515c0473f8677', 'right checksum';
is_deeply $reader->metadata, {foo => 'bar'}, 'right structure';
is $reader->size, 12, 'right size';
is $reader->chunk_size, 261120, 'right chunk size';
is length $reader->upload_date, length(time) + 3, 'right time format';
my $data;
while (defined(my $chunk = $reader->read)) { $data .= $chunk }
is $reader->tell, 12, 'right position';
is $data, 'hello world!', 'right content';
$data = undef;
$reader->seek(0);
is $reader->tell, 0, 'right position';
$reader->seek(2);
is $reader->tell, 2, 'right position';
while (defined(my $chunk = $reader->read)) { $data .= $chunk }
is $data, 'llo world!', 'right content';
is_deeply $gridfs->list, ['foo.txt'], 'right files';
$gridfs->delete($oid);
is_deeply $gridfs->list, [], 'no files';
is $gridfs->chunks->find->count, 0, 'no chunks left';
$gridfs->$_->drop for qw(files chunks);
# Non-blocking roundtrip
$writer = $gridfs->writer->chunk_size(4);
$writer->filename('foo.txt')->content_type('text/plain')
->metadata({foo => 'bar'});
ok !$writer->is_closed, 'file has not been closed';
my ($fail, $result);
my $delay = Mojo::IOLoop->delay(
sub {
my $delay = shift;
$writer->write('he' => $delay->begin);
},
sub {
my ($delay, $err) = @_;
return $delay->pass($err) if $err;
$writer->write('llo ' => $delay->begin);
},
sub {
my ($delay, $err) = @_;
return $delay->pass($err) if $err;
$writer->write('w' => $delay->begin);
$writer->write('orld!' => $delay->begin);
},
sub {
my ($delay, $err) = @_;
return $delay->pass($err) if $err;
$writer->close($delay->begin);
},
sub {
my ($delay, $err, $oid) = @_;
$fail = $err;
$result = $oid;
}
);
$delay->wait;
ok !$fail, 'no error';
ok $writer->is_closed, 'file has been closed';
$reader = $gridfs->reader;
$fail = undef;
$reader->open(
$result => sub {
my ($reader, $err) = @_;
$fail = $err;
Mojo::IOLoop->stop;
}
);
Mojo::IOLoop->start;
ok !$fail, 'no error';
is $reader->filename, 'foo.txt', 'right filename';
is $reader->content_type, 'text/plain', 'right content type';
is $reader->md5, 'fc3ff98e8c6a0d3087d515c0473f8677', 'right checksum';
is_deeply $reader->metadata, {foo => 'bar'}, 'right structure';
is $reader->size, 12, 'right size';
is $reader->chunk_size, 4, 'right chunk size';
is length $reader->upload_date, length(time) + 3, 'right time format';
($fail, $data) = ();
my $cb;
$cb = sub {
my ($reader, $err, $chunk) = @_;
$fail ||= $err;
return Mojo::IOLoop->stop unless defined $chunk;
$data .= $chunk;
$reader->read($cb);
};
$reader->$cb(undef, '');
Mojo::IOLoop->start;
ok !$fail, 'no error';
is $data, 'hello world!', 'right content';
my ($before, $after);
$fail = undef;
$delay = Mojo::IOLoop->delay(
sub { $gridfs->list(shift->begin) },
sub {
my ($delay, $err, $names) = @_;
return $delay->pass($err) if $err;
$before = $names;
$gridfs->delete($result => $delay->begin);
},
sub {
my ($delay, $err) = @_;
return $delay->pass($err) if $err;
$gridfs->list($delay->begin);
},
sub {
my ($delay, $err, $names) = @_;
$fail = $err;
$after = $names;
}
);
$delay->wait;
ok !$fail, 'no error';
is_deeply $before, ['foo.txt'], 'right files';
is_deeply $after, [], 'no files';
is $gridfs->chunks->find->count, 0, 'no chunks left';
$gridfs->$_->drop for qw(files chunks);
# Find and slurp versions blocking
my $one
= $gridfs->writer->chunk_size(1)->filename('test.txt')->write('One1')->close;
is $gridfs->find_version('test.txt', -1), $one, 'right version';
my $two = $gridfs->writer->filename('test.txt')->write('Two')->close;
is $gridfs->find_version('test.txt', -1), $two, 'right version';
is $gridfs->find_version('test.txt', -2), $one, 'right version';
is $gridfs->find_version('test.txt', -3), undef, 'no version';
is_deeply $gridfs->list, ['test.txt'], 'right files';
is $gridfs->find_version('test.txt', 0), $one, 'right version';
is $gridfs->find_version('test.txt', 1), $two, 'right version';
is $gridfs->find_version('test.txt', 2), undef, 'no version';
is $gridfs->reader->open($one)->slurp, 'One1', 'right content';
is $gridfs->reader->open($one)->seek(1)->slurp, 'ne1', 'right content';
is $gridfs->reader->open($two)->slurp, 'Two', 'right content';
is $gridfs->reader->open($two)->seek(1)->slurp, 'wo', 'right content';
$gridfs->$_->drop for qw(files chunks);
# Find and slurp versions non-blocking
$one = $gridfs->writer->filename('test.txt')->write('One')->close;
$two = $gridfs->writer->filename('test.txt')->write('Two')->close;
is_deeply $gridfs->list, ['test.txt'], 'right files';
my @results;
$fail = undef;
$delay = Mojo::IOLoop->delay(
sub {
my $delay = shift;
$gridfs->find_version(('test.txt', 2) => $delay->begin);
$gridfs->find_version(('test.txt', 1) => $delay->begin);
$gridfs->find_version(('test.txt', 0) => $delay->begin);
},
sub {
my ($delay, $three_err, $three, $two_err, $two, $one_err, $one) = @_;
$fail = $one_err || $two_err || $three_err;
@results = ($one, $two, $three);
}
);
$delay->wait;
ok !$fail, 'no error';
is $results[0], $one, 'right version';
is $results[1], $two, 'right version';
is $results[2], undef, 'no version';
my $one_reader = $gridfs->reader;
my $two_reader = $gridfs->reader;
($fail, @results) = ();
$delay = Mojo::IOLoop->delay(
sub {
my $delay = shift;
$one_reader->open($one => $delay->begin);
$two_reader->open($two => $delay->begin);
},
sub {
my ($delay, $one_err, $two_err) = @_;
if (my $err = $one_err || $two_err) { return $delay->pass($err) }
$one_reader->slurp($delay->begin);
$two_reader->slurp($delay->begin);
},
sub {
my ($delay, $one_err, $one, $two_err, $two) = @_;
$fail = $one_err || $two_err;
@results = ($one, $two);
}
);
$delay->wait;
ok !$fail, 'no error';
is $results[0], 'One', 'right content';
is $results[1], 'Two', 'right content';
$gridfs->$_->drop for qw(files chunks);
# File already closed
$writer = $gridfs->writer;
ok !$writer->is_closed, 'file has not been closed';
$oid = $writer->write('Test')->close;
ok $writer->is_closed, 'file has been closed';
eval { $writer->write('123') };
like $@, qr/^File already closed/, 'right error';
$fail = undef;
$writer->write(
'123' => sub {
my ($writer, $err) = @_;
$fail = $err;
Mojo::IOLoop->stop;
}
);
Mojo::IOLoop->start;
like $fail, qr/^File already closed/, 'right error';
ok $writer->is_closed, 'file is still closed';
is $writer->close, $oid, 'right result';
($fail, $result) = ();
$writer->close(
sub {
my ($writer, $err, $oid) = @_;
$fail = $err;
$result = $oid;
Mojo::IOLoop->stop;
}
);
Mojo::IOLoop->start;
ok !$fail, 'no error';
is $result, $oid, 'right result';
ok $writer->is_closed, 'file is still closed';
$gridfs->$_->drop for qw(files chunks);
# Big chunks and concurrent readers
$oid = $gridfs->writer->write('x' x 1000000)->close;
($fail, @results) = ();
$delay = Mojo::IOLoop->delay(
sub {
my $delay = shift;
$gridfs->reader->open($oid => $delay->begin(0));
$gridfs->reader->open($oid => $delay->begin(0));
},
sub {
my ($delay, $reader1, $err1, $reader2, $err2) = @_;
if (my $err = $err1 || $err2) { return $delay->pass($err) }
$reader1->slurp($delay->begin);
$reader2->slurp($delay->begin);
},
sub {
my ($delay, $err1, $data1, $err2, $data2) = @_;
$fail = $err1 || $err2;
@results = ($data1, $data2);
}
);
$delay->wait;
ok !$fail, 'no error';
is $results[0], 'x' x 1000000, 'right content';
is $results[1], 'x' x 1000000, 'right content';
$gridfs->$_->drop for qw(files chunks);
# Open missing file blocking
$oid = bson_oid;
eval { $gridfs->reader->open($oid) };
like $@, qr/^$oid does not exist/, 'right error';
# Open missing file non-blocking
$fail = undef;
$gridfs->reader->open(
$oid => sub {
my ($reader, $err) = @_;
$fail = $err;
Mojo::IOLoop->stop;
}
);
Mojo::IOLoop->start;
like $fail, qr/^$oid does not exist/, 'right error';
done_testing();