File Coverage

blib/lib/CCfnX/Dependencies.pm
Criterion Covered Total %
statement 19 53 35.8
branch 11 20 55.0
condition 3 6 50.0
subroutine 4 10 40.0
pod 0 9 0.0
total 37 98 37.7


line stmt bran cond sub pod time code
1             package CCfnX::Dependencies {
2 21     21   13884 use Moose::Role;
  21         55  
  21         165  
3              
4             sub resolve_references_to_logicalid_with {
5 45     45 0 315 my ($self, $logical_id, $object) = @_;
6 45         734 $self->Properties->resolve_references_to_logicalid_with($logical_id, $object);
7             }
8              
9       0 0   sub resolve_parameters {
10             # Scan all resources resolving parameters to their value
11             }
12              
13       0 0   sub resolve_functions {
14             # Execute functions
15             }
16              
17       0 0   sub resolve_references {
18             #
19             }
20              
21             sub get_deps_from_object {
22 172     172 0 3815 my ($object, $deps) = @_;
23              
24 172 100       1505 return $deps if (not defined $object);
25            
26 81 100 100     794 if ($object->isa('Cfn::Value::Array')) {
    100          
    100          
    50          
    100          
27 8         16 get_deps_from_object($_, $deps) for (@{ $object->Value });
  8         199  
28             } elsif ($object->isa('Cfn::Value::Function::Ref') or $object->isa('Cfn::Value::Function::GetAtt')) {
29 38         152 $deps->{ $object->LogicalId } = 1;
30             } elsif ($object->isa('Cfn::Value::Function')) {
31 1         32 get_deps_from_object($object->Value, $deps);
32             } elsif ($object->isa('Cfn::Value::Hash')) {
33 0         0 get_deps_from_object($object->Value->{ $_ }, $deps) for (keys %{ $object->Value });
  0         0  
34             } elsif ($object->isa('Cfn::Resource')) {
35             # Deps in attributes
36 32         678 get_deps_from_object($object->Properties->$_, $deps) for map { $_->name } ($object->Properties->meta->get_all_attributes);
  128         3561  
37             # Add explicit DependsOn
38 32         118 $deps->{ $_ } = 1 for ($object->DependsOnList);
39             }
40 81         769 return $deps;
41             }
42              
43             sub dependencies {
44 32     32 0 58 my $self = shift;
45 32         46 return [ keys %{ get_deps_from_object($self, { }) } ];
  32         77  
46             }
47              
48             sub undeclared_dependencies {
49 0     0 0   my $self = shift;
50             # register all deps in
51 0   0       my @errors = grep { not $self->Resource($_) and not $self->Parameter($_) } @{ $self->dependencies };
  0            
  0            
52 0           return @errors;
53             }
54              
55             # Calculates the dependency tree between resources
56             # Dies upon circular dependencies or not declared resource
57             sub dependency_tree {
58 0     0 0   my($self, $deps, $dtree) = @_;
59 0           my @resources = $self->ResourceList;
60            
61 0 0         if (!$dtree) {
62 0           $dtree = Tree->new('root');
63 0           $deps = \@resources;
64             }
65            
66 0           foreach my $dep (@$deps) {
67 0           my $curr = Tree->new($dep);
68 0           $dtree->add_child($curr);
69            
70             # Detect circular dependencies
71 0 0         if ($dtree->depth > scalar @resources) {
72 0           my $dep_resources = {};
73 0           while (!$dtree->is_root) { # Approximate resources involved
74 0           $dep_resources->{$dtree->value} = 1; # in the circular dependency
75 0           $dtree = $dtree->parent;
76             }
77 0           die "Could not create dependency tree due to circular dependencies around resources: ". join(',', keys %$dep_resources)."\n";
78             }
79 0 0         die "Could not find resource $dep declared as a dependency of ".$dtree->value."\n" if(!$self->Resources->{$dep});
80 0           $curr = $self->dependency_tree( $self->Resources->{$dep}->DependsOn, $curr );
81             }
82 0           return $dtree;
83             }
84            
85             # Returns ArrayRef of resource names in order of creation to respect dependencies
86             sub resource_creation_order {
87 0     0 0   my $self = shift;
88 0           my $dep_tree = $self->dependency_tree;
89            
90 0           my @nodes = $dep_tree->traverse( $dep_tree->POST_ORDER );
91 0           pop @nodes; # ditch 'root' node
92            
93 0           my $created_resources = {};
94 0           my @create_order;
95             #my @create_order = map { $_->value } @nodes;
96            
97             # Avoid returning duplicates using aux hash?
98             # `·->Must! per distingir del cas de recursos amb noms duplicats
99 0           foreach (@nodes) {
100 0 0         push @create_order, $_->value unless($created_resources->{$_->value}); # if not created already
101 0           $created_resources->{$_->value} = 1;
102             }
103 0           return \@create_order;
104             }
105             }
106              
107             1;