App-Netdisco
view release on metacpan or search on metacpan
xt/159-macsuck-redundant-writes.t view on Meta::CPAN
#!/usr/bin/env perl
use strict;
use warnings;
# macsuck rewrote rows that did not change: the freshness archive set
# active = false again on every stale row already archived, and is_uplink
# was written true once per MAC seen through a port (and per MAC on a LAG
# member, to its parent) even when the port was already an uplink. Each of
# those is a new row version.
#
# Only the database edges are faked: the schema, the device port rows, and
# the lookup of which MACs belong to devices.
BEGIN { $ENV{DANCER_ENVDIR} = '/dev/null'; }
use Test::More 0.88;
use App::Netdisco;
use Dancer ':tests';
use App::Netdisco::Worker::Plugin::Macsuck::Nodes;
set logger => 'null';
my $NODES = 'App::Netdisco::Worker::Plugin::Macsuck::Nodes';
my (@searched, @port_updates, $port_macs);
package FakeNodes;
sub new { return bless {}, $_[0] }
sub resultset { return $_[0] }
sub search { push @searched, $_[1]; return $_[0] }
sub update { return 3 }
package FakePort;
sub new { my ($class, %col) = @_; return bless {%col}, $class }
sub port { $_[0]{port} }
sub update {
my ($self, $set) = @_;
push @port_updates, [$self->{port}, $set];
$self->{$_} = $set->{$_} for keys %$set;
return $self;
}
for my $col (qw/is_uplink neighbor remote_ip remote_id remote_type slave_of is_master/) {
no strict 'refs';
*{"FakePort::$col"} = sub { $_[0]{$col} };
}
package FakeDevice;
sub new { return bless {}, $_[0] }
sub ip { '192.0.2.10' }
package main;
{
no warnings 'redefine';
no strict 'refs';
*{"${NODES}::schema"} = sub { FakeNodes->new };
*{"${NODES}::get_port_macs"} = sub { $port_macs };
}
my $device = FakeDevice->new;
my ($mac_a, $mac_b) = ('00:11:22:33:44:01', '00:11:22:33:44:02');
sub run_sanity {
my ($cache, %ports) = @_;
@port_updates = ();
$NODES->can('sanity_macs')->($device, $cache, \%ports);
return scalar @port_updates;
}
subtest 'archive_stale_nodes__search__filters_active' => sub {
set node_freshness => 60;
@searched = ();
ok(my $archive = $NODES->can('archive_stale_nodes'), 'defined') or return;
my $archived = $archive->($device, 'LOCALTIMESTAMP');
is($archived, 3, 'returns the update count');
is(scalar @searched, 1, 'one search');
is($searched[0]{switch}, '192.0.2.10');
is($searched[0]{-bool}, 'active', 'only active rows');
ok(exists $searched[0]{time_last}, 'time_last bound');
};
subtest 'archive_stale_nodes__no_freshness__does_nothing' => sub {
set node_freshness => 0;
@searched = ();
ok(my $archive = $NODES->can('archive_stale_nodes'), 'defined') or return;
is($archive->($device, 'LOCALTIMESTAMP'), 0);
is(scalar @searched, 0);
};
subtest 'sanity_macs__port_already_uplink__no_update' => sub {
$port_macs = { $mac_a => '192.0.2.99' };
my $port = FakePort->new(port => 'Gi1', is_uplink => 1, remote_ip => '192.0.2.99');
is(run_sanity({ 0 => { Gi1 => { $mac_a => 1 } } }, Gi1 => $port), 0);
$port = FakePort->new(port => 'Gi1', is_uplink => 0, remote_ip => '192.0.2.99');
is(run_sanity({ 0 => { Gi1 => { $mac_a => 1 } } }, Gi1 => $port), 1, 'set when not yet an uplink');
( run in 1.313 second using v1.01-cache-2.11-cpan-145b269f2f3 )