Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add methods to fetch terraform stdout for showing in UI. #78

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,29 +83,35 @@ def raw_stdout_via_worker(userid, format = 'txt')

def raw_stdout(format = 'txt')
case format
when "json" then raw_stdout_json
when "html" then raw_stdout_html
else raw_stdout_txt
end
end

def raw_stdout_json
raw_stdout_txt.split("\n")
end

def raw_stdout_txt
job = miq_task.job
terraform_stack_id = job.options[:terraform_stack_id]
data = terraform_runner_stack_data

return if terraform_stack_id.blank?
return '' if data.nil?
putmanoj marked this conversation as resolved.
Show resolved Hide resolved

response = Terraform::Runner.fetch_result_by_stack_id(terraform_stack_id)
response.message
data.message
end

def raw_stdout_html
text = raw_stdout_txt
text = _("No output available") if text.blank?
TerminalToHtml.render(text)
end

private

def terraform_runner_stack_data
return if miq_task.nil? || miq_task.job.nil?

job = miq_task.job
terraform_stack_id = job.options[:terraform_stack_id]

return if terraform_stack_id.blank?

Terraform::Runner.fetch_result_by_stack_id(terraform_stack_id)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,125 @@
end
end
end

describe "#raw_stdout" do
let(:stack) { FactoryBot.create(:terraform_stack) }
let(:template) { FactoryBot.create(:terraform_template) }

context "when miq_task.job present" do
require 'webmock/rspec'
putmanoj marked this conversation as resolved.
Show resolved Hide resolved
require 'json'
let(:terraform_runner_url) { "https://1.2.3.4:7000" }
let(:hello_world_retrieve_response) do
JSON.parse(File.read(File.join(__dir__, "../../../../../lib/terraform/runner/data/responses/hello-world-retrieve-success.json")))
Copy link
Member

@agrare agrare Oct 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to consider moving this up to spec/data or something if it is going to be used by more than just the Terraform::Runner specs since this ../../../etc... makes it hard to read where this file lives. Without counting the parent dirs I thought this lived in the "production" lib/terraform directory not spec/lib/terraform

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes agree makes it harder to read,
could make it like
"../../../../../../spec/lib/terraform/runner/data/responses/hello-world-retrieve-success.json"

also maybe should move this common test data, to somewhere like <base-dir>/spec/data. then still look like
"../../../../../../spec/data/responses/hello-world-retrieve-success.json"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't know if there more easier way to refer to test data resources without using "../../../../../../"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use the ManageIQ::Providers::EmbeddedTerraform::Engine.root Pathname to build a path from the root of the plugin

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

end
let(:miq_task) do
miq_task = FactoryBot.create(:miq_task)
miq_task.job = job
miq_task
end
putmanoj marked this conversation as resolved.
Show resolved Hide resolved

let(:job) do
ManageIQ::Providers::EmbeddedTerraform::AutomationManager::Job.create_job(template, {}, {}, []).tap do |job|
job.state = "finished"
job.options = {
:terraform_stack_id => hello_world_retrieve_response['stack_id']
}
Comment on lines +47 to +51
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a FactoryBot factory would be a better way to set up these Job objects

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#80

end
end

let(:terraform_runner_stdout) { hello_world_retrieve_response['message'] }
let(:terraform_runner_stdout_html) { TerminalToHtml.render(terraform_runner_stdout) }

retrieve_stub = nil
putmanoj marked this conversation as resolved.
Show resolved Hide resolved

before do
stack.miq_task = miq_task
putmanoj marked this conversation as resolved.
Show resolved Hide resolved

stub_const("ENV", ENV.to_h.merge("TERRAFORM_RUNNER_URL" => terraform_runner_url))

retrieve_stub = stub_request(:post, "#{terraform_runner_url}/api/stack/retrieve")
.with(:body => hash_including({:stack_id => hello_world_retrieve_response['stack_id']}))
.to_return(
:status => 200,
:body => hello_world_retrieve_response.to_json
)
putmanoj marked this conversation as resolved.
Show resolved Hide resolved
end

it "json" do
expect(stack.raw_stdout("json")).to eq terraform_runner_stdout

expect(retrieve_stub).to(have_been_requested.times(1))
end

it "txt" do
expect(stack.raw_stdout("txt")).to eq terraform_runner_stdout

expect(retrieve_stub).to(have_been_requested.times(1))
end

it "html" do
expect(stack.raw_stdout("html")).to eq terraform_runner_stdout_html

expect(retrieve_stub).to(have_been_requested.times(1))
end

it "nil" do
expect(stack.raw_stdout).to eq terraform_runner_stdout

expect(retrieve_stub).to(have_been_requested.times(1))
end
end

shared_examples_for "terraform runner stdout not available from miq_task" do
it "json" do
expect(stack.raw_stdout("json")).to eq("")
end

it "txt" do
expect(stack.raw_stdout("txt")).to eq ""
end

it "html" do
expect(stack.raw_stdout("html")).to include <<~EOHTML
<div class='term-container'>
No output available
</div>
EOHTML
end

it "nil" do
expect(stack.raw_stdout).to eq ""
end
end

context "when miq_task.job is missing" do
before do
stack.miq_task = nil
end
putmanoj marked this conversation as resolved.
Show resolved Hide resolved

it_behaves_like "terraform runner stdout not available from miq_task"
end

context "when miq_task present, but missing miq_task.job" do
before do
stack.miq_task = FactoryBot.create(:miq_task)
stack.miq_task.job = nil
end
putmanoj marked this conversation as resolved.
Show resolved Hide resolved

it_behaves_like "terraform runner stdout not available from miq_task"
end

context "when miq_task.job.options present but missing terraform_stack_id" do
before do
stack.miq_task = FactoryBot.create(:miq_task)
stack.miq_task.job = ManageIQ::Providers::EmbeddedTerraform::AutomationManager::Job.create_job(template, {}, {}, []).tap do |job|
job.state = "waiting_to_start"
job.options = {}
end
putmanoj marked this conversation as resolved.
Show resolved Hide resolved
end

it_behaves_like "terraform runner stdout not available from miq_task"
end
end
end