Ruby 3-Unterstützung für das Mocha-Gem

Ich habe ein weiteres Thema zur Unterstützung von Ruby 3.

Schritte zur Reproduktion

$ bundle exec rspec ./spec/lib/backup_restore/database_restorer_multisite_spec.rb:15

Tatsächliches Ergebnis mit Ruby 3.0.2

$ ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
$ bundle exec rspec ./spec/lib/backup_restore/database_restorer_multisite_spec.rb:15
Run options: include {:locations=>{"./spec/lib/backup_restore/database_restorer_multisite_spec.rb"=>[15]}}

Randomized with seed 43732
F

Failures:

  1) BackupRestore::DatabaseRestorer#restore database connection reconnects to the correct database
     Failure/Error:
       log Discourse::Utils.execute_command(
         {
           "SKIP_POST_DEPLOYMENT_MIGRATIONS" => "0",
           "SKIP_OPTIMIZE_ICONS" => "1",
           "DISABLE_TRANSLATION_OVERRIDES" => "1"
         },
         "rake", "db:migrate",
         failure_message: "Failed to migrate database.",
         chdir: Rails.root
       )

     Mocha::ExpectationError:
       unexpected invocation: Discourse::Utils.execute_command({"SKIP_POST_DEPLOYMENT_MIGRATIONS" => "0", "SKIP_OPTIMIZE_ICONS" => "1", "DISABLE_TRANSLATION_OVERRIDES" => "1"}, "rake", "db:migrate", {:failure_message => "Failed to migrate database.", :chdir => #<Pathname:0xd548>})
       unsatisfied expectations:
       - expected exactly once, invoked never: Discourse::Utils.execute_command()
       satisfied expectations:
       - expected exactly once, invoked once: BackupRestore.move_tables_between_schemas("public", "backup")
       - expected at least once, invoked 77 times: Migration::BaseDropper.create_readonly_function(any_parameters)
       - expected exactly once, invoked once: #<Mock:psql status>.exitstatus(any_parameters)
       - expected exactly once, invoked once: Process.last_status(any_parameters)
       - expected exactly twice, invoked twice: #<Mock:psql>.readline(any_parameters)
       - expected exactly once, invoked once: IO.popen(any_parameters)
     # ./lib/backup_restore/database_restorer.rb:138:in `migrate_database'
     # ./lib/backup_restore/database_restorer.rb:27:in `restore'
     # ./spec/lib/backup_restore/shared_context_for_backup_restore.rb:59:in `execute_stubbed_restore'
     # ./spec/lib/backup_restore/database_restorer_multisite_spec.rb:17:in `block (4 levels) in <top (required)>'
     # ./spec/rails_helper.rb:279:in `block (2 levels) in <top (required)>'

Finished in 0.28437 seconds (files took 2.37 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/lib/backup_restore/database_restorer_multisite_spec.rb:15 # BackupRestore::DatabaseRestorer#restore database connection reconnects to the correct database

Randomized with seed 43732

$

Tatsächliches Ergebnis mit Ruby 2.7.4

$ ruby -v
ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-linux]
$ bundle exec rspec ./spec/lib/backup_restore/database_restorer_multisite_spec.rb:15
Run options: include {:locations=>{"./spec/lib/backup_restore/database_restorer_multisite_spec.rb"=>[15]}}

Randomized with seed 37771
.

Finished in 0.63589 seconds (files took 2.63 seconds to load)
1 example, 0 failures

Randomized with seed 37771

$

Was ich bisher herausgefunden habe

Tatsächlich ist dies ein weiteres Thema, das die Unterstützung von Ruby-3-Schlüsselwortargumenten erfordert.

  • Ausführung mit Ruby 2.7.4 unter Aktivierung von -w ergibt: warning: Using the last argument as keyword parameters is deprecated
$ bundle exec rspec -w ./spec/lib/backup_restore/database_restorer_multisite_spec.rb:15 2>&1 | grep keyword
/home/yahonda/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/mocha-1.13.0/lib/mocha/parameters_matcher.rb:13: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
  • Hier ist der schnelle, schmutzige Fix mit Debug-Ausgabecode.
$ git diff 191823e8696881ab8c72948165834eca18315cb3...8141f2f0eca4bedcf59e34f31dd9ca35e39c2a25
diff --git a/lib/mocha/parameters_matcher.rb b/lib/mocha/parameters_matcher.rb
index 2b6ed84..26c4a25 100644
--- a/lib/mocha/parameters_matcher.rb
+++ b/lib/mocha/parameters_matcher.rb
@@ -10,7 +10,11 @@ module Mocha

     def match?(actual_parameters = [])
       if @matching_block
-        @matching_block.call(*actual_parameters)
+        p actual_parameters
+        if actual_parameters.last.is_a? Hash
+          kwargs = actual_parameters.pop
+        end
+        @matching_block.call(*actual_parameters, **kwargs)
       else
         parameters_match?(actual_parameters)
       end
$

Ergebnis mit modifiziertem Mocha-Code

$ bundle exec rspec ./spec/lib/backup_restore/database_restorer_multisite_spec.rb:15
Run options: include {:locations=>{"./spec/lib/backup_restore/database_restorer_multisite_spec.rb"=>[15]}}

Randomized with seed 27573
[{"SKIP_POST_DEPLOYMENT_MIGRATIONS"=>"0", "SKIP_OPTIMIZE_ICONS"=>"1", "DISABLE_TRANSLATION_OVERRIDES"=>"1"}, "rake", "db:migrate", {:failure_message=>"Failed to migrate database.", :chdir=>#<Pathname:/home/yahonda/src/github.com/discourse/discourse>}]
.

Finished in 0.40263 seconds (files took 2.88 seconds to load)
1 example, 0 failures

Randomized with seed 27573

$

Ich muss möglicherweise einen Minimalfall für Mocha erstellen. Es wäre sehr hilfreich, wenn jemand Vorschläge hat.

Ja, sieht nach einer Korrektur für Mocha aus. Hast du dafür am Ende einen Fehlerbericht auf GitHub eröffnet?

Noch nicht. Ich werde diese Woche noch einmal genauer hinschauen.

Ich habe einen ähnlichen gemeldeten Fehler gefunden, und eine Workaround-Lösung wird erklärt:

Verwende kwargs statt **kwargs; dann ist kwargs ein Hash, den du in deiner Assertion verwenden kannst, und es werden keine Warnungen generiert…

Die Anwendung des vorgeschlagenen Workarounds sorgt dafür, dass fehlerhafte Tests grün werden.

https://github.com/yahonda/discourse/commit/356f15b02cb4a0bb869d19adf2a2018d07ee79bf

$ git diff main
diff --git a/spec/lib/backup_restore/shared_context_for_backup_restore.rb b/spec/lib/backup_restore/shared_context_for_backup_restore.rb
index 2ff78176ea..0fbc8ade15 100644
--- a/spec/lib/backup_restore/shared_context_for_backup_restore.rb
+++ b/spec/lib/backup_restore/shared_context_for_backup_restore.rb
@@ -33,7 +33,7 @@ shared_context "shared stuff" do
   end

   def expect_db_migrate
-    Discourse::Utils.expects(:execute_command).with do |env, *command, **options|
+    Discourse::Utils.expects(:execute_command).with do |env, *command, options|
       env["SKIP_POST_DEPLOYMENT_MIGRATIONS"] == "0" &&
         env["SKIP_OPTIMIZE_ICONS"] == "1" &&
         env["DISABLE_TRANSLATION_OVERRIDES"] == "1" &&
$

Ich würde gerne einen Pull Request eröffnen.

Geöffnet: FIX: `BackupRestore::DatabaseRestorer` failures with Ruby 3 by yahonda · Pull Request #14580 · discourse/discourse · GitHub