Commit 817fb3bd authored by Johan Ouwerkerk's avatar Johan Ouwerkerk

Add initial test suite for new dependency resolution algorithm(s).

parent 19789dd3
use 5.014;
use strict;
use warnings;
# Test comparison operation for sorting modules into build order
use Test::More;
use ksb::DependencyResolver;
# Redefine ksb::Module to stub isKDEProject() results
package ksb::Module {
no warnings 'redefine';
sub new
{
my ($class, $kde) = @_;
my $self = {
kde => $kde
};
bless $self, $class;
return $self;
}
sub isKDEProject
{
my $self = shift;
return $self->{kde};
}
};
my $graph1 = {
'a' => {
votes => {
'b' => 1,
'd' => 1
},
module => new ksb::Module(1)
},
'b' => {
votes => {},
module => new ksb::Module(1)
},
'c' => {
votes => {
'd' => 1
},
module => new ksb::Module(1)
},
'd' => {
votes => {},
module => new ksb::Module(1)
},
'e' => {
votes => {},,
module => new ksb::Module(0)
},
'f' => => {
votes => {},,
module => new ksb::Module(0)
}
};
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'a', 'a'), 0, "'a' should be sorted at the same position as itself");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'a', 'b'), -1, "'a' should be sorted before 'b' by dependency ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'a', 'c'), -1, "'a' should be sorted before 'c' by vote ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'a', 'd'), -1, "'a' should be sorted before 'd' by dependency ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'a', 'e'), 1, "'a' should be sorted after 'e' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'a', 'f'), 1, "'a' should be sorted after 'f' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'b', 'a'), 1, "'b' should be sorted after 'a' by dependency ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'b', 'b'), 0, "'b' should be sorted at the same position as itself");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'b', 'c'), 1, "'b' should be sorted after 'c' by vote ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'b', 'd'), -1, "'b' should be sorted before 'd' by lexicographic ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'b', 'e'), 1, "'b' should be sorted after 'e' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'b', 'f'), 1, "'b' should be sorted after 'f' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'c', 'a'), 1, "'c' should be sorted after 'c' by vote ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'c', 'b'), -1, "'c' should be sorted before 'b' by vote ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'c', 'c'), 0, "'c' should be sorted at the same position as itself");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'c', 'd'), -1, "'c' should be sorted before 'd' by dependency ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'c', 'e'), 1, "'c' should be sorted after 'e' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'c', 'f'), 1, "'c' should be sorted after 'f' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'd', 'a'), 1, "'d' should be sorted after 'a' by dependency ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'd', 'b'), 1, "'d' should be sorted after 'b' by lexicographic ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'd', 'c'), 1, "'d' should be sorted after 'c' by dependency ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'd', 'd'), 0, "'d' should be sorted at the same position as itself");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'd', 'e'), 1, "'d' should be sorted after 'e' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'd', 'f'), 1, "'d' should be sorted after 'f' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'e', 'a'), -1, "'e' should be sorted before 'a' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'e', 'b'), -1, "'e' should be sorted before 'b' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'e', 'c'), -1, "'e' should be sorted before 'c' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'e', 'd'), -1, "'e' should be sorted before 'd' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'e', 'e'), 0, "'e' should be sorted at the same position as itself");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'e', 'f'), -1, "'e' should be sorted before 'f' by lexicographic ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'f', 'a'), -1, "'f' should be sorted before 'a' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'f', 'b'), -1, "'f' should be sorted before 'b' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'f', 'c'), -1, "'f' should be sorted before 'c' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'f', 'd'), -1, "'f' should be sorted before 'd' by prioritising non-KDE modules over KDE ones");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'f', 'e'), 1, "'f' should be sorted after 'e' by lexicographic ordering");
is(ksb::DependencyResolver::_compareBuildOrder($graph1, 'f', 'f'), 0, "'f' should be sorted at the same position as itself");
done_testing();
use 5.014;
use strict;
use warnings;
# Test running the full vote for dependencies
use Test::More;
use ksb::DependencyResolver;
my $graph1 = {
'a' => {
deps => {
'b' => 1
},
allDeps => {}
},
'b' => {
deps => {
'c' => 1
},
allDeps => {}
},
'c' => {
deps => {},
allDeps => {}
},
#
# an item might depend through multiple (transitive) paths on the same
# dependency at the same time
#
'd' => {
deps => {
'b' => 1,
'c' => 1
},
allDeps => {}
},
'e' => {
deps => {},
allDeps => {}
}
};
my $expected1 = {
'a' => {
deps => {
'b' => 1
},
allDeps => {
done => 1,
items => {
'b' => 1,
'c' => 1
}
}
},
'b' => {
deps => {
'c' => 1
},
allDeps => {
done => 1,
items => {
'c' => 1
}
}
},
'c' => {
deps => {},
allDeps => {
done => 1,
items => {}
}
},
'd' => {
deps => {
'b' => 1,
'c' => 1
},
allDeps => {
done => 1,
items => {
'b' => 1,
'c' => 1
}
}
},
'e' => {
deps => {},
allDeps => {
done => 1,
items => {}
}
}
};
is_deeply(ksb::DependencyResolver::_copyUpDependencies($graph1), $expected1, "should copy up dependencies correctly");
done_testing();
use 5.014;
use strict;
use warnings;
# Test detection of dependency cycles in a dependency graph
use Test::More;
use ksb::DependencyResolver;
#
# trivial cycle a -> a
#
my $graph1 = {
'a' => {
deps => {
'a' => {}
}
},
'b' => {
deps => {}
}
};
is(ksb::DependencyResolver::_detectDependencyCycle($graph1, 'a', 'a'), 1, "should detect 'trivial' cycles of an item to itself");
my $graph2 = {
'a' => {
deps => {
'b' => {}
}
},
'b' => {
deps => {
'a' => {}
}
}
};
is(ksb::DependencyResolver::_detectDependencyCycle($graph2, 'a', 'a'), 1, "should detect cycle: a -> b -> a");
is(ksb::DependencyResolver::_detectDependencyCycle($graph2, 'b', 'b'), 1, "should detect cycle: b -> a -> b");
#
# no cycles, should therefore not 'detect' any false positives
#
my $graph3 = {
'a' => {
deps => {
'b' => {}
}
},
'b' => {
deps => {}
}
};
is(ksb::DependencyResolver::_detectDependencyCycle($graph3, 'a', 'a'), 0, "should not report false positives for 'a'");
is(ksb::DependencyResolver::_detectDependencyCycle($graph3, 'b', 'b'), 0, "should not report false positives for 'b'");
done_testing();
use 5.014;
use strict;
use warnings;
#
# Verify that _getDependencyPathOf() works properly
#
use Test::More;
use ksb::DependencyResolver;
# Redefine ksb::Module to stub fullProjectPath() results
package ksb::Module {
no warnings 'redefine';
sub new
{
my ($class, $projectPath) = @_;
my $self = {
projectPath => $projectPath,
};
bless $self, $class;
return $self;
}
sub fullProjectPath
{
my $self = shift;
return $self->{projectPath};
}
};
my $module1 = ksb::Module->new('test/path');
is(ksb::DependencyResolver::_getDependencyPathOf($module1, 'foo', 'bar'), 'test/path', "should return full project path if a module object is passed");
my $module2 = undef;
is(ksb::DependencyResolver::_getDependencyPathOf($module2, 'foo', 'bar'), 'bar', "should return the provided default if no module is passed");
done_testing();
use 5.014;
use strict;
use warnings;
# Test running the full vote for dependencies
use Test::More;
use ksb::DependencyResolver;
my $graph1 = {
'a' => {
votes => {},
allDeps => {
items => {
'b' => 1,
'c' => 1
}
}
},
'b' => {
votes => {},
allDeps => {
items => {
'c' => 1
}
}
},
'c' => {
votes => {},
allDeps => {
items => {}
}
},
#
# an item might depend through multiple (transitive) paths on the same
# dependency at the same time
#
'd' => {
votes => {},
allDeps => {
items => {
'b' => 1,
'c' => 1
}
}
},
'e' => {
votes => {},
allDeps => {
items => {}
}
}
};
my $expected1 = {
'a' => {
votes => {},
allDeps => {
items => {
'b' => 1,
'c' => 1
}
}
},
'b' => {
votes => {
'a' => 1,
'd' => 1
},
allDeps => {
items => {
'c' => 1
}
}
},
'c' => {
votes => {
'a' => 1,
'b' => 1,
'd' => 1
},
allDeps => {
items => {}
}
},
'd' => {
votes => {},
allDeps => {
items => {
'b' => 1,
'c' => 1
}
}
},
'e' => {
votes => {},
allDeps => {
items => {}
}
}
};
ksb::DependencyResolver::_runDependencyVote($graph1);
is_deeply($graph1, $expected1, "should yield expected votes");
done_testing();
use 5.014;
use strict;
use warnings;
# Test sorting modules into build order
use Test::More;
use ksb::DependencyResolver;
# Redefine ksb::Module to stub isKDEProject() results
package ksb::Module {
no warnings 'redefine';
sub new
{
my ($class, $kde, $name) = @_;
my $self = {
kde => $kde,
name => $name
};
bless $self, $class;
return $self;
}
sub isKDEProject
{
my $self = shift;
return $self->{kde};
}
sub name
{
my $self = shift;
return $self->{name};
}
};
my $graph1 = {
'a' => {
votes => {
'b' => 1,
'd' => 1
},
build => 1,
module => new ksb::Module(1, 'a')
},
'b' => {
votes => {},
build => 1,
module => new ksb::Module(1, 'b')
},
'c' => {
votes => {
'd' => 1
},
build => 1,
module => new ksb::Module(1, 'c')
},
'd' => {
votes => {},
build => 1,
module => new ksb::Module(1, 'd')
},
'e' => {
votes => {},
build => 1,
module => new ksb::Module(0, 'e')
},
'f' => {
votes => {},
build => 1,
module => new ksb::Module(0, 'f')
}
};
my @expected1 = ('e', 'f', 'a', 'c', 'b', 'd');
my @actual1 = map { $_->name() } (ksb::DependencyResolver::sortModulesIntoBuildOrder($graph1));
is_deeply(\@actual1, \@expected1, "should sort modules into the proper build order");
# use some random key strokes for names:
# unlikely to yield keys in equivalent order as $graph1: key order *should not matter*
my $graph2 = {
'avdnrvrl' => {
votes => {
'd' => 1
},
build => 1,
module => new ksb::Module(1, 'c')
},
'lexical1' => {
votes => {},
build => 1,
module => new ksb::Module(1, 'b')
},
'nllfmvrb' => {
votes => {
'b' => 1,
'd' => 1
},
build => 1,
module => new ksb::Module(1, 'a')
},
'lexical2' => {
votes => {},
build => 1,
module => new ksb::Module(1, 'd')
},
'non-KDE-f' => {
votes => {},
build => 1,
module => new ksb::Module(0, 'f')
},
'non-KDE-e' => {
votes => {},
build => 1,
module => new ksb::Module(0, 'e')
}
};
my @expected2 = ('e', 'f', 'a', 'c', 'b', 'd');
my @actual2 = map { $_->name() } (ksb::DependencyResolver::sortModulesIntoBuildOrder($graph2));
is_deeply(\@actual2, \@expected2, "key order should not matter for build order");
my $graph3 = {
'a' => {
votes => {
'b' => 1,
'd' => 1
},
build => 0,
module => new ksb::Module(1, 'a')
},
'b' => {
votes => {},
build => 1,
module => undef
},
'c' => {
votes => {
'd' => 1
},
build => 1,
module => new ksb::Module(1, 'c')
},
'd' => {
votes => {},
build => 1,
module => new ksb::Module(1, 'd')
}
};
my @expected3 = ('c', 'd');
my @actual3 = map { $_->name() } (ksb::DependencyResolver::sortModulesIntoBuildOrder($graph3));
is_deeply(\@actual3, \@expected3, "modules that are not to be built should be omitted");
done_testing();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment