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

Rails7 fixes #1263

Merged
merged 2 commits into from
Jul 23, 2024
Merged

Rails7 fixes #1263

merged 2 commits into from
Jul 23, 2024

Conversation

jrafanie
Copy link
Member

@jrafanie jrafanie commented Jul 9, 2024

These are backwards compatible changes to get rails 7 to work on this repository.

@@ -56,6 +56,10 @@ def normalize_attr(attr, value)
Float::INFINITY.to_s
elsif Api.resource_attribute?(attr)
normalize_resource(value)
elsif value == NilClass
{}
Copy link
Member Author

@jrafanie jrafanie Jul 10, 2024

Choose a reason for hiding this comment

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

@kbrock do you have any idea why this was needed? The test below was expecting a NilClass v_workflow_class to come back as {}. Not a string, not json null, but {}. Note, it's the NilClass object, a Class Object, not nil (an instance of NilClass).

@@ -269,8 +269,7 @@
"id" => request.id.to_s,
"workflow" => a_hash_including("values"),
"v_allowed_tags" => [a_hash_including("children")],
"v_workflow_class" => a_hash_including(
"instance_logger" => a_hash_including("klass" => request.workflow.class.to_s))
Copy link
Member Author

Choose a reason for hiding this comment

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

I have no idea why this passed on rails 6.1 🤣

Copy link
Member Author

Choose a reason for hiding this comment

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

FYI, instance_logger is an instance variable coming from the Vmdb::Logging stuff. Not sure why this was coming back previously. Maybe json dump of the class object included the ivars. That's why I'm changing it to return the Class#name as it's weird to store the Class object.

Copy link
Member

Choose a reason for hiding this comment

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

where is v_workflow_class defined?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

The rescue nil in the class method drives me mad and I think it's related to the NilClass {} above. I really have no idea how any of this stuff works but this instance_logger in the test was completely wrong and thankfully rails 7 detected it. Not sure why it worked in 6.1

Copy link
Member

@kbrock kbrock Jul 15, 2024

Choose a reason for hiding this comment

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

Wow, I had so much trouble tracking down where this method was defined delegate is not very grep friendly. It was added in ManageIQ/manageiq#13441

  virtual_column  :v_workflow_class,     :type => :string,   :uses => :workflow
  delegate :class,                       :to => :workflow,   :prefix => :v_workflow

Interestingly, there is a workflow_class method that we probably should be using instead.
But more importantly, it is declared to return a String (which it probably should be), but it returns a Class. It is possible that our serialization of a Class may have changed.

It appears that the example is not properly creating a workflow, so nil.class is returning a NilClass.


I put a byebug into the class but getting all sorts of errors:

These all work in rails c for me, but fail when I'm running this specific spec.

(byebug) MiqRequest.new.description
*** NameError Exception: uninitialized constant MiqRequest::TASK_DESCRIPTION

  default_value_for(:message)       { |r| "#{r.class::TASK_DESCRIPTION} - Request Created" }
(byebug) request.class
MiqProvisionRequest
(byebug) MiqProvisionRequest.new.description
nil
(byebug) request.v_workflow_class
*** NameError Exception: uninitialized constant MiqRequestWorkflow::DialogFieldValidation

  include DialogFieldValidation
          ^^^^^^^^^^^^^^^^^^^^^

(byebug) require "miq_request_workflow/dialog_field_validation"
(byebug) MiqProvisionRequest.new.v_workflow_class
(byebug) MiqProvisionRequest.new.workflow_class
^^^ all give the same error

I tried redefining the DialogFieldValidation to the long style (class MiqProvisionWorkflow; module DialogFieldValidator; end; end instead of module parent::DialogFieldValidator) but that did not help.

This is a tangent, but this feels a little chicken and egg.
If you want to define the child module, define the parent class (which references the child module)

Copy link
Member

Choose a reason for hiding this comment

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

update:

The MiqProvisionRequest.workflow_class references a class, but constantize throws that exception listed above. Match that with a rescue nil and we get a nil coming out. nil.class == NilClass

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, is the test and code busted or just the test? I can try to create a proper workflow to fix the test.

Copy link
Member

Choose a reason for hiding this comment

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

Thnx Jason: once I updated all my repos, I was able to load this just fine.

One thing about the code, it compares the workflow.class and the workflow_class. So if it gets busted (goes from a value to nil), then it will always pass the test.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm punting on this (see below). We'll tackle this if we determine the correct behavior it should have. Right now, it doesn't make sense why it's ok on rails 6.1 when it's clearly wrong. It's possible no one is using it and not reported a bug. Either way, we can handle it when it's a problem.

@@ -110,7 +110,7 @@
server = FactoryBot.create(:miq_server, :status => 'started')

expect { post(api_server_url(nil, server), :params => gen_request(:delete)) }.to change(MiqServer, :count).by(0)
expect_single_action_result(:success => false, :message => 'Failed to destroy the record')
expect_single_action_result(:success => false, :message => 'Failed to destroy')
Copy link
Member Author

Choose a reason for hiding this comment

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

Rails change the method here to add more record information so it's easier to use a simpler string check to satisfy this on rails 6.1 and 7.

@kbrock
Copy link
Member

kbrock commented Jul 17, 2024

While I think we do want to understand why NilClass is not working the same as all other classes, and previous rails NilClass behavior, let us remember that this method under test is bogus and needs to be removed.

It is not referenced (don't think it ever has been), and I find it hard to believe that we want a method that returns an obscure hash. My bet is we wanted the name of the workflow class. TBH/ not sure why the front end would even need that.

@jrafanie
Copy link
Member Author

While I think we do want to understand why NilClass is not working the same as all other classes, and previous rails NilClass behavior, let us remember that this method under test is bogus and needs to be removed.

It is not referenced (don't think it ever has been), and I find it hard to believe that we want a method that returns an obscure hash. My bet is we wanted the name of the workflow class. TBH/ not sure why the front end would even need that.

Ok, I'll drop the components of the tests that are checking v_workflow_class. I agree that we probably want the class name... so I think the first hunk in the patch below seems like the correct thing to do... but I'm fine with doing it if we need to do it.

diff --git a/app/controllers/api/base_controller/normalizer.rb b/app/controllers/api/base_controller/normalizer.rb
index f2585e2c..ddefee7d 100644
--- a/app/controllers/api/base_controller/normalizer.rb
+++ b/app/controllers/api/base_controller/normalizer.rb
@@ -56,6 +56,10 @@ module Api
           Float::INFINITY.to_s
         elsif Api.resource_attribute?(attr)
           normalize_resource(value)
+        elsif value == NilClass
+          {}
+        elsif value.kind_of?(Class)
+          value.name
         else
           value
         end
diff --git a/spec/requests/requests_spec.rb b/spec/requests/requests_spec.rb
index f9a20d49..9111cc7c 100644
--- a/spec/requests/requests_spec.rb
+++ b/spec/requests/requests_spec.rb
@@ -269,8 +269,7 @@ RSpec.describe "Requests API" do
         "id"               => request.id.to_s,
         "workflow"         => a_hash_including("values"),
         "v_allowed_tags"   => [a_hash_including("children")],
-        "v_workflow_class" => a_hash_including(
-          "instance_logger" => a_hash_including("klass" => request.workflow.class.to_s))
+        "v_workflow_class" => request.workflow.class.to_s
       )

       expect(response.parsed_body).to match(expected_response)
@@ -318,7 +317,7 @@ RSpec.describe "Requests API" do

       expected_response = a_hash_including(
         "id"               => request.id.to_s,
-        "v_workflow_class" => {}
+        "v_workflow_class" => {} # Need to figure out why NilClass comes back as {} previously
       )

       expect(response.parsed_body).to match(expected_response)

@jrafanie
Copy link
Member Author

@miq-bot cross-repo-tests ManageIQ/manageiq#22873

miq-bot pushed a commit to ManageIQ/manageiq-cross_repo-tests that referenced this pull request Jul 23, 2024
@miq-bot
Copy link
Member

miq-bot commented Jul 23, 2024

Checked commits jrafanie/manageiq-api@2fb626a~...3ebce41 with ruby 3.1.5, rubocop 1.56.3, haml-lint 0.51.0, and yamllint
2 files checked, 0 offenses detected
Everything looks fine. 🍰

@jrafanie jrafanie removed the wip label Jul 23, 2024
@jrafanie
Copy link
Member Author

Ok, I think I resolved all the issues. I've removed the bogus test areas that asserted values for v_workflow_class as that's not functioning "correctly" and we don't have good reasons to change the bogus behavior, so we'll tackle that later if needed.

@jrafanie jrafanie changed the title [WIP] Rails7 fixes Rails7 fixes Jul 23, 2024
@kbrock kbrock self-assigned this Jul 23, 2024
@kbrock
Copy link
Member

kbrock commented Jul 23, 2024

Glad you dropped this rather than trying to track down our serialization of classes (which was probably a non-implemented feature anyway)

@kbrock kbrock merged commit 20fd786 into ManageIQ:master Jul 23, 2024
4 checks passed
@jrafanie jrafanie deleted the rails7_fixes branch July 25, 2024 14:23
@kbrock kbrock added test and removed enhancement labels Aug 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants