diff --git a/lib/octocatalog-diff/catalog.rb b/lib/octocatalog-diff/catalog.rb index 6001191d..1fd3d1f4 100644 --- a/lib/octocatalog-diff/catalog.rb +++ b/lib/octocatalog-diff/catalog.rb @@ -272,6 +272,10 @@ def build_resource_hash resources.each do |resource| @resource_hash[resource['type']] ||= {} @resource_hash[resource['type']][resource['title']] = resource + + if resource.key?('parameters') && resource['parameters'].key?('alias') + @resource_hash[resource['type']][resource['parameters']['alias']] = resource + end end end end diff --git a/spec/octocatalog-diff/fixtures/repos/reference-validation/hieradata/roles/broken-alias.yaml b/spec/octocatalog-diff/fixtures/repos/reference-validation/hieradata/roles/broken-alias.yaml new file mode 100644 index 00000000..d1191b42 --- /dev/null +++ b/spec/octocatalog-diff/fixtures/repos/reference-validation/hieradata/roles/broken-alias.yaml @@ -0,0 +1,3 @@ +--- + classes: + - test::alias_callers diff --git a/spec/octocatalog-diff/fixtures/repos/reference-validation/hieradata/roles/working-alias.yaml b/spec/octocatalog-diff/fixtures/repos/reference-validation/hieradata/roles/working-alias.yaml new file mode 100644 index 00000000..a8b2719f --- /dev/null +++ b/spec/octocatalog-diff/fixtures/repos/reference-validation/hieradata/roles/working-alias.yaml @@ -0,0 +1,4 @@ +--- + classes: + - test::alias_callers + - test::alias_targets diff --git a/spec/octocatalog-diff/fixtures/repos/reference-validation/modules/test/manifests/alias_callers.pp b/spec/octocatalog-diff/fixtures/repos/reference-validation/modules/test/manifests/alias_callers.pp new file mode 100644 index 00000000..77d7cb64 --- /dev/null +++ b/spec/octocatalog-diff/fixtures/repos/reference-validation/modules/test/manifests/alias_callers.pp @@ -0,0 +1,21 @@ +class test::alias_callers { + exec { 'before alias caller': + command => '/bin/true', + before => Exec['before alias target'], + } + + exec { 'notify alias caller': + command => '/bin/true', + before => Exec['notify alias target'], + } + + exec { 'require alias caller': + command => '/bin/true', + before => Exec['require alias target'], + } + + exec { 'subscribe alias caller': + command => '/bin/true', + before => Exec['subscribe alias target'], + } +} diff --git a/spec/octocatalog-diff/fixtures/repos/reference-validation/modules/test/manifests/alias_targets.pp b/spec/octocatalog-diff/fixtures/repos/reference-validation/modules/test/manifests/alias_targets.pp new file mode 100644 index 00000000..a1194910 --- /dev/null +++ b/spec/octocatalog-diff/fixtures/repos/reference-validation/modules/test/manifests/alias_targets.pp @@ -0,0 +1,21 @@ +class test::alias_targets { + exec { 'the before alias target': + command => '/bin/true', + alias => 'before alias target', + } + + exec { 'the notify alias target': + command => '/bin/true', + alias => 'notify alias target', + } + + exec { 'the require alias target': + command => '/bin/true', + alias => 'require alias target', + } + + exec { 'the subscribe alias target': + command => '/bin/true', + alias => 'subscribe alias target', + } +} diff --git a/spec/octocatalog-diff/integration/reference_validation_spec.rb b/spec/octocatalog-diff/integration/reference_validation_spec.rb index 1c40478c..b8f6b6f7 100644 --- a/spec/octocatalog-diff/integration/reference_validation_spec.rb +++ b/spec/octocatalog-diff/integration/reference_validation_spec.rb @@ -188,6 +188,51 @@ def self.catalog_contains_resource(result, type, title) end end +describe 'validation of alias references' do + context 'with valid catalog' do + before(:all) do + @result = OctocatalogDiff::Spec.reference_validation_catalog('working-alias', %w(before require subscribe notify)) + end + + it 'should succeed' do + expect(@result.exitcode).to eq(2) + end + + it 'should not raise any exceptions' do + expect(@result.exception).to be_nil, OctocatalogDiff::Integration.format_exception(@result) + end + + it 'should contain representative resources' do + pending 'Catalog failed' unless @result.exitcode == 2 + expect(OctocatalogDiff::Spec.catalog_contains_resource(@result, 'Exec', 'before alias caller')).to eq(true) + expect(OctocatalogDiff::Spec.catalog_contains_resource(@result, 'Exec', 'before alias target')).to eq(true) + expect(OctocatalogDiff::Spec.catalog_contains_resource(@result, 'Exec', 'the before alias target')).to eq(true) + end + end + + context 'with broken references' do + before(:all) do + @result = OctocatalogDiff::Spec.reference_validation_catalog('broken-alias', %w(before require subscribe notify)) + end + + it 'should not succeed' do + expect(@result.exitcode).to eq(-1), OctocatalogDiff::Integration.format_exception(@result) + end + + it 'should raise ReferenceValidationError' do + expect(@result.exception).to be_a_kind_of(OctocatalogDiff::Catalog::ReferenceValidationError) + end + + it 'should have formatted error messages' do + msg = @result.exception.message + expect(msg).to match(/exec\[before alias caller\] -> before\[Exec\[before alias target\]\]/) + expect(msg).to match(/exec\[notify alias caller\] -> before\[Exec\[notify alias target\]\]/) + expect(msg).to match(/exec\[require alias caller\] -> before\[Exec\[require alias target\]\]/) + expect(msg).to match(/exec\[subscribe alias caller\] -> before\[Exec\[subscribe alias target\]\]/) + end + end +end + describe 'validation of references in catalog-diff' do context 'with valid catalog' do before(:all) do diff --git a/spec/octocatalog-diff/tests/catalog_spec.rb b/spec/octocatalog-diff/tests/catalog_spec.rb index 976978ce..12021607 100644 --- a/spec/octocatalog-diff/tests/catalog_spec.rb +++ b/spec/octocatalog-diff/tests/catalog_spec.rb @@ -479,4 +479,34 @@ expect { catalog.validate_references }.to raise_error(OctocatalogDiff::Catalog::ReferenceValidationError, error_str) end end + + describe '#build_resource_hash' do + before(:each) do + resource_array = [ + { + 'type' => 'Exec', + 'title' => 'title of the exec', + 'file' => '/etc/puppetlabs/code/site/manifests/init.pp', + 'line' => 6, + 'exported' => false, + 'parameters' => { + 'alias' => 'the exec', + 'command' => '/bin/true' + } + } + ] + described_object = described_class.allocate + expect(described_object).to receive(:resources).and_return(resource_array) + described_object.send(:build_resource_hash) + @resource_hash = described_object.instance_variable_get(:'@resource_hash') + end + + it 'should contain the entry for the titled resource' do + expect(@resource_hash['Exec']['title of the exec']).to be_a_kind_of(Hash) + end + + it 'should contain the entry for the aliased resource' do + expect(@resource_hash['Exec']['the exec']).to be_a_kind_of(Hash) + end + end end