diff --git a/lib/kubernetes-deploy/renderer.rb b/lib/kubernetes-deploy/renderer.rb index 44ee00a23..3b4f08201 100644 --- a/lib/kubernetes-deploy/renderer.rb +++ b/lib/kubernetes-deploy/renderer.rb @@ -8,13 +8,13 @@ module KubernetesDeploy class Renderer class InvalidPartialError < InvalidTemplateError - attr_reader :parents, :content, :filename + attr_accessor :parents, :content, :filename def initialize(msg, parents: [], content: nil, filename:) @parents = parents super(msg, content: content, filename: filename) end end - class PartialNotFound < InvalidPartialError; end + class PartialNotFound < InvalidTemplateError; end def initialize(current_sha:, template_dir:, logger:, bindings: {}) @current_sha = current_sha @@ -35,9 +35,9 @@ def render_template(filename, raw_template) ERB.new(raw_template, nil, '-').result(erb_binding) rescue InvalidPartialError => err - all_parents = err.parents.dup.unshift(filename) - raise InvalidTemplateError.new(err.message, - filename: "#{err.filename} (partial included from: #{all_parents.join(' -> ')})", content: err.content) + err.parents = err.parents.dup.unshift(filename) + err.filename = "#{err.filename} (partial included from: #{err.parents.join(' -> ')})" + raise err rescue StandardError => err raise InvalidTemplateError.new(err.message, filename: filename, content: raw_template) end @@ -60,10 +60,12 @@ def render_partial(partial, locals) # Note that JSON is a subset of YAML. JSON.generate(docs.children.first.to_ruby) rescue PartialNotFound => err - raise InvalidPartialError.new(err.message, filename: err.filename) + # get the filename from the first parent, not the missing partial itself + raise err if err.filename == partial + raise InvalidPartialError.new(err.message, filename: partial, content: expanded_template || template) rescue InvalidPartialError => err - parents = err.parents.dup.unshift(File.basename(partial_path)) - raise InvalidPartialError.new(err.message, parents: parents, filename: err.filename, content: err.content) + err.parents = err.parents.dup.unshift(File.basename(partial_path)) + raise err rescue StandardError => err raise InvalidPartialError.new(err.message, filename: partial_path, content: expanded_template || template) end diff --git a/test/fixtures/missing-partials/include-missing-partials.yml.erb b/test/fixtures/missing-partials/include-missing-partials.yml.erb deleted file mode 100644 index 809ff18d0..000000000 --- a/test/fixtures/missing-partials/include-missing-partials.yml.erb +++ /dev/null @@ -1 +0,0 @@ -<%= partial 'nest-missing-partial' %> diff --git a/test/fixtures/missing-partials/parent-with-missing-child.yml.erb b/test/fixtures/missing-partials/parent-with-missing-child.yml.erb new file mode 100644 index 000000000..935856999 --- /dev/null +++ b/test/fixtures/missing-partials/parent-with-missing-child.yml.erb @@ -0,0 +1 @@ +<%= partial 'does-not-exist' %> diff --git a/test/fixtures/missing-partials/parent-with-missing-grandchild.yml.erb b/test/fixtures/missing-partials/parent-with-missing-grandchild.yml.erb new file mode 100644 index 000000000..b24195829 --- /dev/null +++ b/test/fixtures/missing-partials/parent-with-missing-grandchild.yml.erb @@ -0,0 +1 @@ +<%= partial 'parent-with-missing-child' %> diff --git a/test/fixtures/missing-partials/partials/nest-missing-partial.yml.erb b/test/fixtures/missing-partials/partials/nest-missing-partial.yml.erb deleted file mode 100644 index 395ab96ea..000000000 --- a/test/fixtures/missing-partials/partials/nest-missing-partial.yml.erb +++ /dev/null @@ -1 +0,0 @@ -<%= partial 'missing' %> diff --git a/test/fixtures/missing-partials/partials/parent-with-missing-child.yml.erb b/test/fixtures/missing-partials/partials/parent-with-missing-child.yml.erb new file mode 100644 index 000000000..935856999 --- /dev/null +++ b/test/fixtures/missing-partials/partials/parent-with-missing-child.yml.erb @@ -0,0 +1 @@ +<%= partial 'does-not-exist' %> diff --git a/test/helpers/fixture_deploy_helper.rb b/test/helpers/fixture_deploy_helper.rb index 49f234851..f59f507ad 100644 --- a/test/helpers/fixture_deploy_helper.rb +++ b/test/helpers/fixture_deploy_helper.rb @@ -44,6 +44,11 @@ def deploy_raw_fixtures(set, wait: true, bindings: {}, subset: nil) success = false if subset Dir.mktmpdir("fixture_dir") do |target_dir| + partials_dir = File.join(fixture_path(set), 'partials') + if File.directory?(partials_dir) + FileUtils.copy_entry(partials_dir, File.join(target_dir, 'partials')) + end + subset.each do |file| FileUtils.copy_entry(File.join(fixture_path(set), file), File.join(target_dir, file)) end diff --git a/test/integration/kubernetes_deploy_test.rb b/test/integration/kubernetes_deploy_test.rb index b43615ed2..ca71c5196 100644 --- a/test/integration/kubernetes_deploy_test.rb +++ b/test/integration/kubernetes_deploy_test.rb @@ -141,7 +141,7 @@ def test_success_with_unrecognized_resource_type end def test_invalid_yaml_fails_fast - refute deploy_dir(fixture_path("invalid")) + assert_deploy_failure(deploy_dir(fixture_path("invalid"))) assert_logs_match_all([ "Failed to render and parse template", "Invalid template: yaml-error.yml", @@ -152,7 +152,7 @@ def test_invalid_yaml_fails_fast end def test_invalid_yaml_in_partial_prints_helpful_error - refute deploy_raw_fixtures("invalid-partials") + assert_deploy_failure(deploy_raw_fixtures("invalid-partials")) included_from = "partial included from: include-invalid-partial.yml.erb" assert_logs_match_all([ "Result: FAILURE", @@ -172,18 +172,32 @@ def test_invalid_yaml_in_partial_prints_helpful_error assert_logs_match("Error message:", 1) end - def test_missing_nested_partial_prints_helpful_error - refute deploy_raw_fixtures("missing-partials") - included_from = "partial included from: include-missing-partials.yml.erb -> nest-missing-partial.yml.erb" + def test_missing_partial_correctly_identifies_invalid_template + assert_deploy_failure(deploy_raw_fixtures("missing-partials", subset: ["parent-with-missing-child.yml.erb"])) + assert_logs_match_all([ "Result: FAILURE", "Failed to render and parse template", - "Invalid template: missing (#{included_from})", + "Invalid template: parent-with-missing-child.yml.erb", # the thing with the invalid `partial` call in it "> Error message:", - %r{Could not find partial 'missing' in any of.*fixtures/missing-partials/partials:.*/fixtures/partials} + %r{Could not find partial 'does-not-exist' in any of .*fixture_dir[^/]*/partials:.*/partials}, + "> Template content:", + "<%= partial 'does-not-exist' %>", ], in_order: true) + end - refute_logs_match("Template content") + def test_missing_nested_partial_correctly_identifies_invalid_template_and_its_parents + assert_deploy_failure(deploy_raw_fixtures("missing-partials", subset: ["parent-with-missing-grandchild.yml.erb"])) + + assert_logs_match_all([ + "Result: FAILURE", + "Failed to render and parse template", + "Invalid template: parent-with-missing-child (partial included from: parent-with-missing-grandchild.yml.erb)", + "> Error message:", + %r{Could not find partial 'does-not-exist' in any of .*fixture_dir[^/]*/partials:.*/partials}, + "> Template content:", + "<%= partial 'does-not-exist' %>" + ], in_order: true) end def test_invalid_k8s_spec_that_is_valid_yaml_fails_fast_and_prints_template diff --git a/test/unit/kubernetes-deploy/renderer_test.rb b/test/unit/kubernetes-deploy/renderer_test.rb index 2b7bee319..dd0edcf50 100644 --- a/test/unit/kubernetes-deploy/renderer_test.rb +++ b/test/unit/kubernetes-deploy/renderer_test.rb @@ -58,8 +58,8 @@ def test_non_existent_partial_raises end base = "Could not find partial 'foobarbaz' in any of" assert_match %r{#{base} .*/fixtures/for_unit_tests/partials:.*/fixtures/partials}, err.message - assert_equal "foobarbaz (partial included from: including-non-existent-partial.yaml.erb)", err.filename - assert_nil err.content + assert_equal "including-non-existent-partial.yaml.erb", err.filename + assert_equal "---\n<%= partial 'foobarbaz' %>\n", err.content end def test_nesting_fields