%PDF- %PDF-
| Direktori : /home/opti/optisoftcom/.cpanm/work/1544535406.20768/MongoDB-v2.0.2/t/ |
| Current File : /home/opti/optisoftcom/.cpanm/work/1544535406.20768/MongoDB-v2.0.2/t/changestreams.t |
# Copyright 2018 - present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
use strict;
use warnings;
use utf8;
use Test::More 0.96;
use MongoDB;
use lib "t/lib";
use MongoDBTest qw/
skip_unless_mongod
skip_unless_sessions
uuid_to_string
build_client
get_test_db
server_version
server_type
/;
skip_unless_mongod();
my @events;
my $conn = build_client(monitoring_callback => sub {
push @events, shift;
});
my $testdb = get_test_db($conn);
my $server_version = server_version($conn);
my $server_type = server_type($conn);
my $coll = $testdb->get_collection('test_collection');
plan skip_all => 'MongoDB replica set required'
unless $server_type eq 'RSPrimary';
subtest 'client' => sub {
plan skip_all => 'MongoDB version 4.0 or higher required'
unless $server_version >= version->parse('v4.0.0');
run_tests_for($conn);
};
subtest 'database' => sub {
plan skip_all => 'MongoDB version 4.0 or higher required'
unless $server_version >= version->parse('v4.0.0');
run_tests_for($testdb);
};
subtest 'collection' => sub {
plan skip_all => 'MongoDB version 3.6 or higher required'
unless $server_version >= version->parse('v3.6.0');
run_tests_for($coll);
};
done_testing;
sub run_tests_for {
my ($watchable) = @_;
subtest 'basic' => sub {
$coll->drop;
$coll->insert_one({ value => 1 });
$coll->insert_one({ value => 2 });
my $change_stream = $watchable->watch();
is $change_stream->next, undef, 'next without changes';
for my $index (1..10) {
$coll->insert_one({ value => 100 + $index });
}
my %changed;
while (my $change = $change_stream->next) {
is $changed{ $change->{fullDocument}{value} }++, 0,
'first seen '.$change->{fullDocument}{value};
}
is scalar(keys %changed), 10, 'seen all changes';
};
subtest 'change streams w/ maxAwaitTimeMS' => sub {
$coll->drop;
my $change_stream = $watchable->watch([], { maxAwaitTimeMS => 3000 });
my $start = time;
is $change_stream->next, undef, 'next without changes';
my $elapsed = time - $start;
my $min_elapsed = 2;
ok $elapsed > $min_elapsed, "waited for at least $min_elapsed secs";
};
subtest 'change streams w/ fullDocument' => sub {
$coll->drop;
$coll->insert_one({ value => 1 });
my $change_stream = $watchable->watch(
[],
{ fullDocument => 'updateLookup' },
);
$coll->update_one(
{ value => 1 },
{ '$set' => { updated => 3 }},
);
my $change = $change_stream->next;
is $change->{operationType}, 'update', 'change is an update';
ok exists($change->{fullDocument}), 'delta contains full document';
};
subtest 'change streams w/ resumeAfter' => sub {
$coll->drop;
my $id = do {
my $change_stream = $watchable->watch();
$coll->insert_one({ value => 200 });
$coll->insert_one({ value => 201 });
my $change = $change_stream->next;
ok $change, 'change exists';
is $change->{fullDocument}{value}, 200,
'correct change';
$change->{_id}
};
do {
my $change_stream = $watchable->watch(
[],
{ resumeAfter => $id },
);
my $change = $change_stream->next;
ok $change, 'change exists after resume';
is $change->{fullDocument}{value}, 201,
'correct change after resume';
is $change_stream->next, undef, 'no more changes';
};
};
subtest 'change streams w/ CursorNotFound reconnection' => sub {
$coll->drop;
my $change_stream = $watchable->watch;
$coll->insert_one({ value => 301 });
my $change = $change_stream->next;
ok $change, 'change received';
is $change->{fullDocument}{value}, 301, 'correct change';
$testdb->run_command([
killCursors => $coll->name,
cursors => [$change_stream->_result->_cursor_id],
]);
$coll->insert_one({ value => 302 });
$change = $change_stream->next;
ok $change, 'change received after reconnect';
is $change->{fullDocument}{value}, 302, 'correct change';
};
subtest 'startAtOperationTime' => sub {
plan skip_all => 'MongoDB version 4.0 or higher required'
unless $server_version >= version->parse('v4.0.0');
$coll->drop;
my $change_stream = $watchable->watch([], {
startAtOperationTime => scalar(time + 3),
});
$coll->insert_one({ value => 401 });
sleep 4;
$coll->insert_one({ value => 402 });
my $change = $change_stream->next;
ok $change, 'change received';
is $change->{fullDocument}{value}, 402, 'correct change';
ok !defined($change_stream->next), 'no more changes';
};
subtest 'sessions' => sub {
skip_unless_sessions();
@events = ();
my $session = $conn->start_session;
my $change_stream = $watchable->watch([], {
session => $session,
});
$change_stream->next;
my ($event) = grep {
$_->{commandName} eq 'aggregate' and
$_->{type} eq 'command_started'
} @events;
ok(defined($event), 'found event')
or return;
my $lsid = uuid_to_string(
$session->_server_session->session_id->{id}->data,
);
my $command = $event->{command};
my $command_sid = uuid_to_string($command->{lsid}{id}->data);
is $command_sid, $lsid, 'command has correct session id';
};
}