From d70ee8faf30cefac381dbaadb0e76011190cc0cc Mon Sep 17 00:00:00 2001 From: Ivan Shamatov Date: Wed, 4 Aug 2021 10:17:50 +0300 Subject: [PATCH 001/194] Documentation `disable!` typo --- docs/recipes/factory_all_stub.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/factory_all_stub.md b/docs/recipes/factory_all_stub.md index 5a84ab72..13d7d4a4 100644 --- a/docs/recipes/factory_all_stub.md +++ b/docs/recipes/factory_all_stub.md @@ -25,7 +25,7 @@ TestProf::FactoryAllStub.enable! To disable _all-stub_ mode and use factories as always: ```ruby -TestProf::FactoryAllStub.enable! +TestProf::FactoryAllStub.disable! ``` ## RSpec From ef07109ecdd43683a3148946eed9389121324442 Mon Sep 17 00:00:00 2001 From: Chris Barton Date: Fri, 30 Jul 2021 12:59:28 -0700 Subject: [PATCH 002/194] Allow access to `let_it_be` defined variables in after(:context) [This commit](https://github.com/test-prof/test-prof/commit/250346445396bcd892dae7d8005111a907848498) changed the way we detect the context for fetching the `let_it_be` defined variables, matching only the `before(:context)`. Those variables should be accessible by both before/after, so this adds back the generic `:context` matcher to support all hooks. --- CHANGELOG.md | 2 ++ lib/test_prof/recipes/rspec/let_it_be.rb | 2 +- spec/integrations/fixtures/rspec/let_it_be_fixture.rb | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8840f3ef..7aacee2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unrealeased) +- Fix access to `let_it_be` variables in `after(:all)` hook. ([@cbarton][]) + ## 1.0.6 (2021-06-23) - Fix Spring detection when `DISABLE_SPRING=1` is used. ([@palkan][]) diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index 84feee7d..66c18bb8 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -107,7 +107,7 @@ def let_it_be(identifier, **options, &block) define_method(identifier) do # Trying to detect the context # Based on https://github.com/rspec/rspec-rails/commit/7cb796db064f58da7790a92e73ab906ef50b1f34 - if @__inspect_output.include?("before(:context)") || @__inspect_output.include?("before_all") + if /(before|after)\(:context\)/.match?(@__inspect_output) || @__inspect_output.include?("before_all") instance_variable_get(:"#{PREFIX}#{identifier}") else # Fallback to let definition diff --git a/spec/integrations/fixtures/rspec/let_it_be_fixture.rb b/spec/integrations/fixtures/rspec/let_it_be_fixture.rb index 4f51f708..0db4476a 100644 --- a/spec/integrations/fixtures/rspec/let_it_be_fixture.rb +++ b/spec/integrations/fixtures/rspec/let_it_be_fixture.rb @@ -40,6 +40,7 @@ let_it_be(:user) { create(:user) } before(:all) { @cache[:user_name] = user.name } + after(:all) { expect(user.name).to eq @cache[:user_name] } it "is cached" do expect(user.name).to eq @cache[:user_name] From d46ded4669a4235173f34f538d5d92b3b2a06c9f Mon Sep 17 00:00:00 2001 From: Peter Retzlaff Date: Sat, 15 May 2021 10:44:14 +0200 Subject: [PATCH 003/194] feature: Add support for (process) parallelized tests to before_all for minitest. When the test suite is run in parallel, the run method only enqueues the test jobs and returns right after that, so we mustn't roll back the transaction at that point. Instead, intercept the Minitest.run_one_method call that actually runs a test case. In each process, we will keep track of when the last test case of a test file has run, and roll back the transaction in that moment. This works because test cases from different test files are added to the queue and processed in order, i.e. once we see a test case from a different class/test file, no test cases from the previous test file will be run anymore. --- CHANGELOG.md | 4 +++ lib/test_prof/recipes/minitest/before_all.rb | 38 +++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aacee2d..42619acf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ - Fix access to `let_it_be` variables in `after(:all)` hook. ([@cbarton][]) +- Add support for using the before_all hook with Rails' parallelize feature (using processes). ([@peret][]) + +Make sure to include `TestProf::BeforeAll::Minitest` before you call `parallelize`. + ## 1.0.6 (2021-06-23) - Fix Spring detection when `DISABLE_SPRING=1` is used. ([@palkan][]) diff --git a/lib/test_prof/recipes/minitest/before_all.rb b/lib/test_prof/recipes/minitest/before_all.rb index ef5337b5..601d469c 100644 --- a/lib/test_prof/recipes/minitest/before_all.rb +++ b/lib/test_prof/recipes/minitest/before_all.rb @@ -2,6 +2,21 @@ require "test_prof/before_all" +Minitest.singleton_class.prepend(Module.new do + @previous_klass = nil + + def run_one_method(klass, method_name) + return super unless klass.before_all_executor && klass.parallelized + + if @previous_klass && @previous_klass != klass + klass.before_all_executor.deactivate! + end + @previous_klass = klass + + super + end +end) + module TestProf module BeforeAll # Add before_all hook to Minitest: wrap all examples into a transaction and @@ -83,6 +98,27 @@ def perform_teardown(test_object) class << self def included(base) base.extend ClassMethods + + base.singleton_class.cattr_accessor :parallelized + base.singleton_class.prepend(Module.new do + def parallelize(workers: :number_of_processors, with: :processes) + # super.parallelize returns nil when no parallelization is set up + if super(workers: workers, with: with).nil? + return + end + + case with + when :processes + self.parallelized = true + when :threads + warn "!!! before_all is not implemented for parallalization with threads and " \ + "could work incorrectly" + else + warn "!!! tests are using an unknown parallelization strategy and before_all " \ + "could work incorrectly" + end + end + end) end end @@ -118,7 +154,7 @@ def before_setup def run(*) super ensure - before_all_executor&.deactivate! + before_all_executor&.deactivate! unless self.parallelized end end) end From 4d7eb361f57637585ede8a0119b93b160f7418ee Mon Sep 17 00:00:00 2001 From: Peter Retzlaff Date: Fri, 25 Jun 2021 21:37:52 +0200 Subject: [PATCH 004/194] fix: call deactivate on the correct before_all_executor for parallel tests --- lib/test_prof/recipes/minitest/before_all.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/test_prof/recipes/minitest/before_all.rb b/lib/test_prof/recipes/minitest/before_all.rb index 601d469c..0ba71d4e 100644 --- a/lib/test_prof/recipes/minitest/before_all.rb +++ b/lib/test_prof/recipes/minitest/before_all.rb @@ -6,10 +6,10 @@ @previous_klass = nil def run_one_method(klass, method_name) - return super unless klass.before_all_executor && klass.parallelized + return super unless klass.parallelized if @previous_klass && @previous_klass != klass - klass.before_all_executor.deactivate! + @previous_klass.before_all_executor&.deactivate! end @previous_klass = klass From f91c5c3754f9b9915e23708e668c44692b6b0986 Mon Sep 17 00:00:00 2001 From: Peter Retzlaff Date: Tue, 6 Jul 2021 22:28:04 +0200 Subject: [PATCH 005/194] fix: deactivate before_all_executor after last test file per process parallelize_teardown allows registering callbacks that are run after parallel test execution. It is called after all tests are run and before the forked processes are closed, so we can use it to clean up the last of the before_all transactions. --- lib/test_prof/recipes/minitest/before_all.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/test_prof/recipes/minitest/before_all.rb b/lib/test_prof/recipes/minitest/before_all.rb index 0ba71d4e..01d09a6d 100644 --- a/lib/test_prof/recipes/minitest/before_all.rb +++ b/lib/test_prof/recipes/minitest/before_all.rb @@ -3,10 +3,11 @@ require "test_prof/before_all" Minitest.singleton_class.prepend(Module.new do + attr_reader :previous_klass @previous_klass = nil def run_one_method(klass, method_name) - return super unless klass.parallelized + return super unless klass.respond_to?(:parallelized) && klass.parallelized if @previous_klass && @previous_klass != klass @previous_klass.before_all_executor&.deactivate! @@ -100,6 +101,13 @@ def included(base) base.extend ClassMethods base.singleton_class.cattr_accessor :parallelized + base.parallelize_teardown do + last_klass = ::Minitest.previous_klass + if last_klass&.respond_to?(:parallelized) && last_klass.parallelized + last_klass.before_all_executor&.deactivate! + end + end + base.singleton_class.prepend(Module.new do def parallelize(workers: :number_of_processors, with: :processes) # super.parallelize returns nil when no parallelization is set up @@ -154,7 +162,7 @@ def before_setup def run(*) super ensure - before_all_executor&.deactivate! unless self.parallelized + before_all_executor&.deactivate! unless parallelized end end) end From b3384125592994714ecce36843d716d1f60cf616 Mon Sep 17 00:00:00 2001 From: Peter Retzlaff Date: Sat, 10 Jul 2021 16:10:34 +0200 Subject: [PATCH 006/194] fix: fix Rubocop warning and before_all test cases --- lib/test_prof/recipes/minitest/before_all.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/test_prof/recipes/minitest/before_all.rb b/lib/test_prof/recipes/minitest/before_all.rb index 01d09a6d..95240605 100644 --- a/lib/test_prof/recipes/minitest/before_all.rb +++ b/lib/test_prof/recipes/minitest/before_all.rb @@ -100,11 +100,13 @@ class << self def included(base) base.extend ClassMethods - base.singleton_class.cattr_accessor :parallelized - base.parallelize_teardown do - last_klass = ::Minitest.previous_klass - if last_klass&.respond_to?(:parallelized) && last_klass.parallelized - last_klass.before_all_executor&.deactivate! + base.cattr_accessor :parallelized + if base.respond_to?(:parallelize_teardown) + base.parallelize_teardown do + last_klass = ::Minitest.previous_klass + if last_klass&.respond_to?(:parallelized) && last_klass&.parallelized + last_klass.before_all_executor&.deactivate! + end end end From cd7e7fa9cc188055100be306177a82e5b7ef4500 Mon Sep 17 00:00:00 2001 From: Peter Retzlaff Date: Wed, 14 Jul 2021 18:43:02 +0200 Subject: [PATCH 007/194] fix: check that Rails is present, i.e. the including class supports #parallelize --- lib/test_prof/recipes/minitest/before_all.rb | 38 ++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/lib/test_prof/recipes/minitest/before_all.rb b/lib/test_prof/recipes/minitest/before_all.rb index 95240605..25bb1d47 100644 --- a/lib/test_prof/recipes/minitest/before_all.rb +++ b/lib/test_prof/recipes/minitest/before_all.rb @@ -110,25 +110,27 @@ def included(base) end end - base.singleton_class.prepend(Module.new do - def parallelize(workers: :number_of_processors, with: :processes) - # super.parallelize returns nil when no parallelization is set up - if super(workers: workers, with: with).nil? - return + if base.respond_to?(:parallelize) + base.singleton_class.prepend(Module.new do + def parallelize(workers: :number_of_processors, with: :processes) + # super.parallelize returns nil when no parallelization is set up + if super(workers: workers, with: with).nil? + return + end + + case with + when :processes + self.parallelized = true + when :threads + warn "!!! before_all is not implemented for parallalization with threads and " \ + "could work incorrectly" + else + warn "!!! tests are using an unknown parallelization strategy and before_all " \ + "could work incorrectly" + end end - - case with - when :processes - self.parallelized = true - when :threads - warn "!!! before_all is not implemented for parallalization with threads and " \ - "could work incorrectly" - else - warn "!!! tests are using an unknown parallelization strategy and before_all " \ - "could work incorrectly" - end - end - end) + end) + end end end From cc6a8448517acf6fc1b873aeb00a9c79e3d65a8e Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 30 Aug 2021 15:48:32 +0300 Subject: [PATCH 008/194] Bump 1.0.7 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42619acf..21843307 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unrealeased) +## 1.0.7 (2021-08-30) + - Fix access to `let_it_be` variables in `after(:all)` hook. ([@cbarton][]) - Add support for using the before_all hook with Rails' parallelize feature (using processes). ([@peret][]) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index bc3d4189..a94a18db 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.0.6" + VERSION = "1.0.7" end From 6bec4dc5641f000cbc194cb1c128ea4eeedf2f83 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 27 Sep 2021 14:41:07 +0300 Subject: [PATCH 009/194] upd: suggest using d3-flamegraph for stack_prof Closes #222 --- lib/test_prof/stack_prof.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/stack_prof.rb b/lib/test_prof/stack_prof.rb index bd4c9324..680a0902 100644 --- a/lib/test_prof/stack_prof.rb +++ b/lib/test_prof/stack_prof.rb @@ -162,7 +162,7 @@ def dump_html_report(path) log :info, <<~MSG Run the following command to generate a flame graph report: - stackprof --flamegraph #{path} > #{html_path} && stackprof --flamegraph-viewer=#{html_path} + stackprof --d3-flamegraph #{path} > #{html_path} && stackprof --flamegraph-viewer=#{html_path} MSG end From 12cdc12592276e3bbd683bb97144c96fc695a462 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 9 Nov 2021 14:07:47 +0300 Subject: [PATCH 010/194] Update BACKERS.md --- BACKERS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BACKERS.md b/BACKERS.md index 3ee5b600..10ca60a5 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -2,4 +2,5 @@ ## Personal Sponsors -Be the first one :) +- [Makar Ermokhin](https://github.com/Earendil95) +- [Burkhard Vogel-Kreykenbohm](https://github.com/bvogel) From 7b89b548e50a509c528ea02787348f5499f07bd0 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 11 Nov 2021 13:42:29 +0300 Subject: [PATCH 011/194] style: rubocop upgrade --- lib/test_prof/recipes/logging.rb | 2 -- lib/test_prof/rspec_stamp.rb | 2 -- lib/test_prof/rspec_stamp/parser.rb | 2 -- lib/test_prof/stack_prof.rb | 2 +- spec/integrations/fixtures/rspec/let_it_be_fixture.rb | 2 +- spec/integrations/profilers_spec.rb | 2 +- spec/spec_helper.rb | 2 +- spec/test_prof/factory_prof/printers/flamegraph_spec.rb | 1 - 8 files changed, 4 insertions(+), 11 deletions(-) diff --git a/lib/test_prof/recipes/logging.rb b/lib/test_prof/recipes/logging.rb index 60199b90..f45d7afc 100644 --- a/lib/test_prof/recipes/logging.rb +++ b/lib/test_prof/recipes/logging.rb @@ -24,8 +24,6 @@ def ar_loggables ] end - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/PerceivedComplexity def all_loggables return @all_loggables if instance_variable_defined?(:@all_loggables) diff --git a/lib/test_prof/rspec_stamp.rb b/lib/test_prof/rspec_stamp.rb index c4d5b4f2..a1246345 100644 --- a/lib/test_prof/rspec_stamp.rb +++ b/lib/test_prof/rspec_stamp.rb @@ -116,8 +116,6 @@ def apply_tags(code, lines, tags) private - # rubocop: disable Metrics/CyclomaticComplexity - # rubocop: disable Metrics/PerceivedComplexity def stamp_example(example, tags) matches = example.match(EXAMPLE_RXP) return false unless matches diff --git a/lib/test_prof/rspec_stamp/parser.rb b/lib/test_prof/rspec_stamp/parser.rb index 3f3000f5..1f1f7442 100644 --- a/lib/test_prof/rspec_stamp/parser.rb +++ b/lib/test_prof/rspec_stamp/parser.rb @@ -28,8 +28,6 @@ def remove_tag(tag) end class << self - # rubocop: disable Metrics/CyclomaticComplexity - # rubocop: disable Metrics/PerceivedComplexity def parse(code) sexp = Ripper.sexp(code) return unless sexp diff --git a/lib/test_prof/stack_prof.rb b/lib/test_prof/stack_prof.rb index 680a0902..640b52c2 100644 --- a/lib/test_prof/stack_prof.rb +++ b/lib/test_prof/stack_prof.rb @@ -168,7 +168,7 @@ def dump_html_report(path) def dump_json_report(path) report = ::StackProf::Report.new( - Marshal.load(IO.binread(path)) # rubocop:disable Security/MarshalLoad + Marshal.load(IO.binread(path)) ) json_path = path.gsub(/\.dump$/, ".json") File.write(json_path, JSON.generate(report.data)) diff --git a/spec/integrations/fixtures/rspec/let_it_be_fixture.rb b/spec/integrations/fixtures/rspec/let_it_be_fixture.rb index 0db4476a..0bc6dc21 100644 --- a/spec/integrations/fixtures/rspec/let_it_be_fixture.rb +++ b/spec/integrations/fixtures/rspec/let_it_be_fixture.rb @@ -91,7 +91,7 @@ end context "with refind option" do - да_будет_так(:post, refind: true) { create(:post) } # rubocop:disable Naming/AsciiIdentifiers + да_будет_так(:post, refind: true) { create(:post) } let(:user) { post.user } diff --git a/spec/integrations/profilers_spec.rb b/spec/integrations/profilers_spec.rb index f4f4009c..bbd5bb8d 100644 --- a/spec/integrations/profilers_spec.rb +++ b/spec/integrations/profilers_spec.rb @@ -4,7 +4,7 @@ begin require "stackprof" require "ruby-prof" - rescue LoadError # rubocop:disable Lint/HandleExceptions + rescue LoadError end describe "general profilers", skip: !PROFILERS_AVAILABLE do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 75dfcc41..d21a5cf9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,7 +3,7 @@ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__) begin require "pry-byebug" -rescue LoadError # rubocop:disable Lint/HandleExceptions +rescue LoadError end require "open3" diff --git a/spec/test_prof/factory_prof/printers/flamegraph_spec.rb b/spec/test_prof/factory_prof/printers/flamegraph_spec.rb index f5c875a2..faf5550a 100644 --- a/spec/test_prof/factory_prof/printers/flamegraph_spec.rb +++ b/spec/test_prof/factory_prof/printers/flamegraph_spec.rb @@ -3,7 +3,6 @@ describe TestProf::FactoryProf::Printers::Flamegraph do subject { described_class } - # rubocop:disable Style/BracesAroundHashParameters describe ".convert_stacks" do it "converts stacks to hierarchy Hash" do stacks = [] From 2335ab5b4497a6124711b4f984bf53b93e0c5adc Mon Sep 17 00:00:00 2001 From: Scott Bader Date: Fri, 10 Dec 2021 12:55:45 -0500 Subject: [PATCH 012/194] Updates spec to confirm newlines work --- spec/test_prof/any_fixture_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/test_prof/any_fixture_spec.rb b/spec/test_prof/any_fixture_spec.rb index b65ba97f..e0ee8a1e 100644 --- a/spec/test_prof/any_fixture_spec.rb +++ b/spec/test_prof/any_fixture_spec.rb @@ -86,7 +86,7 @@ tmp_user.destroy! crypto = "crypto$5a$31$OsQLJ8tnIkCChMDcd?AiD?S.c/xUwe.Sk" - how_are_you = "How are you doing? OK?" + how_are_you = "How are you doing?\nOK?" expect do subject.register_dump("users") do From 51c3abd8555ddaa429d5e6c53b022dfc0d1b192b Mon Sep 17 00:00:00 2001 From: Scott Bader Date: Fri, 10 Dec 2021 12:56:05 -0500 Subject: [PATCH 013/194] Adds functionality in sqlite and postgresql to support newlines --- lib/test_prof/any_fixture/dump/postgresql.rb | 2 +- lib/test_prof/any_fixture/dump/sqlite.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/test_prof/any_fixture/dump/postgresql.rb b/lib/test_prof/any_fixture/dump/postgresql.rb index 5a22841d..2fba6425 100644 --- a/lib/test_prof/any_fixture/dump/postgresql.rb +++ b/lib/test_prof/any_fixture/dump/postgresql.rb @@ -23,7 +23,7 @@ def reset_sequence!(table_name, start) end def compile_sql(sql, binds) - sql.gsub(/\$\d+/) { binds.shift } + sql.gsub(/\$\d+/) { binds.shift.gsub("\n", "' || chr(10) || '") } end def import(path) diff --git a/lib/test_prof/any_fixture/dump/sqlite.rb b/lib/test_prof/any_fixture/dump/sqlite.rb index 5c6c9357..654067fd 100644 --- a/lib/test_prof/any_fixture/dump/sqlite.rb +++ b/lib/test_prof/any_fixture/dump/sqlite.rb @@ -18,7 +18,7 @@ def reset_sequence!(table_name, start) end def compile_sql(sql, binds) - sql.gsub(/\?/) { binds.shift } + sql.gsub(/\?/) { binds.shift.gsub("\n", "' || char(10) || '") } end def import(path) From 25dbdf61e8070d822e2721b09feec481c1991e6e Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 6 Jan 2022 21:42:31 -0600 Subject: [PATCH 014/194] JRuby is cat friendly All recent versions of JRuby support unicode identifiers. --- lib/test_prof/recipes/rspec/let_it_be.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index 66c18bb8..06ba606e 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -75,7 +75,7 @@ def validate_modifiers!(mods) # Use uniq prefix for instance variables to avoid collisions # We want to use the power of Ruby's unicode support) # And we love cats!) - PREFIX = RUBY_ENGINE == "jruby" ? "@__jruby_is_not_cat_friendly__" : "@😸" + PREFIX = "@😸" FROZEN_ERROR_HINT = "\nIf you are using `let_it_be`, you may want to pass `reload: true` or `refind: true` modifier to it." From bcddd55bb6c4f31da0e473e6177a73d3b3d1d37c Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 11 Jan 2022 12:59:32 +0300 Subject: [PATCH 015/194] spec: fix time helpers loading in Rails 7+ --- spec/bugs/fixtures/time_patch_fixture.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/bugs/fixtures/time_patch_fixture.rb b/spec/bugs/fixtures/time_patch_fixture.rb index 3e7d00c3..c51ea9d4 100644 --- a/spec/bugs/fixtures/time_patch_fixture.rb +++ b/spec/bugs/fixtures/time_patch_fixture.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true $LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require "active_support" require "active_support/testing/time_helpers" require "test-prof" From 09135ac6cadf75ee000f3b420ff7eac684a29615 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 9 Feb 2022 13:15:49 +0300 Subject: [PATCH 016/194] chore: add missing requires and use require instead of require_relative Fixes #233 --- lib/test_prof/any_fixture.rb | 1 + lib/test_prof/before_all.rb | 2 ++ lib/test_prof/cops/rspec/aggregate_examples.rb | 10 +++++----- .../aggregate_examples/matchers_with_side_effects.rb | 2 +- .../cops/rspec/aggregate_examples/node_matchers.rb | 2 +- lib/test_prof/factory_all_stub.rb | 1 + lib/test_prof/factory_default.rb | 1 + lib/test_prof/recipes/rspec/let_it_be.rb | 2 +- lib/test_prof/rspec_dissect/collectors/before.rb | 2 +- lib/test_prof/rspec_dissect/collectors/let.rb | 2 +- lib/test_prof/rubocop.rb | 2 +- 11 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/test_prof/any_fixture.rb b/lib/test_prof/any_fixture.rb index 2f724903..7b2ce071 100644 --- a/lib/test_prof/any_fixture.rb +++ b/lib/test_prof/any_fixture.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "test_prof" require "test_prof/ext/float_duration" require "test_prof/any_fixture/dump" diff --git a/lib/test_prof/before_all.rb b/lib/test_prof/before_all.rb index b654a353..e12b1f4b 100644 --- a/lib/test_prof/before_all.rb +++ b/lib/test_prof/before_all.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "test_prof" + module TestProf # `before_all` helper configuration module BeforeAll diff --git a/lib/test_prof/cops/rspec/aggregate_examples.rb b/lib/test_prof/cops/rspec/aggregate_examples.rb index 5c031091..78837544 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true -require_relative "aggregate_examples/line_range_helpers" -require_relative "aggregate_examples/metadata_helpers" -require_relative "aggregate_examples/node_matchers" +require "test_prof/cops/rspec/aggregate_examples/line_range_helpers" +require "test_prof/cops/rspec/aggregate_examples/metadata_helpers" +require "test_prof/cops/rspec/aggregate_examples/node_matchers" -require_relative "aggregate_examples/its" -require_relative "aggregate_examples/matchers_with_side_effects" +require "test_prof/cops/rspec/aggregate_examples/its" +require "test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects" module RuboCop module Cop diff --git a/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb b/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb index e4b1dcb6..21af5b5f 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../language" +require "test_prof/cops/rspec/language" module RuboCop module Cop diff --git a/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb b/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb index 627ea82c..40e77e63 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../language" +require "test_prof/cops/rspec/language" module RuboCop module Cop diff --git a/lib/test_prof/factory_all_stub.rb b/lib/test_prof/factory_all_stub.rb index 06b33b57..95cf2ced 100644 --- a/lib/test_prof/factory_all_stub.rb +++ b/lib/test_prof/factory_all_stub.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "test_prof" require "test_prof/factory_bot" require "test_prof/factory_all_stub/factory_bot_patch" diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index f4efdb93..37bc8b59 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "test_prof" require "test_prof/factory_bot" require "test_prof/factory_default/factory_bot_patch" diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index 06ba606e..1e5867fc 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "test_prof" -require_relative "./before_all" +require "test_prof/recipes/rspec/before_all" module TestProf # Just like `let`, but persist the result for the whole group. diff --git a/lib/test_prof/rspec_dissect/collectors/before.rb b/lib/test_prof/rspec_dissect/collectors/before.rb index 64fb1a77..ea5608e8 100644 --- a/lib/test_prof/rspec_dissect/collectors/before.rb +++ b/lib/test_prof/rspec_dissect/collectors/before.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "./base" +require "test_prof/rspec_dissect/collectors/base" module TestProf module RSpecDissect diff --git a/lib/test_prof/rspec_dissect/collectors/let.rb b/lib/test_prof/rspec_dissect/collectors/let.rb index ae858fbc..d3ad0014 100644 --- a/lib/test_prof/rspec_dissect/collectors/let.rb +++ b/lib/test_prof/rspec_dissect/collectors/let.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "./base" +require "test_prof/rspec_dissect/collectors/base" module TestProf module RSpecDissect diff --git a/lib/test_prof/rubocop.rb b/lib/test_prof/rubocop.rb index c7ebdada..31516818 100644 --- a/lib/test_prof/rubocop.rb +++ b/lib/test_prof/rubocop.rb @@ -9,5 +9,5 @@ require "rubocop" -require_relative "cops/inject" +require "test_prof/cops/inject" require "test_prof/cops/rspec/aggregate_examples" From e47c9ee3de9d3a2dad0822bb4c9bd93259938210 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 9 Feb 2022 13:48:19 +0300 Subject: [PATCH 017/194] fix(specs): kwargs -> hash for RubyProf::Profile.new stub --- spec/test_prof/ruby_prof_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/test_prof/ruby_prof_spec.rb b/spec/test_prof/ruby_prof_spec.rb index db5755c2..287107d7 100644 --- a/spec/test_prof/ruby_prof_spec.rb +++ b/spec/test_prof/ruby_prof_spec.rb @@ -39,10 +39,10 @@ end specify "with default config" do - expect(ruby_prof).to receive(:new).with( + expect(ruby_prof).to receive(:new).with({ merge_fibers: true, include_threads: [Thread.current] - ).and_return(profile) + }).and_return(profile) expect(described_class.profile).to be_a(described_class::Report) end @@ -50,9 +50,9 @@ specify "with custom config" do described_class.config.include_threads = true - expect(ruby_prof).to receive(:new).with( + expect(ruby_prof).to receive(:new).with({ merge_fibers: true - ).and_return(profile) + }).and_return(profile) described_class.profile end From 98537dac0b2be412f8d5131caef68eccad1a6ed0 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 24 Feb 2022 16:47:56 +0300 Subject: [PATCH 018/194] Thanks @pennylane-hq! --- BACKERS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BACKERS.md b/BACKERS.md index 10ca60a5..944da9a0 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -1,5 +1,9 @@ # Sponsors & Backers +## Companies + +- [Pennylane](https://github.com/pennylane-hq) + ## Personal Sponsors - [Makar Ermokhin](https://github.com/Earendil95) From abcb7e76a39d78fd9be1da7de48e2f517a26d927 Mon Sep 17 00:00:00 2001 From: Guillermo Siliceo <98428834+grillermo-everlyhealth@users.noreply.github.com> Date: Mon, 28 Feb 2022 08:14:25 -0600 Subject: [PATCH 019/194] Respect the printer on the configure block (#237) * Respect the printer on the configure block It was being cached and ignoring the one defined the configuration * Update CHANGELOG * Fix rubocop warnings * Satisfy rubocop * Update CHANGELOG.md Co-authored-by: Guillermo Siliceo Co-authored-by: Vladimir Dementyev --- CHANGELOG.md | 3 +++ lib/test_prof/factory_prof.rb | 12 ++++++--- .../rubocop/aggregate_failures_fixture.rb | 6 +++-- spec/test_prof/factory_prof_spec.rb | 27 +++++++++++++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21843307..d249d996 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unrealeased) +- Fixes the configuration of a printer for factory_prof runs + ## 1.0.7 (2021-08-30) - Fix access to `let_it_be` variables in `after(:all)` hook. ([@cbarton][]) @@ -267,3 +269,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@stefkin]: https://github.com/stefkin [@jaimerson]: https://github.com/jaimerson [@alexvko]: https://github.com/alexvko +[@grillermo]: https://github.com/grillermo diff --git a/lib/test_prof/factory_prof.rb b/lib/test_prof/factory_prof.rb index 8dad4641..f083f944 100644 --- a/lib/test_prof/factory_prof.rb +++ b/lib/test_prof/factory_prof.rb @@ -100,15 +100,21 @@ def patch! def run init - printer = config.printer - started_at = TestProf.now - at_exit { printer.dump(result, start_time: started_at) } + at_exit do + print(started_at) + end start end + def print(started_at) + printer = config.printer + + printer.dump(result, start_time: started_at) + end + def start reset! @running = true diff --git a/spec/integrations/fixtures/rubocop/aggregate_failures_fixture.rb b/spec/integrations/fixtures/rubocop/aggregate_failures_fixture.rb index 4f439db0..f7f8f8b5 100644 --- a/spec/integrations/fixtures/rubocop/aggregate_failures_fixture.rb +++ b/spec/integrations/fixtures/rubocop/aggregate_failures_fixture.rb @@ -2,7 +2,9 @@ describe "something" do context "many examples" do - it { is_expected.to be_ok } - it { expect(subject).to_not be_nil } + it do + is_expected.to be_ok + expect(subject).to_not be_nil + end end end diff --git a/spec/test_prof/factory_prof_spec.rb b/spec/test_prof/factory_prof_spec.rb index 4ced127a..77d2238d 100644 --- a/spec/test_prof/factory_prof_spec.rb +++ b/spec/test_prof/factory_prof_spec.rb @@ -22,6 +22,33 @@ def without_time(xs) end end + describe "#print" do + let(:started_at) { Time.now } + + subject(:print) { described_class.print(started_at) } + + it "calls the default printer" do + expect(TestProf::FactoryProf::Printers::Simple).to receive(:dump) + + print + end + + context "when the printer is customized" do + let(:custom_printer) { double(dump: lambda { |result, start_time: nil| }) } + + before do + described_class.configure do |config| + config.printer = custom_printer + end + end + + it "calls the customer printer" do + expect(custom_printer).to receive(:dump) + print + end + end + end + describe "#result" do subject(:result) { described_class.result } From 09fa3e5605fe2bc7cbc560a90ca7fa90e4062560 Mon Sep 17 00:00:00 2001 From: Kosei Moriyama Date: Mon, 28 Feb 2022 23:15:44 +0900 Subject: [PATCH 020/194] restore the lock_thread value after rollback (#236) * restore the lock_thread value after rollback * use :@lock_thread instead of "@lock_thread" * avoid instance variable collisions with cats * add a changelog entry Co-authored-by: Vladimir Dementyev --- CHANGELOG.md | 3 ++ .../before_all/adapters/active_record.rb | 9 ++++++ spec/integrations/before_all_spec.rb | 12 +++++++ .../minitest/before_all_connection_fixture.rb | 31 +++++++++++++++++++ .../rspec/before_all_connection_fixture.rb | 28 +++++++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 spec/integrations/fixtures/minitest/before_all_connection_fixture.rb create mode 100644 spec/integrations/fixtures/rspec/before_all_connection_fixture.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index d249d996..d90104cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unrealeased) +- Restore the lock_thread value after rollback. ([@cou929][]) + - Fixes the configuration of a printer for factory_prof runs ## 1.0.7 (2021-08-30) @@ -270,3 +272,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@jaimerson]: https://github.com/jaimerson [@alexvko]: https://github.com/alexvko [@grillermo]: https://github.com/grillermo +[@cou929]: https://github.com/cou929 diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 48c96444..dfed64d4 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -37,6 +37,9 @@ def setup_fixtures(test_object) end end + # avoid instance variable collisions with cats + PREFIX_RESTORE_LOCK_THREAD = "@😺" + configure do |config| # Make sure ActiveRecord uses locked thread. # It only gets locked in `before` / `setup` hook, @@ -44,8 +47,14 @@ def setup_fixtures(test_object) # might lead to leaking connections config.before(:begin) do next unless ::ActiveRecord::Base.connection.pool.respond_to?(:lock_thread=) + instance_variable_set("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread", ::ActiveRecord::Base.connection.pool.instance_variable_get(:@lock_thread)) ::ActiveRecord::Base.connection.pool.lock_thread = true end + + config.after(:rollback) do + next unless ::ActiveRecord::Base.connection.pool.respond_to?(:lock_thread=) + ::ActiveRecord::Base.connection.pool.lock_thread = instance_variable_get("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread") + end end end end diff --git a/spec/integrations/before_all_spec.rb b/spec/integrations/before_all_spec.rb index 7c69bcd9..5216c81e 100644 --- a/spec/integrations/before_all_spec.rb +++ b/spec/integrations/before_all_spec.rb @@ -27,6 +27,12 @@ expect(output).not_to include("SampleJob") expect(output).to include("FailingJob") end + + specify "database connection" do + output = run_rspec("before_all_connection") + + expect(output).to include("0 failures") + end end context "Minitest" do @@ -47,5 +53,11 @@ expect(output).to include("0 failures, 0 errors, 0 skips") end + + specify "database connection" do + output = run_minitest("before_all_connection") + + expect(output).to include("0 failures, 0 errors, 0 skip") + end end end diff --git a/spec/integrations/fixtures/minitest/before_all_connection_fixture.rb b/spec/integrations/fixtures/minitest/before_all_connection_fixture.rb new file mode 100644 index 00000000..bfd4bde0 --- /dev/null +++ b/spec/integrations/fixtures/minitest/before_all_connection_fixture.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require_relative "../../../support/ar_models" +require_relative "../../../support/transactional_minitest" +require "minitest/autorun" + +require "test_prof/recipes/minitest/before_all" + +describe "database connection owner" do + describe "with before_all" do + include TestProf::BeforeAll::Minitest + before_all {} + + it "uses the connection owned by main thread" do + main_thread = Thread.current + Thread.new do + assert_equal ActiveRecord::Base.connection.owner, main_thread + end.join + end + end + + describe "without before_all" do + it "uses the connection owned by each thread" do + Thread.new do + child_thread = Thread.current + assert_equal ActiveRecord::Base.connection.owner, child_thread + end.join + end + end +end diff --git a/spec/integrations/fixtures/rspec/before_all_connection_fixture.rb b/spec/integrations/fixtures/rspec/before_all_connection_fixture.rb new file mode 100644 index 00000000..5f33b5e4 --- /dev/null +++ b/spec/integrations/fixtures/rspec/before_all_connection_fixture.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require_relative "../../../support/ar_models" +require_relative "../../../support/transactional_context" +require "test_prof/recipes/rspec/before_all" + +describe "database connection owner" do + context "with before_all" do + before_all {} + + it "uses the connection owned by main thread" do + main_thread = Thread.current + Thread.new do + expect(ActiveRecord::Base.connection.owner).to eq(main_thread) + end.join + end + end + + context "without before_all" do + it "uses the connection owned by each thread" do + Thread.new do + child_thread = Thread.current + expect(ActiveRecord::Base.connection.owner).to eq(child_thread) + end.join + end + end +end From 78b0a5064c392ad78872d8f153978d51bf5c362d Mon Sep 17 00:00:00 2001 From: Nathaniel Watts <1141717+thewatts@users.noreply.github.com> Date: Thu, 3 Mar 2022 11:31:46 -0600 Subject: [PATCH 021/194] Make defaults threadsafe This is to ensure that if tests were run in parallel, that values would not override each other/be used from other threads. --- CHANGELOG.md | 2 ++ lib/test_prof/factory_default.rb | 7 ++++--- .../fixtures/rspec/factory_default_fixture.rb | 13 +++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d90104cd..fc8381d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - Fixes the configuration of a printer for factory_prof runs +- Ensure that defaults are stored in a threadsafe manner + ## 1.0.7 (2021-08-30) - Fix access to `let_it_be` variables in `after(:all)` hook. ([@cbarton][]) diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 37bc8b59..101f164a 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -32,7 +32,6 @@ def init TestProf::FactoryBot::Strategy::Build.prepend StrategyExt TestProf::FactoryBot::Strategy::Stub.prepend StrategyExt - @store = {} # default is false to retain backward compatibility @preserve_traits = false end @@ -58,12 +57,14 @@ def remove(name) end def reset - @store.clear + store.clear end private - attr_reader :store + def store + Thread.current[:testprof_factory_store] ||= {} + end end end end diff --git a/spec/integrations/fixtures/rspec/factory_default_fixture.rb b/spec/integrations/fixtures/rspec/factory_default_fixture.rb index 5e41b8ab..d8eadc1d 100644 --- a/spec/integrations/fixtures/rspec/factory_default_fixture.rb +++ b/spec/integrations/fixtures/rspec/factory_default_fixture.rb @@ -83,5 +83,18 @@ }.to change(User, :count).by(3) end end + + context "thread safety" do + let(:user) { TestProf::FactoryBot.create(:user) } + let(:post) { TestProf::FactoryBot.create(:post) } + + it "storing defaults is done per thread" do + user + + Thread.new { TestProf::FactoryBot.set_factory_default(:user, user) }.join + + expect(post.user).not_to eq user + end + end end end From 9a9922c00abd7ee7609d8173dcfda219d43bff40 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 11 Mar 2022 20:25:18 +0300 Subject: [PATCH 022/194] fix: revert rubocop fixture --- .../fixtures/rubocop/aggregate_failures_fixture.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/spec/integrations/fixtures/rubocop/aggregate_failures_fixture.rb b/spec/integrations/fixtures/rubocop/aggregate_failures_fixture.rb index f7f8f8b5..4f439db0 100644 --- a/spec/integrations/fixtures/rubocop/aggregate_failures_fixture.rb +++ b/spec/integrations/fixtures/rubocop/aggregate_failures_fixture.rb @@ -2,9 +2,7 @@ describe "something" do context "many examples" do - it do - is_expected.to be_ok - expect(subject).to_not be_nil - end + it { is_expected.to be_ok } + it { expect(subject).to_not be_nil } end end From d394e47ea8e77d5dc85d9855a09e0a90e8d80a37 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 11 Mar 2022 20:42:13 +0300 Subject: [PATCH 023/194] Bump 1.0.8 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc8381d3..1367b223 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unrealeased) +## 1.0.8 (2022-03-11) + - Restore the lock_thread value after rollback. ([@cou929][]) - Fixes the configuration of a printer for factory_prof runs diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index a94a18db..20c34f8a 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.0.7" + VERSION = "1.0.8" end From fd399f43721d0c7ca436b570844166b621bb2701 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 11 Mar 2022 22:36:12 +0300 Subject: [PATCH 024/194] typo(changelog): unrealeased -> unreleased --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1367b223..e713131f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change log -## master (unrealeased) +## master (unreleased) ## 1.0.8 (2022-03-11) From 8a69b9b15b3fcf9b71b34608e3d6dd976fcce99c Mon Sep 17 00:00:00 2001 From: Ruslan Shakirov <16711718+ruslanshakirov@users.noreply.github.com> Date: Wed, 23 Mar 2022 00:12:13 +0000 Subject: [PATCH 025/194] feat: implement AnyFixture.before_reset and AnyFixture.after_reset --- lib/test_prof/any_fixture.rb | 17 ++++++ lib/test_prof/any_fixture/dsl.rb | 10 +++- .../rspec/any_fixture_callbacks_fixture.rb | 53 +++++++++++++++++++ spec/test_prof/any_fixture_spec.rb | 24 +++++++++ 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 spec/integrations/fixtures/rspec/any_fixture_callbacks_fixture.rb diff --git a/lib/test_prof/any_fixture.rb b/lib/test_prof/any_fixture.rb index 7b2ce071..1e839958 100644 --- a/lib/test_prof/any_fixture.rb +++ b/lib/test_prof/any_fixture.rb @@ -175,9 +175,22 @@ def clean # Reset all information and clean tables def reset + callbacks[:before_reset].each(&:call) + clean tables_cache.clear cache.clear + + callbacks[:after_reset].each(&:call) + callbacks.clear + end + + def before_reset(&block) + callbacks[:before_reset] << block + end + + def after_reset(&block) + callbacks[:after_reset] << block end def subscriber(_event, _start, _finish, _id, data) @@ -254,6 +267,10 @@ def tables_cache @tables_cache ||= {} end + def callbacks + @callbacks ||= Hash.new { |h, k| h[k] = [] } + end + def disable_referential_integrity connection = ActiveRecord::Base.connection return yield unless connection.respond_to?(:disable_referential_integrity) diff --git a/lib/test_prof/any_fixture/dsl.rb b/lib/test_prof/any_fixture/dsl.rb index dbaa63cf..310ba3da 100644 --- a/lib/test_prof/any_fixture/dsl.rb +++ b/lib/test_prof/any_fixture/dsl.rb @@ -2,7 +2,7 @@ module TestProf module AnyFixture - # Adds "global" `fixture` method (through refinement) + # Adds "global" `fixture`, `before_reset` and `after_reset` methods (through refinement) module DSL # Refine object, 'cause refining modules (Kernel) is vulnerable to prepend: # - https://bugs.ruby-lang.org/issues/13446 @@ -11,6 +11,14 @@ module DSL def fixture(id, &block) ::TestProf::AnyFixture.register(:"#{id}", &block) end + + def before_reset(&block) + ::TestProf::AnyFixture.before_reset(&block) + end + + def after_reset(&block) + ::TestProf::AnyFixture.after_reset(&block) + end end end end diff --git a/spec/integrations/fixtures/rspec/any_fixture_callbacks_fixture.rb b/spec/integrations/fixtures/rspec/any_fixture_callbacks_fixture.rb new file mode 100644 index 00000000..88d60c09 --- /dev/null +++ b/spec/integrations/fixtures/rspec/any_fixture_callbacks_fixture.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require_relative "../../../support/ar_models" +require "test_prof/recipes/rspec/any_fixture" + +require "test_prof/any_fixture/dsl" +using TestProf::AnyFixture::DSL + +shared_context "user_and_post", user_and_post: true do + before(:all) do + @user = fixture(:user) do + TestProf::FactoryBot.create(:user) + end + end + + before { TestProf::FactoryBot.create(:post) } + + let(:user) { User.find(fixture(:user).id) } +end + +describe "before_reset callback", :user_and_post do + before(:all) do + before_reset do + Post.delete_all + end + end + + it "deletes post" do + expect { TestProf::AnyFixture.reset }.to change(Post, :count).by(-1) + end +end + +describe "after_reset callback", :user_and_post do + before(:all) do + after_reset do + Post.delete_all + end + end + + it "deletes post" do + expect { TestProf::AnyFixture.reset }.to change(Post, :count).by(-1) + end +end + +describe "without callbacks", :user_and_post do + before { TestProf::FactoryBot.create(:post) } + after { Post.delete_all } + + it "doesn't delete post" do + expect { TestProf::AnyFixture.reset }.not_to change(Post, :count) + end +end diff --git a/spec/test_prof/any_fixture_spec.rb b/spec/test_prof/any_fixture_spec.rb index e0ee8a1e..db475aa8 100644 --- a/spec/test_prof/any_fixture_spec.rb +++ b/spec/test_prof/any_fixture_spec.rb @@ -61,6 +61,30 @@ expect(User.count).to eq 1 end + + context "with before_reset callback" do + it "runs callback" do + subject.register(:user) { TestProf::FactoryBot.create(:user) } + subject.before_reset { Post.delete_all } + TestProf::FactoryBot.create(:post) + + subject.reset + expect(User.count).to eq 0 + expect(Post.count).to eq 0 + end + end + + context "with after_reset callback" do + it "runs callback" do + subject.register(:user) { TestProf::FactoryBot.create(:user) } + subject.after_reset { Post.delete_all } + TestProf::FactoryBot.create(:post) + + subject.reset + expect(User.count).to eq 0 + expect(Post.count).to eq 0 + end + end end describe "#register_dump" do From 7fac1599d9fcf5496b4abf7591434594d3cc1c0a Mon Sep 17 00:00:00 2001 From: Ruslan Shakirov <16711718+ruslanshakirov@users.noreply.github.com> Date: Wed, 23 Mar 2022 01:15:37 +0000 Subject: [PATCH 026/194] chore: update docs and changelog --- CHANGELOG.md | 3 +++ docs/recipes/any_fixture.md | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e713131f..b48158bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Add `AnyFixture.before_reset` and `AnyFixture.after_reset` callbacks. ([@ruslanshakirov][]) + ## 1.0.8 (2022-03-11) - Restore the lock_thread value after rollback. ([@cou929][]) @@ -277,3 +279,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@alexvko]: https://github.com/alexvko [@grillermo]: https://github.com/grillermo [@cou929]: https://github.com/cou929 +[@ruslanshakirov]: https://github.com/ruslanshakirov diff --git a/docs/recipes/any_fixture.md b/docs/recipes/any_fixture.md index 0916db0c..bd381523 100644 --- a/docs/recipes/any_fixture.md +++ b/docs/recipes/any_fixture.md @@ -35,6 +35,16 @@ RSpec.shared_context "account", account: true do let(:account) { Account.find(TestProf::AnyFixture.register(:account).id) } end +# You can enhance the existing database cleaning. Posts will be deleted before reset +TestProf::AnyFixture.before_reset do + Post.delete_all +end + +# Or after reset +TestProf::AnyFixture.after_reset do + Post.delete_all +end + # Then in your tests # Active this fixture using a tag @@ -77,7 +87,7 @@ at_exit { TestProf::AnyFixture.clean } ## DSL -We provide an optional _syntactic sugar_ (through Refinement) to make it easier to define fixtures: +We provide an optional _syntactic sugar_ (through Refinement) to make it easier to define fixtures and use callbacks: ```ruby require "test_prof/any_fixture/dsl" @@ -90,6 +100,10 @@ before(:all) { fixture(:account) } # You can also use it to fetch the record (instead of storing it in instance variable) let(:account) { fixture(:account) } + +# You can just use `before_reset` or `after_reset` callbacks +before_reset { Post.delete_all } +after_reset { Post.delete_all } ``` ## `ActiveRecord#refind` From 524d0650ac41f754a6fd9da1c8dc3a5cf0728b46 Mon Sep 17 00:00:00 2001 From: Ruslan Shakirov <16711718+ruslanshakirov@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:16:56 +0000 Subject: [PATCH 027/194] chore: rename AnyFixture callbacks --- CHANGELOG.md | 2 +- docs/recipes/any_fixture.md | 12 ++++++------ lib/test_prof/any_fixture.rb | 12 ++++++------ lib/test_prof/any_fixture/dsl.rb | 10 +++++----- .../fixtures/rspec/any_fixture_callbacks_fixture.rb | 8 ++++---- spec/test_prof/any_fixture_spec.rb | 8 ++++---- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b48158bf..ce056948 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## master (unreleased) -- Add `AnyFixture.before_reset` and `AnyFixture.after_reset` callbacks. ([@ruslanshakirov][]) +- Add `AnyFixture.before_fixtures_reset` and `AnyFixture.after_fixtures_reset` callbacks. ([@ruslanshakirov][]) ## 1.0.8 (2022-03-11) diff --git a/docs/recipes/any_fixture.md b/docs/recipes/any_fixture.md index bd381523..95682b24 100644 --- a/docs/recipes/any_fixture.md +++ b/docs/recipes/any_fixture.md @@ -35,13 +35,13 @@ RSpec.shared_context "account", account: true do let(:account) { Account.find(TestProf::AnyFixture.register(:account).id) } end -# You can enhance the existing database cleaning. Posts will be deleted before reset -TestProf::AnyFixture.before_reset do +# You can enhance the existing database cleaning. Posts will be deleted before fixtures reset +TestProf::AnyFixture.before_fixtures_reset do Post.delete_all end # Or after reset -TestProf::AnyFixture.after_reset do +TestProf::AnyFixture.after_fixtures_reset do Post.delete_all end @@ -101,9 +101,9 @@ before(:all) { fixture(:account) } # You can also use it to fetch the record (instead of storing it in instance variable) let(:account) { fixture(:account) } -# You can just use `before_reset` or `after_reset` callbacks -before_reset { Post.delete_all } -after_reset { Post.delete_all } +# You can just use `before_fixtures_reset` or `after_fixtures_reset` callbacks +before_fixtures_reset { Post.delete_all } +after_fixtures_reset { Post.delete_all } ``` ## `ActiveRecord#refind` diff --git a/lib/test_prof/any_fixture.rb b/lib/test_prof/any_fixture.rb index 1e839958..b9d40d5e 100644 --- a/lib/test_prof/any_fixture.rb +++ b/lib/test_prof/any_fixture.rb @@ -175,22 +175,22 @@ def clean # Reset all information and clean tables def reset - callbacks[:before_reset].each(&:call) + callbacks[:before_fixtures_reset].each(&:call) clean tables_cache.clear cache.clear - callbacks[:after_reset].each(&:call) + callbacks[:after_fixtures_reset].each(&:call) callbacks.clear end - def before_reset(&block) - callbacks[:before_reset] << block + def before_fixtures_reset(&block) + callbacks[:before_fixtures_reset] << block end - def after_reset(&block) - callbacks[:after_reset] << block + def after_fixtures_reset(&block) + callbacks[:after_fixtures_reset] << block end def subscriber(_event, _start, _finish, _id, data) diff --git a/lib/test_prof/any_fixture/dsl.rb b/lib/test_prof/any_fixture/dsl.rb index 310ba3da..81cc44a7 100644 --- a/lib/test_prof/any_fixture/dsl.rb +++ b/lib/test_prof/any_fixture/dsl.rb @@ -2,7 +2,7 @@ module TestProf module AnyFixture - # Adds "global" `fixture`, `before_reset` and `after_reset` methods (through refinement) + # Adds "global" `fixture`, `before_fixtures_reset` and `after_fixtures_reset` methods (through refinement) module DSL # Refine object, 'cause refining modules (Kernel) is vulnerable to prepend: # - https://bugs.ruby-lang.org/issues/13446 @@ -12,12 +12,12 @@ def fixture(id, &block) ::TestProf::AnyFixture.register(:"#{id}", &block) end - def before_reset(&block) - ::TestProf::AnyFixture.before_reset(&block) + def before_fixtures_reset(&block) + ::TestProf::AnyFixture.before_fixtures_reset(&block) end - def after_reset(&block) - ::TestProf::AnyFixture.after_reset(&block) + def after_fixtures_reset(&block) + ::TestProf::AnyFixture.after_fixtures_reset(&block) end end end diff --git a/spec/integrations/fixtures/rspec/any_fixture_callbacks_fixture.rb b/spec/integrations/fixtures/rspec/any_fixture_callbacks_fixture.rb index 88d60c09..6b1b24c4 100644 --- a/spec/integrations/fixtures/rspec/any_fixture_callbacks_fixture.rb +++ b/spec/integrations/fixtures/rspec/any_fixture_callbacks_fixture.rb @@ -19,9 +19,9 @@ let(:user) { User.find(fixture(:user).id) } end -describe "before_reset callback", :user_and_post do +describe "before_fixtures_reset callback", :user_and_post do before(:all) do - before_reset do + before_fixtures_reset do Post.delete_all end end @@ -31,9 +31,9 @@ end end -describe "after_reset callback", :user_and_post do +describe "after_fixtures_reset callback", :user_and_post do before(:all) do - after_reset do + after_fixtures_reset do Post.delete_all end end diff --git a/spec/test_prof/any_fixture_spec.rb b/spec/test_prof/any_fixture_spec.rb index db475aa8..2673ec4e 100644 --- a/spec/test_prof/any_fixture_spec.rb +++ b/spec/test_prof/any_fixture_spec.rb @@ -62,10 +62,10 @@ expect(User.count).to eq 1 end - context "with before_reset callback" do + context "with before_fixtures_reset callback" do it "runs callback" do subject.register(:user) { TestProf::FactoryBot.create(:user) } - subject.before_reset { Post.delete_all } + subject.before_fixtures_reset { Post.delete_all } TestProf::FactoryBot.create(:post) subject.reset @@ -74,10 +74,10 @@ end end - context "with after_reset callback" do + context "with after_fixtures_reset callback" do it "runs callback" do subject.register(:user) { TestProf::FactoryBot.create(:user) } - subject.after_reset { Post.delete_all } + subject.after_fixtures_reset { Post.delete_all } TestProf::FactoryBot.create(:post) subject.reset From 44b136ba960031ca5225cf9ddbba4e066c0bce8a Mon Sep 17 00:00:00 2001 From: Ruslan Shakirov <16711718+ruslanshakirov@users.noreply.github.com> Date: Thu, 24 Mar 2022 18:28:51 +0000 Subject: [PATCH 028/194] lint: fix Layout/CaseIndentation offense --- .../cops/rspec/aggregate_examples/its.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/test_prof/cops/rspec/aggregate_examples/its.rb b/lib/test_prof/cops/rspec/aggregate_examples/its.rb index a67033ae..3377689e 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/its.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/its.rb @@ -48,14 +48,15 @@ def new_body(node) def transform_its(body, arguments) argument = arguments.first - replacement = case argument.type - when :array - key = argument.values.first - "expect(subject[#{key.source}])" - else - property = argument.value - "expect(subject.#{property})" - end + replacement = + case argument.type + when :array + key = argument.values.first + "expect(subject[#{key.source}])" + else + property = argument.value + "expect(subject.#{property})" + end body.source.gsub(/is_expected|are_expected/, replacement) end From 53eded1392710d1ce162e9b9bef445edb4c85b91 Mon Sep 17 00:00:00 2001 From: Ruslan Shakirov <16711718+ruslanshakirov@users.noreply.github.com> Date: Fri, 25 Mar 2022 15:57:30 +0000 Subject: [PATCH 029/194] fix: fix AnyFixture after_fixtures_reset spec --- spec/test_prof/any_fixture_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/test_prof/any_fixture_spec.rb b/spec/test_prof/any_fixture_spec.rb index 2673ec4e..37ed2a2d 100644 --- a/spec/test_prof/any_fixture_spec.rb +++ b/spec/test_prof/any_fixture_spec.rb @@ -78,7 +78,7 @@ it "runs callback" do subject.register(:user) { TestProf::FactoryBot.create(:user) } subject.after_fixtures_reset { Post.delete_all } - TestProf::FactoryBot.create(:post) + TestProf::FactoryBot.create(:post, user: nil) subject.reset expect(User.count).to eq 0 From c9b6740a14434bce98dcc08755841fd4da1f7dd6 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 12 Apr 2022 12:49:11 +0200 Subject: [PATCH 030/194] fix: raise meaningful error on a missing any fixture --- lib/test_prof/any_fixture.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/test_prof/any_fixture.rb b/lib/test_prof/any_fixture.rb index b9d40d5e..63d4e86a 100644 --- a/lib/test_prof/any_fixture.rb +++ b/lib/test_prof/any_fixture.rb @@ -119,6 +119,8 @@ def reporting_enabled # returns the result of the block execution def register(id) cached(id) do + raise "No fixture named #{id} has been registered" unless block_given? + ActiveSupport::Notifications.subscribed(method(:subscriber), "sql.active_record") do yield end From 408e72c7971ba82904897ac516c6b3161028119f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 12 Apr 2022 17:14:13 +0200 Subject: [PATCH 031/194] Thank you, Charles! @charly --- BACKERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BACKERS.md b/BACKERS.md index 944da9a0..3da1b7d8 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -8,3 +8,4 @@ - [Makar Ermokhin](https://github.com/Earendil95) - [Burkhard Vogel-Kreykenbohm](https://github.com/bvogel) +- [Charles Sistovaris](https://github.com/charly) From f45fb41d19f24ad0d351468990fc4789fd97bb38 Mon Sep 17 00:00:00 2001 From: Mark Edmondson Date: Mon, 2 May 2022 19:51:53 +0100 Subject: [PATCH 032/194] Fix Postgres dump with ActiveRecord 6.1 --- CHANGELOG.md | 2 ++ lib/test_prof/any_fixture/dump/postgresql.rb | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce056948..aae21280 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - Add `AnyFixture.before_fixtures_reset` and `AnyFixture.after_fixtures_reset` callbacks. ([@ruslanshakirov][]) +- Fixes ActiveRecord 6.1 issue with AnyFixture and Postgres config ([@markedmondson][]) + ## 1.0.8 (2022-03-11) - Restore the lock_thread value after rollback. ([@cou929][]) diff --git a/lib/test_prof/any_fixture/dump/postgresql.rb b/lib/test_prof/any_fixture/dump/postgresql.rb index 2fba6425..4e42989f 100644 --- a/lib/test_prof/any_fixture/dump/postgresql.rb +++ b/lib/test_prof/any_fixture/dump/postgresql.rb @@ -30,7 +30,7 @@ def import(path) # Test if psql is installed `psql --version` - tasks = ActiveRecord::Tasks::PostgreSQLDatabaseTasks.new(conn.pool.spec.config.with_indifferent_access) + tasks = ActiveRecord::Tasks::PostgreSQLDatabaseTasks.new(config) while_disconnected do tasks.structure_load(path, "--output=/dev/null") @@ -85,6 +85,15 @@ def teardown_env def execute(query) super.values end + + def config + conn_pool = conn.pool + if conn_pool.respond_to?(:spec) # Support for Rails < 6.1 + conn_pool.spec.config + else + conn_pool.db_config + end + end end end end From 9720f700ce6391a9bcdf4f508e563b3e53abe4df Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 5 May 2022 22:11:29 -0400 Subject: [PATCH 033/194] Bump 1.0.9 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aae21280..add5a468 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.0.9 (2022-05-05) + - Add `AnyFixture.before_fixtures_reset` and `AnyFixture.after_fixtures_reset` callbacks. ([@ruslanshakirov][]) - Fixes ActiveRecord 6.1 issue with AnyFixture and Postgres config ([@markedmondson][]) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 20c34f8a..e82b7214 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.0.8" + VERSION = "1.0.9" end From 8becefe3c1fccb6690b10e6ca32b5d61da7c49c0 Mon Sep 17 00:00:00 2001 From: Sergey Toy Date: Thu, 2 Jun 2022 12:08:41 +0000 Subject: [PATCH 034/194] fix option name --- docs/profilers/tag_prof.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/profilers/tag_prof.md b/docs/profilers/tag_prof.md index e246f530..ea78332c 100644 --- a/docs/profilers/tag_prof.md +++ b/docs/profilers/tag_prof.md @@ -2,7 +2,7 @@ TagProf is a simple profiler which collects examples statistics grouped by a provided tag value. -That's pretty useful in conjunction with `rspec-rails` built-in feature – `infer_spec_types_from_location!` – which automatically adds `type` to examples metadata. +That's pretty useful in conjunction with `rspec-rails` built-in feature – `infer_spec_type_from_file_location!` – which automatically adds `type` to examples metadata. Example output: From 2b49a0279bf7b552122f7ee7cfaaf98f1d0c6e7b Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 24 Jun 2022 15:17:29 -0400 Subject: [PATCH 035/194] Thanks, @github! --- BACKERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BACKERS.md b/BACKERS.md index 3da1b7d8..f5260794 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -2,6 +2,7 @@ ## Companies +- [GitHub](https://github.com/github) - [Pennylane](https://github.com/pennylane-hq) ## Personal Sponsors From b35b4e082d9d3e9f17aa32da66bf8a848c3d4f70 Mon Sep 17 00:00:00 2001 From: Nate Berkopec Date: Fri, 12 Aug 2022 11:55:26 +0900 Subject: [PATCH 036/194] Reset colors before newline --- lib/test_prof/logging.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/logging.rb b/lib/test_prof/logging.rb index 7a16c7f4..6a2aeba0 100644 --- a/lib/test_prof/logging.rb +++ b/lib/test_prof/logging.rb @@ -11,7 +11,7 @@ module Logging class Formatter def call(severity, _time, progname, msg) - colorize(severity.to_sym, "[#{progname} #{severity}] #{msg}\n") + colorize(severity.to_sym, "[#{progname} #{severity}] #{msg}") + "\n" end private From 709e1b354d09da5d94e327bd6f3c342726805719 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 12 Aug 2022 10:22:08 -0400 Subject: [PATCH 037/194] fix: style --- lib/test_prof/factory_doctor/minitest.rb | 4 ++-- lib/test_prof/factory_doctor/rspec.rb | 2 +- lib/test_prof/rspec_stamp.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/test_prof/factory_doctor/minitest.rb b/lib/test_prof/factory_doctor/minitest.rb index bbe6c287..5e6be051 100644 --- a/lib/test_prof/factory_doctor/minitest.rb +++ b/lib/test_prof/factory_doctor/minitest.rb @@ -74,8 +74,8 @@ def report @example_groups.each do |group, examples| msgs << "#{group[:description]} (#{group[:location]})\n" examples.each do |ex| - msgs << " #{ex[:description]} (#{ex[:location]}) "\ - "– #{pluralize_records(ex[:factories])} created, "\ + msgs << " #{ex[:description]} (#{ex[:location]}) " \ + "– #{pluralize_records(ex[:factories])} created, " \ "#{ex[:time].duration}\n" end msgs << "\n" diff --git a/lib/test_prof/factory_doctor/rspec.rb b/lib/test_prof/factory_doctor/rspec.rb index d4534e35..a7555515 100644 --- a/lib/test_prof/factory_doctor/rspec.rb +++ b/lib/test_prof/factory_doctor/rspec.rb @@ -67,7 +67,7 @@ def print examples.each do |ex| msgs << " #{ex.description} (#{ex.metadata[:location]}) " \ - "– #{pluralize_records(ex.metadata[:factories])} created, "\ + "– #{pluralize_records(ex.metadata[:factories])} created, " \ "#{ex.metadata[:time].duration}\n" end msgs << "\n" diff --git a/lib/test_prof/rspec_stamp.rb b/lib/test_prof/rspec_stamp.rb index a1246345..7af30dc6 100644 --- a/lib/test_prof/rspec_stamp.rb +++ b/lib/test_prof/rspec_stamp.rb @@ -153,8 +153,8 @@ def stamp_example(example, tags) end end - replacement = "\\1#{parsed.fname}#{need_parens ? "(" : " "}"\ - "#{[desc, tags_str, htags_str].compact.join(", ")}"\ + replacement = "\\1#{parsed.fname}#{need_parens ? "(" : " "}" \ + "#{[desc, tags_str, htags_str].compact.join(", ")}" \ "#{need_parens ? ") " : " "}\\3" if config.dry_run? From 87a1b930edcc6e8a5e6f0e91649d3924e6c19b87 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 12 Aug 2022 10:23:18 -0400 Subject: [PATCH 038/194] ci: upgrade jruby --- .github/workflows/rspec-jruby.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec-jruby.yml b/.github/workflows/rspec-jruby.yml index 98df8299..7532a5f2 100644 --- a/.github/workflows/rspec-jruby.yml +++ b/.github/workflows/rspec-jruby.yml @@ -22,7 +22,7 @@ jobs: bundle- - uses: ruby/setup-ruby@v1 with: - ruby-version: jruby-9.2.15.0 + ruby-version: jruby-9.3.6.0 - name: Bundle install run: | bundle config path /home/runner/bundle From 1768d8df160823990d95ad4b764cdf6148b3f04c Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 12 Aug 2022 12:30:18 -0400 Subject: [PATCH 039/194] fix(tests): fabrication setup --- spec/integrations/fixtures/rspec/factory_doctor_fixture.rb | 5 +++-- spec/support/ar_models.rb | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/spec/integrations/fixtures/rspec/factory_doctor_fixture.rb b/spec/integrations/fixtures/rspec/factory_doctor_fixture.rb index df20e3c6..1a9f0a93 100644 --- a/spec/integrations/fixtures/rspec/factory_doctor_fixture.rb +++ b/spec/integrations/fixtures/rspec/factory_doctor_fixture.rb @@ -35,8 +35,9 @@ let(:user) { Fabricate(:user) } it "creates and reloads user" do - user = Fabricate(:user) - expect(User.find(user.id).name).to eq "John 1" + user + user2 = Fabricate(:user) + expect(User.find(user2.id).name).to eq "John 1" end it "validates name" do diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index 3a72f0e2..54b80b7b 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -116,10 +116,10 @@ class Post < ActiveRecord::Base end Fabricator(:user) do - name Fabricate.sequence(:name) { |n| "John #{n}" } + name { sequence(:name) { |n| "John #{n}" } } end Fabricator(:post) do - text Fabricate.sequence(:text) { |n| "Post ##{n}}" } + text { sequence(:text) { |n| "Post ##{n}}" } } user end From 728cf0e4e9f2ee82cfb6a2bca0cbbbce0848a9b3 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 12 Aug 2022 12:32:10 -0400 Subject: [PATCH 040/194] feat: improve logging --- CHANGELOG.md | 8 +++ lib/test_prof/recipes/logging.rb | 41 +++++++++--- .../fixtures/rspec/logging_fixture.rb | 67 +++++++++++++++++++ spec/integrations/logging_spec.rb | 35 ++++++++++ spec/support/ar_models.rb | 7 +- 5 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 spec/integrations/fixtures/rspec/logging_fixture.rb create mode 100644 spec/integrations/logging_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index add5a468..cbf391bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## master (unreleased) +- Allow overriding global logger. ([@palkan][]) + +```ruby +require "test_prof/recipes/logging" + +TestProf::Rails::LoggingHelpers.logger = CustomLogger.new +``` + ## 1.0.9 (2022-05-05) - Add `AnyFixture.before_fixtures_reset` and `AnyFixture.after_fixtures_reset` callbacks. ([@ruslanshakirov][]) diff --git a/lib/test_prof/recipes/logging.rb b/lib/test_prof/recipes/logging.rb index f45d7afc..a40a59ad 100644 --- a/lib/test_prof/recipes/logging.rb +++ b/lib/test_prof/recipes/logging.rb @@ -7,12 +7,38 @@ module Rails # Add `with_logging` and `with_ar_logging helpers` module LoggingHelpers class << self - attr_writer :logger + def logger=(logger) + @logger = logger + + # swap global loggers + global_loggables.each do |loggable| + loggable.logger = logger + end + end def logger return @logger if instance_variable_defined?(:@logger) - @logger = Logger.new($stdout) + @logger = if defined?(ActiveSupport::TaggedLogging) + ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new($stdout)) + elsif defined?(ActiveSupport::Logger) + ActiveSupport::Logger.new($stdout) + else + Logger.new($stdout) + end + end + + def global_loggables + return @global_loggables if instance_variable_defined?(:@global_loggables) + + @global_loggables = [] + end + + def swap_logger!(loggables) + loggables.each do |loggable| + loggable.logger = logger + global_loggables << loggable + end end def ar_loggables @@ -77,7 +103,9 @@ def with_ar_logging if TestProf.rspec? RSpec.shared_context "logging:verbose" do around(:each) do |ex| - with_logging(&ex) + next with_logging(&ex) if ex.metadata[:log] == true || ex.metadata[:log] == :all + + ex.call end end @@ -96,13 +124,10 @@ def with_ar_logging TestProf.activate("LOG", "all") do TestProf.log :info, "Rails verbose logging enabled" - ActiveSupport::LogSubscriber.logger = - Rails.logger = - ActiveRecord::Base.logger = TestProf::Rails::LoggingHelpers.logger + TestProf::Rails::LoggingHelpers.swap_logger!(TestProf::Rails::LoggingHelpers.all_loggables) end TestProf.activate("LOG", "ar") do TestProf.log :info, "Active Record verbose logging enabled" - ActiveSupport::LogSubscriber.logger = - ActiveRecord::Base.logger = TestProf::Rails::LoggingHelpers.logger + TestProf::Rails::LoggingHelpers.swap_logger!(TestProf::Rails::LoggingHelpers.ar_loggables) end diff --git a/spec/integrations/fixtures/rspec/logging_fixture.rb b/spec/integrations/fixtures/rspec/logging_fixture.rb new file mode 100644 index 00000000..a42c6e72 --- /dev/null +++ b/spec/integrations/fixtures/rspec/logging_fixture.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require_relative "../../../support/ar_models" +require "test-prof" + +module Rails + class << self + attr_writer :logger + + def logger + @logger ||= Logger.new(IO::NULL) + end + end +end + +require "test_prof/recipes/logging" + +TestProf.configure do |config| + config.output_dir = "../../../../tmp/test_prof" +end + +describe "Logging" do + context "global", test: :global do + context "ActiveRecord" do + let(:user) { TestProf::FactoryBot.create(:user) } + + it "generates users" do + user2 = TestProf::FactoryBot.create(:user, name: "a") + Rails.logger.debug "USER: #{user2.name}" + expect(user.name).not_to eq user2.name + end + end + + context "all" do + let(:user) { TestProf::FactoryBot.create(:user) } + + it "generates users" do + user2 = TestProf::FactoryBot.create(:user, name: "b") + Rails.logger.debug "USER: #{user2.name}" + expect(user.name).not_to eq user2.name + end + end + end + + context "tags", test: :tags do + context "tags active_record", log: :ar do + let(:user) { Fabricate(:user) } + + it "generates users" do + user2 = Fabricate(:user, name: "invisible") + Rails.logger.debug "USER: #{user2.name}" + expect(user.name).not_to eq user2.name + end + end + + context "tags all", log: :all do + let(:user) { Fabricate(:user) } + + it "generates users" do + user2 = Fabricate(:user, name: "visible") + Rails.logger.debug "USER: #{user2.name}" + expect(user.name).not_to eq user2.name + end + end + end +end diff --git a/spec/integrations/logging_spec.rb b/spec/integrations/logging_spec.rb new file mode 100644 index 00000000..1d04fb87 --- /dev/null +++ b/spec/integrations/logging_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +describe "Logging" do + context "RSpec integration" do + specify "global all", :aggregate_failures do + output = run_rspec("logging", env: {"LOG" => "all"}, options: "--tag test:global") + + expect(output).to include("examples, 0 failures") + + expect(output).to include("INSERT INTO") + expect(output).to include("USER: a") + expect(output).to include("USER: b") + end + + specify "global active record", :aggregate_failures do + output = run_rspec("logging", env: {"LOG" => "ar"}, options: "--tag test:global") + + expect(output).to include("examples, 0 failures") + + expect(output).to include("INSERT INTO") + expect(output).not_to include("USER: a") + expect(output).not_to include("USER: b") + end + + specify "tegs", :aggregate_failures do + output = run_rspec("logging", env: {"LOG" => "ar"}, options: "--tag test:tags") + + expect(output).to include("examples, 0 failures") + + expect(output).to include("INSERT INTO") + expect(output).not_to include("USER: invisible") + expect(output).to include("USER: visible") + end + end +end diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index 54b80b7b..638f22ec 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -59,7 +59,12 @@ end end -ActiveRecord::Base.logger = Logger.new($stdout) if ENV["LOG"] +ActiveRecord::Base.logger = + if ENV["DEBUG"] + Logger.new($stdout) + else + Logger.new(IO::NULL) + end class User < ActiveRecord::Base validates :name, presence: true From e90f2d54bdbedd45dba9d1cfe4cc3dca99d6c747 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 12 Aug 2022 12:32:24 -0400 Subject: [PATCH 041/194] ci: add Ruby 3.1 and Rails 7 --- .github/workflows/rspec.yml | 6 ++++++ Gemfile | 1 - gemfiles/activerecord7.gemfile | 11 +++++++++++ lefthook.yml | 18 ------------------ 4 files changed, 17 insertions(+), 19 deletions(-) create mode 100644 gemfiles/activerecord7.gemfile delete mode 100644 lefthook.yml diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 398e87de..4f37b7c9 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -19,6 +19,12 @@ jobs: gemfile: ["gemfiles/activerecord6.gemfile"] db: ["postgres"] include: + - ruby: 3.1 + gemfile: "gemfiles/activerecord7.gemfile" + db: "sqlite" + - ruby: 3.1 + gemfile: "gemfiles/activerecord7.gemfile" + db: "postgres" - ruby: 3.0 gemfile: "gemfiles/activerecord6.gemfile" db: "sqlite" diff --git a/Gemfile b/Gemfile index 6081092e..f87f32d5 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,6 @@ if File.exist?(local_gemfile) else platform :mri do gem "sqlite3", "~> 1.4" - gem "pg", "~> 1.0" end platform :jruby do diff --git a/gemfiles/activerecord7.gemfile b/gemfiles/activerecord7.gemfile new file mode 100644 index 00000000..89e854cf --- /dev/null +++ b/gemfiles/activerecord7.gemfile @@ -0,0 +1,11 @@ +source 'https://rubygems.org' + +gem "activerecord", "~> 7.0" +gem "factory_bot" +gem "fabrication" +gem "sqlite3" +gem "sidekiq" +gem "timecop" +gem "pg" + +gemspec path: '..' diff --git a/lefthook.yml b/lefthook.yml deleted file mode 100644 index ca5678ca..00000000 --- a/lefthook.yml +++ /dev/null @@ -1,18 +0,0 @@ -pre-commit: - commands: - mdl: - tags: style - glob: "**/*.md" - run: mdl {staged_files} - liche: - tags: links - glob: "*.md" - run: liche -d docs/ -r docs/* CHANGELOG.md README.md && test "{staged_files}" - forspell: - tags: grammar - glob: "**/*.md" - run: forspell {staged_files} - rubocop: - tags: style - glob: "**/*.md" - run: BUNDLE_GEMFILE=gemfiles/rubocop.gemfile bundle exec rubocop {staged_files} From dda8b4f90a51f598dee0ecf9871097bcd4c7adb5 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 12 Aug 2022 12:45:07 -0400 Subject: [PATCH 042/194] Bump 1.0.10 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbf391bd..aa706bbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.0.10 (2022-08-12) + - Allow overriding global logger. ([@palkan][]) ```ruby diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index e82b7214..f799c9bd 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.0.9" + VERSION = "1.0.10" end From 417f040dc1fd5b65307539e0c3777764a8430af6 Mon Sep 17 00:00:00 2001 From: Peter Leitzen Date: Wed, 14 Sep 2022 14:08:37 +0200 Subject: [PATCH 043/194] Fix typo in event TestProf::EventProf code comment --- lib/test_prof/event_prof.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/event_prof.rb b/lib/test_prof/event_prof.rb index 6eea925a..68e29413 100644 --- a/lib/test_prof/event_prof.rb +++ b/lib/test_prof/event_prof.rb @@ -8,7 +8,7 @@ module TestProf # EventProf profiles your tests and suites against custom events, - # such as ActiveSupport::Notifacations. + # such as ActiveSupport::Notifications. # # It works very similar to `rspec --profile` but can track arbitrary events. # From 4c713605fda2ba3085760f9fe2f71f0e33e24e2c Mon Sep 17 00:00:00 2001 From: ygelfand Date: Mon, 19 Sep 2022 12:29:36 -0400 Subject: [PATCH 044/194] don't overwrite saved lock_thread value in nested contexts Signed-off-by: ygelfand --- lib/test_prof/before_all/adapters/active_record.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index dfed64d4..8b337607 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -47,7 +47,7 @@ def setup_fixtures(test_object) # might lead to leaking connections config.before(:begin) do next unless ::ActiveRecord::Base.connection.pool.respond_to?(:lock_thread=) - instance_variable_set("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread", ::ActiveRecord::Base.connection.pool.instance_variable_get(:@lock_thread)) + instance_variable_set("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread", ::ActiveRecord::Base.connection.pool.instance_variable_get(:@lock_thread)) unless instance_variable_defined? "#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread" ::ActiveRecord::Base.connection.pool.lock_thread = true end From 854256791abe47d73bf06ce8070d7665edf90316 Mon Sep 17 00:00:00 2001 From: ygelfand Date: Mon, 19 Sep 2022 12:34:46 -0400 Subject: [PATCH 045/194] changelog Signed-off-by: ygelfand --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa706bbb..c9b3a9c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Fixed restoring lock_thread value in nested contexts ([@ygelfand][]) + ## 1.0.10 (2022-08-12) - Allow overriding global logger. ([@palkan][]) @@ -294,3 +296,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@grillermo]: https://github.com/grillermo [@cou929]: https://github.com/cou929 [@ruslanshakirov]: https://github.com/ruslanshakirov +[@ygelfand]: https://github.com/ygelfand From 09e7859f6c235eb0a89e726bf9f7ae6d37e5327f Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Wed, 5 Oct 2022 09:54:57 +0200 Subject: [PATCH 046/194] Disable GC frames with TEST_STACK_PROF_IGNORE_GC=1 --- CHANGELOG.md | 2 ++ docs/profilers/stack_prof.md | 4 ++++ lib/test_prof/stack_prof.rb | 5 +++-- spec/test_prof/stack_prof_spec.rb | 13 +++++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9b3a9c2..230534f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Disable garbage collection frames when `TEST_STACK_PROF_IGNORE_GC` env variable is set ([@cbliard][]) + - Fixed restoring lock_thread value in nested contexts ([@ygelfand][]) ## 1.0.10 (2022-08-12) diff --git a/docs/profilers/stack_prof.md b/docs/profilers/stack_prof.md index 06b65d02..9ed34135 100644 --- a/docs/profilers/stack_prof.md +++ b/docs/profilers/stack_prof.md @@ -76,4 +76,8 @@ You can also change StackProf interval through `TEST_STACK_PROF_INTERVAL` env va For modes `wall` and `cpu`, `TEST_STACK_PROF_INTERVAL` represents microseconds and will default to 1000 as per `stackprof`. For mode `object`, `TEST_STACK_PROF_INTERVAL` represents allocations and will default to 1 as per `stackprof`. +You can disable garbage collection frames by setting `TEST_STACK_PROF_IGNORE_GC` env variable. +Garbage collection time will still be present in the profile but not explicitly marked with +its own frame. + See [stack_prof.rb](https://github.com/test-prof/test-prof/tree/master/lib/test_prof/stack_prof.rb) for all available configuration options and their usage. diff --git a/lib/test_prof/stack_prof.rb b/lib/test_prof/stack_prof.rb index 640b52c2..99e49d43 100644 --- a/lib/test_prof/stack_prof.rb +++ b/lib/test_prof/stack_prof.rb @@ -24,8 +24,7 @@ module StackProf class Configuration FORMATS = %w[html json].freeze - attr_accessor :mode, :interval, :raw, :target, :format - + attr_accessor :mode, :raw, :target, :format, :interval, :ignore_gc def initialize @mode = ENV.fetch("TEST_STACK_PROF_MODE", :wall).to_sym @target = ENV["TEST_STACK_PROF"] == "boot" ? :boot : :suite @@ -39,6 +38,7 @@ def initialize sample_interval = ENV["TEST_STACK_PROF_INTERVAL"].to_i @interval = sample_interval > 0 ? sample_interval : nil + @ignore_gc = ENV.fetch("TEST_STACK_PROF_IGNORE_GC", false) end def raw? @@ -96,6 +96,7 @@ def profile(name = nil) } options[:interval] = config.interval if config.interval + options[:ignore_gc] = true if config.ignore_gc if block_given? options[:out] = build_path(name) diff --git a/spec/test_prof/stack_prof_spec.rb b/spec/test_prof/stack_prof_spec.rb index e8618794..33f7ba78 100644 --- a/spec/test_prof/stack_prof_spec.rb +++ b/spec/test_prof/stack_prof_spec.rb @@ -42,6 +42,19 @@ described_class.profile end + specify "with ignore_gc option" do + allow(ENV).to receive(:fetch).and_call_original + allow(ENV).to receive(:fetch).with("TEST_STACK_PROF_IGNORE_GC", any_args).and_return("1") + + expect(stack_prof).to receive(:start).with( + mode: :wall, + raw: true, + ignore_gc: true + ) + + described_class.profile + end + specify "when block is given" do expect(stack_prof).to receive(:run).with( out: File.join(TestProf.config.output_dir, "stack-prof-report-wall-raw-stub.dump").to_s, From 04d840cbabeb7508b30ae09705b2ffe21d17bd7d Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 27 Oct 2022 12:06:05 -0400 Subject: [PATCH 047/194] ci: liche -> lychee --- .github/workflows/docs-lint.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docs-lint.yml b/.github/workflows/docs-lint.yml index 716b4235..d94f3931 100644 --- a/.github/workflows/docs-lint.yml +++ b/.github/workflows/docs-lint.yml @@ -53,18 +53,14 @@ jobs: run: gem install forspell - name: Run Forspell run: forspell docs/ - liche: + lychee: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up Go - uses: actions/setup-go@v1 - with: - go-version: 1.13.x - - name: Run liche + - name: Link Checker + id: lychee + uses: lycheeverse/lychee-action@v1.5.1 env: - GO111MODULE: "on" - run: | - export PATH=$PATH:$(go env GOPATH)/bin - go get -u github.com/raviqqe/liche - liche -r docs -d docs || true + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + with: + args: docs/* -v From a972a28f4fa5434b8d0db821f58c021d9f3cafb2 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 27 Oct 2022 12:27:57 -0400 Subject: [PATCH 048/194] fix: stack_prof_spec --- lib/test_prof/stack_prof.rb | 2 +- spec/test_prof/stack_prof_spec.rb | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/test_prof/stack_prof.rb b/lib/test_prof/stack_prof.rb index 99e49d43..40e6ec28 100644 --- a/lib/test_prof/stack_prof.rb +++ b/lib/test_prof/stack_prof.rb @@ -38,7 +38,7 @@ def initialize sample_interval = ENV["TEST_STACK_PROF_INTERVAL"].to_i @interval = sample_interval > 0 ? sample_interval : nil - @ignore_gc = ENV.fetch("TEST_STACK_PROF_IGNORE_GC", false) + @ignore_gc = !ENV["TEST_STACK_PROF_IGNORE_GC"].nil? end def raw? diff --git a/spec/test_prof/stack_prof_spec.rb b/spec/test_prof/stack_prof_spec.rb index 33f7ba78..d307cf4f 100644 --- a/spec/test_prof/stack_prof_spec.rb +++ b/spec/test_prof/stack_prof_spec.rb @@ -43,8 +43,7 @@ end specify "with ignore_gc option" do - allow(ENV).to receive(:fetch).and_call_original - allow(ENV).to receive(:fetch).with("TEST_STACK_PROF_IGNORE_GC", any_args).and_return("1") + described_class.config.ignore_gc = true expect(stack_prof).to receive(:start).with( mode: :wall, From 35f9e3bd47448a7c3656a24bc09bbcdf2fc06fc3 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 27 Oct 2022 12:33:07 -0400 Subject: [PATCH 049/194] style: ignore md indentation --- .mdlrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mdlrc b/.mdlrc index 094d3e0d..77f87fdd 100644 --- a/.mdlrc +++ b/.mdlrc @@ -1 +1 @@ -rules "~MD013", "~MD033" +rules "~MD013", "~MD033", "~MD007" From a5d8d02dd98d1d491f2f1c37fe6a41eea7ad4a8a Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 27 Oct 2022 12:08:06 -0400 Subject: [PATCH 050/194] fix(event_prof): monitor methods with kwargs in Ruby 2.7+ --- CHANGELOG.md | 3 +++ lib/test_prof/event_prof/monitor.rb | 13 ++++++++++--- .../fixtures/rspec/event_prof_monitor_fixture.rb | 6 +++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 230534f5..80967dc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Fix monitoring methods with keyword args in Ruby 3+. ([@palkan][]) + - Disable garbage collection frames when `TEST_STACK_PROF_IGNORE_GC` env variable is set ([@cbliard][]) - Fixed restoring lock_thread value in nested contexts ([@ygelfand][]) @@ -299,3 +301,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@cou929]: https://github.com/cou929 [@ruslanshakirov]: https://github.com/ruslanshakirov [@ygelfand]: https://github.com/ygelfand +[@cbliard]: https://github.com/cbliard diff --git a/lib/test_prof/event_prof/monitor.rb b/lib/test_prof/event_prof/monitor.rb index c0a599d4..afa932e4 100644 --- a/lib/test_prof/event_prof/monitor.rb +++ b/lib/test_prof/event_prof/monitor.rb @@ -48,9 +48,16 @@ def call(mod, event, *mids, guard: nil, top_level: false) patch = Module.new do mids.each do |mid| - define_method(mid) do |*args, &block| - next super(*args, &block) unless guard.nil? || instance_exec(*args, &guard) - tracker.track { super(*args, &block) } + if RUBY_VERSION >= "2.7.0" + define_method(mid) do |*args, **kwargs, &block| + next super(*args, **kwargs, &block) unless guard.nil? || instance_exec(*args, **kwargs, &guard) + tracker.track { super(*args, **kwargs, &block) } + end + else + define_method(mid) do |*args, &block| + next super(*args, &block) unless guard.nil? || instance_exec(*args, &guard) + tracker.track { super(*args, &block) } + end end end end diff --git a/spec/integrations/fixtures/rspec/event_prof_monitor_fixture.rb b/spec/integrations/fixtures/rspec/event_prof_monitor_fixture.rb index 91fef698..ae2ecc95 100644 --- a/spec/integrations/fixtures/rspec/event_prof_monitor_fixture.rb +++ b/spec/integrations/fixtures/rspec/event_prof_monitor_fixture.rb @@ -14,8 +14,8 @@ def one true end - def two - false + def two(flag: false) + flag end end @@ -28,6 +28,6 @@ def two end it "invokes twice" do - expect(w.one && w.two).to eq false + expect(w.two(flag: true) && w.two).to eq false end end From 12b785abf97e997b386d2fe01b27dfdd12a7d0db Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 27 Oct 2022 13:08:09 -0400 Subject: [PATCH 051/194] ci: use latest jruby --- .github/workflows/rspec-jruby.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec-jruby.yml b/.github/workflows/rspec-jruby.yml index 7532a5f2..0c3f2352 100644 --- a/.github/workflows/rspec-jruby.yml +++ b/.github/workflows/rspec-jruby.yml @@ -22,7 +22,7 @@ jobs: bundle- - uses: ruby/setup-ruby@v1 with: - ruby-version: jruby-9.3.6.0 + ruby-version: jruby - name: Bundle install run: | bundle config path /home/runner/bundle From 8c1b71b1595a5c53f1627038d2d6a6a355751d19 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 27 Oct 2022 13:08:24 -0400 Subject: [PATCH 052/194] Bump 1.0.11 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80967dc3..0997ab4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.0.11 (2022-10-27) + - Fix monitoring methods with keyword args in Ruby 3+. ([@palkan][]) - Disable garbage collection frames when `TEST_STACK_PROF_IGNORE_GC` env variable is set ([@cbliard][]) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index f799c9bd..07279451 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.0.10" + VERSION = "1.0.11" end From be5a3eb7fb2370f3271220cce4b30e6f8e936f2f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 25 Nov 2022 20:43:34 -0500 Subject: [PATCH 053/194] feat(factory_default): allow skipping defaults --- CHANGELOG.md | 4 ++ docs/recipes/factory_default.md | 11 ++++ lib/test_prof/factory_default.rb | 29 ++++++++++ spec/support/ar_models.rb | 4 ++ spec/test_prof/factory_default_spec.rb | 75 ++++++++++++++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 spec/test_prof/factory_default_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 0997ab4d..bcdede08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +- FactoryDefault: Add `skip_factory_default(&block)` to temporary disable default factories. ([@palkan][]) + +You can also use `TestProf::FactoryDefault.disable!(&block)`. + ## 1.0.11 (2022-10-27) - Fix monitoring methods with keyword args in Ruby 3+. ([@palkan][]) diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index f2499ac6..25978c2c 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -128,3 +128,14 @@ and set a default for `user` factory - you will find the same object used in all To prevent this - set `FactoryDefault.preserve_traits = true` or use per-factory override `create_default(:user, preserve_traits: true)`. This reverts back to original FactoryBot behavior for associations that have explicit traits defined. + +### Ignoring default factories + +You can temporary disable the defaults usage by wrapping a code with the `skip_factory_default` method: + +```ruby +account = create_default(:account) +another_account = skip_factory_default { create(:account) } + +expect(another_account).not_to eq(account) +``` diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 101f164a..8c1a04ec 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -20,6 +20,10 @@ def create_default(name, *args, &block) def set_factory_default(name, obj, preserve_traits: nil) FactoryDefault.register(name, obj, preserve_traits: preserve_traits) end + + def skip_factory_default(&block) + FactoryDefault.disable!(&block) + end end class << self @@ -32,6 +36,7 @@ def init TestProf::FactoryBot::Strategy::Build.prepend StrategyExt TestProf::FactoryBot::Strategy::Stub.prepend StrategyExt + @enabled = true # default is false to retain backward compatibility @preserve_traits = false end @@ -43,6 +48,8 @@ def register(name, obj, **options) end def get(name, traits = nil) + return unless enabled? + record = store[name] return unless record @@ -60,6 +67,28 @@ def reset store.clear end + def enabled? + @enabled + end + + def enable! + was_enabled = @enabled + @enabled = true + return unless block_given? + yield + ensure + @enabled = was_enabled + end + + def disable! + was_enabled = @enabled + @enabled = false + return unless block_given? + yield + ensure + @enabled = was_enabled + end + private def store diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index 638f22ec..4c2364c0 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -110,6 +110,10 @@ class Post < ActiveRecord::Base user { create(:user) } end + trait :with_tagged_user do + association :user, tag: "some tag" + end + trait :with_traited_user do association :user, factory: %i[user traited] end diff --git a/spec/test_prof/factory_default_spec.rb b/spec/test_prof/factory_default_spec.rb new file mode 100644 index 00000000..3d22101e --- /dev/null +++ b/spec/test_prof/factory_default_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +# Init FactoryDefault +require "test_prof/factory_default" + +TestProf::FactoryDefault.init +TestProf::FactoryDefault.disable! + +describe TestProf::FactoryDefault, :transactional do + before { described_class.enable! } + after do + described_class.reset + described_class.disable! + end + + let!(:user) { TestProf::FactoryBot.create_default(:user) } + + it "re-uses the same default record" do + post = TestProf::FactoryBot.create(:post) + + expect(post.user).to eq user + end + + it "re-uses default record independently of traits" do + post = TestProf::FactoryBot.create(:post, :with_traited_user) + + expect(post.user).to eq user + end + + it "re-uses default record independently of attributes" do + post = TestProf::FactoryBot.create(:post, :with_tagged_user) + + expect(post.user).to eq user + end + + specify ".disable!(&block)" do + post = TestProf::FactoryBot.skip_factory_default { TestProf::FactoryBot.create(:post) } + expect(post.user).not_to eq(user) + end + + context "when preserve_traits = true" do + before { described_class.preserve_traits = true } + after { described_class.preserve_traits = false } + + it "ignores default when trait is specified" do + post = TestProf::FactoryBot.create_default(:post) + post_traited = TestProf::FactoryBot.create(:post, :with_traited_user) + + expect(post.user).to eq user + expect(post_traited.user).not_to eq user + end + end + + xcontext "when preserve_attributes = true" do + before { described_class.preserve_attributes = true } + after { described_class.preserve_attributes = false } + + it "ignores default when explicit attributes don't match" do + post = TestProf::FactoryBot.create_default(:post) + user_2 = TestProf::FactoryBot.create(:user, tag: "another") + post_2 = TestProf::FactoryBot.create(:post, user: user_2) + + expect(post.user).to eq user + expect(post_2.user).to eq user_2 + expect(post_2).not_to eq post + end + + it "re-uses default when attributes match" do + post = TestProf::FactoryBot.create_default(:post, text: "Test") + post_2 = TestProf::FactoryBot.create(:post, text: "Test") + + expect(post_2).to eq post + end + end +end From 4611b7208c459e5bcc94005ab13f3eaddd11b199 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 25 Nov 2022 21:00:23 -0500 Subject: [PATCH 054/194] feat(factory_default): add preserve_attributes support --- CHANGELOG.md | 10 ++++++ docs/recipes/factory_default.md | 26 ++++++++++++++ lib/test_prof/factory_default.rb | 34 ++++++++++++++----- .../factory_default/factory_bot_patch.rb | 10 ++---- spec/test_prof/factory_default_spec.rb | 33 ++++++++++-------- 5 files changed, 81 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcdede08..c11a2140 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ ## master (unreleased) +- FactoryDefault: Add `preserve_attributes = false | true` option. ([@palkan][]) + +Allow skipping defaults if association is defined with overrides, e.g.: + +```ruby +factory :post do + association :user, name: "Post Author" +end +``` + - FactoryDefault: Add `skip_factory_default(&block)` to temporary disable default factories. ([@palkan][]) You can also use `TestProf::FactoryDefault.disable!(&block)`. diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index 25978c2c..4d50c131 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -129,6 +129,32 @@ and set a default for `user` factory - you will find the same object used in all To prevent this - set `FactoryDefault.preserve_traits = true` or use per-factory override `create_default(:user, preserve_traits: true)`. This reverts back to original FactoryBot behavior for associations that have explicit traits defined. +### Handling attribute overrides + +It's possible to define attribute overrides for associations: + +```ruby +factory :post do + association :user, name: "Poster" +end + +factory :view do + association :user, name: "Viewer" +end +``` + +FactoryDefault ignores such overrides and still returns a default `user` record (if created). You can turn the attribute awareness feature on to skip the default record if overrides don't match the default object attributes: + +```ruby +# Globally +FactoryDefault.preserve_attributes = true + +# or in-place +create_default :user, preserve_attributes: true +``` + +**NOTE:** In the future versions of Test Prof, both `preserve_traits` and `preserve_attributes` will default to true. We recommend settings them to true if you just starting using this feature. + ### Ignoring default factories You can temporary disable the defaults usage by wrapping a code with the `skip_factory_default` method: diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 8c1a04ec..08972968 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -11,14 +11,20 @@ module FactoryDefault module DefaultSyntax # :nodoc: def create_default(name, *args, &block) options = args.extract_options! - preserve = options.delete(:preserve_traits) + default_options = {} + default_options[:preserve_traits] = options.delete(:preserve_traits) if options.key?(:preserve_traits) + default_options[:preserve_attributes] = options.delete(:preserve_attributes) if options.key?(:preserve_attributes) obj = TestProf::FactoryBot.create(name, *args, options, &block) - set_factory_default(name, obj, preserve_traits: preserve) + set_factory_default(name, obj, **default_options) end - def set_factory_default(name, obj, preserve_traits: nil) - FactoryDefault.register(name, obj, preserve_traits: preserve_traits) + def set_factory_default(name, obj, preserve_traits: FactoryDefault.preserve_traits, preserve_attributes: FactoryDefault.preserve_attributes) + FactoryDefault.register( + name, obj, + preserve_traits: preserve_traits, + preserve_attributes: preserve_attributes + ) end def skip_factory_default(&block) @@ -27,7 +33,7 @@ def skip_factory_default(&block) end class << self - attr_accessor :preserve_traits + attr_accessor :preserve_traits, :preserve_attributes def init TestProf::FactoryBot::Syntax::Methods.include DefaultSyntax @@ -39,24 +45,34 @@ def init @enabled = true # default is false to retain backward compatibility @preserve_traits = false + @preserve_attributes = false end def register(name, obj, **options) - options[:preserve_traits] = true if FactoryDefault.preserve_traits store[name] = {object: obj, **options} obj end - def get(name, traits = nil) + def get(name, traits = nil, overrides = nil) return unless enabled? record = store[name] return unless record if traits && !traits.empty? - return if FactoryDefault.preserve_traits || record[:preserve_traits] + return if record[:preserve_traits] end - record[:object] + + object = record[:object] + + if overrides && !overrides.empty? && record[:preserve_attributes] + overrides.each do |name, value| + return unless object.respond_to?(name) # rubocop:disable Lint/NonLocalExitFromIterator + return if object.public_send(name) != value # rubocop:disable Lint/NonLocalExitFromIterator + end + end + + object end def remove(name) diff --git a/lib/test_prof/factory_default/factory_bot_patch.rb b/lib/test_prof/factory_default/factory_bot_patch.rb index 065d8c59..c483155f 100644 --- a/lib/test_prof/factory_default/factory_bot_patch.rb +++ b/lib/test_prof/factory_default/factory_bot_patch.rb @@ -4,13 +4,7 @@ module TestProf module FactoryDefault # :nodoc: all module RunnerExt refine TestProf::FactoryBot::FactoryRunner do - def name - @name - end - - def traits - @traits - end + attr_reader :name, :traits, :overrides end end @@ -18,7 +12,7 @@ def traits module StrategyExt def association(runner) - FactoryDefault.get(runner.name, runner.traits) || super + FactoryDefault.get(runner.name, runner.traits, runner.overrides) || super end end end diff --git a/spec/test_prof/factory_default_spec.rb b/spec/test_prof/factory_default_spec.rb index 3d22101e..820adfbd 100644 --- a/spec/test_prof/factory_default_spec.rb +++ b/spec/test_prof/factory_default_spec.rb @@ -7,7 +7,15 @@ TestProf::FactoryDefault.disable! describe TestProf::FactoryDefault, :transactional do - before { described_class.enable! } + let(:preserve_traits) { false } + let(:preserve_attributes) { false } + + before do + described_class.enable! + described_class.preserve_traits = preserve_traits + described_class.preserve_attributes = preserve_attributes + end + after do described_class.reset described_class.disable! @@ -39,8 +47,7 @@ end context "when preserve_traits = true" do - before { described_class.preserve_traits = true } - after { described_class.preserve_traits = false } + let(:preserve_traits) { true } it "ignores default when trait is specified" do post = TestProf::FactoryBot.create_default(:post) @@ -51,25 +58,21 @@ end end - xcontext "when preserve_attributes = true" do - before { described_class.preserve_attributes = true } - after { described_class.preserve_attributes = false } + context "when preserve_attributes = true" do + let(:preserve_attributes) { true } it "ignores default when explicit attributes don't match" do - post = TestProf::FactoryBot.create_default(:post) - user_2 = TestProf::FactoryBot.create(:user, tag: "another") - post_2 = TestProf::FactoryBot.create(:post, user: user_2) + post = TestProf::FactoryBot.create(:post, :with_tagged_user) - expect(post.user).to eq user - expect(post_2.user).to eq user_2 - expect(post_2).not_to eq post + expect(post.user).not_to eq user end it "re-uses default when attributes match" do - post = TestProf::FactoryBot.create_default(:post, text: "Test") - post_2 = TestProf::FactoryBot.create(:post, text: "Test") + user.update!(tag: "some tag") + + post = TestProf::FactoryBot.create(:post, :with_tagged_user) - expect(post_2).to eq post + expect(post.user).to eq user end end end From 03dacfb144fdf055f5d801db445c6399f927eb35 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 25 Nov 2022 21:46:06 -0500 Subject: [PATCH 055/194] refactor(factory_default): add configuration object --- docs/recipes/factory_default.md | 21 +++++++++--- lib/test_prof/factory_default.rb | 32 ++++++++++++++++--- .../fixtures/rspec/factory_default_fixture.rb | 13 ++++++-- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index 4d50c131..e1c584b8 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -112,7 +112,7 @@ before { FactoryBot.set_factory_default(:user, user) } ### Working with traits -When you have traits in your associations like: +You can use traits in your associations, for example: ```ruby factory :post do @@ -124,10 +124,19 @@ factory :view do end ``` -and set a default for `user` factory - you will find the same object used in all of the above factories. Sometimes this may break your logic. +If there is a default value for the `user` factory, it's gonna be used independently of traits. This may break your logic. -To prevent this - set `FactoryDefault.preserve_traits = true` or use per-factory override -`create_default(:user, preserve_traits: true)`. This reverts back to original FactoryBot behavior for associations that have explicit traits defined. +To prevent this, configure FactoryDefault to preserve traits: + +```ruby +# Globally +TestProf::FactoryDefault.configure do |config| + config.preserve_traits = true +end + +# or in-place +create_default(:user, preserve_traits: true) +``` ### Handling attribute overrides @@ -147,7 +156,9 @@ FactoryDefault ignores such overrides and still returns a default `user` record ```ruby # Globally -FactoryDefault.preserve_attributes = true +TestProf::FactoryDefault.configure do |config| + config.preserve_attributes = true +end # or in-place create_default :user, preserve_attributes: true diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 08972968..2f4818f3 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -19,7 +19,7 @@ def create_default(name, *args, &block) set_factory_default(name, obj, **default_options) end - def set_factory_default(name, obj, preserve_traits: FactoryDefault.preserve_traits, preserve_attributes: FactoryDefault.preserve_attributes) + def set_factory_default(name, obj, preserve_traits: FactoryDefault.config.preserve_traits, preserve_attributes: FactoryDefault.config.preserve_attributes) FactoryDefault.register( name, obj, preserve_traits: preserve_traits, @@ -32,9 +32,17 @@ def skip_factory_default(&block) end end - class << self + class Configuration attr_accessor :preserve_traits, :preserve_attributes + def initialize + # TODO(v2): Switch to true + @preserve_traits = false + @preserve_attributes = false + end + end + + class << self def init TestProf::FactoryBot::Syntax::Methods.include DefaultSyntax TestProf::FactoryBot.extend DefaultSyntax @@ -43,9 +51,23 @@ def init TestProf::FactoryBot::Strategy::Stub.prepend StrategyExt @enabled = true - # default is false to retain backward compatibility - @preserve_traits = false - @preserve_attributes = false + end + + def config + @config ||= Configuration.new + end + + def configure + yield config + end + + # TODO(v2): drop + def preserve_traits=(val) + config.preserve_traits = val + end + + def preserve_attributes=(val) + config.preserve_attributes = val end def register(name, obj, **options) diff --git a/spec/integrations/fixtures/rspec/factory_default_fixture.rb b/spec/integrations/fixtures/rspec/factory_default_fixture.rb index d8eadc1d..a4613d06 100644 --- a/spec/integrations/fixtures/rspec/factory_default_fixture.rb +++ b/spec/integrations/fixtures/rspec/factory_default_fixture.rb @@ -47,7 +47,11 @@ let(:traited_user) { TestProf::FactoryBot.create_default(:user, :traited, tag: "foo") } context "global setting" do - before { TestProf::FactoryDefault.preserve_traits = true } + before do + TestProf::FactoryDefault.configure do |config| + config.preserve_traits = true + end + end it "can still be set default" do expect(traited_user.tag).to eq "foo" @@ -66,7 +70,12 @@ end context "local override" do - before { TestProf::FactoryDefault.preserve_traits = false } + before do + TestProf::FactoryDefault.configure do |config| + config.preserve_traits = false + end + end + let(:override_user) { TestProf::FactoryBot.create_default(:user, preserve_traits: true) } let(:other_traited_post) { TestProf::FactoryBot.create(:post, :with_traited_user) } From 1a67ad3777e2f952df4c589758a4aeb3a91133a7 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 25 Nov 2022 22:26:27 -0500 Subject: [PATCH 056/194] feat: make factory default before_all-compatible --- CHANGELOG.md | 4 ++ docs/recipes/factory_default.md | 10 ++++- lib/test_prof/before_all.rb | 18 ++++---- lib/test_prof/factory_default.rb | 12 +++-- lib/test_prof/recipes/rspec/before_all.rb | 8 ++-- .../recipes/rspec/factory_default.rb | 19 +++++++- spec/integrations/factory_default_spec.rb | 6 +++ .../factory_default_let_it_be_fixture.rb | 44 +++++++++++++++++++ 8 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 spec/integrations/fixtures/rspec/factory_default_let_it_be_fixture.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index c11a2140..c17101e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +- Support using FactoryDefault with before_all/let_it_be. ([@palkan][]) + +Currently, RSpec only. Default factories created within `before_all` or `let_it_be` are not reset 'till the end of the corresponding context. Thus, now it's possible to use `create_default` within `let_it_be` without any additional hacks. + - FactoryDefault: Add `preserve_attributes = false | true` option. ([@palkan][]) Allow skipping defaults if association is defined with overrides, e.g.: diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index e1c584b8..41290c42 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -108,7 +108,15 @@ before { FactoryBot.set_factory_default(:user, user) } - `FactoryBot#create_default(factory, *args)` – is a shortcut for `create` + `set_factory_default`. -**NOTE**. Defaults are **cleaned up after each example** by default. That means you cannot create defaults within `before(:all)` / [`before_all`](./before_all.md) / [`let_it_be`](./let_it_be.md) definitions. That could be changed in the future, for now [check this workaround](https://github.com/test-prof/test-prof/issues/125#issuecomment-471706752). +**IMPORTANT:** Defaults are **cleaned up after each example** by default (i.e., when using `test_prof/recipes/rspec/factory_default`). + +### Using with `before_all` / `let_it_be` + +Defaults created within `before_all` and `let_it_be` are not reset after each example, but only at the end of the corresponding example group. So, it's possible to call `create_defatul` within `let_it_be` without any additional configuration. **RSpec only** + +**IMPORTANT:** You must load FactoryDefault after loading BeforeAll to make this feature work. + +**NOTE**. Regulart `before(:all)` callbacks are not supported. ### Working with traits diff --git a/lib/test_prof/before_all.rb b/lib/test_prof/before_all.rb index e12b1f4b..42016f9e 100644 --- a/lib/test_prof/before_all.rb +++ b/lib/test_prof/before_all.rb @@ -17,19 +17,19 @@ def initialize class << self attr_accessor :adapter - def begin_transaction + def begin_transaction(scope = nil) raise AdapterMissing if adapter.nil? - config.run_hooks(:begin) do + config.run_hooks(:begin, scope) do adapter.begin_transaction end yield end - def rollback_transaction + def rollback_transaction(scope = nil) raise AdapterMissing if adapter.nil? - config.run_hooks(:rollback) do + config.run_hooks(:rollback, scope) do adapter.rollback_transaction end end @@ -58,10 +58,10 @@ def initialize(type) @after = [] end - def run - before.each(&:call) + def run(scope = nil) + before.each { |clbk| clbk.call(scope) } yield - after.each(&:call) + after.each { |clbk| clbk.call(scope) } end end @@ -93,9 +93,9 @@ def after(type, &block) hooks[type].after << block if block end - def run_hooks(type) # :nodoc: + def run_hooks(type, scope = nil) # :nodoc: validate_hook_type!(type) - hooks[type].run { yield } + hooks[type].run(scope) { yield } end private diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 2f4818f3..c082d99d 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -43,6 +43,8 @@ def initialize end class << self + attr_accessor :current_context + def init TestProf::FactoryBot::Syntax::Methods.include DefaultSyntax TestProf::FactoryBot.extend DefaultSyntax @@ -71,7 +73,7 @@ def preserve_attributes=(val) end def register(name, obj, **options) - store[name] = {object: obj, **options} + store[name] = {object: obj, context: current_context, **options} obj end @@ -101,8 +103,12 @@ def remove(name) store.delete(name) end - def reset - store.clear + def reset(context: nil) + return store.clear unless context + + store.delete_if do |_name, metadata| + metadata[:context] == context + end end def enabled? diff --git a/lib/test_prof/recipes/rspec/before_all.rb b/lib/test_prof/recipes/rspec/before_all.rb index 44060939..2c0a00e9 100644 --- a/lib/test_prof/recipes/rspec/before_all.rb +++ b/lib/test_prof/recipes/rspec/before_all.rb @@ -17,23 +17,23 @@ def before_all(setup_fixtures: BeforeAll.config.setup_fixtures, &block) return end - @__before_all_activated__ = true + @__before_all_activation__ = context = self before(:all) do @__inspect_output = "before_all hook" BeforeAll.setup_fixtures(self) if setup_fixtures - BeforeAll.begin_transaction do + BeforeAll.begin_transaction(context) do instance_eval(&block) end end after(:all) do - BeforeAll.rollback_transaction + BeforeAll.rollback_transaction(context) end end def within_before_all? - instance_variable_defined?(:@__before_all_activated__) + instance_variable_defined?(:@__before_all_activation__) end end end diff --git a/lib/test_prof/recipes/rspec/factory_default.rb b/lib/test_prof/recipes/rspec/factory_default.rb index c56f85cd..bc712630 100644 --- a/lib/test_prof/recipes/rspec/factory_default.rb +++ b/lib/test_prof/recipes/rspec/factory_default.rb @@ -4,6 +4,23 @@ TestProf::FactoryDefault.init +if defined?(TestProf::BeforeAll) + TestProf::BeforeAll.configure do |config| + config.before(:begin) do |context| + TestProf::FactoryDefault.current_context = context + end + + config.after(:rollback) do |context| + TestProf::FactoryDefault.reset(context: context) + end + end +end + RSpec.configure do |config| - config.after(:each) { TestProf::FactoryDefault.reset } + if defined?(TestProf::BeforeAll) + config.before(:each) { TestProf::FactoryDefault.current_context = :example } + config.after(:each) { TestProf::FactoryDefault.reset(context: :example) } + else + config.after(:each) { TestProf::FactoryDefault.reset } + end end diff --git a/spec/integrations/factory_default_spec.rb b/spec/integrations/factory_default_spec.rb index b773da3b..2f5d7143 100644 --- a/spec/integrations/factory_default_spec.rb +++ b/spec/integrations/factory_default_spec.rb @@ -6,4 +6,10 @@ expect(output).to include("0 failures") end + + specify "let_it_be integration", :aggregate_failures do + output = run_rspec("factory_default_let_it_be") + + expect(output).to include("0 failures") + end end diff --git a/spec/integrations/fixtures/rspec/factory_default_let_it_be_fixture.rb b/spec/integrations/fixtures/rspec/factory_default_let_it_be_fixture.rb new file mode 100644 index 00000000..d795eb04 --- /dev/null +++ b/spec/integrations/fixtures/rspec/factory_default_let_it_be_fixture.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require_relative "../../../support/ar_models" +require_relative "../../../support/transactional_context" + +require "test_prof/recipes/rspec/let_it_be" +require "test_prof/recipes/rspec/factory_default" + +describe "Post" do + let(:post) { TestProf::FactoryBot.create(:post) } + + context "with let_it_be" do + let_it_be(:user) { TestProf::FactoryBot.create_default(:user) } + + it "creates post with the same user" do + user + expect { post }.not_to change(User, :count) + expect(post.user).to eq user + end + + it "still uses the default from let_it_be" do + expect { post }.not_to change(User, :count) + end + + context "when nested" do + let_it_be(:post) { TestProf::FactoryBot.create_default(:post) } + + it "still uses the default from let_it_be" do + expect { post }.not_to change(User, :count) + end + + it "default is used within let_it_be" do + expect(post.user).to eq user + end + end + end + + context "without let_it_be" do + it "creates a new record" do + expect { post }.to change(User, :count).by(1) + end + end +end From 0faa354c3b3fc5c943d351188cdf21f4f6d957f3 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Sat, 26 Nov 2022 22:11:45 -0500 Subject: [PATCH 057/194] feat(factory_default): add stats --- CHANGELOG.md | 5 ++ docs/recipes/factory_default.md | 22 +++++ lib/test_prof/factory_default.rb | 83 +++++++++++++++++-- .../recipes/rspec/factory_default.rb | 2 + 4 files changed, 105 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c17101e9..be534ec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## master (unreleased) +- FactoryDefault: Add stats support. ([@palkan][]) + +Now you can see how often the default factory values have been used by specifying +the `FACTORY_DEFAULT_SUMMARY=1` or `FACTORY_DEFAULT_STATS=1` env var. + - Support using FactoryDefault with before_all/let_it_be. ([@palkan][]) Currently, RSpec only. Default factories created within `before_all` or `let_it_be` are not reset 'till the end of the corresponding context. Thus, now it's possible to use `create_default` within `let_it_be` without any additional hacks. diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index 41290c42..2ca35662 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -184,3 +184,25 @@ another_account = skip_factory_default { create(:account) } expect(another_account).not_to eq(account) ``` + +### Showing usage stats + +You can display the FactoryDefault usage stats by setting the `FACTORY_DEFAULT_SUMMARY=1` or `FACTORY_DEFAULT_STATS=1` env vars or by setting the configuration values: + +```ruby +TestProf::FactoryDefault.configure do |config| + config.report_summary = true + # Report stats prints the detailed usage information (including summary) + config.report_stats = true +end +``` + +For example: + +```sh +$ FACTORY_DEFAULT_SUMMARY=1 bundle exec rspec + +FactoryDefault summary: hit=11 miss=3 +``` + +Where `hit` indicates the number of times the default factory value was used instead of a new one when an association was created; `miss` indicates the number of time the default value was ignored due to traits or attributes mismatch. diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index c082d99d..f6c4adc1 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -3,11 +3,14 @@ require "test_prof" require "test_prof/factory_bot" require "test_prof/factory_default/factory_bot_patch" +require "test_prof/ext/float_duration" module TestProf # FactoryDefault allows use to re-use associated objects # in factories implicilty module FactoryDefault + using FloatDuration + module DefaultSyntax # :nodoc: def create_default(name, *args, &block) options = args.extract_options! @@ -16,14 +19,16 @@ def create_default(name, *args, &block) default_options[:preserve_attributes] = options.delete(:preserve_attributes) if options.key?(:preserve_attributes) obj = TestProf::FactoryBot.create(name, *args, options, &block) + set_factory_default(name, obj, **default_options) end - def set_factory_default(name, obj, preserve_traits: FactoryDefault.config.preserve_traits, preserve_attributes: FactoryDefault.config.preserve_attributes) + def set_factory_default(name, obj, preserve_traits: FactoryDefault.config.preserve_traits, preserve_attributes: FactoryDefault.config.preserve_attributes, **other) FactoryDefault.register( name, obj, preserve_traits: preserve_traits, - preserve_attributes: preserve_attributes + preserve_attributes: preserve_attributes, + **other ) end @@ -33,17 +38,23 @@ def skip_factory_default(&block) end class Configuration - attr_accessor :preserve_traits, :preserve_attributes + attr_accessor :preserve_traits, :preserve_attributes, + :report_summary, :report_stats def initialize # TODO(v2): Switch to true @preserve_traits = false @preserve_attributes = false + @report_summary = ENV["FACTORY_DEFAULT_SUMMARY"] == "1" + @report_stats = ENV["FACTORY_DEFAULT_STATS"] == "1" end end class << self + include Logging + attr_accessor :current_context + attr_reader :stats def init TestProf::FactoryBot::Syntax::Methods.include DefaultSyntax @@ -52,7 +63,8 @@ def init TestProf::FactoryBot::Strategy::Build.prepend StrategyExt TestProf::FactoryBot::Strategy::Stub.prepend StrategyExt - @enabled = true + @enabled = ENV["FACTORY_DEFAULT_DISABLED"] != "1" + @stats = {} end def config @@ -74,6 +86,7 @@ def preserve_attributes=(val) def register(name, obj, **options) store[name] = {object: obj, context: current_context, **options} + stats[name] ||= {hit: 0, miss: 0} obj end @@ -83,8 +96,10 @@ def get(name, traits = nil, overrides = nil) record = store[name] return unless record - if traits && !traits.empty? - return if record[:preserve_traits] + stats[name][:miss] += 1 + + if traits && !traits.empty? && record[:preserve_traits] + return end object = record[:object] @@ -96,6 +111,9 @@ def get(name, traits = nil, overrides = nil) end end + stats[name][:miss] -= 1 + stats[name][:hit] += 1 + object end @@ -133,10 +151,61 @@ def disable! @enabled = was_enabled end + def print_report + return unless config.report_stats || config.report_summary + + if stats.empty? + log :info, "FactoryDefault has not been used" + return + end + + msgs = [] + + if config.report_stats + msgs << + <<~MSG + FactoryDefault usage stats: + MSG + + first_column = stats.keys.map(&:size).max + 2 + + msgs << format( + "%#{first_column}s %9s %9s", + "factory", "hit", "miss" + ) + + msgs << "" + end + + total_hit = 0 + total_miss = 0 + + stats.to_a.sort_by { |(_, v)| -v[:hit] }.each do |(key, record_stats)| + total_hit += record_stats[:hit] + total_miss += record_stats[:miss] + + if config.report_stats + msgs << format( + "%#{first_column}s %9d %9d", + key, record_stats[:hit], record_stats[:miss] + ) + end + end + + msgs << "" if config.report_stats + + msgs << + <<~MSG + FactoryDefault summary: hit=#{total_hit} miss=#{total_miss} + MSG + + log :info, msgs.join("\n") + end + private def store - Thread.current[:testprof_factory_store] ||= {} + Thread.current[:testprof_factory_default_store] ||= {} end end end diff --git a/lib/test_prof/recipes/rspec/factory_default.rb b/lib/test_prof/recipes/rspec/factory_default.rb index bc712630..ca4601ae 100644 --- a/lib/test_prof/recipes/rspec/factory_default.rb +++ b/lib/test_prof/recipes/rspec/factory_default.rb @@ -23,4 +23,6 @@ else config.after(:each) { TestProf::FactoryDefault.reset } end + + config.after(:suite) { TestProf::FactoryDefault.print_report } end From cacd8f5c6de9a5ab2127f534a7a41ee7131e836f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Sun, 27 Nov 2022 19:02:32 -0500 Subject: [PATCH 058/194] feat(factory_default): per-trait defaults --- CHANGELOG.md | 4 ++++ docs/recipes/factory_default.md | 18 ++++++++++++++ lib/test_prof/factory_default.rb | 33 ++++++++++++++++++++++++-- spec/test_prof/factory_default_spec.rb | 12 ++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be534ec1..8b6b6348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +- FactoryDefault: Allow creating a default per trait (or set of traits). ([@palkan][]) + +Now `create_default(:user)` and `create_default(:user, :admin)` would result into two defaults corresponding to the specified traits. + - FactoryDefault: Add stats support. ([@palkan][]) Now you can see how often the default factory values have been used by specifying diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index 2ca35662..a9e419c5 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -123,6 +123,10 @@ Defaults created within `before_all` and `let_it_be` are not reset after each ex You can use traits in your associations, for example: ```ruby +factory :comment do + user +end + factory :post do association :user, factory: %i[user able_to_post] end @@ -146,6 +150,20 @@ end create_default(:user, preserve_traits: true) ``` +Creating a default with trait works as follows: + +```ruby +# Create a default with trait +user = create_default(:user_poster, :able_to_post) + +# When an association has no traits specified, the default with trait is used +create(:comment).user == user #=> true +# When an association has the matching trait specified, the default is used, too +create(:post).user == user #=> true +# When the association's trait differs, default is skipped +create(:view).user == user #=> false +``` + ### Handling attribute overrides It's possible to define attribute overrides for associations: diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index f6c4adc1..ebb65173 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -20,6 +20,9 @@ def create_default(name, *args, &block) obj = TestProf::FactoryBot.create(name, *args, options, &block) + # Factory with traits + name = [name, *args] if args.any? + set_factory_default(name, obj, **default_options) end @@ -85,8 +88,13 @@ def preserve_attributes=(val) end def register(name, obj, **options) - store[name] = {object: obj, context: current_context, **options} - stats[name] ||= {hit: 0, miss: 0} + # Name with traits + if name.is_a?(Array) + register_traited_record(*name, obj, **options) + else + register_default_record(name, obj, **options) + end + obj end @@ -96,6 +104,12 @@ def get(name, traits = nil, overrides = nil) record = store[name] return unless record + if traits && (trait_key = record[:traits][traits]) + name = trait_key + record = store[name] + traits = nil + end + stats[name][:miss] += 1 if traits && !traits.empty? && record[:preserve_traits] @@ -204,6 +218,21 @@ def print_report private + def register_default_record(name, obj, **options) + store[name] = {object: obj, traits: {}, context: current_context, **options} + stats[name] ||= {hit: 0, miss: 0} + end + + def register_traited_record(name, *traits, obj, **options) + name_with_traits = "#{name}[#{traits.join(",")}]" + + register_default_record(name_with_traits, obj, **options) + register_default_record(name, obj, **options) unless store[name] + + # Add reference to the traited default to the original default record + store[name][:traits][traits] = name_with_traits + end + def store Thread.current[:testprof_factory_default_store] ||= {} end diff --git a/spec/test_prof/factory_default_spec.rb b/spec/test_prof/factory_default_spec.rb index 820adfbd..e25d0f0e 100644 --- a/spec/test_prof/factory_default_spec.rb +++ b/spec/test_prof/factory_default_spec.rb @@ -56,6 +56,18 @@ expect(post.user).to eq user expect(post_traited.user).not_to eq user end + + context "when has default with the trait" do + let!(:traited_user) { TestProf::FactoryBot.create_default(:user, :traited) } + + it "re-uses default record for this trait" do + post = TestProf::FactoryBot.create_default(:post) + post_traited = TestProf::FactoryBot.create(:post, :with_traited_user) + + expect(post.user).to eq user + expect(post_traited.user).to eq traited_user + end + end end context "when preserve_attributes = true" do From 5d3502f9177c17d2a048abeeb163174b963c2deb Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Sun, 27 Nov 2022 19:51:46 -0500 Subject: [PATCH 059/194] feat: add factory_default profiling --- CHANGELOG.md | 2 + docs/recipes/factory_default.md | 28 ++++ lib/test_prof/factory_default.rb | 137 +++++++++++++++++- .../factory_default/factory_bot_patch.rb | 3 +- spec/integrations/factory_default_spec.rb | 49 ++++++- .../rspec/factory_default_analyze_fixture.rb | 42 ++++++ 6 files changed, 250 insertions(+), 11 deletions(-) create mode 100644 spec/integrations/fixtures/rspec/factory_default_analyze_fixture.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b6b6348..7a248890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Add FactoryDefault profiler (factory associations profilers). ([@palkan][]) + - FactoryDefault: Allow creating a default per trait (or set of traits). ([@palkan][]) Now `create_default(:user)` and `create_default(:user, :admin)` would result into two defaults corresponding to the specified traits. diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index a9e419c5..6dab5b8a 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -224,3 +224,31 @@ FactoryDefault summary: hit=11 miss=3 ``` Where `hit` indicates the number of times the default factory value was used instead of a new one when an association was created; `miss` indicates the number of time the default value was ignored due to traits or attributes mismatch. + +## Factory Default profiling, or when to use defaults? + +Factory Default ships with the profiler, which can help you to see how associations are beeing used in your test suite, so you can decide on using `create_default` or not. + +To enable profiling, run your tests with the `FACTORY_DEFAULT_PROF=1` set: + +```sh +$ FACTORY_DEFAULT_PROF=1 bundle exec rspec spec/some/file_spec.rb + +..... + +[TEST PROF INFO] Factory associations usage: + + factory count total time + + user 17 00:42.010 + user[traited] 15 00:31.560 + user{tag:"some tag"} 1 00:00.205 + +Total associations created: 33 +Total uniq associations created: 3 +Total time spent: 01:13.775 +``` + +Since default factories are usually registered per an example group (or test class), we recommend running this profiler against a particular file, so you can quickly identify the possibility of adding `create_default` and improve the tests speed. + +**NOTE:** You can also use the profiler to measure the effect of adding `create_default`; for that, compare the results of running the profiler with FactoryDefault enabled and disabled (you can do that by passing the `FACTORY_DEFAULT_DISABLED=1` env var). diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index ebb65173..8119beef 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -11,6 +11,133 @@ module TestProf module FactoryDefault using FloatDuration + using(Module.new do + refine Object do + def to_override_key + "<#{self.class.name}::$id$#{object_id}$di$>" + end + end + + if defined?(::ActiveRecord::Base) + refine ::ActiveRecord::Base do + def to_override_key + "<#{self.class.name}\#$id$#{public_send(self.class.primary_key)}$di$>" + end + end + end + + [ + String, + Integer, + Float, + FalseClass, + TrueClass, + NilClass, + Regexp + ].each do |mod| + refine(mod) do + def to_override_key + inspect + end + end + end + end) + + class Profiler + include Logging + + attr_reader :data + + def initialize + @data = Hash.new { |h, k| h[k] = {count: 0, time: 0.0} } + end + + def instrument(name, traits, overrides) + start = TestProf.now + yield.tap do + time = TestProf.now - start + key = build_association_name(name, traits, overrides) + data[key][:count] += 1 + data[key][:time] += time + end + end + + def print_report + if data.empty? + log :info, "FactoryDefault profiler collected no data" + return + end + + # Merge object overrides into one stats record + data = self.data.each_with_object({}) do |(name, stats), acc| + name = name.gsub(/\$id\$.+\$di\$/, "") + if acc.key?(name) + acc[name][:count] += stats[:count] + acc[name][:time] += stats[:time] + else + acc[name] = stats + end + end + + msgs = [] + + msgs << + <<~MSG + Factory associations usage: + MSG + + first_column = data.keys.map(&:size).max + 2 + + msgs << format( + "%#{first_column}s %9s %12s", + "factory", "count", "total time" + ) + + msgs << "" + + total_count = 0 + total_time = 0.0 + + data.to_a.sort_by { |(_, v)| -v[:time] }.each do |(key, factory_stats)| + total_count += factory_stats[:count] + total_time += factory_stats[:time] + + msgs << format( + "%#{first_column}s %9d %12s", + key, factory_stats[:count], factory_stats[:time].duration + ) + end + + msgs << + <<~MSG + + Total associations created: #{total_count} + Total uniq associations created: #{data.size} + Total time spent: #{total_time.duration} + + MSG + + log :info, msgs.join("\n") + end + + private + + def build_association_name(name, traits, overrides) + traits_str = "[#{traits.join(",")}]" if traits&.any? + overrides_str = "{#{overrides.map { |k, v| "#{k}:#{v.to_override_key}" }.join(",")}}" if overrides&.any? + "#{name}#{traits_str}#{overrides_str}" + end + end + + class NoopProfiler + def instrument(*) + yield + end + + def print_report + end + end + module DefaultSyntax # :nodoc: def create_default(name, *args, &block) options = args.extract_options! @@ -42,12 +169,16 @@ def skip_factory_default(&block) class Configuration attr_accessor :preserve_traits, :preserve_attributes, - :report_summary, :report_stats + :report_summary, :report_stats, + :profiling_enabled + + alias_method :profiling_enabled?, :profiling_enabled def initialize # TODO(v2): Switch to true @preserve_traits = false @preserve_attributes = false + @profiling_enabled = ENV["FACTORY_DEFAULT_PROF"] == "1" @report_summary = ENV["FACTORY_DEFAULT_SUMMARY"] == "1" @report_stats = ENV["FACTORY_DEFAULT_STATS"] == "1" end @@ -57,7 +188,7 @@ class << self include Logging attr_accessor :current_context - attr_reader :stats + attr_reader :stats, :profiler def init TestProf::FactoryBot::Syntax::Methods.include DefaultSyntax @@ -66,6 +197,7 @@ def init TestProf::FactoryBot::Strategy::Build.prepend StrategyExt TestProf::FactoryBot::Strategy::Stub.prepend StrategyExt + @profiler = config.profiling_enabled? ? Profiler.new : NoopProfiler.new @enabled = ENV["FACTORY_DEFAULT_DISABLED"] != "1" @stats = {} end @@ -166,6 +298,7 @@ def disable! end def print_report + profiler.print_report return unless config.report_stats || config.report_summary if stats.empty? diff --git a/lib/test_prof/factory_default/factory_bot_patch.rb b/lib/test_prof/factory_default/factory_bot_patch.rb index c483155f..32d83991 100644 --- a/lib/test_prof/factory_default/factory_bot_patch.rb +++ b/lib/test_prof/factory_default/factory_bot_patch.rb @@ -12,7 +12,8 @@ module RunnerExt module StrategyExt def association(runner) - FactoryDefault.get(runner.name, runner.traits, runner.overrides) || super + FactoryDefault.get(runner.name, runner.traits, runner.overrides) || + FactoryDefault.profiler.instrument(runner.name, runner.traits, runner.overrides) { super } end end end diff --git a/spec/integrations/factory_default_spec.rb b/spec/integrations/factory_default_spec.rb index 2f5d7143..1e1e2760 100644 --- a/spec/integrations/factory_default_spec.rb +++ b/spec/integrations/factory_default_spec.rb @@ -1,15 +1,48 @@ # frozen_string_literal: true -describe "FactoryDefault" do - specify "RSpec integration", :aggregate_failures do - output = run_rspec("factory_default") +describe "FactoryDefault", :aggregate_failures do + context "RSpec integration" do + specify "basic" do + output = run_rspec("factory_default") - expect(output).to include("0 failures") - end + expect(output).to include("0 failures") + end + + specify "let_it_be integration" do + output = run_rspec("factory_default_let_it_be") + + expect(output).to include("0 failures") + end + + specify "stats" do + output = run_rspec("factory_default", env: {"FACTORY_DEFAULT_STATS" => "1"}) + + expect(output).to include("0 failures") + + expect(output).to include("FactoryDefault summary: hit=11 miss=3") + expect(output).to match(/factory\s+hit\s+miss\n\n/) + expect(output).to match(/user\s+11\s+3/) + end + + specify "analyze" do + output = run_rspec( + "factory_default_analyze", + env: { + "FACTORY_DEFAULT_PROF" => "1" + } + ) - specify "let_it_be integration", :aggregate_failures do - output = run_rspec("factory_default_let_it_be") + expect(output).to include("0 failures") - expect(output).to include("0 failures") + expect(output).to include("Factory associations usage:") + expect(output).to match(/factory\s+count\s+total time\n\n/) + expect(output).to match(/user\s+7\s+\d{2}:\d{2}\.\d{3}/) + expect(output).to match(/user\[traited\]\s+1\s+\d{2}:\d{2}\.\d{3}/) + expect(output).to match(/user\{tag:"some tag"\}\s+1\s+\d{2}:\d{2}\.\d{3}/) + expect(output).to include("Total associations created: 9") + expect(output).to include("Total uniq associations created: 3") + expect(output).to match(/Total time spent: \d{2}:\d{2}\.\d{3}/) + expect(output).to include("0 failures") + end end end diff --git a/spec/integrations/fixtures/rspec/factory_default_analyze_fixture.rb b/spec/integrations/fixtures/rspec/factory_default_analyze_fixture.rb new file mode 100644 index 00000000..0ca497a7 --- /dev/null +++ b/spec/integrations/fixtures/rspec/factory_default_analyze_fixture.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require_relative "../../../support/ar_models" +require_relative "../../../support/transactional_context" +require "test_prof/recipes/rspec/factory_default" + +describe "Post" do + let(:user) { TestProf::FactoryBot.create(:user) } + let(:post) { TestProf::FactoryBot.create(:post) } + + it "creates post with different user" do + user + expect { post }.to change(User, :count) + expect(post.user).not_to eq user + end + + it "creates user if no default" do + expect { post }.to change(User, :count).by(1) + end + + it "creates many records" do + user + expect { TestProf::FactoryBot.create_list(:post, 5) }.to change(User, :count).by(5) + end + + context "with traits" do + let(:post) { TestProf::FactoryBot.create(:post, :with_traited_user) } + + it "can still be set default" do + expect(post.user.tag).to eq "traited" + end + end + + context "with overrides" do + let(:post) { TestProf::FactoryBot.create(:post, :with_tagged_user) } + + it "can still be set default" do + expect(post.user.tag).to eq "some tag" + end + end +end From 9dd50b5d19f827bdbd0ef46467ca1fe3f62824c9 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Sun, 27 Nov 2022 20:43:54 -0500 Subject: [PATCH 060/194] fix(factory_default): refind default records created outside of examples --- lib/test_prof/factory_default.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 8119beef..51e8cc33 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -4,18 +4,24 @@ require "test_prof/factory_bot" require "test_prof/factory_default/factory_bot_patch" require "test_prof/ext/float_duration" +require "test_prof/ext/active_record_refind" if defined?(::ActiveRecord::Base) module TestProf # FactoryDefault allows use to re-use associated objects # in factories implicilty module FactoryDefault using FloatDuration + using Ext::ActiveRecordRefind if defined?(::ActiveRecord::Base) using(Module.new do refine Object do def to_override_key "<#{self.class.name}::$id$#{object_id}$di$>" end + + def refind + self + end end if defined?(::ActiveRecord::Base) @@ -260,7 +266,11 @@ def get(name, traits = nil, overrides = nil) stats[name][:miss] -= 1 stats[name][:hit] += 1 - object + if record[:context] && (record[:context] != :example) + object.refind + else + object + end end def remove(name) From 4a4ba70071a41c2687a0f8145fb60f0878288c55 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 28 Nov 2022 12:05:31 -0500 Subject: [PATCH 061/194] fix: style --- docs/recipes/factory_default.md | 6 +++--- lefthook.yml | 19 +++++++++++++++++++ lib/test_prof/factory_doctor/minitest.rb | 2 +- lib/test_prof/factory_prof.rb | 2 +- lib/test_prof/rspec_dissect.rb | 2 +- lib/test_prof/stack_prof.rb | 4 ++-- lib/test_prof/tag_prof/rspec.rb | 2 +- 7 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 lefthook.yml diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index 6dab5b8a..e2735a37 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -116,7 +116,7 @@ Defaults created within `before_all` and `let_it_be` are not reset after each ex **IMPORTANT:** You must load FactoryDefault after loading BeforeAll to make this feature work. -**NOTE**. Regulart `before(:all)` callbacks are not supported. +**NOTE**. Regular `before(:all)` callbacks are not supported. ### Working with traits @@ -225,9 +225,9 @@ FactoryDefault summary: hit=11 miss=3 Where `hit` indicates the number of times the default factory value was used instead of a new one when an association was created; `miss` indicates the number of time the default value was ignored due to traits or attributes mismatch. -## Factory Default profiling, or when to use defaults? +## Factory Default profiling, or when to use defaults -Factory Default ships with the profiler, which can help you to see how associations are beeing used in your test suite, so you can decide on using `create_default` or not. +Factory Default ships with the profiler, which can help you to see how associations are being used in your test suite, so you can decide on using `create_default` or not. To enable profiling, run your tests with the `FACTORY_DEFAULT_PROF=1` set: diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 00000000..4bcefd5f --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,19 @@ +pre-commit: + commands: + mdl: + tags: style + glob: "**/*.md" + exclude: ".github/*" + run: mdl {staged_files} + forspell: + tags: grammar + glob: "**/*.md" + run: forspell {staged_files} + rubocop: + tags: style + glob: "**/*.md" + run: bundle exec rubocop --force-exclusion {staged_files} + lychee: + tags: links + glob: "**/*.md" + run: lychee docs/* diff --git a/lib/test_prof/factory_doctor/minitest.rb b/lib/test_prof/factory_doctor/minitest.rb index 5e6be051..7b1de4d0 100644 --- a/lib/test_prof/factory_doctor/minitest.rb +++ b/lib/test_prof/factory_doctor/minitest.rb @@ -87,7 +87,7 @@ def report private def pluralize_records(count) - count == 1 ? "1 record" : "#{count} records" + (count == 1) ? "1 record" : "#{count} records" end end end diff --git a/lib/test_prof/factory_prof.rb b/lib/test_prof/factory_prof.rb index f083f944..36c4b243 100644 --- a/lib/test_prof/factory_prof.rb +++ b/lib/test_prof/factory_prof.rb @@ -18,7 +18,7 @@ class Configuration attr_accessor :mode, :printer def initialize - @mode = ENV["FPROF"] == "flamegraph" ? :flamegraph : :simple + @mode = (ENV["FPROF"] == "flamegraph") ? :flamegraph : :simple @printer = case ENV["FPROF"] when "flamegraph" diff --git a/lib/test_prof/rspec_dissect.rb b/lib/test_prof/rspec_dissect.rb index 2a9769e4..0ddfc108 100644 --- a/lib/test_prof/rspec_dissect.rb +++ b/lib/test_prof/rspec_dissect.rb @@ -47,7 +47,7 @@ def initialize @let_top_count = (ENV["RD_PROF_LET_TOP"] || 3).to_i @top_count = (ENV["RD_PROF_TOP"] || 5).to_i @stamp = ENV["RD_PROF_STAMP"] - @mode = ENV["RD_PROF"] == "1" ? "all" : ENV["RD_PROF"] + @mode = (ENV["RD_PROF"] == "1") ? "all" : ENV["RD_PROF"] unless MODES.include?(mode) raise "Unknown RSpecDissect mode: #{mode};" \ diff --git a/lib/test_prof/stack_prof.rb b/lib/test_prof/stack_prof.rb index 40e6ec28..061063a6 100644 --- a/lib/test_prof/stack_prof.rb +++ b/lib/test_prof/stack_prof.rb @@ -27,7 +27,7 @@ class Configuration attr_accessor :mode, :raw, :target, :format, :interval, :ignore_gc def initialize @mode = ENV.fetch("TEST_STACK_PROF_MODE", :wall).to_sym - @target = ENV["TEST_STACK_PROF"] == "boot" ? :boot : :suite + @target = (ENV["TEST_STACK_PROF"] == "boot") ? :boot : :suite @raw = ENV["TEST_STACK_PROF_RAW"] != "0" @format = if FORMATS.include?(ENV["TEST_STACK_PROF_FORMAT"]) @@ -37,7 +37,7 @@ def initialize end sample_interval = ENV["TEST_STACK_PROF_INTERVAL"].to_i - @interval = sample_interval > 0 ? sample_interval : nil + @interval = (sample_interval > 0) ? sample_interval : nil @ignore_gc = !ENV["TEST_STACK_PROF_IGNORE_GC"].nil? end diff --git a/lib/test_prof/tag_prof/rspec.rb b/lib/test_prof/tag_prof/rspec.rb index a974b360..734e402a 100644 --- a/lib/test_prof/tag_prof/rspec.rb +++ b/lib/test_prof/tag_prof/rspec.rb @@ -13,7 +13,7 @@ class RSpecListener # :nodoc: attr_reader :result, :printer def initialize - @printer = ENV["TAG_PROF_FORMAT"] == "html" ? Printers::HTML : Printers::Simple + @printer = (ENV["TAG_PROF_FORMAT"] == "html") ? Printers::HTML : Printers::Simple @result = if ENV["TAG_PROF_EVENT"].nil? From f13ee7099a7e45788c525a4a6784f940e1ff438f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 28 Nov 2022 16:30:02 -0500 Subject: [PATCH 062/194] fix(let_it_be): array-like records detection #map is to generic and could be implemented by hashes/structs; #to_ary is a better check --- lib/test_prof/recipes/rspec/let_it_be.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index 1e5867fc..ca64feff 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -192,7 +192,7 @@ def deep_freeze(record) next record.reload if record.is_a?(::ActiveRecord::Base) - if record.respond_to?(:map) + if record.respond_to?(:to_ary) next record.map do |rec| rec.is_a?(::ActiveRecord::Base) ? rec.reload : rec end @@ -205,7 +205,7 @@ def deep_freeze(record) next record.refind if record.is_a?(::ActiveRecord::Base) - if record.respond_to?(:map) + if record.respond_to?(:to_ary) next record.map do |rec| rec.is_a?(::ActiveRecord::Base) ? rec.refind : rec end From bc938cb62cb08b57fa45b687cfa242f011346429 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 29 Nov 2022 12:02:25 -0500 Subject: [PATCH 063/194] ci: jruby-9.3 9.4 has some problems (e.g., https://github.com/jruby/jruby/issues/7487) --- .github/workflows/rspec-jruby.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec-jruby.yml b/.github/workflows/rspec-jruby.yml index 0c3f2352..b6122574 100644 --- a/.github/workflows/rspec-jruby.yml +++ b/.github/workflows/rspec-jruby.yml @@ -22,7 +22,7 @@ jobs: bundle- - uses: ruby/setup-ruby@v1 with: - ruby-version: jruby + ruby-version: jruby-9.3 - name: Bundle install run: | bundle config path /home/runner/bundle From d5054b358efaa44ffe6b062dd9ffe7644eb562f5 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 29 Nov 2022 13:38:43 -0500 Subject: [PATCH 064/194] fix: freeze let_it_be objects on initialization Fixes #224 --- CHANGELOG.md | 2 ++ lib/test_prof/recipes/rspec/let_it_be.rb | 26 +++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a248890..00a8b2ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- LetItBe: freeze records during initialization with `freeze: true`. ([@palkan][]) + - Add FactoryDefault profiler (factory associations profilers). ([@palkan][]) - FactoryDefault: Allow creating a default per trait (or set of traits). ([@palkan][]) diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index ca64feff..acbd2402 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -7,6 +7,12 @@ module TestProf # Just like `let`, but persist the result for the whole group. # NOTE: Experimental and magical, for more control use `before_all`. module LetItBe + Modifier = Struct.new(:scope, :block) do + def call(record, config) + block.call(record, config) + end + end + class Configuration # Define an alias for `let_it_be` with the predefined options: # @@ -17,10 +23,13 @@ def alias_to(name, **default_args) LetItBe.define_let_it_be_alias(name, **default_args) end - def register_modifier(key, &block) + # Register modifier by providing the name of key, + # optional scope (when to apply the modifier, on initialization (:initialize) + # or when accessed # via let (:let)) + def register_modifier(key, on: :let, &block) raise ArgumentError, "Modifier #{key} is already defined for let_it_be" if LetItBe.modifiers.key?(key) - LetItBe.modifiers[key] = block + LetItBe.modifiers[key] = Modifier.new(on, block) end def default_modifiers @@ -41,17 +50,18 @@ def modifiers @modifiers ||= {} end - def wrap_with_modifiers(mods, &block) + def wrap_with_modifiers(mods, on: :let, &block) + mods = mods.select { |k, val| LetItBe.modifiers.fetch(k).scope == on } return block if mods.empty? validate_modifiers! mods - -> { + proc do record = instance_eval(&block) mods.inject(record) do |rec, (k, v)| LetItBe.modifiers.fetch(k).call(rec, v) end - } + end end def module_for(group) @@ -97,9 +107,11 @@ def let_it_be(identifier, **options, &block) options = default_options.merge(options) + initializer = LetItBe.wrap_with_modifiers(options, on: :initialize, &initializer) + before_all(&initializer) - let_accessor = LetItBe.wrap_with_modifiers(options) do + let_accessor = LetItBe.wrap_with_modifiers(options, on: :let) do instance_variable_get(:"#{PREFIX}#{identifier}") end @@ -213,7 +225,7 @@ def deep_freeze(record) record end - config.register_modifier :freeze do |record, val| + config.register_modifier :freeze, on: :initialize do |record, val| if val == false TestProf::LetItBe::Freezer::Stoplist.stop!(record) next record From 74351b61b3e45eca768e0817a616fe4c4d40f755 Mon Sep 17 00:00:00 2001 From: maxshend Date: Fri, 25 Nov 2022 23:55:17 +0300 Subject: [PATCH 065/194] feat: add global before_all tags --- CHANGELOG.md | 15 +++++ docs/recipes/before_all.md | 17 ++++++ lib/test_prof/before_all.rb | 61 +++++++++++++------ lib/test_prof/recipes/rspec/before_all.rb | 5 +- .../rspec/before_all_hooks_fixture.rb | 26 ++++++++ 5 files changed, 105 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00a8b2ab..a5c13f76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,20 @@ end You can also use `TestProf::FactoryDefault.disable!(&block)`. +- Add support for global `before_all` tags ([@maxshend][]) +```ruby +TestProf::BeforeAll.configure do |config| + config.before(:begin, reset_sequences: proc(&:present?)) do + warn <<~MESSAGE + Do NOT create objects outside of transaction + because all db sequences will be reset to 1 + in every single example, so that IDs of new objects + can get into conflict with the long-living ones. + MESSAGE + end +end +``` + ## 1.0.11 (2022-10-27) - Fix monitoring methods with keyword args in Ruby 3+. ([@palkan][]) @@ -335,3 +349,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@ruslanshakirov]: https://github.com/ruslanshakirov [@ygelfand]: https://github.com/ygelfand [@cbliard]: https://github.com/cbliard +[@maxshend]: https://github.com/maxshend diff --git a/docs/recipes/before_all.md b/docs/recipes/before_all.md index 2a25feb2..b339b498 100644 --- a/docs/recipes/before_all.md +++ b/docs/recipes/before_all.md @@ -235,3 +235,20 @@ TestProf::BeforeAll.configure do |config| config.setup_fixtures = true end ``` + +## Global Tags + +You can register callbacks for specific RSpec Example Groups using tags: + +```ruby +TestProf::BeforeAll.configure do |config| + config.before(:begin, reset_sequences: proc(&:present?)) do + warn <<~MESSAGE + Do NOT create objects outside of transaction + because all db sequences will be reset to 1 + in every single example, so that IDs of new objects + can get into conflict with the long-living ones. + MESSAGE + end +end +``` diff --git a/lib/test_prof/before_all.rb b/lib/test_prof/before_all.rb index 42016f9e..10e13c16 100644 --- a/lib/test_prof/before_all.rb +++ b/lib/test_prof/before_all.rb @@ -17,19 +17,19 @@ def initialize class << self attr_accessor :adapter - def begin_transaction(scope = nil) + def begin_transaction(scope = nil, metadata = []) raise AdapterMissing if adapter.nil? - config.run_hooks(:begin, scope) do + config.run_hooks(:begin, scope, metadata) do adapter.begin_transaction end yield end - def rollback_transaction(scope = nil) + def rollback_transaction(scope = nil, metadata = []) raise AdapterMissing if adapter.nil? - config.run_hooks(:rollback, scope) do + config.run_hooks(:rollback, scope, metadata) do adapter.rollback_transaction end end @@ -49,6 +49,33 @@ def configure end end + class HookEntry # :nodoc: + attr_reader :filters, :block + + def initialize(block:, filters: []) + @block = block + @filters = TestProf.rspec? ? ::RSpec::Core::Metadata.build_hash_from(filters) : filters + end + + def run(scope, metadata) + return unless filters_apply?(metadata) + + block.call(scope) + end + + private + + def filters_apply?(metadata) + return true unless filters.present? && TestProf.rspec? + + ::RSpec::Core::MetadataFilter.apply?( + :all?, + filters, + metadata + ) + end + end + class HooksChain # :nodoc: attr_reader :type, :after, :before @@ -58,10 +85,10 @@ def initialize(type) @after = [] end - def run(scope = nil) - before.each { |clbk| clbk.call(scope) } + def run(scope = nil, metadata = []) + before.each { |hook| hook.run(scope, metadata) } yield - after.each { |clbk| clbk.call(scope) } + after.each { |hook| hook.run(scope, metadata) } end end @@ -76,26 +103,26 @@ def initialize end # Add `before` hook for `begin` or - # `rollback` operation: + # `rollback` operation with optional filters: # - # config.before(:rollback) { ... } - def before(type, &block) + # config.before(:rollback, foo: :bar) { ... } + def before(type, *filters, &block) validate_hook_type!(type) - hooks[type].before << block if block + hooks[type].before << HookEntry.new(block: block, filters: filters) if block end # Add `after` hook for `begin` or - # `rollback` operation: + # `rollback` operation with optional filters: # - # config.after(:begin) { ... } - def after(type, &block) + # config.after(:begin, foo: :bar) { ... } + def after(type, *filters, &block) validate_hook_type!(type) - hooks[type].after << block if block + hooks[type].after << HookEntry.new(block: block, filters: filters) if block end - def run_hooks(type, scope = nil) # :nodoc: + def run_hooks(type, scope = nil, metadata = []) # :nodoc: validate_hook_type!(type) - hooks[type].run(scope) { yield } + hooks[type].run(scope, metadata) { yield } end private diff --git a/lib/test_prof/recipes/rspec/before_all.rb b/lib/test_prof/recipes/rspec/before_all.rb index 2c0a00e9..b91d2552 100644 --- a/lib/test_prof/recipes/rspec/before_all.rb +++ b/lib/test_prof/recipes/rspec/before_all.rb @@ -18,17 +18,18 @@ def before_all(setup_fixtures: BeforeAll.config.setup_fixtures, &block) end @__before_all_activation__ = context = self + current_metadata = metadata before(:all) do @__inspect_output = "before_all hook" BeforeAll.setup_fixtures(self) if setup_fixtures - BeforeAll.begin_transaction(context) do + BeforeAll.begin_transaction(context, current_metadata) do instance_eval(&block) end end after(:all) do - BeforeAll.rollback_transaction(context) + BeforeAll.rollback_transaction(context, current_metadata) end end diff --git a/spec/integrations/fixtures/rspec/before_all_hooks_fixture.rb b/spec/integrations/fixtures/rspec/before_all_hooks_fixture.rb index a6d0dc37..37e82913 100644 --- a/spec/integrations/fixtures/rspec/before_all_hooks_fixture.rb +++ b/spec/integrations/fixtures/rspec/before_all_hooks_fixture.rb @@ -30,10 +30,18 @@ def add_event(event) Events.add_event :setup_before_all end + config.before(:begin, :with_meta) do + Events.add_event :setup_before_all_with_meta + end + config.after(:begin) do Events.add_event :before_all_was_set_up end + config.after(:begin, with_meta: proc(&:present?)) do + Events.add_event :before_all_was_set_up_with_meta + end + config.before(:rollback) do # create user to check the it's created within a transaction hook_user = TestProf::FactoryBot.create(:user) @@ -82,4 +90,22 @@ def add_event(event) end end end + + context "with before_all" do + context "with matched metadata", with_meta: true do + before_all { Events.add_event :before_all } + after(:all) { Events.events.clear } + + it "should setup before_all_with_meta" do + expect(Events.events).to eq([ + :setup_before_all, + :setup_before_all_with_meta, + :before_all_was_set_up, + :before_all_was_set_up_with_meta, + :before_all, + :before_each + ]) + end + end + end end From 0c47cd6d15a9d1255d10de157009cb5a4e050bad Mon Sep 17 00:00:00 2001 From: maxshend Date: Tue, 29 Nov 2022 21:50:53 +0300 Subject: [PATCH 066/194] feat: add more specs for global before_all tags --- CHANGELOG.md | 2 +- docs/recipes/before_all.md | 2 +- .../fixtures/rspec/before_all_hooks_fixture.rb | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5c13f76..69d4d481 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ You can also use `TestProf::FactoryDefault.disable!(&block)`. - Add support for global `before_all` tags ([@maxshend][]) ```ruby TestProf::BeforeAll.configure do |config| - config.before(:begin, reset_sequences: proc(&:present?)) do + config.before(:begin, reset_sequences: true, foo: :bar) do warn <<~MESSAGE Do NOT create objects outside of transaction because all db sequences will be reset to 1 diff --git a/docs/recipes/before_all.md b/docs/recipes/before_all.md index b339b498..ef412bc6 100644 --- a/docs/recipes/before_all.md +++ b/docs/recipes/before_all.md @@ -242,7 +242,7 @@ You can register callbacks for specific RSpec Example Groups using tags: ```ruby TestProf::BeforeAll.configure do |config| - config.before(:begin, reset_sequences: proc(&:present?)) do + config.before(:begin, reset_sequences: true, foo: :bar) do warn <<~MESSAGE Do NOT create objects outside of transaction because all db sequences will be reset to 1 diff --git a/spec/integrations/fixtures/rspec/before_all_hooks_fixture.rb b/spec/integrations/fixtures/rspec/before_all_hooks_fixture.rb index 37e82913..514c8ed9 100644 --- a/spec/integrations/fixtures/rspec/before_all_hooks_fixture.rb +++ b/spec/integrations/fixtures/rspec/before_all_hooks_fixture.rb @@ -34,6 +34,18 @@ def add_event(event) Events.add_event :setup_before_all_with_meta end + config.before(:begin, with_meta: false) do + Events.add_event :setup_before_all_with_meta_false + end + + config.before(:begin, foo: :bar) do + Events.add_event :setup_before_all_with_bar_tag + end + + config.before(:begin, foo: :baz) do + Events.add_event :setup_before_all_with_baz_tag + end + config.after(:begin) do Events.add_event :before_all_was_set_up end @@ -92,7 +104,7 @@ def add_event(event) end context "with before_all" do - context "with matched metadata", with_meta: true do + context "with matched metadata", with_meta: true, foo: :bar do before_all { Events.add_event :before_all } after(:all) { Events.events.clear } @@ -100,6 +112,7 @@ def add_event(event) expect(Events.events).to eq([ :setup_before_all, :setup_before_all_with_meta, + :setup_before_all_with_bar_tag, :before_all_was_set_up, :before_all_was_set_up_with_meta, :before_all, From 620feaa492100f3745d7fe5e655e0664e7786fff Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 6 Dec 2022 17:05:39 -0500 Subject: [PATCH 067/194] Bump 1.1.0 --- CHANGELOG.md | 3 +++ lib/test_prof/version.rb | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69d4d481..7a62d146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.1.0 (2022-12-06) + - LetItBe: freeze records during initialization with `freeze: true`. ([@palkan][]) - Add FactoryDefault profiler (factory associations profilers). ([@palkan][]) @@ -34,6 +36,7 @@ end You can also use `TestProf::FactoryDefault.disable!(&block)`. - Add support for global `before_all` tags ([@maxshend][]) + ```ruby TestProf::BeforeAll.configure do |config| config.before(:begin, reset_sequences: true, foo: :bar) do diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 07279451..b9f6f58b 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.0.11" + VERSION = "1.1.0" end From 153c10280ce89c90d43c0ac513d84b01b22a4a61 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 6 Dec 2022 18:08:14 -0500 Subject: [PATCH 068/194] chore(any_fixture): drop deprecated reporting_enabled --- lib/test_prof/any_fixture.rb | 13 ------------- spec/test_prof/any_fixture_spec.rb | 10 ---------- 2 files changed, 23 deletions(-) diff --git a/lib/test_prof/any_fixture.rb b/lib/test_prof/any_fixture.rb index 63d4e86a..7b696d04 100644 --- a/lib/test_prof/any_fixture.rb +++ b/lib/test_prof/any_fixture.rb @@ -102,19 +102,6 @@ def configure yield config end - # Backward compatibility - def reporting_enabled=(val) - warn "AnyFixture.reporting_enabled is deprecated and will be removed in 1.1. Use AnyFixture.config.reporting_enabled instead" - config.reporting_enabled = val - end - - def reporting_enabled - warn "AnyFixture.reporting_enabled is deprecated and will be removed in 1.1. Use AnyFixture.config.reporting_enabled instead" - config.reporting_enabled - end - - alias_method :reporting_enabled?, :reporting_enabled - # Register a block of code as a fixture, # returns the result of the block execution def register(id) diff --git a/spec/test_prof/any_fixture_spec.rb b/spec/test_prof/any_fixture_spec.rb index 37ed2a2d..a0e1cffb 100644 --- a/spec/test_prof/any_fixture_spec.rb +++ b/spec/test_prof/any_fixture_spec.rb @@ -308,14 +308,4 @@ expect(User.count).to eq 1 end end - - describe "#reporting_enabled" do - it "returns the config value" do - raise "Remove deprecated #reporting_enabled" if TestProf::VERSION >= "1.1" - - allow(described_class.config).to receive(:reporting_enabled) { :truth } - - expect(described_class.reporting_enabled).to eq :truth - end - end end From 18deb96090b5bee08526c3266b1125fc1d55ab72 Mon Sep 17 00:00:00 2001 From: Keita Urashima Date: Wed, 7 Dec 2022 17:07:23 +0900 Subject: [PATCH 069/194] Fix typo --- docs/recipes/factory_default.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index e2735a37..1310a9fa 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -112,7 +112,7 @@ before { FactoryBot.set_factory_default(:user, user) } ### Using with `before_all` / `let_it_be` -Defaults created within `before_all` and `let_it_be` are not reset after each example, but only at the end of the corresponding example group. So, it's possible to call `create_defatul` within `let_it_be` without any additional configuration. **RSpec only** +Defaults created within `before_all` and `let_it_be` are not reset after each example, but only at the end of the corresponding example group. So, it's possible to call `create_default` within `let_it_be` without any additional configuration. **RSpec only** **IMPORTANT:** You must load FactoryDefault after loading BeforeAll to make this feature work. From a0a52852752ea6b1153da76fb4a37965b974ec4d Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Thu, 24 Nov 2022 16:34:20 +0100 Subject: [PATCH 070/194] Add support for multiple databases --- .../before_all/adapters/active_record.rb | 22 ++++-- .../before_all/adapters/active_record_spec.rb | 69 +++++++++++++++++++ 2 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 spec/test_prof/before_all/adapters/active_record_spec.rb diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 8b337607..277a4e3e 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -6,17 +6,27 @@ module Adapters # ActiveRecord adapter for `before_all` module ActiveRecord class << self + def all_connection_classes + @all_connection_classes ||= [::ActiveRecord::Base] + ::ActiveRecord::Base.descendants.select do |descendant| + descendant&.connection_class? + end.compact + end + def begin_transaction - ::ActiveRecord::Base.connection.begin_transaction(joinable: false) + all_connection_classes.each do |connection_class| + connection_class.connection.begin_transaction(joinable: false) + end end def rollback_transaction - if ::ActiveRecord::Base.connection.open_transactions.zero? - warn "!!! before_all transaction has been already rollbacked and " \ - "could work incorrectly" - return + all_connection_classes.each do |connection_class| + if connection_class.connection.open_transactions.zero? + warn "!!! before_all transaction has been already rollbacked and " \ + "could work incorrectly" + next + end + connection_class.connection.rollback_transaction end - ::ActiveRecord::Base.connection.rollback_transaction end def setup_fixtures(test_object) diff --git a/spec/test_prof/before_all/adapters/active_record_spec.rb b/spec/test_prof/before_all/adapters/active_record_spec.rb new file mode 100644 index 00000000..c20653ba --- /dev/null +++ b/spec/test_prof/before_all/adapters/active_record_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module TestProf + module BeforeAll + def self.configure + end + end +end + +require "test_prof/before_all/adapters/active_record" + +describe "TestProf::BeforeAll::Adapters::ActiveRecord" do + let(:connection_class_1) { ActiveRecord::Base } + let(:connection_1) { connection_class_1.connection } + + let(:connection_class_2) { ActiveRecord::Base } + let(:connection_2) { connection_class_2.connection } + + before do + allow(ActiveRecord::Base).to receive(:descendants).and_return([connection_class_2]) + + allow(connection_class_2).to receive(:connection_class?).and_return(true) + allow(connection_class_2).to receive(:connection).and_return(connection_2) + end + + describe ".begin_transaction" do + subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.begin_transaction } + + it "calls begin_transaction on all available connections" do + expect(connection_1).to receive(:begin_transaction).with(joinable: false) + expect(connection_2).to receive(:begin_transaction).with(joinable: false) + + subject + end + end + + describe ".rollback_transaction" do + subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.rollback_transaction } + + context "when not all connections have started a transaction" do + before do + # Ensure no transactions are open due to randomization of specs + connection_1.rollback_transaction unless connection_1.open_transactions.zero? + connection_2.rollback_transaction unless connection_2.open_transactions.zero? + connection_2.begin_transaction + end + + it "warns when connection does not have open transaction" do + expect { subject }.to output( + "!!! before_all transaction has been already rollbacked and could work incorrectly\n" + ).to_stderr + end + end + + context "when the connection is a transaction" do + before do + connection_1.begin_transaction + connection_2.begin_transaction + end + + it "calls rollback_transaction on all available connections" do + expect(connection_1).to receive(:rollback_transaction) + expect(connection_2).to receive(:rollback_transaction) + + subject + end + end + end +end From 026faae129aaecc10ec31399469b09e001530301 Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Mon, 28 Nov 2022 11:08:22 +0100 Subject: [PATCH 071/194] update before_all documentation --- CHANGELOG.md | 2 ++ docs/recipes/before_all.md | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a62d146..33a7d65d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Add support for ActiveRecord multiple databases ([@rutgerw][]) + ## 1.1.0 (2022-12-06) - LetItBe: freeze records during initialization with `freeze: true`. ([@palkan][]) diff --git a/docs/recipes/before_all.md b/docs/recipes/before_all.md index ef412bc6..904021b7 100644 --- a/docs/recipes/before_all.md +++ b/docs/recipes/before_all.md @@ -59,6 +59,36 @@ Make sure to check the [Caveats section](#caveats) of this document for details. ## Instructions +### Multiple database support + +The ActiveRecord BeforeAll adapter will only start a transaction using ActiveRecord::Base connection. +If you want to ensure `before_all` can use multiple connections, you need to ensure the connection +classes are loaded before using `before_all`. + +For example, imagine you have `ApplicationRecord` and a separate database for user accounts: + +```ruby +class Users < AccountsRecord + +end + +class Articles < ApplicationRecord + +end +``` + +Then those two Connection Classes do need to be loaded before the tests are run: + +```ruby + +# Ensure connection classes are loaded +ApplicationRecord +AccountsRecord +``` + +This code can be added to `rails_helper.rb` or the rake tasks thats runs minitests. + + ### RSpec In your `rails_helper.rb` (or `spec_helper.rb` after *ActiveRecord* has been loaded): From bce283b44d3c2d3d63c15bb313f88b52cc6e0aaa Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Fri, 2 Dec 2022 15:51:02 +0100 Subject: [PATCH 072/194] Use database adapter for retrieving connection --- .../before_all/adapters/active_record.rb | 16 +++++++--------- .../before_all/adapters/active_record_spec.rb | 13 ++++--------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 277a4e3e..99bd644e 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -6,26 +6,24 @@ module Adapters # ActiveRecord adapter for `before_all` module ActiveRecord class << self - def all_connection_classes - @all_connection_classes ||= [::ActiveRecord::Base] + ::ActiveRecord::Base.descendants.select do |descendant| - descendant&.connection_class? - end.compact + def all_connections + @all_connections ||= ::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).map(&:connection) end def begin_transaction - all_connection_classes.each do |connection_class| - connection_class.connection.begin_transaction(joinable: false) + all_connections.each do |connection| + connection.begin_transaction(joinable: false) end end def rollback_transaction - all_connection_classes.each do |connection_class| - if connection_class.connection.open_transactions.zero? + all_connections.each do |connection| + if connection.open_transactions.zero? warn "!!! before_all transaction has been already rollbacked and " \ "could work incorrectly" next end - connection_class.connection.rollback_transaction + connection.rollback_transaction end end diff --git a/spec/test_prof/before_all/adapters/active_record_spec.rb b/spec/test_prof/before_all/adapters/active_record_spec.rb index c20653ba..545f661a 100644 --- a/spec/test_prof/before_all/adapters/active_record_spec.rb +++ b/spec/test_prof/before_all/adapters/active_record_spec.rb @@ -10,17 +10,12 @@ def self.configure require "test_prof/before_all/adapters/active_record" describe "TestProf::BeforeAll::Adapters::ActiveRecord" do - let(:connection_class_1) { ActiveRecord::Base } - let(:connection_1) { connection_class_1.connection } - - let(:connection_class_2) { ActiveRecord::Base } - let(:connection_2) { connection_class_2.connection } + let(:connection_pool_list) { [ActiveRecord::Base, ActiveRecord::Base.clone] } + let(:connection_1) { connection_pool_list.first.connection } + let(:connection_2) { connection_pool_list.second.connection } before do - allow(ActiveRecord::Base).to receive(:descendants).and_return([connection_class_2]) - - allow(connection_class_2).to receive(:connection_class?).and_return(true) - allow(connection_class_2).to receive(:connection).and_return(connection_2) + allow(::ActiveRecord::Base.connection_handler).to receive(:connection_pool_list).with(:writing).and_return(connection_pool_list) end describe ".begin_transaction" do From b04553fa0b8656bafda8236b1324bd3ba9a94461 Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Tue, 20 Dec 2022 11:03:49 +0100 Subject: [PATCH 073/194] Use multiple databases --- .../rspec/before_all_isolator_fixture.rb | 2 +- spec/support/ar_models.rb | 70 ++++++++++- .../before_all/adapters/active_record_spec.rb | 110 ++++++++++++------ 3 files changed, 144 insertions(+), 38 deletions(-) diff --git a/spec/integrations/fixtures/rspec/before_all_isolator_fixture.rb b/spec/integrations/fixtures/rspec/before_all_isolator_fixture.rb index ac831bca..23d6dc23 100644 --- a/spec/integrations/fixtures/rspec/before_all_isolator_fixture.rb +++ b/spec/integrations/fixtures/rspec/before_all_isolator_fixture.rb @@ -28,7 +28,7 @@ def perform(*_args) end end -class User < ActiveRecord::Base +class User < ApplicationRecord attr_accessor :commited end diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index 4c2364c0..0958cdb0 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -13,6 +13,12 @@ rescue LoadError end +def multi_db? + return false unless ENV["MULTI_DB"] + + ENV["MULTI_DB"] == "true" +end + DB_CONFIG = if ENV["DB"] == "sqlite-file" FileUtils.mkdir_p TestProf.config.output_dir @@ -32,6 +38,35 @@ {adapter: "sqlite3", database: ":memory:"} end +if multi_db? + FileUtils.mkdir_p TestProf.config.output_dir + db_comments_path = File.join(TestProf.config.output_dir, "testdb_comments.sqlite") + FileUtils.rm(db_comments_path) if File.file?(db_comments_path) + DB_CONFIG_COMMENTS = {adapter: "sqlite3", database: db_comments_path} + ActiveRecord::Base.configurations = {default_env: {comments: DB_CONFIG_COMMENTS, posts: DB_CONFIG}} + + class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true + + connects_to database: {writing: :posts, reading: :posts} + end + + class CommentsRecord < ApplicationRecord + self.abstract_class = true + + connects_to database: {writing: :comments, reading: :comments} + end + CommentsRecord.establish_connection +else + ActiveRecord::Base.configurations = {default_env: DB_CONFIG} + class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true + end + + class CommentsRecord < ApplicationRecord + end +end + ActiveRecord::Base.establish_connection(**DB_CONFIG) # #truncate_tables is not supported in older Rails, let's just ignore the failures @@ -59,16 +94,25 @@ end end +ActiveRecord::Base.establish_connection DB_CONFIG_COMMENTS if multi_db? +ActiveRecord::Schema.define do + create_table :comments, if_not_exists: true do |t| + t.string :post_id # String because it could be a UUID + t.string :user_id # String because it could be a UUID + t.string :comment + end +end + ActiveRecord::Base.logger = if ENV["DEBUG"] Logger.new($stdout) else Logger.new(IO::NULL) end - -class User < ActiveRecord::Base +class User < ApplicationRecord validates :name, presence: true has_many :posts, dependent: :destroy + has_many :comments, dependent: :destroy def clone copy = dup @@ -77,12 +121,16 @@ def clone end end -class Post < ActiveRecord::Base +class Post < ApplicationRecord belongs_to :user attr_accessor :dirty end +class Comment < CommentsRecord + belongs_to :user, dependent: :destroy +end + TestProf::FactoryBot.define do factory :user do sequence(:name) { |n| "John #{n}" } @@ -122,6 +170,22 @@ class Post < ActiveRecord::Base association :user, factory: %i[user other_trait] end end + + factory :comment do + comment { "Interesting Post!" } + + trait :with_post do + after(:create) do + TestProf::FactoryBot.create(:post) + end + end + + trait :with_user do + after(:create) do + TestProf::FactoryBot.create(:user) + end + end + end end Fabricator(:user) do diff --git a/spec/test_prof/before_all/adapters/active_record_spec.rb b/spec/test_prof/before_all/adapters/active_record_spec.rb index 545f661a..c9482757 100644 --- a/spec/test_prof/before_all/adapters/active_record_spec.rb +++ b/spec/test_prof/before_all/adapters/active_record_spec.rb @@ -9,55 +9,97 @@ def self.configure require "test_prof/before_all/adapters/active_record" -describe "TestProf::BeforeAll::Adapters::ActiveRecord" do - let(:connection_pool_list) { [ActiveRecord::Base, ActiveRecord::Base.clone] } - let(:connection_1) { connection_pool_list.first.connection } - let(:connection_2) { connection_pool_list.second.connection } +describe TestProf::BeforeAll::Adapters::ActiveRecord do + context "when using single database", skip: (multi_db? ? "Using multiple databases" : nil) do + let(:connection_pool) { ApplicationRecord } + let(:connection) { connection_pool.connection } - before do - allow(::ActiveRecord::Base.connection_handler).to receive(:connection_pool_list).with(:writing).and_return(connection_pool_list) - end + describe ".begin_transaction" do + subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.begin_transaction } + + it "calls begin_transaction on all available connections" do + expect(connection).to receive(:begin_transaction).with(joinable: false) + + subject + end + end + + describe ".rollback_transaction" do + subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.rollback_transaction } + + context "when not all connections have started a transaction" do + before do + # Ensure no transactions are open due to randomization of specs + connection.rollback_transaction unless connection.open_transactions.zero? + end + + it "warns when connection does not have open transaction" do + expect { subject }.to output( + "!!! before_all transaction has been already rollbacked and could work incorrectly\n" + ).to_stderr + end + end - describe ".begin_transaction" do - subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.begin_transaction } + context "when the connection is a transaction" do + before do + connection.begin_transaction + end - it "calls begin_transaction on all available connections" do - expect(connection_1).to receive(:begin_transaction).with(joinable: false) - expect(connection_2).to receive(:begin_transaction).with(joinable: false) + it "calls rollback_transaction on all available connections" do + expect(connection).to receive(:rollback_transaction) - subject + subject + end + end end end - describe ".rollback_transaction" do - subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.rollback_transaction } + context "when using multiple databases", skip: ((!multi_db?) ? "Using single database" : nil) do + let(:connection_pool_list) { [ApplicationRecord, CommentsRecord] } + let(:connection_1) { connection_pool_list.first.connection } + let(:connection_2) { connection_pool_list.second.connection } - context "when not all connections have started a transaction" do - before do - # Ensure no transactions are open due to randomization of specs - connection_1.rollback_transaction unless connection_1.open_transactions.zero? - connection_2.rollback_transaction unless connection_2.open_transactions.zero? - connection_2.begin_transaction - end + describe ".begin_transaction" do + subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.begin_transaction } - it "warns when connection does not have open transaction" do - expect { subject }.to output( - "!!! before_all transaction has been already rollbacked and could work incorrectly\n" - ).to_stderr + it "calls begin_transaction on all available connections" do + expect(connection_1).to receive(:begin_transaction).with(joinable: false) + expect(connection_2).to receive(:begin_transaction).with(joinable: false) + + subject end end - context "when the connection is a transaction" do - before do - connection_1.begin_transaction - connection_2.begin_transaction + describe ".rollback_transaction" do + subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.rollback_transaction } + + context "when not all connections have started a transaction" do + before do + # Ensure no transactions are open due to randomization of specs + connection_1.rollback_transaction unless connection_1.open_transactions.zero? + connection_2.rollback_transaction unless connection_2.open_transactions.zero? + connection_2.begin_transaction + end + + it "warns when connection does not have open transaction" do + expect { subject }.to output( + "!!! before_all transaction has been already rollbacked and could work incorrectly\n" + ).to_stderr + end end - it "calls rollback_transaction on all available connections" do - expect(connection_1).to receive(:rollback_transaction) - expect(connection_2).to receive(:rollback_transaction) + context "when the connection is a transaction" do + before do + connection_1.begin_transaction + connection_2.begin_transaction + end - subject + it "calls rollback_transaction on all available connections" do + expect(connection_1).to receive(:rollback_transaction) + expect(connection_2).to receive(:rollback_transaction) + + subject + end end end end From 14aef7a3855b5a302eaf6b90c5e5ee115788116c Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Tue, 20 Dec 2022 11:24:11 +0100 Subject: [PATCH 074/194] Ensure ActiveRecord 5 is supported --- lib/test_prof/before_all/adapters/active_record.rb | 6 +++++- spec/support/ar_models.rb | 13 ++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 99bd644e..726e91a6 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -7,7 +7,11 @@ module Adapters module ActiveRecord class << self def all_connections - @all_connections ||= ::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).map(&:connection) + @all_connections ||= if ::ActiveRecord::Base.respond_to? :connects_to + ::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).map(&:connection) + else + Array.wrap(::ActiveRecord::Base.connection) + end end def begin_transaction diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index 0958cdb0..e819b449 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -14,6 +14,7 @@ end def multi_db? + return false unless ActiveRecord::Base.respond_to? :connects_to return false unless ENV["MULTI_DB"] ENV["MULTI_DB"] == "true" @@ -56,6 +57,11 @@ class CommentsRecord < ApplicationRecord connects_to database: {writing: :comments, reading: :comments} end + + class Comment < CommentsRecord + belongs_to :user, dependent: :destroy + end + CommentsRecord.establish_connection else ActiveRecord::Base.configurations = {default_env: DB_CONFIG} @@ -63,7 +69,8 @@ class ApplicationRecord < ActiveRecord::Base self.abstract_class = true end - class CommentsRecord < ApplicationRecord + class Comment < ApplicationRecord + belongs_to :user, dependent: :destroy end end @@ -127,10 +134,6 @@ class Post < ApplicationRecord attr_accessor :dirty end -class Comment < CommentsRecord - belongs_to :user, dependent: :destroy -end - TestProf::FactoryBot.define do factory :user do sequence(:name) { |n| "John #{n}" } From fa560f75e208a4d65e0c3577b636b123fa6ca73e Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Tue, 27 Dec 2022 15:50:49 +0100 Subject: [PATCH 075/194] Run rspec with MULTI_DB=true for ActiveRecord 7 specs --- .github/workflows/rspec.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 4f37b7c9..48c8842a 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -22,9 +22,11 @@ jobs: - ruby: 3.1 gemfile: "gemfiles/activerecord7.gemfile" db: "sqlite" + multi_db: "true" - ruby: 3.1 gemfile: "gemfiles/activerecord7.gemfile" db: "postgres" + multi_db: "true" - ruby: 3.0 gemfile: "gemfiles/activerecord6.gemfile" db: "sqlite" @@ -75,6 +77,7 @@ jobs: - name: Run RSpec env: DB: ${{ matrix.db }} + MULTI_DB: ${{ matrix.multi_db }} DATABASE_URL: postgres://postgres:postgres@localhost:5432 DB_NAME: postgres run: | From 1aea7b333fcda1144cb718e954d677c6a2727b30 Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Tue, 27 Dec 2022 15:52:18 +0100 Subject: [PATCH 076/194] Remove duplicate empty line --- docs/recipes/before_all.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/recipes/before_all.md b/docs/recipes/before_all.md index 904021b7..68a4f199 100644 --- a/docs/recipes/before_all.md +++ b/docs/recipes/before_all.md @@ -88,7 +88,6 @@ AccountsRecord This code can be added to `rails_helper.rb` or the rake tasks thats runs minitests. - ### RSpec In your `rails_helper.rb` (or `spec_helper.rb` after *ActiveRecord* has been loaded): From 0cb123d50ba8f115ffd4ebb57221e8bdd7ada7c6 Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Tue, 27 Dec 2022 16:45:35 +0100 Subject: [PATCH 077/194] Reset available connections when transaction is started --- lib/test_prof/before_all/adapters/active_record.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 726e91a6..983e72ee 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -15,6 +15,7 @@ def all_connections end def begin_transaction + @all_connections = nil all_connections.each do |connection| connection.begin_transaction(joinable: false) end From 28be35902a6fa6794ec8f60970922dc08e300635 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 4 Jan 2023 10:59:34 -0500 Subject: [PATCH 078/194] fix(ci): install latest postgres --- .github/workflows/rspec.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 48c8842a..e59a3c20 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -44,7 +44,7 @@ jobs: db: "sqlite" services: postgres: - image: postgres:12 + image: postgres:latest ports: ["5432:5432"] env: POSTGRES_PASSWORD: postgres @@ -67,7 +67,7 @@ jobs: - name: Install system deps run: | sudo apt-get update - sudo apt-get install libsqlite3-dev libpq-dev postgresql-client-12 + sudo apt-get install libsqlite3-dev libpq-dev postgresql-client - name: Bundle install run: | bundle config path /home/runner/bundle From 7d0f838801c3b6ef26826071125cd815ee5f3ba3 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 4 Jan 2023 11:00:49 -0500 Subject: [PATCH 079/194] fix: style --- docs/recipes/before_all.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/recipes/before_all.md b/docs/recipes/before_all.md index 68a4f199..e91f6bb4 100644 --- a/docs/recipes/before_all.md +++ b/docs/recipes/before_all.md @@ -69,11 +69,11 @@ For example, imagine you have `ApplicationRecord` and a separate database for us ```ruby class Users < AccountsRecord - + # ... end class Articles < ApplicationRecord - + # ... end ``` @@ -86,7 +86,7 @@ ApplicationRecord AccountsRecord ``` -This code can be added to `rails_helper.rb` or the rake tasks thats runs minitests. +This code can be added to `rails_helper.rb` or the rake tasks that runs minitests. ### RSpec From 7fb00f64753b3dd9e77bd5b75b13476bc3921791 Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Thu, 5 Jan 2023 12:49:53 +0100 Subject: [PATCH 080/194] For multi db, use ApplicationRecord to create connection --- spec/support/ar_models.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index e819b449..5435b964 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -62,6 +62,7 @@ class Comment < CommentsRecord belongs_to :user, dependent: :destroy end + ApplicationRecord.establish_connection CommentsRecord.establish_connection else ActiveRecord::Base.configurations = {default_env: DB_CONFIG} @@ -72,9 +73,9 @@ class ApplicationRecord < ActiveRecord::Base class Comment < ApplicationRecord belongs_to :user, dependent: :destroy end -end -ActiveRecord::Base.establish_connection(**DB_CONFIG) + ActiveRecord::Base.establish_connection(**DB_CONFIG) +end # #truncate_tables is not supported in older Rails, let's just ignore the failures ActiveRecord::Base.connection.truncate_tables(*ActiveRecord::Base.connection.tables) rescue nil # rubocop:disable Style/RescueModifier From 8e30fa32cccebc52b382cca00db6956293f90135 Mon Sep 17 00:00:00 2001 From: Rutger Wessels Date: Thu, 5 Jan 2023 13:25:19 +0100 Subject: [PATCH 081/194] Fix ArgumentError --- lib/test_prof/before_all/adapters/active_record.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 983e72ee..b9fdf7ff 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -8,7 +8,7 @@ module ActiveRecord class << self def all_connections @all_connections ||= if ::ActiveRecord::Base.respond_to? :connects_to - ::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).map(&:connection) + ::ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection) else Array.wrap(::ActiveRecord::Base.connection) end From 841dc694331f0448d9cedc97a050381bd0e28f90 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 7 Feb 2023 13:21:29 -0500 Subject: [PATCH 082/194] feat: allow specifying let_it_be ivar prefix --- .github/workflows/rspec-jruby.yml | 1 + lib/test_prof/recipes/rspec/let_it_be.rb | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rspec-jruby.yml b/.github/workflows/rspec-jruby.yml index b6122574..a2d128fa 100644 --- a/.github/workflows/rspec-jruby.yml +++ b/.github/workflows/rspec-jruby.yml @@ -12,6 +12,7 @@ jobs: env: BUNDLE_JOBS: 4 BUNDLE_RETRY: 3 + LET_IT_BE_IVAR_PREFIX: "@_matroskin_" steps: - uses: actions/checkout@v2 - uses: actions/cache@v1 diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index acbd2402..ec730de1 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -82,10 +82,12 @@ def validate_modifiers!(mods) "Available modifiers are: #{modifiers.keys.join(", ")}" end end + # Use uniq prefix for instance variables to avoid collisions # We want to use the power of Ruby's unicode support) # And we love cats!) - PREFIX = "@😸" + # Allow overriding the prefix (there are some intermittent issues on JRuby still) + PREFIX = ENV.fetch("LET_IT_BE_IVAR_PREFIX", "@😸") FROZEN_ERROR_HINT = "\nIf you are using `let_it_be`, you may want to pass `reload: true` or `refind: true` modifier to it." From 93340548bdb0e8b879423ca3fa3ab7bd1f6f6e67 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 7 Feb 2023 13:26:26 -0500 Subject: [PATCH 083/194] style: upd rubocop config --- .rubocop.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 2578d186..40b38d41 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -30,10 +30,9 @@ Style/TrailingCommaInHashLiteral: Layout/ParameterAlignment: EnforcedStyle: with_first_parameter -# See https://github.com/rubocop-hq/rubocop/issues/4222 -Lint/AmbiguousBlockAssociation: - Exclude: - - 'spec/**/*' +# See https://github.com/rubocop/rubocop/issues/11521 +Lint/FormatParameterMismatch: + Enabled: false Naming/FileName: Exclude: From 1d01b2fe5fb9d72fbd08600d2e592192786a1e4f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 7 Feb 2023 17:29:52 -0500 Subject: [PATCH 084/194] ci: add jobs timeout --- .github/workflows/rspec-jruby.yml | 1 + .github/workflows/rspec.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/rspec-jruby.yml b/.github/workflows/rspec-jruby.yml index a2d128fa..263e0e83 100644 --- a/.github/workflows/rspec-jruby.yml +++ b/.github/workflows/rspec-jruby.yml @@ -9,6 +9,7 @@ on: jobs: rspec-jruby: runs-on: ubuntu-latest + timeout-minutes: 20 env: BUNDLE_JOBS: 4 BUNDLE_RETRY: 3 diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index e59a3c20..d8ad3040 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -9,6 +9,7 @@ on: jobs: rspec: runs-on: ubuntu-latest + timeout-minutes: 10 env: BUNDLE_JOBS: 4 BUNDLE_RETRY: 3 From 5cd75f1a29d98ec57f44302cda74bcb6671e8147 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 7 Feb 2023 18:56:48 -0500 Subject: [PATCH 085/194] changelog: fix links --- CHANGELOG.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33a7d65d..bc80b164 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -281,7 +281,7 @@ end - Add threshold and custom event support to FactoryDoctor. ([@palkan][]) ```sh -$ FDOC=1 FDOC_EVENT="sql.rom" FDOC_THRESHOLD=0.1 rspec +FDOC=1 FDOC_EVENT="sql.rom" FDOC_THRESHOLD=0.1 rspec ``` - Add Fabrication support to FactoryDoctor. ([@palkan][]) @@ -330,16 +330,6 @@ end See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) for versions <0.9.0. [@palkan]: https://github.com/palkan -[@marshall-lee]: https://github.com/marshall-lee -[@danielwestendorf]: https://github.com/danielwestendorf -[@shkrt]: https://github.com/Shkrt -[@idolgirev]: https://github.com/IDolgirev -[@desoleary]: https://github.com/desoleary -[@rabotyaga]: https://github.com/rabotyaga -[@vasfed]: https://github.com/Vasfed -[@szemek]: https://github.com/szemek -[@mkldon]: https://github.com/mkldon -[@dmagro]: https://github.com/dmagro [@danielwaterworth]: https://github.com/danielwaterworth [@envek]: https://github.com/Envek [@tyleriguchi]: https://github.com/tyleriguchi @@ -349,9 +339,12 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@stefkin]: https://github.com/stefkin [@jaimerson]: https://github.com/jaimerson [@alexvko]: https://github.com/alexvko -[@grillermo]: https://github.com/grillermo [@cou929]: https://github.com/cou929 [@ruslanshakirov]: https://github.com/ruslanshakirov [@ygelfand]: https://github.com/ygelfand [@cbliard]: https://github.com/cbliard [@maxshend]: https://github.com/maxshend +[@rutgerw]: https://github.com/rutgerw +[@markedmondson]: https://github.com/markedmondson +[@cbarton]: https://github.com/cbarton +[@peret]: https://github.com/peret From b4f702d6e1256821c7ba96d1ce504ee0908ec037 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 7 Feb 2023 20:45:26 -0500 Subject: [PATCH 086/194] fix(specs): stuck postgres connections in before_all --- spec/test_prof/before_all/adapters/active_record_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/test_prof/before_all/adapters/active_record_spec.rb b/spec/test_prof/before_all/adapters/active_record_spec.rb index c9482757..e0263399 100644 --- a/spec/test_prof/before_all/adapters/active_record_spec.rb +++ b/spec/test_prof/before_all/adapters/active_record_spec.rb @@ -43,12 +43,12 @@ def self.configure context "when the connection is a transaction" do before do connection.begin_transaction + allow(connection).to receive(:rollback_transaction).and_call_original end it "calls rollback_transaction on all available connections" do - expect(connection).to receive(:rollback_transaction) - subject + expect(connection).to have_received(:rollback_transaction) end end end From dadfe0bd431552f725d737c94c878efb55c09649 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 7 Feb 2023 21:37:11 -0500 Subject: [PATCH 087/194] Bump 1.2.0 --- CHANGELOG.md | 4 +++- lib/test_prof/version.rb | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc80b164..b73b76f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ ## master (unreleased) -- Add support for ActiveRecord multiple databases ([@rutgerw][]) +## 1.2.0 (2023-02-07) + +- Add support for multiple databases to `before_all` / `let_it_be` with Active Record. ([@rutgerw][]) ## 1.1.0 (2022-12-06) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index b9f6f58b..4baeb158 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.1.0" + VERSION = "1.2.0" end From ff504045e7e72df1295714cfb3b8bf64c01decca Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 21 Mar 2023 20:46:26 -0400 Subject: [PATCH 088/194] fix: upgrade to ruby-prof 1.4+ Fixes #263 --- CHANGELOG.md | 2 ++ docs/profilers/ruby_prof.md | 4 ++-- lefthook.yml | 19 ------------------- lib/test_prof/ruby_prof.rb | 6 ++---- spec/test_prof/ruby_prof_spec.rb | 5 +---- 5 files changed, 7 insertions(+), 29 deletions(-) delete mode 100644 lefthook.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index b73b76f6..1bd588ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Upgrade to RubyProf 1.4+. ([@palkan][]) + ## 1.2.0 (2023-02-07) - Add support for multiple databases to `before_all` / `let_it_be` with Active Record. ([@rutgerw][]) diff --git a/docs/profilers/ruby_prof.md b/docs/profilers/ruby_prof.md index 56fb736e..0e41b6aa 100644 --- a/docs/profilers/ruby_prof.md +++ b/docs/profilers/ruby_prof.md @@ -4,12 +4,12 @@ Easily integrate the power of [ruby-prof](https://github.com/ruby-prof/ruby-prof ## Instructions -Install `ruby-prof` gem (>= 0.17): +Install `ruby-prof` gem (>= 1.4.0): ```ruby # Gemfile group :development, :test do - gem "ruby-prof", ">= 0.17.0", require: false + gem "ruby-prof", ">= 1.4.0", require: false end ``` diff --git a/lefthook.yml b/lefthook.yml deleted file mode 100644 index 4bcefd5f..00000000 --- a/lefthook.yml +++ /dev/null @@ -1,19 +0,0 @@ -pre-commit: - commands: - mdl: - tags: style - glob: "**/*.md" - exclude: ".github/*" - run: mdl {staged_files} - forspell: - tags: grammar - glob: "**/*.md" - run: forspell {staged_files} - rubocop: - tags: style - glob: "**/*.md" - run: bundle exec rubocop --force-exclusion {staged_files} - lychee: - tags: links - glob: "**/*.md" - run: lychee docs/* diff --git a/lib/test_prof/ruby_prof.rb b/lib/test_prof/ruby_prof.rb index b9867b0b..f28464a3 100644 --- a/lib/test_prof/ruby_prof.rb +++ b/lib/test_prof/ruby_prof.rb @@ -173,9 +173,7 @@ def profile return unless init_ruby_prof - options = { - merge_fibers: true - } + options = {} options[:include_threads] = [Thread.current] unless config.include_threads? @@ -214,7 +212,7 @@ def init_ruby_prof <<~MSG Please, install 'ruby-prof' first: # Gemfile - gem 'ruby-prof', '>= 0.16.0', require: false + gem 'ruby-prof', '>= 1.4.0', require: false MSG ) { check_ruby_prof_version } end diff --git a/spec/test_prof/ruby_prof_spec.rb b/spec/test_prof/ruby_prof_spec.rb index 287107d7..de246472 100644 --- a/spec/test_prof/ruby_prof_spec.rb +++ b/spec/test_prof/ruby_prof_spec.rb @@ -40,7 +40,6 @@ specify "with default config" do expect(ruby_prof).to receive(:new).with({ - merge_fibers: true, include_threads: [Thread.current] }).and_return(profile) @@ -50,9 +49,7 @@ specify "with custom config" do described_class.config.include_threads = true - expect(ruby_prof).to receive(:new).with({ - merge_fibers: true - }).and_return(profile) + expect(ruby_prof).to receive(:new).with({}).and_return(profile) described_class.profile end From 5701ad839ffd776f59e491e6531bfbe5276a2524 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 21 Mar 2023 21:25:15 -0400 Subject: [PATCH 089/194] specs: add before_all + rails fixture spec --- Gemfile | 2 + spec/integrations/before_all_spec.rb | 6 +++ .../before_all_rails_fixtures_fixture.rb | 53 +++++++++++++++++++ .../fixtures/rspec/fixtures/users.yml | 3 ++ test-prof.gemspec | 2 +- 5 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb create mode 100644 spec/integrations/fixtures/rspec/fixtures/users.yml diff --git a/Gemfile b/Gemfile index f87f32d5..a9e61931 100644 --- a/Gemfile +++ b/Gemfile @@ -20,6 +20,8 @@ else end gem "activerecord", "~> 6.0" + gem "actionview" + gem "actionpack" gem "activerecord-import" gem "factory_bot", "~> 5.0" diff --git a/spec/integrations/before_all_spec.rb b/spec/integrations/before_all_spec.rb index 5216c81e..af352c09 100644 --- a/spec/integrations/before_all_spec.rb +++ b/spec/integrations/before_all_spec.rb @@ -28,6 +28,12 @@ expect(output).to include("FailingJob") end + it "works with Rails fixtures" do + output = run_rspec("before_all_rails_fixtures", success: true) + + expect(output).to include("3 examples, 0 failures") + end + specify "database connection" do output = run_rspec("before_all_connection") diff --git a/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb b/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb new file mode 100644 index 00000000..59138881 --- /dev/null +++ b/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) + +require "action_controller/railtie" +require "action_view/railtie" +require "active_record/railtie" +require "rspec/rails" + +require_relative "../../../support/ar_models" +require_relative "../../../support/transactional_context" +require "test_prof/recipes/rspec/before_all" +require "test_prof/recipes/rspec/let_it_be" + +RSpec.configure do |config| + config.fixture_path = File.join(__dir__, "fixtures") +end + +TestProf::BeforeAll.configure do |config| + config.setup_fixtures = true +end + +describe "Post", :transactional do + fixtures :users + + context "with before_all" do + before_all do + @post = TestProf::FactoryBot.create(:post, text: "Test fixtures", user: users(:vova)) + end + + let(:post) { Post.find(@post.id) } + + it "text and user" do + expect(post.user).not_to be_nil + post.text = "" + post.user_id = nil + post.save! + expect(post.reload.text).to be_empty + expect(post.user).to be_nil + end + + it "old text and user" do + expect(post.text).to eq "Test fixtures" + expect(post.user.name).to eq "Vova" + end + end + + context "without before_all" do + specify "no posts" do + expect(Post.count).to eq 0 + end + end +end diff --git a/spec/integrations/fixtures/rspec/fixtures/users.yml b/spec/integrations/fixtures/rspec/fixtures/users.yml new file mode 100644 index 00000000..d4b1e1ec --- /dev/null +++ b/spec/integrations/fixtures/rspec/fixtures/users.yml @@ -0,0 +1,3 @@ +vova: + name: "Vova" + tag: "martian" diff --git a/test-prof.gemspec b/test-prof.gemspec index f4fb492d..d6b20e54 100644 --- a/test-prof.gemspec +++ b/test-prof.gemspec @@ -35,7 +35,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler", ">= 1.16" spec.add_development_dependency "rake", "~> 13.0" - spec.add_development_dependency "rspec", "~> 3.4" + spec.add_development_dependency "rspec-rails", ">= 4.0" spec.add_development_dependency "isolator", ">= 0.6" spec.add_development_dependency "minitest", ">= 5.9" spec.add_development_dependency "rubocop", ">= 0.77.0" From deb83e6789512aa5e14be4f9cfd28a36151f5d6d Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 21 Mar 2023 21:25:55 -0400 Subject: [PATCH 090/194] ci: run tests against rspec-rails 4.x --- .github/workflows/rspec.yml | 3 +++ Gemfile | 4 ++-- gemfiles/rspecrails4.gemfile | 12 ++++++++++++ spec/spec_helper.rb | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 gemfiles/rspecrails4.gemfile diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index d8ad3040..3bdac47a 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -31,6 +31,9 @@ jobs: - ruby: 3.0 gemfile: "gemfiles/activerecord6.gemfile" db: "sqlite" + - ruby: 3.0 + gemfile: "gemfiles/rspecrails4.gemfile" + db: "sqlite" - ruby: 3.0 gemfile: "gemfiles/railsmaster.gemfile" db: "sqlite" diff --git a/Gemfile b/Gemfile index a9e61931..4e80fdf2 100644 --- a/Gemfile +++ b/Gemfile @@ -31,8 +31,8 @@ else gem "timecop", "~> 0.9.1" platform :mri do - gem "pry-byebug" - gem "ruby-prof", ">= 0.16.0" + gem "debug" unless ENV["CI"] + gem "ruby-prof", ">= 1.4.0" gem "stackprof", ">= 0.2.9" end end diff --git a/gemfiles/rspecrails4.gemfile b/gemfiles/rspecrails4.gemfile new file mode 100644 index 00000000..bac2123d --- /dev/null +++ b/gemfiles/rspecrails4.gemfile @@ -0,0 +1,12 @@ +source 'https://rubygems.org' + +gem "activerecord", "~> 6.0" +gem "factory_bot", "~> 5.0" +gem "fabrication" +gem "sqlite3", "~> 1.4" +gem "sidekiq", "~> 6.0" +gem "timecop", "~> 0.9.1" +gem "pg" +gem "rspec-rails", "~> 4.0" + +gemspec path: '..' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d21a5cf9..c05000a3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,7 +2,7 @@ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__) begin - require "pry-byebug" + require "debug" unless ENV["CI"] rescue LoadError end From 80e232481940dc2b343439e6b461997692d382a3 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 21 Mar 2023 21:36:39 -0400 Subject: [PATCH 091/194] fix: use RSpec.current_scope if available --- lib/test_prof/recipes/rspec/before_all.rb | 2 ++ lib/test_prof/recipes/rspec/let_it_be.rb | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/test_prof/recipes/rspec/before_all.rb b/lib/test_prof/recipes/rspec/before_all.rb index b91d2552..85d664bb 100644 --- a/lib/test_prof/recipes/rspec/before_all.rb +++ b/lib/test_prof/recipes/rspec/before_all.rb @@ -12,6 +12,7 @@ def before_all(setup_fixtures: BeforeAll.config.setup_fixtures, &block) if within_before_all? before(:all) do @__inspect_output = "before_all hook" + ::RSpec.current_scope = :before_all if ::RSpec.respond_to?(:current_scope=) instance_eval(&block) end return @@ -22,6 +23,7 @@ def before_all(setup_fixtures: BeforeAll.config.setup_fixtures, &block) before(:all) do @__inspect_output = "before_all hook" + ::RSpec.current_scope = :before_all if ::RSpec.respond_to?(:current_scope=) BeforeAll.setup_fixtures(self) if setup_fixtures BeforeAll.begin_transaction(context, current_metadata) do instance_eval(&block) diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index ec730de1..9364731e 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -120,11 +120,13 @@ def let_it_be(identifier, **options, &block) LetItBe.module_for(self).module_eval do define_method(identifier) do # Trying to detect the context - # Based on https://github.com/rspec/rspec-rails/commit/7cb796db064f58da7790a92e73ab906ef50b1f34 - if /(before|after)\(:context\)/.match?(@__inspect_output) || @__inspect_output.include?("before_all") + # First, check for ::RSpec.current_scope (modern RSpec) and then read @__inspect_output + # (based on https://github.com/rspec/rspec-rails/commit/7cb796db064f58da7790a92e73ab906ef50b1f34) + if ::RSpec.respond_to?(:current_scope) && %i[before_all before_context_hook after_context_hook].include?(::RSpec.current_scope) + instance_variable_get(:"#{PREFIX}#{identifier}") + elsif /(before|after)\(:context\)/.match?(@__inspect_output) || @__inspect_output.include?("before_all") instance_variable_get(:"#{PREFIX}#{identifier}") else - # Fallback to let definition super() end end From 28a8f7fa8f0f7128960501b947174147ca6c6f16 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 22 Mar 2023 11:44:00 -0400 Subject: [PATCH 092/194] fix(specs): set RAILS_ENV=test --- spec/support/ar_models.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index 5435b964..2b3e23b5 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +# Set RAILS_ENV explicitily, so configurations could be picked up +ENV["RAILS_ENV"] = "test" + require "active_record" require "fabrication" require "test_prof" @@ -44,7 +47,7 @@ def multi_db? db_comments_path = File.join(TestProf.config.output_dir, "testdb_comments.sqlite") FileUtils.rm(db_comments_path) if File.file?(db_comments_path) DB_CONFIG_COMMENTS = {adapter: "sqlite3", database: db_comments_path} - ActiveRecord::Base.configurations = {default_env: {comments: DB_CONFIG_COMMENTS, posts: DB_CONFIG}} + ActiveRecord::Base.configurations = {test: {comments: DB_CONFIG_COMMENTS, posts: DB_CONFIG}} class ApplicationRecord < ActiveRecord::Base self.abstract_class = true @@ -65,7 +68,7 @@ class Comment < CommentsRecord ApplicationRecord.establish_connection CommentsRecord.establish_connection else - ActiveRecord::Base.configurations = {default_env: DB_CONFIG} + ActiveRecord::Base.configurations = {test: DB_CONFIG} class ApplicationRecord < ActiveRecord::Base self.abstract_class = true end From b34ebdb6fb5499b5c010f4f3fd86d952165c5418 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 22 Mar 2023 12:20:01 -0400 Subject: [PATCH 093/194] ci: upgrade jruby gemfile to Rails 7 --- .github/workflows/rspec-jruby.yml | 18 ++++-------------- gemfiles/jruby.gemfile | 13 +++++-------- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/.github/workflows/rspec-jruby.yml b/.github/workflows/rspec-jruby.yml index 263e0e83..21255afe 100644 --- a/.github/workflows/rspec-jruby.yml +++ b/.github/workflows/rspec-jruby.yml @@ -13,24 +13,14 @@ jobs: env: BUNDLE_JOBS: 4 BUNDLE_RETRY: 3 + BUNDLE_GEMFILE: gemfiles/jruby.gemfile LET_IT_BE_IVAR_PREFIX: "@_matroskin_" steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v1 - with: - path: /home/runner/bundle - key: bundle-${{ hashFiles('**/gemfiles/jruby.gemfile') }}-${{ hashFiles('**/*.gemspec') }} - restore-keys: | - bundle- + - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: - ruby-version: jruby-9.3 - - name: Bundle install - run: | - bundle config path /home/runner/bundle - bundle config --global gemfile gemfiles/jruby.gemfile - bundle install - bundle update + ruby-version: jruby-head + bundler-cache: true - name: Run RSpec run: | bundle exec rspec --force-color diff --git a/gemfiles/jruby.gemfile b/gemfiles/jruby.gemfile index 0c1d00aa..ed24f00a 100644 --- a/gemfiles/jruby.gemfile +++ b/gemfiles/jruby.gemfile @@ -1,16 +1,13 @@ source 'https://rubygems.org' -gem "activerecord-jdbcsqlite3-adapter", "~> 52.0" +gem "activerecord-jdbcsqlite3-adapter" gem "jdbc-sqlite3" -gem "activerecord", "~> 5.2" -gem "activerecord-import" -# See https://github.com/ruby-i18n/i18n/issues/555 -gem "i18n", "1.8.7" +gem "activerecord", "~> 7.0" -gem "factory_bot", "~> 5.0" +gem "factory_bot" gem "fabrication" -gem "sidekiq", "~> 5.0" -gem "timecop", "~> 0.9.1" +gem "sidekiq" +gem "timecop" gemspec path: '..' From f1790fef861878531f77ff959bd51f9fd32b66fb Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 22 Mar 2023 17:16:02 -0400 Subject: [PATCH 094/194] fix(specs): use transactional tests with fixtures --- .../fixtures/rspec/before_all_rails_fixtures_fixture.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb b/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb index 59138881..abeed370 100644 --- a/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb +++ b/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb @@ -14,13 +14,14 @@ RSpec.configure do |config| config.fixture_path = File.join(__dir__, "fixtures") + config.use_transactional_fixtures = true end TestProf::BeforeAll.configure do |config| config.setup_fixtures = true end -describe "Post", :transactional do +describe "Post" do fixtures :users context "with before_all" do From ae7b6db5e5f7736589b6de14defec6e89e7b87c3 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 22 Mar 2023 17:25:44 -0400 Subject: [PATCH 095/194] changelog: setup_fixtures fix --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bd588ea..9eb36c13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Fix regression with `before_all(setup_fixtures: true)` and `rspec-rails` v6.0+. ([@palkan][]) + - Upgrade to RubyProf 1.4+. ([@palkan][]) ## 1.2.0 (2023-02-07) From 5d263198f8d558f60302481bc2b2f1353e116b65 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 22 Mar 2023 17:41:00 -0400 Subject: [PATCH 096/194] Bump 1.2.1 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eb36c13..b8ec1654 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.2.1 (2023-03-22) + - Fix regression with `before_all(setup_fixtures: true)` and `rspec-rails` v6.0+. ([@palkan][]) - Upgrade to RubyProf 1.4+. ([@palkan][]) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 4baeb158..05ebcd9b 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.2.0" + VERSION = "1.2.1" end From f82c22ebd22cefd1f3da3c362dbb7b72cc926101 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 20 Jun 2023 12:56:13 -0700 Subject: [PATCH 097/194] fix: rubocop compatibility --- .../cops/rspec/aggregate_examples/its_spec.rb | 12 ++++++++++-- .../matchers_with_side_effects_spec.rb | 4 ++++ spec/test_prof/cops/rspec/aggregate_examples_spec.rb | 4 ++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/spec/test_prof/cops/rspec/aggregate_examples/its_spec.rb b/spec/test_prof/cops/rspec/aggregate_examples/its_spec.rb index 863160d5..6661fd07 100644 --- a/spec/test_prof/cops/rspec/aggregate_examples/its_spec.rb +++ b/spec/test_prof/cops/rspec/aggregate_examples/its_spec.rb @@ -3,8 +3,16 @@ require "cop_helper" require "test_prof/cops/rspec/aggregate_examples" -RSpec.describe RuboCop::Cop::RSpec::AggregateExamples, ".its" do - subject(:cop) { described_class.new } +RSpec.describe RuboCop::Cop::RSpec::AggregateExamples, ".its", :config do + let(:all_cops_config) do + {"DisplayCopNames" => false} + end + + let(:cop_config) do + {"AddAggregateFailuresMetadata" => false} + end + + subject(:cop) { described_class.new(config) } # Regular `its` call with an attribute/method name, or a chain of methods # expressed as a string with dots. diff --git a/spec/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects_spec.rb b/spec/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects_spec.rb index ecf36032..b486d115 100644 --- a/spec/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects_spec.rb +++ b/spec/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects_spec.rb @@ -5,6 +5,10 @@ RSpec.describe RuboCop::Cop::RSpec::AggregateExamples, ".matchers_with_side_effects", :config do + let(:all_cops_config) do + {"DisplayCopNames" => false} + end + subject(:cop) { described_class.new(config) } context "without side effect matchers defined in configuration" do diff --git a/spec/test_prof/cops/rspec/aggregate_examples_spec.rb b/spec/test_prof/cops/rspec/aggregate_examples_spec.rb index 357eae96..0d298982 100644 --- a/spec/test_prof/cops/rspec/aggregate_examples_spec.rb +++ b/spec/test_prof/cops/rspec/aggregate_examples_spec.rb @@ -4,6 +4,10 @@ require "test_prof/cops/rspec/aggregate_examples" RSpec.describe RuboCop::Cop::RSpec::AggregateExamples, :config do + let(:all_cops_config) do + {"DisplayCopNames" => false} + end + subject(:cop) { described_class.new(config) } let(:cop_config) do From ea1bdfbf2de7e770521864d58aca26aba358e0f6 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Fri, 16 Jun 2023 13:44:18 -0500 Subject: [PATCH 098/194] feat: easily ignore pools which cannot cannot For an application with multiple databases, allow the databases not-under-test to not be running (not connectable) and for before_all to still work. --- .../before_all/adapters/active_record.rb | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index b9fdf7ff..5c61cfcd 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -8,12 +8,27 @@ module ActiveRecord class << self def all_connections @all_connections ||= if ::ActiveRecord::Base.respond_to? :connects_to - ::ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection) + ::ActiveRecord::Base.connection_handler.connection_pool_list.filter_map {|pool| + begin + pool.connection + rescue *pool_connection_errors => error + log_pool_connection_error(pool, error) + nil + end + } else Array.wrap(::ActiveRecord::Base.connection) end end + def pool_connection_errors + @pool_connection_errors ||= [] + end + + def log_pool_connection_error(pool, error) + warn "Could not connect to pool #{pool.connection_class.name}. #{error.class}: #{error.message}" + end + def begin_transaction @all_connections = nil all_connections.each do |connection| From 7ac65ae3003d34ff2578736cb4a303595396134c Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 21 Jun 2023 08:38:26 -0700 Subject: [PATCH 099/194] style: :cop: --- lib/test_prof/before_all/adapters/active_record.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 5c61cfcd..cb67c6ec 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -8,7 +8,7 @@ module ActiveRecord class << self def all_connections @all_connections ||= if ::ActiveRecord::Base.respond_to? :connects_to - ::ActiveRecord::Base.connection_handler.connection_pool_list.filter_map {|pool| + ::ActiveRecord::Base.connection_handler.connection_pool_list.filter_map { |pool| begin pool.connection rescue *pool_connection_errors => error From cff8245acf23540f88ca67810a919d65bc614c4f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 21 Jun 2023 14:46:22 -0700 Subject: [PATCH 100/194] chore: test against mysql --- .github/workflows/rspec.yml | 51 +++++++++++-------- .gitignore | 2 +- Gemfile | 6 +-- gemfiles/railsmaster.gemfile | 1 + .../fixtures/let_it_be_savepoint_fixture.rb | 28 ++++++++++ spec/bugs/let_it_be_savepoint_spec.rb | 13 +++++ spec/support/ar_models.rb | 14 ++++- spec/test_prof/any_fixture_spec.rb | 4 ++ 8 files changed, 92 insertions(+), 27 deletions(-) create mode 100644 spec/bugs/fixtures/let_it_be_savepoint_fixture.rb create mode 100644 spec/bugs/let_it_be_savepoint_spec.rb diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 3bdac47a..051e909f 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -13,6 +13,14 @@ jobs: env: BUNDLE_JOBS: 4 BUNDLE_RETRY: 3 + BUNDLE_GEMFILE: ${{ matrix.gemfile }} + CI: true + POSTGRES_URL: postgres://postgres:postgres@localhost:5432 + MYSQL_URL: mysql2://rails:rails@127.0.0.1:3306 + DB: ${{ matrix.db }} + MULTI_DB: ${{ matrix.multi_db }} + # Use postgres for all DB to avoid dealing with PG db creation + DB_NAME: postgres strategy: fail-fast: false matrix: @@ -20,6 +28,9 @@ jobs: gemfile: ["gemfiles/activerecord6.gemfile"] db: ["postgres"] include: + - ruby: 3.2 + gemfile: "gemfiles/railsmaster.gemfile" + db: "mysql" - ruby: 3.1 gemfile: "gemfiles/activerecord7.gemfile" db: "sqlite" @@ -31,6 +42,7 @@ jobs: - ruby: 3.0 gemfile: "gemfiles/activerecord6.gemfile" db: "sqlite" + db_url: ~ - ruby: 3.0 gemfile: "gemfiles/rspecrails4.gemfile" db: "sqlite" @@ -57,33 +69,30 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 5 + mysql: + image: mysql:8 + ports: ["3306:3306"] + env: + MYSQL_PASSWORD: rails + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: postgres + MYSQL_USER: rails + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v1 - with: - path: /home/runner/bundle - key: bundle-${{ matrix.ruby }}-${{ matrix.gemfile }}-${{ hashFiles(matrix.gemfile) }}-${{ hashFiles('**/*.gemspec') }} - restore-keys: | - bundle-${{ matrix.ruby }}-${{ matrix.gemfile }}- - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby }} + - uses: actions/checkout@v3 - name: Install system deps run: | sudo apt-get update sudo apt-get install libsqlite3-dev libpq-dev postgresql-client - - name: Bundle install - run: | - bundle config path /home/runner/bundle - bundle config --global gemfile ${{ matrix.gemfile }} - bundle install - bundle update + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true - name: Run RSpec - env: - DB: ${{ matrix.db }} - MULTI_DB: ${{ matrix.multi_db }} - DATABASE_URL: postgres://postgres:postgres@localhost:5432 - DB_NAME: postgres run: | bundle exec rspec --force-color diff --git a/.gitignore b/.gitignore index be6fa8bb..20d4d8a4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,5 @@ gemfiles/*.lock spec/integrations/fixtures/rspec/tmp/ spec/integrations/fixtures/rspec/gemfiles/*.lock -Gemfile.local +Gemfile.local* tmp/ diff --git a/Gemfile b/Gemfile index 4e80fdf2..229f426b 100644 --- a/Gemfile +++ b/Gemfile @@ -15,11 +15,11 @@ else end platform :jruby do - gem "activerecord-jdbcsqlite3-adapter", "~> 60.0" - gem "activerecord", "~> 6.0" + gem "activerecord-jdbcsqlite3-adapter" + gem "activerecord", "~> 7.0" end - gem "activerecord", "~> 6.0" + gem "activerecord", "~> 7.0" gem "actionview" gem "actionpack" gem "activerecord-import" diff --git a/gemfiles/railsmaster.gemfile b/gemfiles/railsmaster.gemfile index 1fce300d..175868bd 100644 --- a/gemfiles/railsmaster.gemfile +++ b/gemfiles/railsmaster.gemfile @@ -8,5 +8,6 @@ gem "sqlite3", "~> 1.4.0" gem "sidekiq", "~> 4.0" gem "timecop", "~> 0.9.1" gem "pg" +gem "mysql2" gemspec path: ".." diff --git a/spec/bugs/fixtures/let_it_be_savepoint_fixture.rb b/spec/bugs/fixtures/let_it_be_savepoint_fixture.rb new file mode 100644 index 00000000..b5e0433e --- /dev/null +++ b/spec/bugs/fixtures/let_it_be_savepoint_fixture.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "action_controller/railtie" +require "action_view/railtie" +require "active_record/railtie" +require "rspec/rails" + +require_relative "../../support/ar_models" + +RSpec.configure do |config| + config.fixture_path = File.join(__dir__, "fixtures") + config.use_transactional_fixtures = true +end + +require "test_prof/recipes/rspec/let_it_be" + +RSpec.configure do |config| + config.include TestProf::FactoryBot::Syntax::Methods +end + +describe "let_it_be no-op" do + context "without db calls" do + let_it_be(:foo) { 1 } + + specify { expect(1).to eq 1 } + specify { expect(foo).to eq 1 } + end +end diff --git a/spec/bugs/let_it_be_savepoint_spec.rb b/spec/bugs/let_it_be_savepoint_spec.rb new file mode 100644 index 00000000..9015df51 --- /dev/null +++ b/spec/bugs/let_it_be_savepoint_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# https://github.com/test-prof/test-prof/issues/265 +describe "let_it_be + mysql + savepoints", type: :integration do + specify "works" do + output = run_rspec( + "let_it_be_savepoint", + chdir: File.join(__dir__, "fixtures") + ) + + expect(output).to include("0 failures") + end +end diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index 2b3e23b5..dced91d3 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -29,12 +29,21 @@ def multi_db? db_path = File.join(TestProf.config.output_dir, "testdb.sqlite") FileUtils.rm(db_path) if File.file?(db_path) {adapter: "sqlite3", database: db_path} - elsif ENV["DB"] == "postgres" + elsif ENV["DB"] == "postgres" || ENV["DB"] == "mysql" require "active_record/database_configurations" + url = ENV.fetch("DATABASE_URL") do + case ENV["DB"] + when "postgres" + ENV.fetch("POSTGRES_URL") + when "mysql" + ENV.fetch("MYSQL_URL") + end + end + config = ActiveRecord::DatabaseConfigurations::UrlConfig.new( "test", "primary", - ENV.fetch("DATABASE_URL"), + url, {"database" => ENV.fetch("DB_NAME", "test_prof_test")} ) config.respond_to?(:configuration_hash) ? config.configuration_hash : config.config @@ -120,6 +129,7 @@ class Comment < ApplicationRecord else Logger.new(IO::NULL) end + class User < ApplicationRecord validates :name, presence: true has_many :posts, dependent: :destroy diff --git a/spec/test_prof/any_fixture_spec.rb b/spec/test_prof/any_fixture_spec.rb index a0e1cffb..42ee24cf 100644 --- a/spec/test_prof/any_fixture_spec.rb +++ b/spec/test_prof/any_fixture_spec.rb @@ -93,6 +93,10 @@ User.delete_all end + before do + skip unless ActiveRecord::Base.connection.adapter_name.match?(/(sqlite|postgres)/i) + end + after do subject.reset # Reset manually data populated via CLI tools From 3e131231b3ef5ff4a48cf30225154a4953da3fcc Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 26 Jun 2023 11:41:27 -0700 Subject: [PATCH 101/194] ci: increase jruby timeout --- .github/workflows/rspec-jruby.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec-jruby.yml b/.github/workflows/rspec-jruby.yml index 21255afe..c0dfbf23 100644 --- a/.github/workflows/rspec-jruby.yml +++ b/.github/workflows/rspec-jruby.yml @@ -9,7 +9,7 @@ on: jobs: rspec-jruby: runs-on: ubuntu-latest - timeout-minutes: 20 + timeout-minutes: 30 env: BUNDLE_JOBS: 4 BUNDLE_RETRY: 3 From 2c32f4d0e2eebe5cb956e20950c33c7d262fb9ef Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 27 Jun 2023 12:28:36 -0700 Subject: [PATCH 102/194] Bump 1.2.2 --- CHANGELOG.md | 7 +++++++ lib/test_prof/version.rb | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ec1654..d95d88ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## master (unreleased) +## 1.2.2 (2023-06-27) + +- Ignore inaccessible connection pools in `before_all`. ([@bf4][]) + +See [#267](https://github.com/test-prof/test-prof/pull/267). + ## 1.2.1 (2023-03-22) - Fix regression with `before_all(setup_fixtures: true)` and `rspec-rails` v6.0+. ([@palkan][]) @@ -356,3 +362,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@markedmondson]: https://github.com/markedmondson [@cbarton]: https://github.com/cbarton [@peret]: https://github.com/peret +[@bf4]: https://github.com/bf4 diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 05ebcd9b..f6304917 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.2.1" + VERSION = "1.2.2" end From dbf4169b6ede87753be5a31a4c0d17c3667733e3 Mon Sep 17 00:00:00 2001 From: Alex Duller Date: Mon, 3 Jul 2023 09:46:48 +0100 Subject: [PATCH 103/194] chore: Change "haven's" to "haven't" in warning messages. --- lib/test_prof/ruby_prof.rb | 2 +- lib/test_prof/stack_prof.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/test_prof/ruby_prof.rb b/lib/test_prof/ruby_prof.rb index f28464a3..591b59fc 100644 --- a/lib/test_prof/ruby_prof.rb +++ b/lib/test_prof/ruby_prof.rb @@ -166,7 +166,7 @@ def profile log :warn, <<~MSG RubyProf is activated globally, you cannot generate per-example report. - Make sure you haven's set the TEST_RUBY_PROF environmental variable. + Make sure you haven't set the TEST_RUBY_PROF environmental variable. MSG return end diff --git a/lib/test_prof/stack_prof.rb b/lib/test_prof/stack_prof.rb index 061063a6..f17f3dc1 100644 --- a/lib/test_prof/stack_prof.rb +++ b/lib/test_prof/stack_prof.rb @@ -83,7 +83,7 @@ def profile(name = nil) log :warn, <<~MSG StackProf is activated globally, you cannot generate per-example report. - Make sure you haven's set the TEST_STACK_PROF environmental variable. + Make sure you haven't set the TEST_STACK_PROF environmental variable. MSG return false end From 17d674dfe9bbccab45a436f64bb1e1cc774e8572 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 10 Jul 2023 20:49:09 -0700 Subject: [PATCH 104/194] chore: extract test_prof/core.rb Fixes #270 --- lib/test_prof.rb | 166 +--------------------- lib/test_prof/any_fixture.rb | 2 +- lib/test_prof/before_all.rb | 2 +- lib/test_prof/core.rb | 167 +++++++++++++++++++++++ lib/test_prof/factory_all_stub.rb | 2 +- lib/test_prof/factory_default.rb | 2 +- lib/test_prof/recipes/logging.rb | 2 +- lib/test_prof/recipes/rspec/let_it_be.rb | 2 +- 8 files changed, 174 insertions(+), 171 deletions(-) create mode 100644 lib/test_prof/core.rb diff --git a/lib/test_prof.rb b/lib/test_prof.rb index eef6c49c..47decd21 100644 --- a/lib/test_prof.rb +++ b/lib/test_prof.rb @@ -1,171 +1,7 @@ # frozen_string_literal: true -require "fileutils" -require "logger" - require "test_prof/version" -require "test_prof/logging" -require "test_prof/utils" - -# Ruby applications tests profiling tools. -# -# Contains tools to analyze factories usage, integrate with Ruby profilers, -# profile your examples using ActiveSupport notifications (if any) and -# statically analyze your code with custom RuboCop cops. -# -# Example usage: -# -# require 'test_prof' -# -# # Activate a tool by providing environment variable, e.g. -# TEST_RUBY_PROF=1 rspec ... -# -# # or manually in your code -# TestProf::RubyProf.run -# -# See other modules for more examples. -module TestProf - class << self - include Logging - - def config - @config ||= Configuration.new - end - - def configure - yield config - end - - # Returns true if we're inside RSpec - def rspec? - defined?(RSpec::Core) - end - - # Returns true if we're inside Minitest - def minitest? - defined?(Minitest) - end - - # Returns true if Spring is used and not disabled - def spring? - # See https://github.com/rails/spring/blob/577cf01f232bb6dbd0ade7df2df2ac209697e741/lib/spring/binstub.rb - disabled = ENV["DISABLE_SPRING"] - defined?(::Spring::Application) && (disabled.nil? || disabled.empty? || disabled == "0") - end - - # Returns the current process time - def now - Process.clock_gettime(Process::CLOCK_MONOTONIC) - end - - # Require gem and shows a custom - # message if it fails to load - def require(gem_name, msg = nil) - Kernel.require gem_name - block_given? ? yield : true - rescue LoadError - log(:error, msg) if msg - false - end - - # Run block only if provided env var is present and - # equal to the provided value (if any). - # Contains workaround for applications using Spring. - def activate(env_var, val = nil) - if spring? - notify_spring_detected - ::Spring.after_fork do - activate!(env_var, val) do - notify_spring_activate env_var - yield - end - end - else - activate!(env_var, val) { yield } - end - end - - # Return absolute path to asset - def asset_path(filename) - ::File.expand_path(filename, ::File.join(::File.dirname(__FILE__), "..", "assets")) - end - - # Return a path to store artifact - def artifact_path(filename) - create_artifact_dir - - with_timestamps( - ::File.join( - config.output_dir, - with_report_suffix( - filename - ) - ) - ) - end - - def create_artifact_dir - FileUtils.mkdir_p(config.output_dir)[0] - end - - private - - def activate!(env_var, val) - yield if ENV[env_var] && (val.nil? || val === ENV[env_var]) - end - - def with_timestamps(path) - return path unless config.timestamps? - timestamps = "-#{now.to_i}" - "#{path.sub(/\.\w+$/, "")}#{timestamps}#{::File.extname(path)}" - end - - def with_report_suffix(path) - return path if config.report_suffix.nil? - - "#{path.sub(/\.\w+$/, "")}-#{config.report_suffix}#{::File.extname(path)}" - end - - def notify_spring_detected - return if instance_variable_defined?(:@spring_notified) - log :info, "Spring detected" - @spring_notified = true - end - - def notify_spring_activate(env_var) - log :info, "Activating #{env_var} with `Spring.after_fork`" - end - end - - # TestProf configuration - class Configuration - attr_accessor :output, # IO to write logs - :color, # Whether to colorize output or not - :output_dir, # Directory to store artifacts - :timestamps, # Whether to use timestamped names for artifacts, - :report_suffix # Custom suffix for reports/artifacts - - def initialize - @output = $stdout - @color = true - @output_dir = "tmp/test_prof" - @timestamps = false - @report_suffix = ENV["TEST_PROF_REPORT"] - end - - def color? - color == true && output.is_a?(IO) && output.tty? - end - - def timestamps? - timestamps == true - end - - def logger - @logger ||= Logger.new(output, formatter: Logging::Formatter.new) - end - end -end +require "test_prof/core" require "test_prof/ruby_prof" require "test_prof/stack_prof" diff --git a/lib/test_prof/any_fixture.rb b/lib/test_prof/any_fixture.rb index 7b696d04..9e792d25 100644 --- a/lib/test_prof/any_fixture.rb +++ b/lib/test_prof/any_fixture.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "test_prof" +require "test_prof/core" require "test_prof/ext/float_duration" require "test_prof/any_fixture/dump" diff --git a/lib/test_prof/before_all.rb b/lib/test_prof/before_all.rb index 10e13c16..bf30d2fd 100644 --- a/lib/test_prof/before_all.rb +++ b/lib/test_prof/before_all.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "test_prof" +require "test_prof/core" module TestProf # `before_all` helper configuration diff --git a/lib/test_prof/core.rb b/lib/test_prof/core.rb new file mode 100644 index 00000000..921b6e7b --- /dev/null +++ b/lib/test_prof/core.rb @@ -0,0 +1,167 @@ +# frozen_string_literal: true + +require "fileutils" +require "logger" + +require "test_prof/logging" +require "test_prof/utils" + +# Ruby applications tests profiling tools. +# +# Contains tools to analyze factories usage, integrate with Ruby profilers, +# profile your examples using ActiveSupport notifications (if any) and +# statically analyze your code with custom RuboCop cops. +# +# Example usage: +# +# require 'test_prof' +# +# # Activate a tool by providing environment variable, e.g. +# TEST_RUBY_PROF=1 rspec ... +# +# # or manually in your code +# TestProf::RubyProf.run +# +# See other modules for more examples. +module TestProf + class << self + include Logging + + def config + @config ||= Configuration.new + end + + def configure + yield config + end + + # Returns true if we're inside RSpec + def rspec? + defined?(RSpec::Core) + end + + # Returns true if we're inside Minitest + def minitest? + defined?(Minitest) + end + + # Returns true if Spring is used and not disabled + def spring? + # See https://github.com/rails/spring/blob/577cf01f232bb6dbd0ade7df2df2ac209697e741/lib/spring/binstub.rb + disabled = ENV["DISABLE_SPRING"] + defined?(::Spring::Application) && (disabled.nil? || disabled.empty? || disabled == "0") + end + + # Returns the current process time + def now + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + + # Require gem and shows a custom + # message if it fails to load + def require(gem_name, msg = nil) + Kernel.require gem_name + block_given? ? yield : true + rescue LoadError + log(:error, msg) if msg + false + end + + # Run block only if provided env var is present and + # equal to the provided value (if any). + # Contains workaround for applications using Spring. + def activate(env_var, val = nil) + if spring? + notify_spring_detected + ::Spring.after_fork do + activate!(env_var, val) do + notify_spring_activate env_var + yield + end + end + else + activate!(env_var, val) { yield } + end + end + + # Return absolute path to asset + def asset_path(filename) + ::File.expand_path(filename, ::File.join(::File.dirname(__FILE__), "..", "..", "assets")) + end + + # Return a path to store artifact + def artifact_path(filename) + create_artifact_dir + + with_timestamps( + ::File.join( + config.output_dir, + with_report_suffix( + filename + ) + ) + ) + end + + def create_artifact_dir + FileUtils.mkdir_p(config.output_dir)[0] + end + + private + + def activate!(env_var, val) + yield if ENV[env_var] && (val.nil? || val === ENV[env_var]) + end + + def with_timestamps(path) + return path unless config.timestamps? + timestamps = "-#{now.to_i}" + "#{path.sub(/\.\w+$/, "")}#{timestamps}#{::File.extname(path)}" + end + + def with_report_suffix(path) + return path if config.report_suffix.nil? + + "#{path.sub(/\.\w+$/, "")}-#{config.report_suffix}#{::File.extname(path)}" + end + + def notify_spring_detected + return if instance_variable_defined?(:@spring_notified) + log :info, "Spring detected" + @spring_notified = true + end + + def notify_spring_activate(env_var) + log :info, "Activating #{env_var} with `Spring.after_fork`" + end + end + + # TestProf configuration + class Configuration + attr_accessor :output, # IO to write logs + :color, # Whether to colorize output or not + :output_dir, # Directory to store artifacts + :timestamps, # Whether to use timestamped names for artifacts, + :report_suffix # Custom suffix for reports/artifacts + + def initialize + @output = $stdout + @color = true + @output_dir = "tmp/test_prof" + @timestamps = false + @report_suffix = ENV["TEST_PROF_REPORT"] + end + + def color? + color == true && output.is_a?(IO) && output.tty? + end + + def timestamps? + timestamps == true + end + + def logger + @logger ||= Logger.new(output, formatter: Logging::Formatter.new) + end + end +end diff --git a/lib/test_prof/factory_all_stub.rb b/lib/test_prof/factory_all_stub.rb index 95cf2ced..85d19e0d 100644 --- a/lib/test_prof/factory_all_stub.rb +++ b/lib/test_prof/factory_all_stub.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "test_prof" +require "test_prof/core" require "test_prof/factory_bot" require "test_prof/factory_all_stub/factory_bot_patch" diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 51e8cc33..64ce7ab5 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "test_prof" +require "test_prof/core" require "test_prof/factory_bot" require "test_prof/factory_default/factory_bot_patch" require "test_prof/ext/float_duration" diff --git a/lib/test_prof/recipes/logging.rb b/lib/test_prof/recipes/logging.rb index a40a59ad..507f9310 100644 --- a/lib/test_prof/recipes/logging.rb +++ b/lib/test_prof/recipes/logging.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "test_prof" +require "test_prof/core" module TestProf module Rails diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index 9364731e..00073c9f 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "test_prof" +require "test_prof/core" require "test_prof/recipes/rspec/before_all" module TestProf From 4203616d0cf69e7874177ba84fe2a59b0f177a88 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 11 Sep 2023 18:23:15 -0700 Subject: [PATCH 105/194] fix: set ruby-prof measure mode via Profile Fixes #273 --- lib/test_prof/ruby_prof.rb | 20 ++++++++++++++++++-- spec/test_prof/ruby_prof_spec.rb | 13 ++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/lib/test_prof/ruby_prof.rb b/lib/test_prof/ruby_prof.rb index 591b59fc..51f3a713 100644 --- a/lib/test_prof/ruby_prof.rb +++ b/lib/test_prof/ruby_prof.rb @@ -53,7 +53,7 @@ class Configuration def initialize @printer = ENV["TEST_RUBY_PROF"].to_sym if PRINTERS.key?(ENV["TEST_RUBY_PROF"]) @printer ||= ENV.fetch("TEST_RUBY_PROF_PRINTER", :flat).to_sym - @mode = ENV.fetch("TEST_RUBY_PROF_MODE", :wall).to_sym + @mode = ENV.fetch("TEST_RUBY_PROF_MODE", :wall).to_s @min_percent = 1 @include_threads = false @exclude_common_methods = true @@ -84,6 +84,22 @@ def resolve_printer [type, ::RubyProf.const_get(PRINTERS[type])] end + + # Based on deprecated https://github.com/ruby-prof/ruby-prof/blob/fd3a5236a459586c5ca7ce4de506c1835129516a/lib/ruby-prof.rb#L36 + def ruby_prof_mode + case mode + when "wall", "wall_time" + ::RubyProf::WALL_TIME + when "allocations" + ::RubyProf::ALLOCATIONS + when "memory" + ::RubyProf::MEMORY + when "process", "process_time" + ::RubyProf::PROCESS_TIME + else + ::RubyProf::WALL_TIME + end + end end # Wrapper over RubyProf profiler and printer @@ -177,6 +193,7 @@ def profile options[:include_threads] = [Thread.current] unless config.include_threads? + options[:measure_mode] = config.ruby_prof_mode profiler = ::RubyProf::Profile.new(options) profiler.exclude_common_methods! if config.exclude_common_methods? @@ -206,7 +223,6 @@ def locked? def init_ruby_prof return @initialized if instance_variable_defined?(:@initialized) - ENV["RUBY_PROF_MEASURE_MODE"] = config.mode.to_s @initialized = TestProf.require( "ruby-prof", <<~MSG diff --git a/spec/test_prof/ruby_prof_spec.rb b/spec/test_prof/ruby_prof_spec.rb index de246472..6c81a6f8 100644 --- a/spec/test_prof/ruby_prof_spec.rb +++ b/spec/test_prof/ruby_prof_spec.rb @@ -1,6 +1,12 @@ # frozen_string_literal: true describe TestProf::RubyProf do + before do + next if defined?(::RubyProf::WALL_TIME) + + stub_const("::RubyProf::WALL_TIME", 0) + end + # Use fresh config all for every example after { described_class.remove_instance_variable(:@config) } @@ -9,7 +15,7 @@ specify "defaults", :aggregate_failures do expect(subject.printer).to eq :flat - expect(subject.mode).to eq :wall + expect(subject.mode).to eq "wall" expect(subject.min_percent).to eq 1 expect(subject.include_threads).to eq false end @@ -40,7 +46,8 @@ specify "with default config" do expect(ruby_prof).to receive(:new).with({ - include_threads: [Thread.current] + include_threads: [Thread.current], + measure_mode: 0 }).and_return(profile) expect(described_class.profile).to be_a(described_class::Report) @@ -49,7 +56,7 @@ specify "with custom config" do described_class.config.include_threads = true - expect(ruby_prof).to receive(:new).with({}).and_return(profile) + expect(ruby_prof).to receive(:new).with({measure_mode: 0}).and_return(profile) described_class.profile end From 4505ac7b7644fe1221c3981400769d1913e95388 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 11 Sep 2023 18:35:51 -0700 Subject: [PATCH 106/194] fix: Minitest::Unit becomes ancient --- lib/test_prof/recipes/minitest/sample.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/test_prof/recipes/minitest/sample.rb b/lib/test_prof/recipes/minitest/sample.rb index 69976906..e26b6ff5 100644 --- a/lib/test_prof/recipes/minitest/sample.rb +++ b/lib/test_prof/recipes/minitest/sample.rb @@ -6,9 +6,9 @@ module MinitestSample # Do not add these classes to resulted sample CORE_RUNNABLES = [ Minitest::Test, - Minitest::Unit::TestCase, + defined?(Minitest::Unit::TestCase) ? Minitest::Unit::TestCase : nil, Minitest::Spec - ].freeze + ].compact.freeze class << self def suites From 095edc3f0303de896121c869068670927c14283a Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 11 Sep 2023 18:36:36 -0700 Subject: [PATCH 107/194] style: upgrade rubocop --- lib/test_prof/any_fixture/dump/sqlite.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/any_fixture/dump/sqlite.rb b/lib/test_prof/any_fixture/dump/sqlite.rb index 654067fd..962af315 100644 --- a/lib/test_prof/any_fixture/dump/sqlite.rb +++ b/lib/test_prof/any_fixture/dump/sqlite.rb @@ -18,7 +18,7 @@ def reset_sequence!(table_name, start) end def compile_sql(sql, binds) - sql.gsub(/\?/) { binds.shift.gsub("\n", "' || char(10) || '") } + sql.gsub("?") { binds.shift.gsub("\n", "' || char(10) || '") } end def import(path) From bd8502e3a8f2bfdfcc259b2ac900d956c493b079 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 11 Sep 2023 19:04:31 -0700 Subject: [PATCH 108/194] Bump 1.2.3 --- CHANGELOG.md | 4 ++++ lib/test_prof/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d95d88ad..fff918c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +## 1.2.3 (2023-09-11) + +- Minor fixes and dependecies upgrades. + ## 1.2.2 (2023-06-27) - Ignore inaccessible connection pools in `before_all`. ([@bf4][]) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index f6304917..91605a4a 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.2.2" + VERSION = "1.2.3" end From bda0d767b62c4da297ac16380c79ddae7fbaf6b5 Mon Sep 17 00:00:00 2001 From: Sam Clopton Date: Wed, 1 Nov 2023 23:11:21 -0700 Subject: [PATCH 109/194] Rename FactoryGirl to FactoryBot in AnyFixture Docs --- docs/recipes/any_fixture.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/recipes/any_fixture.md b/docs/recipes/any_fixture.md index 95682b24..a6c19ff7 100644 --- a/docs/recipes/any_fixture.md +++ b/docs/recipes/any_fixture.md @@ -18,7 +18,7 @@ RSpec.shared_context "account", account: true do @account = TestProf::AnyFixture.register(:account) do # Do anything here, AnyFixture keeps track of affected DB tables # For example, you can use factories here - FactoryGirl.create(:account) + FactoryBot.create(:account) # or with Fabrication Fabricate(:account) @@ -183,7 +183,7 @@ RSpec.shared_context "account", account: true do TestProf::AnyFixture.register_dump("account") do # Do anything here, AnyFixture keeps track of affected DB tables # For example, you can use factories here - account = FactoryGirl.create(:account, name: "test") + account = FactoryBot.create(:account, name: "test") # or with Fabrication account = Fabricate(:account, name: "test") From ffd472977120bf458b1a05f1d1c48170ac600842 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 2 Nov 2023 20:00:47 -0700 Subject: [PATCH 110/194] ci: use Rails 7.0 with JRuby Rails 7.1 failes due to some ActiveRecord changes, will try later --- gemfiles/jruby.gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gemfiles/jruby.gemfile b/gemfiles/jruby.gemfile index ed24f00a..04e29a72 100644 --- a/gemfiles/jruby.gemfile +++ b/gemfiles/jruby.gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' gem "activerecord-jdbcsqlite3-adapter" gem "jdbc-sqlite3" -gem "activerecord", "~> 7.0" +gem "activerecord", "~> 7.0.0" gem "factory_bot" gem "fabrication" From 2c8ff66ff57c59a85ee1015a6bcf44612845c555 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 2 Nov 2023 20:03:53 -0700 Subject: [PATCH 111/194] fix(before_all): select connections with :writing role only Fixes #279 --- lib/test_prof/before_all/adapters/active_record.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index cb67c6ec..7079c7ee 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -5,10 +5,12 @@ module BeforeAll module Adapters # ActiveRecord adapter for `before_all` module ActiveRecord + POOL_ARGS = ((::ActiveRecord::VERSION::MAJOR > 6) ? [:writing] : []).freeze + class << self def all_connections @all_connections ||= if ::ActiveRecord::Base.respond_to? :connects_to - ::ActiveRecord::Base.connection_handler.connection_pool_list.filter_map { |pool| + ::ActiveRecord::Base.connection_handler.connection_pool_list(*POOL_ARGS).filter_map { |pool| begin pool.connection rescue *pool_connection_errors => error From 34c63c1389082a4619263365cb2582d24cbce11c Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 13 Nov 2023 19:25:22 -0800 Subject: [PATCH 112/194] docs: playbook --- docs/_sidebar.md | 1 + docs/playbook.md | 203 +++++++++++++++++++++++++++++++++++++ docs/profilers/tag_prof.md | 2 +- 3 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 docs/playbook.md diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 7d7bb64d..5a2c2a2d 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,6 +1,7 @@ * [Getting Started](/getting_started.md) +* [Playbook](/playbook.md) * Profilers * [RubyProf Integration](/profilers/ruby_prof.md) diff --git a/docs/playbook.md b/docs/playbook.md new file mode 100644 index 00000000..2866b833 --- /dev/null +++ b/docs/playbook.md @@ -0,0 +1,203 @@ +# Playbook + +This document aims to help you get started with profiling test suites and answers the following questions: which profiles to run first? How do we interpret the results to choose the next steps? Etc. + +**NOTE**: This document assumes you're working with a Ruby on Rails application and RSpec testing framework. The ideas can easily be translated into other frameworks. + +## Step 0. Configuration basics + +Low-hanging configuration fruits: + +- Disable logging in tests—it's useless. If you really need it, use our [logging utils](./recipes/logging.md). + + ```ruby + config.logger = ActiveSupport::TaggedLogging.new(Logger.new(nil)) + config.log_level = :fatal + ``` + +- Disable coverage and built-in profiling by default. Use env var to enable it (e.g., `COVERAGE=true`) + +## Step 1. General profiling + +It helps to identify not-so-low hanging fruits. We recommend using [StackProf](./profilers/stack_prof.md), so you must install it first (if not yet): + +```sh +bundle add stackprof +``` + +Configure Test Prof to generate JSON profiles by default: + +```sh +TestProf::StackProf.configure do |config| + config.format = "json" +end +``` + +We recommend using [speedscope](https://www.speedscope.app) to analyze these profiles. + +### Step 1.1. Application boot profiling + +```sh +TEST_STACK_PROF=boot rspec ./spec/some_spec.rb +``` + +**NOTE:** running a single spec/test is enough for this profiling. + +What to look for? Some examples: + +- No [Bootsnap](https://github.com/Shopify/bootsnap) used or not configured to cache everything (e.g., YAML files) +- Slow Rails initializers that are not needed in tests. + +### Step 1.2. Sampling tests profiling + +The idea is to run a random subset of tests multiple times to reveal some application-wide problems. You must enable the [sampling feature](./recipes/tests_sampling.md) first: + +```rb +# For RSpec in your spec_helper.rb +require "test_prof/recipes/rspec/sample" + +# For Minitest in your test_helper.rb +require "test_prof/recipes/minitest/sample" +``` + +Then run **multiple times** and analyze the obtained flamegraphs: + +```sh +SAMPLE=100 bin/rails test +# or +SAMPLE=100 bin/rspec +``` + +Common findings: + +- Encryption calls (`*crypt*`-whatever): relax the settings in the test env +- Log calls: are you sure you disabled logs? +- Databases: maybe there are some low-hanging fruits (like using DatabaseCleaner truncation for every test instead of transactions) +- Network: should not be there for unit tests, inevitable for browser tests; use [Webmock](https://github.com/bblimke/webmock) to disable HTTP calls completely. + +## Step 2. Narrow down the scope + +This is an important step for large codebases. We must prioritize quick fixes that bring the most value (time reduction) over dealing with complex, slow tests individually (even if they're the slowest ones). For that, we first identify the **types of tests** contributing the most to the overall run time. + +We use [TagProf](./profilers/tag_prof.md) for that: + +```ruby +TAG_PROF=type TAG_PROF_FORMAT=html TAG_PROF_EVENT=sql.active_record,factory.create bin/rspec +``` + +Looking at the generated diagram, you can identify the two most time-consuming test types (usually models and/or controllers among them). + +We assume that it's easier to find a common slowness cause for the whole group and fix it than dealing with individual tests. Given that assumption, we continue the process only within the selected group (let's say, models). + +## Step 3. Specialized profiling + +Within the selected group, we can first perform quick event-based profiling via [EventProf](./profilers/event_prof.md). (Maybe, with sampling enabled as well). + +### Step 3.1. Dependencies configuration + +At this point, we may identify some misconfigured or misused dependencies/gems. Common examples: + +- Inlined Sidekiq jobs: + + ```sh + EVENT_PROF=sidekiq.inline bin/rspec spec/models + ``` + +- Wisper broadcasts ([patch required](https://gist.github.com/palkan/aa7035cebaeca7ed76e433981f90c07b)): + + ```sh + EVENT_PROF=wisper.publisher.broadcast bin/rspec spec/models + ``` + +- PaperTrail logs creation: + + Enable custom profiling: + + ```rb + TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_create) + TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_destroy) + TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_update) + ``` + + Run tests: + + ```sh + EVENT_PROF=paper_trail.record bin/rspec spec/models + ``` + +See [the Sidekiq example](https://evilmartians.com/chronicles/testprof-a-good-doctor-for-slow-ruby-tests#background-jobs) on how to quickly fix such problems using [RSpecStamp](./recipes/rspec_stamp.md). + +### Step 3.2. Data generation + +Identify the slowest tests based on the amount of time spent in the database or factories (if any): + +```sh +# Database interactions +EVENT_PROF=sql.active_record bin/rspec spec/models + +# Factories +EVENT_PROF=factory.create bin/rspec spec/models +``` + +Now, we can narrow our scope further to the top 10 files from the generated reports. If you use factories, use the `factory.create` report. + +**TIP:** In RSpec, you can mark the slowest examples with a custom tag automatically using the following command: + +```sh +EVENT_PROF=factory.create EVEN_PROF_STAMP=slow:factory bin/rspec spec/models +``` + +## Step 4. Factories usage + +Identify the most used factories among the `slow:factory` tests: + +```sh +FPROF=1 bin/rspec --tag slow:factory +``` + +If you see some factories used much more times than the total number of examples, you deal with _factory cascades_. + +Visualize the cascades: + +```sh +FPROF=flamegraph bin/rspec --tag slow:factory +``` + +The visualization should help to identify the factories to be fixed. You find possible solutions in [this post](https://evilmartians.com/chronicles/testprof-2-factory-therapy-for-your-ruby-tests-rspec-minitest). + +### Step 4.1. Factory defaults + +One option to fix cascades produced by model associations is to use [factory defaults](./recipes/factory_default.md). To estimate the potential impact and identify factories to apply this pattern to, run the following profiler: + +```sh +FACTORY_DEFAULT_PROF=1 bin/rspec --tag slow:factory +``` + +Try adding `create_default` and measure the impact: + +```sh +FACTORY_DEFAULT_SUMMARY=1 bin/rspec --tag slow:factory + +# More hits — better +FactoryDefault summary: hit=11 miss=3 +``` + +### Step 4.2. Factory fixtures + +Back to the `FPROF=1` report, see if you have some records created for every example (typically, `user`, `account`, `team`). Consider replacing them with fixtures using [AnyFixture](./recipes/any_fixture.md). + +## Step 5. Reusable setup + +It's common to have the same setup shared across multiple examples. You can measure the time spent in `let` / `before` compared to the actual example time using [RSpecDissect](./profilers/rspec_dissect.md): + +```sh +RD_PROF=1 bin/rspec +``` + +Take a look at the slowest groups and try to replace `let`/`let!` with [let_it_be](./recipes/let_it_be.md) and `before` with [before_all](./recipes/before_all.md). + +**IMPORTANT:** Knapsack Pro users must be aware that per-example balancing eliminates the positive effect of using `let_it_be` / `before_all`. You must switch to per-file balancing while at the same time keeping your files small—that's how you can maximize the effect of using Test Prof optimizations. + +## Conclusion + +After applying the steps above to a given group of tests, you should develop the patterns and techniques optimized for your codebase. Then, all you need is to extrapolate them to other groups. Good luck! diff --git a/docs/profilers/tag_prof.md b/docs/profilers/tag_prof.md index ea78332c..465a3a7e 100644 --- a/docs/profilers/tag_prof.md +++ b/docs/profilers/tag_prof.md @@ -59,7 +59,7 @@ Example output: model 00:01.127 00:00.446 40 32.26 12.82 00:00.028 ``` -Multiple events are also supported. +Multiple events are also supported (comma-separated). ## Pro-Tip: More Types From 049b5776626dcc7c5dc9c20cc98dacd64e4f9e5a Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 11:32:31 -0800 Subject: [PATCH 113/194] forspell: upd --- forspell.dict | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/forspell.dict b/forspell.dict index b9d72081..572a986d 100644 --- a/forspell.dict +++ b/forspell.dict @@ -19,3 +19,9 @@ stackprof Stackprof Tigeot integrations +Bootsnap +Webmock +utils +misconfigured +Inlined +Wisper \ No newline at end of file From f2bf8166edfef10c484055f258c40c749788d096 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 11:33:18 -0800 Subject: [PATCH 114/194] fix(docs): rb -> sh --- docs/playbook.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/playbook.md b/docs/playbook.md index 2866b833..6829d336 100644 --- a/docs/playbook.md +++ b/docs/playbook.md @@ -81,7 +81,7 @@ This is an important step for large codebases. We must prioritize quick fixes th We use [TagProf](./profilers/tag_prof.md) for that: -```ruby +```sh TAG_PROF=type TAG_PROF_FORMAT=html TAG_PROF_EVENT=sql.active_record,factory.create bin/rspec ``` From 2666957a96a02f026d2488cc3a4d4dcdfb0e12d1 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 11:34:57 -0800 Subject: [PATCH 115/194] ci: migrate docs-lint to anycable action --- .github/workflows/docs-lint.yml | 59 ++++----------------------------- 1 file changed, 6 insertions(+), 53 deletions(-) diff --git a/.github/workflows/docs-lint.yml b/.github/workflows/docs-lint.yml index d94f3931..571ae446 100644 --- a/.github/workflows/docs-lint.yml +++ b/.github/workflows/docs-lint.yml @@ -6,61 +6,14 @@ on: - master paths: - "**/*.md" + - ".github/workflows/docs-lint.yml" pull_request: paths: - "**/*.md" + - ".github/workflows/docs-lint.yml" jobs: - markdownlint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7 - - name: Run Markdown linter - run: | - gem install mdl - mdl docs - rubocop: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7 - - name: Lint Markdown files with RuboCop - run: | - gem install bundler - bundle install --gemfile gemfiles/rubocop.gemfile --jobs 4 --retry 3 - bundle exec --gemfile gemfiles/rubocop.gemfile rubocop -c .rubocop-md.yml - forspell: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Install Hunspell - run: | - sudo apt-get install hunspell - - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7 - - name: Cache installed gems - uses: actions/cache@v1 - with: - path: /home/runner/.rubies/ruby-2.7.0/lib/ruby/gems/2.7.0 - key: gems-cache-${{ runner.os }} - - name: Install Forspell - run: gem install forspell - - name: Run Forspell - run: forspell docs/ - lychee: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Link Checker - id: lychee - uses: lycheeverse/lychee-action@v1.5.1 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - with: - args: docs/* -v + docs-lint: + uses: anycable/github-actions/.github/workflows/docs-lint.yml@master + with: + lychee-args: docs/* -v README.md CHANGELOG.md From 51376f6248e1a2a99b8d39e8a41a91efc436aeb7 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 11:41:31 -0800 Subject: [PATCH 116/194] fix(docs): indent style in playbook --- docs/playbook.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/playbook.md b/docs/playbook.md index 6829d336..6dbb9dac 100644 --- a/docs/playbook.md +++ b/docs/playbook.md @@ -10,10 +10,10 @@ Low-hanging configuration fruits: - Disable logging in tests—it's useless. If you really need it, use our [logging utils](./recipes/logging.md). - ```ruby - config.logger = ActiveSupport::TaggedLogging.new(Logger.new(nil)) - config.log_level = :fatal - ``` +```ruby +config.logger = ActiveSupport::TaggedLogging.new(Logger.new(nil)) +config.log_level = :fatal +``` - Disable coverage and built-in profiling by default. Use env var to enable it (e.g., `COVERAGE=true`) @@ -27,7 +27,7 @@ bundle add stackprof Configure Test Prof to generate JSON profiles by default: -```sh +```ruby TestProf::StackProf.configure do |config| config.format = "json" end @@ -99,31 +99,31 @@ At this point, we may identify some misconfigured or misused dependencies/gems. - Inlined Sidekiq jobs: - ```sh - EVENT_PROF=sidekiq.inline bin/rspec spec/models - ``` +```sh +EVENT_PROF=sidekiq.inline bin/rspec spec/models +``` - Wisper broadcasts ([patch required](https://gist.github.com/palkan/aa7035cebaeca7ed76e433981f90c07b)): - ```sh - EVENT_PROF=wisper.publisher.broadcast bin/rspec spec/models - ``` +```sh +EVENT_PROF=wisper.publisher.broadcast bin/rspec spec/models +``` - PaperTrail logs creation: - Enable custom profiling: +Enable custom profiling: - ```rb - TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_create) - TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_destroy) - TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_update) - ``` +```rb +TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_create) +TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_destroy) +TestProf::EventProf.monitor(PaperTrail::RecordTrail, "paper_trail.record", :record_update) +``` - Run tests: +Run tests: - ```sh - EVENT_PROF=paper_trail.record bin/rspec spec/models - ``` +```sh +EVENT_PROF=paper_trail.record bin/rspec spec/models +``` See [the Sidekiq example](https://evilmartians.com/chronicles/testprof-a-good-doctor-for-slow-ruby-tests#background-jobs) on how to quickly fix such problems using [RSpecStamp](./recipes/rspec_stamp.md). From 0ae68148f2ba1a03ec56ed0164240581bb0dd310 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 11:43:31 -0800 Subject: [PATCH 117/194] fix(style): more md and spell fixes --- CHANGELOG.md | 6 +++--- README.md | 2 +- forspell.dict | 7 ++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fff918c3..01eee29e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ## 1.2.3 (2023-09-11) -- Minor fixes and dependecies upgrades. +- Minor fixes and dependencies upgrades. ## 1.2.2 (2023-06-27) @@ -160,7 +160,7 @@ And for every test run see the overall factories usage: ## 1.0.0.rc2 (2021-01-06) -- Make Rails fixtures accesible in `before_all`. ([@palkan][]) +- Make Rails fixtures accessible in `before_all`. ([@palkan][]) You can load and access fixtures when explicitly enabling them via `before_all(setup_fixtures: true, &block)`. @@ -221,7 +221,7 @@ end See more in [#181](https://github.com/test-prof/test-prof/issues/181). -- Adds the ability to define stackprof's interval sampling by using `TEST_STACK_PROF_INTERVAL` env variable ([@LynxEyes][]) +- Adds the ability to define stackprof interval sampling by using `TEST_STACK_PROF_INTERVAL` env variable ([@LynxEyes][]) Now you can use `$ TEST_STACK_PROF=1 TEST_STACK_PROF_INTERVAL=10000 rspec` to define a custom interval (in microseconds). diff --git a/README.md b/README.md index 223029d0..ba30224f 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Supported RSpec version (for RSpec features only): >= 3.5.0 (for older RSpec ver Check out our [docs][]. -## What's next? +## What's next Have an idea? [Propose](https://github.com/test-prof/test-prof/issues/new) a feature request! diff --git a/forspell.dict b/forspell.dict index 572a986d..946be7c3 100644 --- a/forspell.dict +++ b/forspell.dict @@ -24,4 +24,9 @@ Webmock utils misconfigured Inlined -Wisper \ No newline at end of file +Wisper +Pennylane +Makar +Ermokhin +Burkhard +Sistovaris From 67eeb49e82fc657b79e4b9ef04ef9e18e427223c Mon Sep 17 00:00:00 2001 From: Julia Date: Tue, 26 Sep 2023 21:28:34 +0300 Subject: [PATCH 118/194] Introduce MemoryProf for detecting test examples that cause memory spikes --- docs/profilers/memory_prof.md | 85 ++++++ lib/minitest/test_prof_plugin.rb | 10 + lib/test_prof.rb | 1 + lib/test_prof/memory_prof.rb | 78 ++++++ lib/test_prof/memory_prof/minitest.rb | 56 ++++ lib/test_prof/memory_prof/printer.rb | 93 +++++++ .../memory_prof/printer/number_to_human.rb | 44 ++++ lib/test_prof/memory_prof/rspec.rb | 76 ++++++ lib/test_prof/memory_prof/tracker.rb | 84 ++++++ .../memory_prof/tracker/linked_list.rb | 119 +++++++++ lib/test_prof/memory_prof/tracker/rss_tool.rb | 87 ++++++ lib/test_prof/utils/sized_ordered_set.rb | 4 + .../fixtures/minitest/memory_prof_fixture.rb | 28 ++ .../fixtures/rspec/memory_prof_fixture.rb | 47 ++++ .../integrations/memory_prof_minitest_spec.rb | 63 +++++ spec/integrations/memory_prof_rspec_spec.rb | 79 ++++++ .../before_all/adapters/active_record_spec.rb | 4 +- spec/test_prof/memory_prof/minitest_spec.rb | 68 +++++ .../printer/number_to_human_spec.rb | 49 ++++ spec/test_prof/memory_prof/printer_spec.rb | 249 ++++++++++++++++++ spec/test_prof/memory_prof/rspec_spec.rb | 123 +++++++++ .../memory_prof/tracker/linked_list_spec.rb | 143 ++++++++++ .../memory_prof/tracker/rss_tool_spec.rb | 143 ++++++++++ spec/test_prof/memory_prof/tracker_spec.rb | 220 ++++++++++++++++ spec/test_prof/memory_prof_spec.rb | 180 +++++++++++++ 25 files changed, 2131 insertions(+), 2 deletions(-) create mode 100644 docs/profilers/memory_prof.md create mode 100644 lib/test_prof/memory_prof.rb create mode 100644 lib/test_prof/memory_prof/minitest.rb create mode 100644 lib/test_prof/memory_prof/printer.rb create mode 100644 lib/test_prof/memory_prof/printer/number_to_human.rb create mode 100644 lib/test_prof/memory_prof/rspec.rb create mode 100644 lib/test_prof/memory_prof/tracker.rb create mode 100644 lib/test_prof/memory_prof/tracker/linked_list.rb create mode 100644 lib/test_prof/memory_prof/tracker/rss_tool.rb create mode 100644 spec/integrations/fixtures/minitest/memory_prof_fixture.rb create mode 100644 spec/integrations/fixtures/rspec/memory_prof_fixture.rb create mode 100644 spec/integrations/memory_prof_minitest_spec.rb create mode 100644 spec/integrations/memory_prof_rspec_spec.rb create mode 100644 spec/test_prof/memory_prof/minitest_spec.rb create mode 100644 spec/test_prof/memory_prof/printer/number_to_human_spec.rb create mode 100644 spec/test_prof/memory_prof/printer_spec.rb create mode 100644 spec/test_prof/memory_prof/rspec_spec.rb create mode 100644 spec/test_prof/memory_prof/tracker/linked_list_spec.rb create mode 100644 spec/test_prof/memory_prof/tracker/rss_tool_spec.rb create mode 100644 spec/test_prof/memory_prof/tracker_spec.rb create mode 100644 spec/test_prof/memory_prof_spec.rb diff --git a/docs/profilers/memory_prof.md b/docs/profilers/memory_prof.md new file mode 100644 index 00000000..f0bd43d3 --- /dev/null +++ b/docs/profilers/memory_prof.md @@ -0,0 +1,85 @@ +# MemoryProf + +MemoryProf tracks memory usage during your test suite run, and can help to detect test examples and groups that cause memory spikes. Memory profiling supports two metrics: RSS and allocations. + +Example output: + +```sh +[TEST PROF INFO] MemoryProf results + +Final RSS: 673KB + +Top 5 groups (by RSS): + +AnswersController (./spec/controllers/answers_controller_spec.rb:3) – +80KB (13.50%) +QuestionsController (./spec/controllers/questions_controller_spec.rb:3) – +32KB (9.08%) +CommentsController (./spec/controllers/comments_controller_spec.rb:3) – +16KB (3.27%) + +Top 5 examples (by RSS): + +destroys question (./spec/controllers/questions_controller_spec.rb:38) – +144KB (24.38%) +change comments count (./spec/controllers/comments_controller_spec.rb:7) – +120KB (20.00%) +change Votes count (./spec/shared_examples/controllers/voted_examples.rb:23) – +90KB (16.36%) +change Votes count (./spec/shared_examples/controllers/voted_examples.rb:23) – +64KB (12.86%) +fails (./spec/shared_examples/controllers/invalid_examples.rb:3) – +32KB (5.00%) +``` + +The examples block shows the amount of memory used by each example, and the groups block displays the memory allocated by other code defined in the groups. For example, RSpec groups may include heavy `before(:all)` (or `before_all`) setup blocks, so it is helpful to see which groups use the most amount of memory outside of their examples. + +## Instructions + +To activate MemoryProf with: + +### RSpec + +Use `TEST_MEM_PROF` environment variable to set which metric to use: + +```sh +TEST_MEM_PROF='rss' rspec ... +TEST_MEM_PROF='alloc' rake rspec ... +``` + +### Minitest + +Use `TEST_MEM_PROF` environment variable to set which metric to use: + +```sh +TEST_MEM_PROF='rss' rake test +TEST_MEM_PROF='alloc' rspec ... +``` + +or use CLI options as well: + +```sh +# Run a specific file using CLI option +ruby test/my_super_test.rb --mem-prof=rss + +# Show the list of possible options: +ruby test/my_super_test.rb --help +``` + +## Configuration + +By default, MemoryProf tracks the top 5 examples and groups that use the largest amount of memory. +You can set how many examples/groups to display with the option: + +```sh +TEST_MEM_PROF='rss' TEST_MEM_PROF_COUNT=10 rspec ... +``` + +or with CLI options for Minitest: + +```sh +# Run a specific file using CLI option +ruby test/my_super_test.rb --mem-prof=rs --mem-prof-top-count=10 +``` + +## Supported Ruby Engines & OS + +Currently the allocation mode is not supported for JRuby. + +Since RSS depends on the OS, MemoryProf uses different tools to retrieve it: + +* Linux – `/proc/$pid/statm` file, +* macOS, Solaris, BSD – `ps`, +* Windows – `Get-Process`, requires PowerShell to be installed. diff --git a/lib/minitest/test_prof_plugin.rb b/lib/minitest/test_prof_plugin.rb index a21be2a7..c991f909 100644 --- a/lib/minitest/test_prof_plugin.rb +++ b/lib/minitest/test_prof_plugin.rb @@ -2,6 +2,7 @@ require "test_prof/event_prof/minitest" require "test_prof/factory_doctor/minitest" +require "test_prof/memory_prof/minitest" module Minitest # :nodoc: module TestProf # :nodoc: @@ -13,6 +14,8 @@ def self.configure_options(options = {}) opts[:per_example] = true if ENV["EVENT_PROF_EXAMPLES"] opts[:fdoc] = true if ENV["FDOC"] opts[:sample] = true if ENV["SAMPLE"] || ENV["SAMPLE_GROUPS"] + opts[:mem_prof_mode] = ENV["TEST_MEM_PROF"] if ENV["TEST_MEM_PROF"] + opts[:mem_prof_top_count] = ENV["TEST_MEM_PROF_COUNT"] if ENV["TEST_MEM_PROF_COUNT"] end end end @@ -33,6 +36,12 @@ def self.plugin_test_prof_options(opts, options) opts.on "--factory-doctor", TrueClass, "Enable Factory Doctor for your examples" do |flag| options[:fdoc] = flag end + opts.on "--mem-prof=MODE", "Enable MemoryProf for your examples" do |flag| + options[:mem_prof_mode] = flag + end + opts.on "--mem-prof-top-count=N", "Limits MemoryProf results with N groups/examples" do |flag| + options[:mem_prof_top_count] = flag + end end def self.plugin_test_prof_init(options) @@ -40,6 +49,7 @@ def self.plugin_test_prof_init(options) reporter << TestProf::EventProfReporter.new(options[:io], options) if options[:event] reporter << TestProf::FactoryDoctorReporter.new(options[:io], options) if options[:fdoc] + reporter << TestProf::MemoryProfReporter.new(options[:io], options) if options[:mem_prof_mode] ::TestProf::MinitestSample.call if options[:sample] end diff --git a/lib/test_prof.rb b/lib/test_prof.rb index 47decd21..9769ba16 100644 --- a/lib/test_prof.rb +++ b/lib/test_prof.rb @@ -8,6 +8,7 @@ require "test_prof/event_prof" require "test_prof/factory_doctor" require "test_prof/factory_prof" +require "test_prof/memory_prof" require "test_prof/rspec_stamp" require "test_prof/tag_prof" require "test_prof/rspec_dissect" if TestProf.rspec? diff --git a/lib/test_prof/memory_prof.rb b/lib/test_prof/memory_prof.rb new file mode 100644 index 00000000..a50a1c83 --- /dev/null +++ b/lib/test_prof/memory_prof.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require "test_prof/memory_prof/tracker" +require "test_prof/memory_prof/printer" + +module TestProf + # MemoryProf can help in detecting test examples causing memory spikes. + # It supports two metrics: RSS and allocations. + # + # Example: + # + # TEST_MEM_PROF='rss' rspec ... + # TEST_MEM_PROF='alloc' rspec ... + # + # By default MemoryProf shows the top 5 examples and groups (for RSpec) but you can + # set how many items to display with `TEST_MEM_PROF_COUNT`: + # + # TEST_MEM_PROF='rss' TEST_MEM_PROF_COUNT=10 rspec ... + # + # The examples block shows the amount of memory used by each example, and the groups + # block displays the memory allocated by other code defined in the groups. For example, + # RSpec groups may include heavy `before(:all)` (or `before_all`) setup blocks, so it is + # helpful to see which groups use the most amount of memory outside of their examples. + + module MemoryProf + # MemoryProf configuration + class Configuration + attr_reader :mode, :top_count + + def initialize + self.mode = ENV["TEST_MEM_PROF"] + self.top_count = ENV["TEST_MEM_PROF_COUNT"] + end + + def mode=(value) + @mode = (value == "alloc") ? :alloc : :rss + end + + def top_count=(value) + @top_count = value.to_i + @top_count = 5 unless @top_count.positive? + end + end + + class << self + TRACKERS = { + alloc: AllocTracker, + rss: RssTracker + }.freeze + + PRINTERS = { + alloc: AllocPrinter, + rss: RssPrinter + }.freeze + + def config + @config ||= Configuration.new + end + + def configure + yield config + end + + def tracker + tracker = TRACKERS[config.mode] + tracker.new(config.top_count) + end + + def printer(tracker) + printer = PRINTERS[config.mode] + printer.new(tracker) + end + end + end +end + +require "test_prof/memory_prof/rspec" if TestProf.rspec? +require "test_prof/memory_prof/minitest" if TestProf.minitest? diff --git a/lib/test_prof/memory_prof/minitest.rb b/lib/test_prof/memory_prof/minitest.rb new file mode 100644 index 00000000..077ede68 --- /dev/null +++ b/lib/test_prof/memory_prof/minitest.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "minitest/base_reporter" + +module Minitest + module TestProf + class MemoryProfReporter < BaseReporter # :nodoc: + attr_reader :tracker, :printer, :current_example + + def initialize(io = $stdout, options = {}) + super + + configure_profiler(options) + + @tracker = ::TestProf::MemoryProf.tracker + @printer = ::TestProf::MemoryProf.printer(tracker) + + @current_example = nil + end + + def prerecord(group, example) + set_current_example(group, example) + tracker.example_started(current_example) + end + + def record(example) + tracker.example_finished(current_example) + end + + def start + tracker.start + end + + def report + tracker.finish + printer.print + end + + private + + def set_current_example(group, example) + @current_example = { + name: example.gsub(/^test_(?:\d+_)?/, ""), + location: location_with_line_number(group, example) + } + end + + def configure_profiler(options) + ::TestProf::MemoryProf.configure do |config| + config.mode = options[:mem_prof_mode] + config.top_count = options[:mem_prof_top_count] if options[:mem_prof_top_count] + end + end + end + end +end diff --git a/lib/test_prof/memory_prof/printer.rb b/lib/test_prof/memory_prof/printer.rb new file mode 100644 index 00000000..987a9bd3 --- /dev/null +++ b/lib/test_prof/memory_prof/printer.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require "test_prof/memory_prof/printer/number_to_human" +require "test_prof/ext/string_truncate" + +module TestProf + module MemoryProf + class Printer + include Logging + using StringTruncate + + def initialize(tracker) + @tracker = tracker + end + + def print + messages = [ + "MemoryProf results\n\n", + print_total, + print_block("groups", tracker.groups), + print_block("examples", tracker.examples) + ] + + log :info, messages.join + end + + private + + attr_reader :tracker + + def print_block(name, items) + return if items.empty? + + <<~GROUP + Top #{tracker.top_count} #{name} (by #{mode}): + + #{print_items(items)} + GROUP + end + + def print_items(items) + messages = + items.map do |item| + <<~ITEM + #{item[:name].truncate(30)} (#{item[:location]}) – +#{memory_amount(item)} (#{memory_percentage(item)}%) + ITEM + end + + messages.join + end + + def memory_percentage(item) + (100.0 * item[:memory] / tracker.total_memory).round(2) + end + + def number_to_human(value) + NumberToHuman.convert(value) + end + end + + class AllocPrinter < Printer + private + + def mode + "allocations" + end + + def print_total + "Total allocations: #{tracker.total_memory}\n\n" + end + + def memory_amount(item) + item[:memory] + end + end + + class RssPrinter < Printer + private + + def mode + "RSS" + end + + def print_total + "Final RSS: #{number_to_human(tracker.total_memory)}\n\n" + end + + def memory_amount(item) + number_to_human(item[:memory]) + end + end + end +end diff --git a/lib/test_prof/memory_prof/printer/number_to_human.rb b/lib/test_prof/memory_prof/printer/number_to_human.rb new file mode 100644 index 00000000..ff03f44d --- /dev/null +++ b/lib/test_prof/memory_prof/printer/number_to_human.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module TestProf + module MemoryProf + class Printer + module NumberToHuman + BASE = 1024 + UNITS = %w[B KB MB GB TB PB EB ZB] + + class << self + def convert(number) + exponent = exponent(number) + human_size = number.to_f / (BASE**exponent) + + "#{round(human_size)}#{UNITS[exponent]}" + end + + private + + def exponent(number) + return 0 if number.zero? + + max = UNITS.size - 1 + + exponent = (Math.log(number) / Math.log(BASE)).to_i + (exponent > max) ? max : exponent + end + + def round(number) + if integer?(number) + number.round + else + number.round(2) + end + end + + def integer?(number) + number.round == number + end + end + end + end + end +end diff --git a/lib/test_prof/memory_prof/rspec.rb b/lib/test_prof/memory_prof/rspec.rb new file mode 100644 index 00000000..08ccb59f --- /dev/null +++ b/lib/test_prof/memory_prof/rspec.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module TestProf + module MemoryProf + class RSpecListener + NOTIFICATIONS = %i[ + example_started + example_finished + example_group_started + example_group_finished + ].freeze + + attr_reader :tracker, :printer + + def initialize + @tracker = MemoryProf.tracker + @printer = MemoryProf.printer(tracker) + + @tracker.start + end + + def example_started(notification) + tracker.example_started(example(notification)) + end + + def example_finished(notification) + tracker.example_finished(example(notification)) + end + + def example_group_started(notification) + tracker.group_started(group(notification)) + end + + def example_group_finished(notification) + tracker.group_finished(group(notification)) + end + + def report + tracker.finish + printer.print + end + + private + + def example(notification) + { + name: notification.example.description, + location: notification.example.metadata[:location] + } + end + + def group(notification) + { + name: notification.group.description, + location: notification.group.metadata[:location] + } + end + end + end +end + +TestProf.activate("TEST_MEM_PROF") do + RSpec.configure do |config| + listener = nil + + config.before(:suite) do + listener = TestProf::MemoryProf::RSpecListener.new + + config.reporter.register_listener( + listener, *TestProf::MemoryProf::RSpecListener::NOTIFICATIONS + ) + end + + config.after(:suite) { listener&.report } + end +end diff --git a/lib/test_prof/memory_prof/tracker.rb b/lib/test_prof/memory_prof/tracker.rb new file mode 100644 index 00000000..273b89b4 --- /dev/null +++ b/lib/test_prof/memory_prof/tracker.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require "test_prof/memory_prof/tracker/linked_list" +require "test_prof/memory_prof/tracker/rss_tool" + +module TestProf + module MemoryProf + # Tracker is responsible for tracking memory usage and determining + # the top n examples and groups. There are two types of trackers: + # AllocTracker and RssTracker. + # + # A tracker consists of four main parts: + # * list - a linked list that is being used to track memmory for individual groups/examples. + # list is an instance of LinkedList (for more info see tracker/linked_list.rb) + # * examples – the top n examples, an instance of Utils::SizedOrderedSet. + # * groups – the top n groups, an instance of Utils::SizedOrderedSet. + # * track - a method that fetches the amount of memory in use at a certain point. + class Tracker + attr_reader :top_count, :examples, :groups, :total_memory, :list + + def initialize(top_count) + raise "Your Ruby Engine or OS is not supported" unless supported? + + @top_count = top_count + + @examples = Utils::SizedOrderedSet.new(top_count, sort_by: :memory) + @groups = Utils::SizedOrderedSet.new(top_count, sort_by: :memory) + end + + def start + @list = LinkedList.new(track) + end + + def finish + node = list.remove_node(:total, track) + @total_memory = node.total_memory + end + + def example_started(example) + list.add_node(example, track) + end + + def example_finished(example) + node = list.remove_node(example, track) + examples << {**example, memory: node.total_memory} + end + + def group_started(group) + list.add_node(group, track) + end + + def group_finished(group) + node = list.remove_node(group, track) + groups << {**group, memory: node.hooks_memory} + end + end + + class AllocTracker < Tracker + def track + GC.stat[:total_allocated_objects] + end + + def supported? + RUBY_ENGINE != "jruby" + end + end + + class RssTracker < Tracker + def initialize(top_count) + @rss_tool = RssTool.tool + + super + end + + def track + @rss_tool.track + end + + def supported? + !!@rss_tool + end + end + end +end diff --git a/lib/test_prof/memory_prof/tracker/linked_list.rb b/lib/test_prof/memory_prof/tracker/linked_list.rb new file mode 100644 index 00000000..4a68fb5b --- /dev/null +++ b/lib/test_prof/memory_prof/tracker/linked_list.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +module TestProf + module MemoryProf + class Tracker + # LinkedList is a linked list that track memory usage for individual examples/groups. + # A list node (`LinkedListNode`) represents an example/group and its memory usage info: + # + # * memory_at_start - the amount of memory at the start of an example/group + # * memory_at_finish - the amount of memory at the end of an example/group + # * nested_memory - the amount of memory allocated by examples/groups defined inside a group + # * previous - a link to the previous node + # + # Each node has a link to its previous node, and the head node points to the current example/group. + # If we picture a linked list as a tree with root being the top level group and leaves being + # current examples/groups, then the head node will always point to a leaf in that tree. + # + # For example, if we have the following spec: + # + # describe Question do + # decribe "#publish" do + # context "when not published" do + # it "makes the question visible" do + # ... + # end + # end + # end + # end + # + # At the moment when rspec is executing the example, the list has the following structure + # (^ denotes the head node): + # + # ^"makes the question visible" -> "when not published" -> "#publish" -> Question + # + # LinkedList supports two method for working with it: + # + # * add_node – adds a node to the beginig of the list. At this point an example or group + # has started and we track how much memory has already been used. + # * remove_node – removes and returns the head node from the list. It means that the node + # example/group has finished and it is time to calculate its memory usage. + # + # When we remove a node we add its total_memory to the previous node.nested_memory, thus + # gradually tracking the amount of memory used by nested examples inside a group. + # + # In the example above, after we remove the node "makes the question visible", we add its total + # memory usage to nested_memory of the "when not published" node. If the "when not published" + # group contains other examples or sub-groups, their total_memory will also be added to + # "when not published" nested_memory. So when the group finishes we will have the total amount + # of memory used by its nested examples/groups, and thus we will be able to calculate the memory + # used by hooks and other code inside a group by subtracting nested_memory from total_memory. + class LinkedList + attr_reader :head + + def initialize(memory_at_start) + add_node(:total, memory_at_start) + end + + def add_node(item, memory_at_start) + @head = LinkedListNode.new( + item: item, + previous: head, + memory_at_start: memory_at_start + ) + end + + def remove_node(item, memory_at_finish) + return if head.item != item + head.finish(memory_at_finish) + + current = head + @head = head.previous + + current + end + end + + class LinkedListNode + attr_reader :item, :previous, :memory_at_start, :memory_at_finish, :nested_memory + + def initialize(item:, memory_at_start:, previous:) + @item = item + @previous = previous + + @memory_at_start = memory_at_start || 0 + @memory_at_finish = nil + @nested_memory = 0 + end + + def total_memory + return 0 if memory_at_finish.nil? + # It seems that on Windows Minitest may release a lot of memory to + # the OS when it finishes and executes #report, leading to memory_at_finish + # being less than memory_at_start. In this case we return nested_memory + # which does not account for the memory used in `after` hooks, but it + # is better than nothing. + return nested_memory if memory_at_start > memory_at_finish + + memory_at_finish - memory_at_start + end + + def hooks_memory + total_memory - nested_memory + end + + def finish(memory_at_finish) + @memory_at_finish = memory_at_finish + + previous&.add_nested(self) + end + + protected + + def add_nested(node) + @nested_memory += node.total_memory + end + end + end + end +end diff --git a/lib/test_prof/memory_prof/tracker/rss_tool.rb b/lib/test_prof/memory_prof/tracker/rss_tool.rb new file mode 100644 index 00000000..b24fe441 --- /dev/null +++ b/lib/test_prof/memory_prof/tracker/rss_tool.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +require "rbconfig" + +module TestProf + module MemoryProf + class Tracker + module RssTool + class ProcFS + def initialize + @statm = File.open("/proc/#{$$}/statm", "r") + @page_size = get_page_size + end + + def track + @statm.seek(0) + @statm.gets.split(/\s/)[1].to_i * @page_size + end + + private + + def get_page_size + [ + -> { + require "etc" + Etc.sysconf(Etc::SC_PAGE_SIZE) + }, + -> { `getconf PAGE_SIZE`.to_i }, + -> { 0x1000 } + ].each do |strategy| + page_size = begin + strategy.call + rescue + next + end + return page_size + end + end + end + + class PS + def track + `ps -o rss -p #{$$}`.strip.split.last.to_i * 1024 + end + end + + class GetProcess + def track + command.strip.split.last.to_i + end + + private + + def command + `powershell -Command "Get-Process -Id #{$$} | select WS"` + end + end + + TOOLS = { + linux: ProcFS, + macosx: PS, + unix: PS, + windows: GetProcess + }.freeze + + class << self + def tool + TOOLS[os_type]&.new + end + + def os_type + case RbConfig::CONFIG["host_os"] + when /linux/ + :linux + when /darwin|mac os/ + :macosx + when /solaris|bsd/ + :unix + when /mswin|msys|mingw|cygwin|bccwin|wince|emc/ + :windows + end + end + end + end + end + end +end diff --git a/lib/test_prof/utils/sized_ordered_set.rb b/lib/test_prof/utils/sized_ordered_set.rb index 8af86e80..81b00eeb 100644 --- a/lib/test_prof/utils/sized_ordered_set.rb +++ b/lib/test_prof/utils/sized_ordered_set.rb @@ -53,6 +53,10 @@ def size data.size end + def empty? + size.zero? + end + def to_a data.dup end diff --git a/spec/integrations/fixtures/minitest/memory_prof_fixture.rb b/spec/integrations/fixtures/minitest/memory_prof_fixture.rb new file mode 100644 index 00000000..b286e35a --- /dev/null +++ b/spec/integrations/fixtures/minitest/memory_prof_fixture.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "minitest/autorun" +require "test-prof" +require "securerandom" + +describe "First Allocations" do + it "allocates 500 objects" do + 500.times.map { SecureRandom.hex } + end + + it "allocates 1000 objects" do + 1000.times.map { SecureRandom.hex } + end + + it "allocates 10_000 objects" do + 10_000.times.map { SecureRandom.hex } + end +end + +describe "Second Allocations" do + it "allocates nothing" do + end + + it "allocates 100 objects" do + 100.times.map { SecureRandom.hex } + end +end diff --git a/spec/integrations/fixtures/rspec/memory_prof_fixture.rb b/spec/integrations/fixtures/rspec/memory_prof_fixture.rb new file mode 100644 index 00000000..a8b5a865 --- /dev/null +++ b/spec/integrations/fixtures/rspec/memory_prof_fixture.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require "test-prof" +require "securerandom" + +describe "Examples allocations" do + it "allocates 500 objects" do + 500.times.map { SecureRandom.hex } + end + + it "allocates 1000 objects" do + 1000.times.map { SecureRandom.hex } + end + + it "allocates 10_000 objects" do + 10_000.times.map { SecureRandom.hex } + end +end + +describe "Groups Allocations" do + context "with 500 allocations" do + before(:context) do + @array = 500.times.map { SecureRandom.hex } + end + + it "does not allocate anything" do + end + end + + context "with 1000 allocations" do + before(:context) do + @array = 1000.times.map { SecureRandom.hex } + end + + it "does not allocate anything" do + end + end + + context "with 10_000 allocations" do + before(:context) do + @array = 10_000.times.map { SecureRandom.hex } + end + + it "does not allocate anything" do + end + end +end diff --git a/spec/integrations/memory_prof_minitest_spec.rb b/spec/integrations/memory_prof_minitest_spec.rb new file mode 100644 index 00000000..d197ae1d --- /dev/null +++ b/spec/integrations/memory_prof_minitest_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +number_regex = /\d+\.?\d{0,2}/ +memory_human_regex = /#{number_regex}[KMGTPEZ]?B/ +percent_regex = /#{number_regex}%/ + +describe "MemoryProf Minitest" do + specify "with default options", :aggregate_failures do + output = run_minitest("memory_prof", env: {"TEST_MEM_PROF" => "test"}) + + expect(output).to include("MemoryProf results") + expect(output).to match(/Final RSS: #{memory_human_regex}/) + + expect(output).to include("Top 5 examples (by RSS):") + + expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:16\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:12\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:8\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 100 objects \(\.\/memory_prof_fixture.rb:25\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates nothing \(\.\/memory_prof_fixture.rb:22\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + end + + specify "in RSS mode", :aggregate_failures do + output = run_minitest("memory_prof", env: {"TEST_MEM_PROF" => "rss"}) + + expect(output).to include("MemoryProf results") + expect(output).to match(/Final RSS: #{memory_human_regex}/) + + expect(output).to include("Top 5 examples (by RSS):") + + expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:16\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:12\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:8\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 100 objects \(\.\/memory_prof_fixture.rb:25\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates nothing \(\.\/memory_prof_fixture.rb:22\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + end + + if RUBY_ENGINE != "jruby" + specify "in allocations mode", :aggregate_failures do + output = run_minitest("memory_prof", env: {"TEST_MEM_PROF" => "alloc"}) + + expect(output).to include("MemoryProf results") + expect(output).to match(/Total allocations: #{number_regex}/) + + expect(output).to include("Top 5 examples (by allocations):") + + expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:16\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:12\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:8\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 100 objects \(\.\/memory_prof_fixture.rb:25\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates nothing \(\.\/memory_prof_fixture.rb:22\) – \+#{number_regex} \(#{percent_regex}\)/) + end + end + + specify "with top_count", :aggregate_failures do + output = run_minitest("memory_prof", env: {"TEST_MEM_PROF" => "rss", "TEST_MEM_PROF_COUNT" => "3"}) + + expect(output).to include("MemoryProf results") + expect(output).to match(/Final RSS: #{memory_human_regex}/) + + expect(output).to include("Top 3 examples (by RSS):") + end +end diff --git a/spec/integrations/memory_prof_rspec_spec.rb b/spec/integrations/memory_prof_rspec_spec.rb new file mode 100644 index 00000000..a2ae829e --- /dev/null +++ b/spec/integrations/memory_prof_rspec_spec.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +number_regex = /\d+\.?\d{0,2}/ +memory_human_regex = /#{number_regex}[KMGTPEZ]?B/ +percent_regex = /#{number_regex}%/ + +describe "MemoryProf RSpec" do + specify "with default options", :aggregate_failures do + output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "test"}) + + expect(output).to include("MemoryProf results") + expect(output).to match(/Final RSS: #{memory_human_regex}/) + + expect(output).to include("Top 5 groups (by RSS):") + expect(output).to include("Top 5 examples (by RSS):") + + expect(output).to match(/with 10_000 allocations \(\.\/memory_prof_fixture.rb:39\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 1000 allocations \(\.\/memory_prof_fixture.rb:30\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 500 allocations \(\.\/memory_prof_fixture.rb:21\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/Groups Allocations \(\.\/memory_prof_fixture.rb:20\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/Examples allocations \(\.\/memory_prof_fixture.rb:6\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + + expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:15\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:11\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:7\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + end + + specify "in RSS mode", :aggregate_failures do + output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "rss"}) + + expect(output).to include("MemoryProf results") + expect(output).to match(/Final RSS: #{memory_human_regex}/) + + expect(output).to include("Top 5 groups (by RSS):") + expect(output).to include("Top 5 examples (by RSS):") + + expect(output).to match(/with 10_000 allocations \(\.\/memory_prof_fixture.rb:39\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 1000 allocations \(\.\/memory_prof_fixture.rb:30\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 500 allocations \(\.\/memory_prof_fixture.rb:21\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/Groups Allocations \(\.\/memory_prof_fixture.rb:20\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/Examples allocations \(\.\/memory_prof_fixture.rb:6\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + + expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:15\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:11\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:7\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + end + + if RUBY_ENGINE != "jruby" + specify "in allocations mode", :aggregate_failures do + output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "alloc"}) + + expect(output).to include("MemoryProf results") + expect(output).to match(/Total allocations: #{number_regex}/) + + expect(output).to include("Top 5 groups (by allocations):") + expect(output).to include("Top 5 examples (by allocations):") + + expect(output).to match(/with 10_000 allocations \(\.\/memory_prof_fixture.rb:39\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 1000 allocations \(\.\/memory_prof_fixture.rb:30\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 500 allocations \(\.\/memory_prof_fixture.rb:21\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/Groups Allocations \(\.\/memory_prof_fixture.rb:20\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/Examples allocations \(\.\/memory_prof_fixture.rb:6\) – \+#{number_regex} \(#{percent_regex}\)/) + + expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:15\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:11\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:7\) – \+#{number_regex} \(#{percent_regex}\)/) + end + end + + specify "with top_count", :aggregate_failures do + output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "rss", "TEST_MEM_PROF_COUNT" => "3"}) + + expect(output).to include("MemoryProf results") + expect(output).to match(/Final RSS: #{memory_human_regex}/) + + expect(output).to include("Top 3 groups (by RSS):") + expect(output).to include("Top 3 examples (by RSS):") + end +end diff --git a/spec/test_prof/before_all/adapters/active_record_spec.rb b/spec/test_prof/before_all/adapters/active_record_spec.rb index e0263399..f2b85df8 100644 --- a/spec/test_prof/before_all/adapters/active_record_spec.rb +++ b/spec/test_prof/before_all/adapters/active_record_spec.rb @@ -35,7 +35,7 @@ def self.configure it "warns when connection does not have open transaction" do expect { subject }.to output( - "!!! before_all transaction has been already rollbacked and could work incorrectly\n" + /!!! before_all transaction has been already rollbacked and could work incorrectly\n/ ).to_stderr end end @@ -83,7 +83,7 @@ def self.configure it "warns when connection does not have open transaction" do expect { subject }.to output( - "!!! before_all transaction has been already rollbacked and could work incorrectly\n" + /!!! before_all transaction has been already rollbacked and could work incorrectly\n/ ).to_stderr end end diff --git a/spec/test_prof/memory_prof/minitest_spec.rb b/spec/test_prof/memory_prof/minitest_spec.rb new file mode 100644 index 00000000..6390f70a --- /dev/null +++ b/spec/test_prof/memory_prof/minitest_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require "test_prof/memory_prof/minitest" + +describe Minitest::TestProf::MemoryProfReporter do + subject { described_class.new } + + let(:tracker) { subject.tracker } + let(:printer) { subject.printer } + + before do + allow(tracker).to receive(:start) + allow(tracker).to receive(:finish) + allow(tracker).to receive(:example_started) + allow(tracker).to receive(:example_finished) + allow(tracker).to receive(:group_started) + allow(tracker).to receive(:group_finished) + + allow(printer).to receive(:print) + + allow(subject).to receive(:location_with_line_number).and_return("./test/models/reports.rb:57") + end + + describe "#prerecord" do + it "tracks the start of an example" do + subject.prerecord("Report", "test_prepare") + + expect(tracker).to have_received(:example_started).with({ + name: "prepare", + location: "./test/models/reports.rb:57" + }) + end + end + + describe "#record" do + it "tracks the start of an example" do + subject.prerecord("Report", "test_prepare") + subject.record(nil) + + expect(tracker).to have_received(:example_started).with({ + name: "prepare", + location: "./test/models/reports.rb:57" + }) + end + end + + describe "#start" do + it "starts the tracking process" do + subject.start + + expect(tracker).to have_received(:start) + end + end + + describe "#report" do + it "finishes the tracking process" do + subject.report + + expect(tracker).to have_received(:finish) + end + + it "prints the results" do + subject.report + + expect(printer).to have_received(:print) + end + end +end diff --git a/spec/test_prof/memory_prof/printer/number_to_human_spec.rb b/spec/test_prof/memory_prof/printer/number_to_human_spec.rb new file mode 100644 index 00000000..3e9ba739 --- /dev/null +++ b/spec/test_prof/memory_prof/printer/number_to_human_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +describe TestProf::MemoryProf::Printer::NumberToHuman do + subject { described_class } + + describe "#convert" do + let(:convert) { subject.convert(number) } + + context "when number is 0" do + let(:number) { 0 } + + it "returns 0B" do + expect(convert).to eq("0B") + end + end + + context "when number < 1KB" do + let(:number) { 700 } + + it "returns the value in bytes" do + expect(convert).to eq("700B") + end + end + + context "when number > 1024 ZB" do + let(:number) { 7 * 2**80 } + + it "returns the value in ZB" do + expect(convert).to eq("7168ZB") + end + end + + context "when number can be converted to an integer" do + let(:number) { 7 * 2**20 } + + it "returns the value as an integer" do + expect(convert).to eq("7MB") + end + end + + context "when number can not be converted to an integer" do + let(:number) { 7 * 2**20 + 550 * 2**10 } + + it "rounds the value to two digits" do + expect(convert).to eq("7.54MB") + end + end + end +end diff --git a/spec/test_prof/memory_prof/printer_spec.rb b/spec/test_prof/memory_prof/printer_spec.rb new file mode 100644 index 00000000..adb90c0e --- /dev/null +++ b/spec/test_prof/memory_prof/printer_spec.rb @@ -0,0 +1,249 @@ +# frozen_string_literal: true + +shared_examples "TestProf::MemoryProf::Printer" do + subject { described_class.new(tracker) } + + let(:tracker) do + instance_double( + TestProf::MemoryProf::Tracker, + top_count: 3, + total_memory: 500, + groups: groups, + examples: examples + ) + end + + let(:groups) do + [ + {name: "AnswersController", location: "./spec/controllers/answers_controller_spec.rb:3", memory: 200}, + {name: "#publish", location: "./spec/nodels/question_spec.rb:179", memory: 100}, + {name: "when email and name are present", location: "./spec/lib/import_spec.rb:34", memory: 50} + ] + end + + let(:examples) do + [ + {name: "returns nil", location: "./spec/models/reports_spec.rb:57", memory: 75}, + {name: "searches users by email", location: "./spec/searches/users_search_spec.rb:15", memory: 50}, + {name: "calculates the average number of answers", location: "./spec/lib/stats_spec.rb:44", memory: 25} + ] + end + + before do + allow(subject).to receive(:log) + end +end + +describe TestProf::MemoryProf::AllocPrinter do + include_examples "TestProf::MemoryProf::Printer" + + describe "#print" do + let(:print) { subject.print } + + context "and there are both groups and examples" do + let(:message) do + <<~MESSAGE + MemoryProf results + + Total allocations: 500 + + Top 3 groups (by allocations): + + AnswersController (./spec/controllers/answers_controller_spec.rb:3) – +200 (40.0%) + #publish (./spec/nodels/question_spec.rb:179) – +100 (20.0%) + when email an...me are present (./spec/lib/import_spec.rb:34) – +50 (10.0%) + + Top 3 examples (by allocations): + + returns nil (./spec/models/reports_spec.rb:57) – +75 (15.0%) + searches users by email (./spec/searches/users_search_spec.rb:15) – +50 (10.0%) + calculates th...ber of answers (./spec/lib/stats_spec.rb:44) – +25 (5.0%) + + MESSAGE + end + + it "prints results for groups and examples" do + print + + expect(subject).to have_received(:log).with(:info, message) + end + end + + context "and there are no examples" do + let(:examples) { [] } + + let(:message) { + <<~MESSAGE + MemoryProf results + + Total allocations: 500 + + Top 3 groups (by allocations): + + AnswersController (./spec/controllers/answers_controller_spec.rb:3) – +200 (40.0%) + #publish (./spec/nodels/question_spec.rb:179) – +100 (20.0%) + when email an...me are present (./spec/lib/import_spec.rb:34) – +50 (10.0%) + + MESSAGE + } + + it "prints results for groups only" do + print + + expect(subject).to have_received(:log).with(:info, message) + end + end + + context "and there are no groups" do + let(:groups) { [] } + + let(:message) { + <<~MESSAGE + MemoryProf results + + Total allocations: 500 + + Top 3 examples (by allocations): + + returns nil (./spec/models/reports_spec.rb:57) – +75 (15.0%) + searches users by email (./spec/searches/users_search_spec.rb:15) – +50 (10.0%) + calculates th...ber of answers (./spec/lib/stats_spec.rb:44) – +25 (5.0%) + + MESSAGE + } + + it "prints results for examples only" do + print + + expect(subject).to have_received(:log).with(:info, message) + end + end + + context "and there are no groups or examples" do + let(:groups) { [] } + let(:examples) { [] } + + let(:message) { + <<~MESSAGE + MemoryProf results + + Total allocations: 500 + + MESSAGE + } + + it "prints results for examples only" do + print + + expect(subject).to have_received(:log).with(:info, message) + end + end + end +end + +describe TestProf::MemoryProf::RssPrinter do + include_examples "TestProf::MemoryProf::Printer" + + describe "#print" do + let(:print) { subject.print } + + context "and there are both groups and examples" do + let(:message) do + <<~MESSAGE + MemoryProf results + + Final RSS: 500B + + Top 3 groups (by RSS): + + AnswersController (./spec/controllers/answers_controller_spec.rb:3) – +200B (40.0%) + #publish (./spec/nodels/question_spec.rb:179) – +100B (20.0%) + when email an...me are present (./spec/lib/import_spec.rb:34) – +50B (10.0%) + + Top 3 examples (by RSS): + + returns nil (./spec/models/reports_spec.rb:57) – +75B (15.0%) + searches users by email (./spec/searches/users_search_spec.rb:15) – +50B (10.0%) + calculates th...ber of answers (./spec/lib/stats_spec.rb:44) – +25B (5.0%) + + MESSAGE + end + + it "prints results for groups and examples" do + print + + expect(subject).to have_received(:log).with(:info, message) + end + end + + context "and there are no examples" do + let(:examples) { [] } + + let(:message) { + <<~MESSAGE + MemoryProf results + + Final RSS: 500B + + Top 3 groups (by RSS): + + AnswersController (./spec/controllers/answers_controller_spec.rb:3) – +200B (40.0%) + #publish (./spec/nodels/question_spec.rb:179) – +100B (20.0%) + when email an...me are present (./spec/lib/import_spec.rb:34) – +50B (10.0%) + + MESSAGE + } + + it "prints results for groups only" do + print + + expect(subject).to have_received(:log).with(:info, message) + end + end + + context "and there are no groups" do + let(:groups) { [] } + + let(:message) { + <<~MESSAGE + MemoryProf results + + Final RSS: 500B + + Top 3 examples (by RSS): + + returns nil (./spec/models/reports_spec.rb:57) – +75B (15.0%) + searches users by email (./spec/searches/users_search_spec.rb:15) – +50B (10.0%) + calculates th...ber of answers (./spec/lib/stats_spec.rb:44) – +25B (5.0%) + + MESSAGE + } + + it "prints results for examples only" do + print + + expect(subject).to have_received(:log).with(:info, message) + end + end + + context "and there are no groups or examples" do + let(:groups) { [] } + let(:examples) { [] } + + let(:message) { + <<~MESSAGE + MemoryProf results + + Final RSS: 500B + + MESSAGE + } + + it "prints results for examples only" do + print + + expect(subject).to have_received(:log).with(:info, message) + end + end + end +end diff --git a/spec/test_prof/memory_prof/rspec_spec.rb b/spec/test_prof/memory_prof/rspec_spec.rb new file mode 100644 index 00000000..ddb8fe64 --- /dev/null +++ b/spec/test_prof/memory_prof/rspec_spec.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require "test_prof/memory_prof/rspec" + +describe TestProf::MemoryProf::RSpecListener do + subject { described_class.new } + + let(:tracker) { subject.tracker } + let(:printer) { subject.printer } + + let(:example) do + instance_double( + RSpec::Core::Example, + description: "returns nil", + metadata: {location: "./spec/models/reports_spec.rb:57"} + ) + end + + let(:group) do + double( + RSpec::Core::ExampleGroup, + description: "#publish", + metadata: {location: "./spec/nodels/question_spec.rb:179"} + ) + end + + before do + tracker = instance_double( + TestProf::MemoryProf::Tracker, + start: nil, + finish: nil, + example_started: nil, + example_finished: nil, + group_started: nil, + group_finished: nil + ) + + allow(TestProf::MemoryProf).to receive(:tracker).and_return(tracker) + allow(printer).to receive(:print) + end + + xdescribe "#initialize" do + it "starts the tracking process" do + subject + + expect(tracker).to have_received(:start) + end + end + + describe "#example_started" do + let(:notification) do + RSpec::Core::Notifications::ExampleNotification.send(:new, example) + end + + it "tracks the start of an example" do + subject.example_started(notification) + + expect(tracker).to have_received(:example_started).with({ + name: "returns nil", + location: "./spec/models/reports_spec.rb:57" + }) + end + end + + describe "#example_finished" do + let(:notification) do + RSpec::Core::Notifications::ExampleNotification.send(:new, example) + end + + it "tracks the end of an example" do + subject.example_finished(notification) + + expect(tracker).to have_received(:example_finished).with({ + name: "returns nil", + location: "./spec/models/reports_spec.rb:57" + }) + end + end + + describe "#example_group_started" do + let(:notification) do + RSpec::Core::Notifications::GroupNotification.send(:new, group) + end + + it "tracks the end of an example" do + subject.example_group_started(notification) + + expect(tracker).to have_received(:group_started).with({ + name: "#publish", + location: "./spec/nodels/question_spec.rb:179" + }) + end + end + + describe "#example_group_finished" do + let(:notification) do + RSpec::Core::Notifications::GroupNotification.send(:new, group) + end + + it "tracks the end of an example" do + subject.example_group_finished(notification) + + expect(tracker).to have_received(:group_finished).with({ + name: "#publish", + location: "./spec/nodels/question_spec.rb:179" + }) + end + end + + describe "#report" do + it "finishes the tracking process" do + subject.report + + expect(tracker).to have_received(:finish) + end + + it "prints the results" do + subject.report + + expect(printer).to have_received(:print) + end + end +end diff --git a/spec/test_prof/memory_prof/tracker/linked_list_spec.rb b/spec/test_prof/memory_prof/tracker/linked_list_spec.rb new file mode 100644 index 00000000..31e1685f --- /dev/null +++ b/spec/test_prof/memory_prof/tracker/linked_list_spec.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +describe TestProf::MemoryProf::Tracker::LinkedList do + subject { described_class.new(100) } + + it "initializes a head node" do + expect(subject.head).to have_attributes(item: :total, previous: nil, memory_at_start: 100) + end + + describe "#add_node" do + let(:add_node) { subject.add_node(:item, 200) } + + it "add a new node to the beginning of the list" do + previous = subject.head + add_node + + expect(subject.head).to have_attributes(item: :item, previous: previous, memory_at_start: 200) + end + end + + describe "#remove_node" do + let(:remove_node) { subject.remove_node(:item, 300) } + + before do + subject.add_node(:item, 200) + allow(subject.head).to receive(:finish) + end + + it "finishes the current head node" do + current = subject.head + remove_node + + expect(current).to have_received(:finish).with(300) + end + + it "moves the head to the previous node" do + previous = subject.head.previous + remove_node + + expect(subject.head).to eq(previous) + end + + it "return the current head node" do + current = subject.head + + expect(remove_node).to eq(current) + end + end +end + +describe TestProf::MemoryProf::Tracker::LinkedListNode do + subject do + described_class.new( + item: :item, + memory_at_start: 100, + previous: previous + ) + end + + let(:previous) { nil } + + describe "#total_memory" do + before do + subject.instance_variable_set("@memory_at_start", memory_at_start) + subject.instance_variable_set("@memory_at_finish", memory_at_finish) + end + + context "when memory_at_finish is nil" do + let(:memory_at_start) { 100 } + let(:memory_at_finish) { nil } + + it "returns 0" do + expect(subject.total_memory).to eq(0) + end + end + + context "when memory_at_start > memory_at_finish" do + let(:memory_at_start) { 200 } + let(:memory_at_finish) { 100 } + + it "returns 0" do + expect(subject.total_memory).to eq(0) + end + end + + context "when memory_at_start < memory_at_finish" do + let(:memory_at_start) { 100 } + let(:memory_at_finish) { 200 } + + it "calculates the difference between memory_at_finish and memory_at_start" do + expect(subject.total_memory).to eq(100) + end + end + end + + describe "#hooks_memory" do + before do + subject.instance_variable_set("@memory_at_start", 100) + subject.instance_variable_set("@memory_at_finish", 200) + subject.instance_variable_set("@nested_memory", 50) + end + + it "calculates the difference between total_memory and nested_memory" do + expect(subject.hooks_memory).to eq(50) + end + end + + describe "#finish" do + let(:finish) { subject.finish(200) } + + context "when previous node exists" do + let(:previous) do + described_class.new( + item: :previous, + memory_at_start: 50, + previous: nil + ) + end + + it "sets memory_at_finish" do + finish + + expect(subject.memory_at_finish).to eq(200) + end + + it "updates previous.nested_memory" do + finish + + expect(previous.nested_memory).to eq(100) + end + end + + context "when previous node does not exist" do + let(:previous) { nil } + + it "sets memory_at_finish" do + finish + + expect(subject.memory_at_finish).to eq(200) + end + end + end +end diff --git a/spec/test_prof/memory_prof/tracker/rss_tool_spec.rb b/spec/test_prof/memory_prof/tracker/rss_tool_spec.rb new file mode 100644 index 00000000..eb826de1 --- /dev/null +++ b/spec/test_prof/memory_prof/tracker/rss_tool_spec.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +describe TestProf::MemoryProf::Tracker::RssTool do + subject { described_class } + + describe ".tool" do + before do + allow(subject).to receive(:os_type).and_return(os_type) + end + + context "when an OS is supported" do + let(:os_type) { :macosx } + + it "returns an rss tool" do + expect(subject.tool).to be_kind_of(subject::PS) + end + end + + context "when an OS is not supported" do + let(:os_type) { :invalid } + + it "returns nil" do + expect(subject.tool).to eq(nil) + end + end + end + + describe ".os_type" do + before do + @original_os = RbConfig::CONFIG["host_os"] + RbConfig::CONFIG["host_os"] = host_os + end + + after do + RbConfig::CONFIG["host_os"] = @original_os + end + + context "when the host OS is Linux" do + let(:host_os) { "linux" } + + it "returns :linux" do + expect(subject.os_type).to eq(:linux) + end + end + + context "when the host OS is macOS" do + let(:host_os) { "darwin22" } + + it "returns :macosx" do + expect(subject.os_type).to eq(:macosx) + end + end + + context "when the host OS is macOS" do + let(:host_os) { "mac os 14" } + + it "returns :macosx" do + expect(subject.os_type).to eq(:macosx) + end + end + + %w[solaris bsd].each do |os| + context "when the host OS is #{os}" do + let(:host_os) { "#{os} 17" } + + it "returns :unix" do + expect(subject.os_type).to eq(:unix) + end + end + end + + context "when the host OS is Windows" do + let(:host_os) { "mswin" } + + it "returns :windows" do + expect(subject.os_type).to eq(:windows) + end + end + end +end + +describe TestProf::MemoryProf::Tracker::RssTool::ProcFS do + subject { described_class.new } + + describe "#track" do + before do + io = instance_double(IO, seek: nil, gets: "46441 196384 1804 1 0 24133 0\n") + + allow(File).to receive(:open).and_return(io) + subject.instance_variable_set("@page_size", 1024) + end + + it "retrieves rss via proc statm" do + subject.track + + expect(File).to have_received(:open).with(/\/proc\/\d+\/statm/, "r") + end + + it "returns the current rss" do + expect(subject.track).to eq(201097216) + end + end +end + +describe TestProf::MemoryProf::Tracker::RssTool::PS do + subject { described_class.new } + + describe "#track" do + before do + allow(subject).to receive(:`).and_return(" RSS\n196384") + end + + it "retrieves rss via ps" do + subject.track + + expect(subject).to have_received(:`).with(/ps -o rss -p \d+/) + end + + it "returns the current rss" do + expect(subject.track).to eq(201097216) + end + end +end + +describe TestProf::MemoryProf::Tracker::RssTool::GetProcess do + subject { described_class.new } + + describe "#track" do + before do + allow(subject).to receive(:`).and_return("\n WS\n --\n201097216\n\n\n") + end + + it "retrieves rss via Get-Process" do + subject.track + + expect(subject).to have_received(:`).with(/powershell -Command "Get-Process -Id \d+ | select WS"/) + end + + it "returns the current rss" do + expect(subject.track).to eq(201097216) + end + end +end diff --git a/spec/test_prof/memory_prof/tracker_spec.rb b/spec/test_prof/memory_prof/tracker_spec.rb new file mode 100644 index 00000000..2a6f309f --- /dev/null +++ b/spec/test_prof/memory_prof/tracker_spec.rb @@ -0,0 +1,220 @@ +# frozen_string_literal: true + +shared_examples "TestProf::MemoryProf::Tracker" do + let(:list) { TestProf::MemoryProf::Tracker::LinkedList.new(100) } + + describe "#start" do + it "initializes a linked list" do + subject.start + + expect(subject.list).to be_kind_of(TestProf::MemoryProf::Tracker::LinkedList) + end + end + + describe "#finish" do + before do + allow(subject).to receive(:track).and_return(200) + allow(subject).to receive(:list).and_return(list) + end + + it "sets total_memory" do + subject.finish + + expect(subject.total_memory).to eq(100) + end + end + + describe "#example_started" do + let(:example_started) { subject.example_started({name: :example}) } + + before do + allow(subject).to receive(:track).and_return(200) + allow(subject).to receive(:list).and_return(list) + end + + it "tracks memory at the start of an example" do + example_started + + expect(subject.list.head).to have_attributes(item: {name: :example}, memory_at_start: 200) + end + end + + describe "#example_finished" do + let(:example_finished) { subject.example_finished({name: :example}) } + + before do + list.add_node({name: :example}, 200) + + allow(subject).to receive(:track).and_return(350) + allow(subject).to receive(:list).and_return(list) + end + + context "when the example memory > the memory of the top examples" do + before do + [75, 100, 125, 175, 200].each do |memory| + subject.examples << {memory: memory} + end + end + + it "adds the example to the top examples" do + example_finished + + expect(subject.examples).to match_array([ + {memory: 200}, + {memory: 175}, + {name: :example, memory: 150}, + {memory: 125}, + {memory: 100} + ]) + end + end + + context "when the example memory <= the memory of the top examples" do + before do + [175, 200, 225, 250, 275].each do |memory| + subject.examples << {memory: memory} + end + end + + it "adds the example to the top examples" do + example_finished + + expect(subject.examples).to match_array([ + {memory: 275}, + {memory: 250}, + {memory: 225}, + {memory: 200}, + {memory: 175} + ]) + end + end + end + + describe "#group_started" do + let(:group_started) { subject.group_started({name: :group}) } + + before do + allow(subject).to receive(:track).and_return(200) + allow(subject).to receive(:list).and_return(list) + end + + it "tracks memory at the start of a group" do + group_started + + expect(subject.list.head).to have_attributes(item: {name: :group}, memory_at_start: 200) + end + end + + describe "#group_finished" do + let(:group_finished) { subject.group_finished({name: :group}) } + + before do + list.add_node({name: :group}, 200) + + allow(subject).to receive(:track).and_return(350) + allow(subject).to receive(:list).and_return(list) + end + + context "when the group memory > the memory of the top groups" do + before do + [75, 100, 125, 175, 200].each do |memory| + subject.groups << {memory: memory} + end + end + + it "adds the group to the top groups" do + group_finished + + expect(subject.groups).to match_array([ + {memory: 200}, + {memory: 175}, + {name: :group, memory: 150}, + {memory: 125}, + {memory: 100} + ]) + end + end + + context "when the group memory <= the memory of the top groups" do + before do + [175, 200, 225, 250, 275].each do |memory| + subject.groups << {memory: memory} + end + end + + it "adds the group to the top groups" do + group_finished + + expect(subject.groups).to match_array([ + {memory: 275}, + {memory: 250}, + {memory: 225}, + {memory: 200}, + {memory: 175} + ]) + end + end + end +end + +describe TestProf::MemoryProf::AllocTracker do + subject { described_class.new(5) } + + if RUBY_ENGINE == "jruby" + it "raises an error" do + expect { subject }.to raise_error("Your Ruby Engine or OS is not supported") + end + else + it_behaves_like "TestProf::MemoryProf::Tracker" + + describe "#track" do + before do + allow(GC).to receive(:stat).and_return({total_allocated_objects: 100}) + end + + it "returns the current number of allocations" do + expect(subject.track).to eq(100) + end + end + + describe "#supported?" do + it "returns true" do + expect(subject.supported?).to be_truthy + end + end + end +end + +describe TestProf::MemoryProf::RssTracker do + subject { described_class.new(5) } + + let(:tool) { instance_double(TestProf::MemoryProf::Tracker::RssTool::PS, track: 100) } + + before do + allow(TestProf::MemoryProf::Tracker::RssTool).to receive(:tool).and_return(tool) + end + + it_behaves_like "TestProf::MemoryProf::Tracker" + + describe "#track" do + it "returns the current rss" do + expect(subject.track).to eq(100) + end + end + + describe "#supported?" do + context "when the host OS is supported" do + it "returns true" do + expect(subject.supported?).to be_truthy + end + end + + context "when the host OS is not supported" do + let(:tool) { nil } + + it "raises an error" do + expect { subject }.to raise_error("Your Ruby Engine or OS is not supported") + end + end + end +end diff --git a/spec/test_prof/memory_prof_spec.rb b/spec/test_prof/memory_prof_spec.rb new file mode 100644 index 00000000..7272199b --- /dev/null +++ b/spec/test_prof/memory_prof_spec.rb @@ -0,0 +1,180 @@ +# frozen_string_literal: true + +describe TestProf::MemoryProf do + subject { described_class } + + describe ".config" do + let(:config) { subject.config } + + it "returns an instance of TestProf::MemoryProf::Configuration" do + expect(config).to be_kind_of(TestProf::MemoryProf::Configuration) + end + + describe "#mode=" do + let(:set_mode) { config.mode = value } + + context "when value is alloc" do + let(:value) { "alloc" } + + it "sets mode to alloc" do + set_mode + + expect(config.mode).to eq(:alloc) + end + end + + context "when value is rss" do + let(:value) { "rss" } + + it "sets mode to rss" do + set_mode + + expect(config.mode).to eq(:rss) + end + end + + context "when value is neither alloc or rss" do + let(:value) { "invalid" } + + it "sets mode to alloc" do + set_mode + + expect(config.mode).to eq(:rss) + end + end + end + + describe "#top_count=" do + let(:set_top_count) { config.top_count = value } + + context "when value is an integer" do + let(:value) { 5 } + + it "sets top_count to the value" do + set_top_count + + expect(config.top_count).to eq(5) + end + end + + context "when value is a float" do + let(:value) { 5.7 } + + it "transforms the value to an integer" do + set_top_count + + expect(config.top_count).to eq(5) + end + end + + context "when value is 0" do + let(:value) { 0 } + + it "sets top_count to 5" do + set_top_count + + expect(config.top_count).to eq(5) + end + end + + context "when value is negative" do + let(:value) { -7 } + + it "sets top_count to 5" do + set_top_count + + expect(config.top_count).to eq(5) + end + end + + context "when value is nil" do + let(:value) { nil } + + it "sets top_count to 5" do + set_top_count + + expect(config.top_count).to eq(5) + end + end + + context "when value is a text" do + let(:value) { "invalid" } + + it "sets top_count to 5" do + set_top_count + + expect(config.top_count).to eq(5) + end + end + end + end + + describe ".tracker" do + let(:tracker) { subject.tracker } + + context "when mode is alloc" do + before { described_class.config.mode = "alloc" } + + if RUBY_ENGINE == "jruby" + it "raises an error" do + expect { tracker }.to raise_error("Your Ruby Engine or OS is not supported") + end + else + it "returns an instance of AllocTracker" do + expect(tracker).to be_kind_of(TestProf::MemoryProf::AllocTracker) + end + + it "sets tracker.top_count to config.top_count" do + expect(tracker.top_count).to eq(5) + end + end + end + + context "when mode is rss" do + before { described_class.config.mode = "rss" } + + it "returns an instance of RssTracker" do + expect(tracker).to be_kind_of(TestProf::MemoryProf::RssTracker) + end + + it "sets tracker.top_count to config.top_count" do + expect(tracker.top_count).to eq(5) + end + end + end + + describe ".printer" do + let(:printer) { subject.printer(tracker) } + let(:tracker) { subject.tracker } + + context "when mode is alloc" do + before { described_class.config.mode = "alloc" } + + if RUBY_ENGINE == "jruby" + it "raises an error" do + expect { printer }.to raise_error("Your Ruby Engine or OS is not supported") + end + else + it "returns an instance of AllocPrinter" do + expect(printer).to be_kind_of(TestProf::MemoryProf::AllocPrinter) + end + + it "sets printer.tracker" do + expect(printer.send(:tracker)).to eq(tracker) + end + end + end + + context "when mode is rss" do + before { described_class.config.mode = "rss" } + + it "returns an instance of RssPrinter" do + expect(printer).to be_kind_of(TestProf::MemoryProf::RssPrinter) + end + + it "sets printer.tracker" do + expect(printer.send(:tracker)).to eq(tracker) + end + end + end +end From 5ded8f992c81057c6121ca2369dd59187e4b6f79 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 13:43:19 -0800 Subject: [PATCH 119/194] docs: memory prof --- CHANGELOG.md | 3 +++ docs/_sidebar.md | 1 + 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01eee29e..520066d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- MemoryProf ia added. ([@Vankiru][]) + ## 1.2.3 (2023-09-11) - Minor fixes and dependencies upgrades. @@ -367,3 +369,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@cbarton]: https://github.com/cbarton [@peret]: https://github.com/peret [@bf4]: https://github.com/bf4 +[@Vankiru]: https://github.com/Vankiru diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 5a2c2a2d..44244b1a 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -11,6 +11,7 @@ * [Factory Doctor](/profilers/factory_doctor.md) * [Factory Profiler](/profilers/factory_prof.md) * [RSpecDissect Profiler](/profilers/rspec_dissect.md) + * [Memory Profiler](/profilers/memory_prof.md) * Recipes * [`before_all` Hook](/recipes/before_all.md) From 37770c2fc3c84a1b5fad9ce6d5a67f8a740ac036 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 14:14:50 -0800 Subject: [PATCH 120/194] fix: guard negative numbers in exponent --- lib/test_prof/memory_prof/printer/number_to_human.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/memory_prof/printer/number_to_human.rb b/lib/test_prof/memory_prof/printer/number_to_human.rb index ff03f44d..9c2c3a0f 100644 --- a/lib/test_prof/memory_prof/printer/number_to_human.rb +++ b/lib/test_prof/memory_prof/printer/number_to_human.rb @@ -18,7 +18,7 @@ def convert(number) private def exponent(number) - return 0 if number.zero? + return 0 unless number.positive? max = UNITS.size - 1 From 3dfe1cf8494665949c5529b998e90b4e121fbe77 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 15:27:38 -0800 Subject: [PATCH 121/194] docs: merge stack_prof/ruby_prof pages into a single ruby profilers page --- CHANGELOG.md | 2 + docs/_sidebar.md | 3 +- docs/profilers/ruby_prof.md | 86 +-------------- docs/profilers/ruby_profilers.md | 174 ++++++++++++++++++++++++++++++ docs/profilers/stack_prof.md | 85 +-------------- lib/test_prof/stack_prof.rb | 2 +- spec/test_prof/stack_prof_spec.rb | 1 + 7 files changed, 183 insertions(+), 170 deletions(-) create mode 100644 docs/profilers/ruby_profilers.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 520066d8..64a4b424 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- StackProf uses JSON format by default. ([@palkan][]) + - MemoryProf ia added. ([@Vankiru][]) ## 1.2.3 (2023-09-11) diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 44244b1a..17883bc9 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -4,8 +4,7 @@ * [Playbook](/playbook.md) * Profilers - * [RubyProf Integration](/profilers/ruby_prof.md) - * [StackProf Integration](/profilers/stack_prof.md) + * [Ruby profilers](/profilers/ruby_profilers.md) * [Event Profiler](/profilers/event_prof.md) * [Tag Profiler](/profilers/tag_prof.md) * [Factory Doctor](/profilers/factory_doctor.md) diff --git a/docs/profilers/ruby_prof.md b/docs/profilers/ruby_prof.md index 0e41b6aa..013f6b7e 100644 --- a/docs/profilers/ruby_prof.md +++ b/docs/profilers/ruby_prof.md @@ -1,84 +1,2 @@ -# Profiling with RubyProf - -Easily integrate the power of [ruby-prof](https://github.com/ruby-prof/ruby-prof) into your test suite. - -## Instructions - -Install `ruby-prof` gem (>= 1.4.0): - -```ruby -# Gemfile -group :development, :test do - gem "ruby-prof", ">= 1.4.0", require: false -end -``` - -RubyProf profiler has two modes: `global` and `per-example`. - -You can activate the global profiling using the environment variable `TEST_RUBY_PROF`: - -```sh -TEST_RUBY_PROF=1 bundle exec rake test - -# or for RSpec -TEST_RUBY_PROF=1 rspec ... -``` - -Or in your code: - -```ruby -TestProf::RubyProf.run -``` - -TestProf provides a built-in shared context for RSpec to profile examples individually: - -```ruby -it "is doing heavy stuff", :rprof do - # ... -end -``` - -**NOTE:** per-example profiling doesn't work when the global profiling is activated. - -## Configuration - -The most useful configuration option is `printer` – it allows you to specify a RubyProf [printer](https://github.com/ruby-prof/ruby-prof#printers). - -You can specify a printer through environment variable `TEST_RUBY_PROF`: - -```sh -TEST_RUBY_PROF=call_stack bundle exec rake test -``` - -Or in your code: - -```ruby -TestProf::RubyProf.configure do |config| - config.printer = :call_stack -end -``` - -By default, we use `FlatPrinter`. - -**NOTE:** to specify the printer for per-example profiles use `TEST_RUBY_PROF_PRINTER` env variable ('cause using `TEST_RUBY_PROF` activates the global profiling). - -Also, you can specify RubyProf mode (`wall`, `cpu`, etc) through `TEST_RUBY_PROF_MODE` env variable. - -See [ruby_prof.rb](https://github.com/test-prof/test-prof/tree/master/lib/test_prof/ruby_prof.rb) for all available configuration options and their usage. - -### Methods Exclusion - -It's useful to exclude some methods from the profile to focus only on the application code. - -TestProf uses RubyProf [`exclude_common_methods!`](https://github.com/ruby-prof/ruby-prof/blob/e087b7d7ca11eecf1717d95a5c5fea1e36ea3136/lib/ruby-prof/profile/exclude_common_methods.rb) by default (disable it with `config.exclude_common_methods = false`). - -We exclude some other common methods and RSpec specific internal methods by default. -To disable TestProf-defined exclusions set `config.test_prof_exclusions_enabled = false`. - -You can specify custom exclusions through `config.custom_exclusions`, e.g.: - -```ruby -TestProf::RubyProf.configure do |config| - config.custom_exclusions = {User => %i[save save!]} -end -``` + +

Please follow this link.

diff --git a/docs/profilers/ruby_profilers.md b/docs/profilers/ruby_profilers.md new file mode 100644 index 00000000..425813d2 --- /dev/null +++ b/docs/profilers/ruby_profilers.md @@ -0,0 +1,174 @@ +# Using with Ruby profilers + +Test Prof allows you to use general Ruby profilers to profile test suites without needing to write any profiling code yourself. +Just install the profiler library and run your tests! + +Supported profilers: + +- [StackProf](#stackprof) +- [RubyProf](#rubyprof) + +## StackProf + +[StackProf][] is a sampling call-stack profiler for Ruby. + +Make sure you have `stackprof` in your dependencies: + +```ruby +# Gemfile +group :development, :test do + gem "stackprof", ">= 0.2.9", require: false +end +``` + +### Profiling the whole test suite with StackProf + +**NOTE:** It's recommended to use [test sampling](../recipes/tests_sampling.md) to generate smaller profiling reports. + +You can activate StackProf profiling by setting the `TEST_STACK_PROF` env variable: + +```sh +TEST_STACK_PROF=1 bundle exec rake test + +# or for RSpec +TEST_STACK_PROF=1 bundle exec rspec ... +``` + +At the end of the test run, you will see the message from Test Prof including paths to generated reports (raw StackProf format and JSON): + +```sh +... + +[TEST PROF INFO] StackProf report generated: tmp/test_prof/stack-prof-report-wall-raw-total.dump +[TEST PROF INFO] StackProf JSON report generated: tmp/test_prof/stack-prof-report-wall-raw-total.json +``` + +We recommend uploading JSON reports to [Speedscope][] and analyze flamegraphs. Otherwise, feel free to use the `stackprof` CLI +to manipulate the raw report. + +### Profiling individual examples with StackProf + +Test Prof provides a built-in shared context for RSpec to profile examples individually: + +```ruby +it "is doing heavy stuff", :sprof do + # ... +end +``` + +**NOTE:** per-example profiling doesn't work when the global (per-suite) profiling is activated. + +### Profiling application boot with StackProf + +The application boot time could also makes testing slower. Try to profile your boot process with StackProf using the following command: + +```sh +# pick some random spec (1 is enough) +$ TEST_STACK_PROF=boot bundle exec rspec ./spec/some_spec.rb + +... +[TEST PROF INFO] StackProf report generated: tmp/test_prof/stack-prof-report-wall-raw-boot.dump +[TEST PROF INFO] StackProf JSON report generated: tmp/test_prof/stack-prof-report-wall-raw-boot.json +``` + +### StackProf configuration + +You can change StackProf mode (which is `wall` by default) through `TEST_STACK_PROF_MODE` env variable. + +You can also change StackProf interval through `TEST_STACK_PROF_INTERVAL` env variable. +For modes `wall` and `cpu`, `TEST_STACK_PROF_INTERVAL` represents microseconds and will default to 1000 as per `stackprof`. +For mode `object`, `TEST_STACK_PROF_INTERVAL` represents allocations and will default to 1 as per `stackprof`. + +You can disable garbage collection frames by setting `TEST_STACK_PROF_IGNORE_GC` env variable. +Garbage collection time will still be present in the profile but not explicitly marked with +its own frame. + +See [stack_prof.rb](https://github.com/test-prof/test-prof/tree/master/lib/test_prof/stack_prof.rb) for all available configuration options and their usage. + +## RubyProf + +Easily integrate the power of [ruby-prof](https://github.com/ruby-prof/ruby-prof) into your test suite. + +Make sure `ruby-prof` is installed: + +```ruby +# Gemfile +group :development, :test do + gem "ruby-prof", ">= 1.4.0", require: false +end +``` + +### Profiling the whole test suite with RubyProf + +**NOTE:** It's highly recommended to use [test sampling](../recipes/tests_sampling.md) to generate smaller profiling reports and avoid slow test runs (RubyProf has a signifact overhead). + +You can activate the global profiling using the environment variable `TEST_RUBY_PROF`: + +```sh +TEST_RUBY_PROF=1 bundle exec rake test + +# or for RSpec +TEST_RUBY_PROF=1 bundle exec rspec ... +``` + +At the end of the test run, you will see the message from Test Prof including paths to generated reports: + +```sh +[TEST PROF INFO] RubyProf report generated: tmp/test_prof/ruby-prof-report-flat-wall-total.txt +``` + +### Profiling individual examples with RubyProf + +TestProf provides a built-in shared context for RSpec to profile examples individually: + +```ruby +it "is doing heavy stuff", :rprof do + # ... +end +``` + +**NOTE:** per-example profiling doesn't work when the global profiling is activated. + +### RubyProf configuration + +The most useful configuration option is `printer` – it allows you to specify a RubyProf [printer](https://github.com/ruby-prof/ruby-prof#printers). + +You can specify a printer through environment variable `TEST_RUBY_PROF`: + +```sh +TEST_RUBY_PROF=call_stack bundle exec rake test +``` + +Or in your code: + +```ruby +TestProf::RubyProf.configure do |config| + config.printer = :call_stack +end +``` + +By default, we use `FlatPrinter`. + +**NOTE:** to specify the printer for per-example profiles use `TEST_RUBY_PROF_PRINTER` env variable ('cause using `TEST_RUBY_PROF` activates the global profiling). + +Also, you can specify RubyProf mode (`wall`, `cpu`, etc) through `TEST_RUBY_PROF_MODE` env variable. + +See [ruby_prof.rb](https://github.com/test-prof/test-prof/tree/master/lib/test_prof/ruby_prof.rb) for all available configuration options and their usage. + +It's useful to exclude some methods from the profile to focus only on the application code. + +TestProf uses RubyProf [`exclude_common_methods!`](https://github.com/ruby-prof/ruby-prof/blob/e087b7d7ca11eecf1717d95a5c5fea1e36ea3136/lib/ruby-prof/profile/exclude_common_methods.rb) by default (disable it with `config.exclude_common_methods = false`). + +We exclude some other common methods and RSpec specific internal methods by default. +To disable TestProf-defined exclusions set `config.test_prof_exclusions_enabled = false`. + +You can specify custom exclusions through `config.custom_exclusions`, e.g.: + +```ruby +TestProf::RubyProf.configure do |config| + config.custom_exclusions = {User => %i[save save!]} +end +``` + +[StackProf]: https://github.com/tmm1/stackprof +[Speedscope]: https://www.speedscope.app diff --git a/docs/profilers/stack_prof.md b/docs/profilers/stack_prof.md index 9ed34135..013f6b7e 100644 --- a/docs/profilers/stack_prof.md +++ b/docs/profilers/stack_prof.md @@ -1,83 +1,2 @@ -# Profiling with StackProf - -[StackProf](https://github.com/tmm1/stackprof) is a sampling call-stack profiler for ruby. - -## Instructions - -Install `stackprof` gem (>= 0.2.9): - -```ruby -# Gemfile -group :development, :test do - gem "stackprof", ">= 0.2.9", require: false -end -``` - -StackProf profiler has 2 modes: `global` and `per-example`. - -You can activate global profiling using the environment variable `TEST_STACK_PROF`: - -```sh -TEST_STACK_PROF=1 bundle exec rake test - -# or for RSpec -TEST_STACK_PROF=1 rspec ... -``` - -Or in your code: - -```ruby -TestProf::StackProf.run -``` - -TestProf provides a built-in shared context for RSpec to profile examples individually: - -```ruby -it "is doing heavy stuff", :sprof do - # ... -end -``` - -**NOTE:** per-example profiling doesn't work when the global profiling is activated. - -## Report formats - -Stackprof provides a CLI tool to manipulate generated reports (e.g. convert to different formats). - -By default, Test Prof shows you a command\* to generate an HTML report for analyzing flamegraphs, so you should run it yourself. - -\* only if you're collecting _raw_ samples data, which is the default Test Prof behaviour. - -Sometimes it's useful to have a JSON report (e.g. to use it with [speedscope](https://www.speedscope.app)), but `stackprof` only supports this only since version [0.2.13](https://github.com/tmm1/stackprof/blob/master/CHANGELOG.md#0213). - -If you're using an older version of Stackprof, Test Prof can help in generating JSON reports from _raw_ dumps. For that, use `TEST_STACK_PROF_FORMAT=json` or configure the default format in your code: - -```ruby -TestProf::StackProf.configure do |config| - config.format = "json" -end -``` - -## Profiling application boot - -The application boot time could also makes testing slower. Try to profile your boot process with StackProf using the following command: - -```sh -TEST_STACK_PROF=boot rspec ./spec/some_spec.rb -``` - -**NOTE:** we recommend to analyze the boot time using flame graphs, that's why raw data collection is always on in `boot` mode. - -## Configuration - -You can change StackProf mode (which is `wall` by default) through `TEST_STACK_PROF_MODE` env variable. - -You can also change StackProf interval through `TEST_STACK_PROF_INTERVAL` env variable. -For modes `wall` and `cpu`, `TEST_STACK_PROF_INTERVAL` represents microseconds and will default to 1000 as per `stackprof`. -For mode `object`, `TEST_STACK_PROF_INTERVAL` represents allocations and will default to 1 as per `stackprof`. - -You can disable garbage collection frames by setting `TEST_STACK_PROF_IGNORE_GC` env variable. -Garbage collection time will still be present in the profile but not explicitly marked with -its own frame. - -See [stack_prof.rb](https://github.com/test-prof/test-prof/tree/master/lib/test_prof/stack_prof.rb) for all available configuration options and their usage. + +

Please follow this link.

diff --git a/lib/test_prof/stack_prof.rb b/lib/test_prof/stack_prof.rb index f17f3dc1..c73b8758 100644 --- a/lib/test_prof/stack_prof.rb +++ b/lib/test_prof/stack_prof.rb @@ -33,7 +33,7 @@ def initialize if FORMATS.include?(ENV["TEST_STACK_PROF_FORMAT"]) ENV["TEST_STACK_PROF_FORMAT"] else - "html" + "json" end sample_interval = ENV["TEST_STACK_PROF_INTERVAL"].to_i diff --git a/spec/test_prof/stack_prof_spec.rb b/spec/test_prof/stack_prof_spec.rb index d307cf4f..2f00a654 100644 --- a/spec/test_prof/stack_prof_spec.rb +++ b/spec/test_prof/stack_prof_spec.rb @@ -73,6 +73,7 @@ end it "stops profiling and stores results" do + expect(described_class).to receive(:dump_json_report) expect(stack_prof).to receive(:results).with( File.join(TestProf.config.output_dir, "stack-prof-report-wall-raw-stub.dump").to_s ) From df15a5822833361f3b33713f332a88087d122d85 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 19:32:11 -0800 Subject: [PATCH 122/194] feat: vernier integration --- .github/workflows/rspec.yml | 3 + CHANGELOG.md | 2 + Gemfile | 1 + docs/profilers/ruby_profilers.md | 59 +++++++ lib/test_prof.rb | 1 + lib/test_prof/stack_prof.rb | 4 +- lib/test_prof/stack_prof/rspec.rb | 3 +- lib/test_prof/vernier.rb | 152 ++++++++++++++++++ lib/test_prof/vernier/rspec.rb | 59 +++++++ .../fixtures/rspec/vernier_fixture.rb | 18 +++ spec/integrations/profilers_spec.rb | 19 +++ 11 files changed, 318 insertions(+), 3 deletions(-) create mode 100644 lib/test_prof/vernier.rb create mode 100644 lib/test_prof/vernier/rspec.rb create mode 100644 spec/integrations/fixtures/rspec/vernier_fixture.rb diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 051e909f..dcca708f 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -31,6 +31,9 @@ jobs: - ruby: 3.2 gemfile: "gemfiles/railsmaster.gemfile" db: "mysql" + - ruby: 3.2 + gemfile: "Gemfile" + db: "sqlite" - ruby: 3.1 gemfile: "gemfiles/activerecord7.gemfile" db: "sqlite" diff --git a/CHANGELOG.md b/CHANGELOG.md index 64a4b424..f25df0f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Add Vernier integration. ([@palkan][]) + - StackProf uses JSON format by default. ([@palkan][]) - MemoryProf ia added. ([@Vankiru][]) diff --git a/Gemfile b/Gemfile index 229f426b..a3510cb9 100644 --- a/Gemfile +++ b/Gemfile @@ -34,5 +34,6 @@ else gem "debug" unless ENV["CI"] gem "ruby-prof", ">= 1.4.0" gem "stackprof", ">= 0.2.9" + gem "vernier" end end diff --git a/docs/profilers/ruby_profilers.md b/docs/profilers/ruby_profilers.md index 425813d2..d52bd6c0 100644 --- a/docs/profilers/ruby_profilers.md +++ b/docs/profilers/ruby_profilers.md @@ -6,6 +6,7 @@ Just install the profiler library and run your tests! Supported profilers: - [StackProf](#stackprof) +- [Vernier](#vernier) - [RubyProf](#rubyprof) ## StackProf @@ -85,6 +86,63 @@ its own frame. See [stack_prof.rb](https://github.com/test-prof/test-prof/tree/master/lib/test_prof/stack_prof.rb) for all available configuration options and their usage. +## Vernier + +[Vernier][] is next generation sampling profiler for Ruby. Give it a try and see if it can help in identifying test peformance bottlenecks! + +Make sure you have `vernier` in your dependencies: + +```ruby +# Gemfile +group :development, :test do + gem "vernier", ">= 0.3.0", require: false +end +``` + +### Profiling the whole test suite with Vernier + +**NOTE:** It's recommended to use [test sampling](../recipes/tests_sampling.md) to generate smaller profiling reports. + +You can activate Verner profiling by setting the `TEST_VERNIER` env variable: + +```sh +TEST_VERNIER=1 bundle exec rake test + +# or for RSpec +TEST_VERNIER=1 bundle exec rspec ... +``` + +At the end of the test run, you will see the message from Test Prof including the path to the generated report: + +```sh +... + +[TEST PROF INFO] Vernier report generated: tmp/test_prof/vernier-report-wall-raw-total.json +``` + +Use the [profile-viewer](https://github.com/tenderlove/profiler/tree/ruby) gem or upload your profiles to [profiler.firefox.com](https://profiler.firefox.com). + +### Profiling individual examples with Vernier + +Test Prof provides a built-in shared context for RSpec to profile examples individually: + +```ruby +it "is doing heavy stuff", :vernier do + # ... +end +``` + +**NOTE:** per-example profiling doesn't work when the global (per-suite) profiling is activated. + +### Profiling application boot with Vernier + +You can also profile your application boot process: + +```sh +# pick some random spec (1 is enough) +TEST_VERNIER=boot bundle exec rspec ./spec/some_spec.rb +``` + ## RubyProf Easily integrate the power of [ruby-prof](https://github.com/ruby-prof/ruby-prof) into your test suite. @@ -172,3 +230,4 @@ end [StackProf]: https://github.com/tmm1/stackprof [Speedscope]: https://www.speedscope.app +[Vernier]: https://github.com/jhawthorn/vernier diff --git a/lib/test_prof.rb b/lib/test_prof.rb index 9769ba16..acb766c3 100644 --- a/lib/test_prof.rb +++ b/lib/test_prof.rb @@ -5,6 +5,7 @@ require "test_prof/ruby_prof" require "test_prof/stack_prof" +require "test_prof/vernier" require "test_prof/event_prof" require "test_prof/factory_doctor" require "test_prof/factory_prof" diff --git a/lib/test_prof/stack_prof.rb b/lib/test_prof/stack_prof.rb index c73b8758..5ac75f13 100644 --- a/lib/test_prof/stack_prof.rb +++ b/lib/test_prof/stack_prof.rb @@ -81,9 +81,9 @@ def run def profile(name = nil) if locked? log :warn, <<~MSG - StackProf is activated globally, you cannot generate per-example report. + StackProf has been already activated. - Make sure you haven't set the TEST_STACK_PROF environmental variable. + Make sure you have not set the TEST_STACK_PROF environmental variable. MSG return false end diff --git a/lib/test_prof/stack_prof/rspec.rb b/lib/test_prof/stack_prof/rspec.rb index 3457daad..cf7e9642 100644 --- a/lib/test_prof/stack_prof/rspec.rb +++ b/lib/test_prof/stack_prof/rspec.rb @@ -19,12 +19,13 @@ class << self def example_started(notification) return unless profile?(notification.example) + notification.example.metadata[:sprof_report] = TestProf::StackProf.profile end def example_finished(notification) return unless profile?(notification.example) - return unless notification.example.metadata[:sprof_report] == false + return if notification.example.metadata[:sprof_report] == false TestProf::StackProf.dump( self.class.report_name_generator.call(notification.example) diff --git a/lib/test_prof/vernier.rb b/lib/test_prof/vernier.rb new file mode 100644 index 00000000..6d9667c5 --- /dev/null +++ b/lib/test_prof/vernier.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +module TestProf + # Vernier wrapper. + # + # Has 2 modes: global and per-example. + # + # Example: + # + # # To activate global profiling you can use env variable + # TEST_VERNIER=1 rspec ... + # + # To profile a specific examples add :vernier tag to it: + # + # it "is doing heavy stuff", :vernier do + # ... + # end + # + module Vernier + # Vernier configuration + class Configuration + attr_accessor :mode, :target, :interval + + def initialize + @mode = ENV.fetch("TEST_VERNIER_MODE", :wall).to_sym + @target = (ENV["TEST_VERNIER"] == "boot") ? :boot : :suite + + sample_interval = ENV["TEST_VERNIER_INTERVAL"].to_i + @interval = (sample_interval > 0) ? sample_interval : nil + end + + def boot? + target == :boot + end + + def suite? + target == :suite + end + end + + class << self + include Logging + + def config + @config ||= Configuration.new + end + + def configure + yield config + end + + attr_reader :default_collector + + # Run Vernier and automatically dump + # a report when the process exits or when the application is booted. + def run + collector = profile + return unless collector + + @locked = true + @default_collector = collector + + log :info, "Vernier enabled globally: " \ + "mode – #{config.mode}, target – #{config.target}" + + at_exit { dump(collector, "total") } if config.suite? + end + + def profile(name = nil) + if locked? + log :warn, <<~MSG + Vernier has been already activated. + + Make sure you do not have the TEST_VERNIER environmental variable set somewhere. + MSG + + return false + end + + return false unless init_vernier + + options = {} + + options[:interval] = config.interval if config.interval + + if block_given? + options[:mode] = config.mode + options[:out] = build_path(name) + ::Vernier.trace(**options) { yield } + else + collector = ::Vernier::Collector.new(config.mode, **options) + collector.start + + collector + end + end + + def dump(collector, name) + result = collector.stop + + path = build_path(name) + + File.write(path, ::Vernier::Output::Firefox.new(result).output) + + log :info, "Vernier report generated: #{path}" + end + + private + + def build_path(name) + TestProf.artifact_path( + "vernier-report-#{config.mode}-#{name}.json" + ) + end + + def locked? + @locked == true + end + + def init_vernier + return @initialized if instance_variable_defined?(:@initialized) + @locked = false + @initialized = TestProf.require( + "vernier", + <<~MSG + Please, install 'vernier' first: + # Gemfile + gem 'vernier', '>= 0.3.0', require: false + MSG + ) { check_vernier_version } + end + + def check_vernier_version + if Utils.verify_gem_version("vernier", at_least: "0.3.0") + true + else + log :error, <<~MSG + Please, upgrade 'vernier' to version >= 0.3.0. + MSG + false + end + end + end + end +end + +require "test_prof/vernier/rspec" if TestProf.rspec? + +# Hook to run Vernier globally +TestProf.activate("TEST_VERNIER") do + TestProf::Vernier.run +end diff --git a/lib/test_prof/vernier/rspec.rb b/lib/test_prof/vernier/rspec.rb new file mode 100644 index 00000000..51148094 --- /dev/null +++ b/lib/test_prof/vernier/rspec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "test_prof/utils/rspec" + +module TestProf + module Vernier + # Reporter for RSpec to profile specific examples with Vernier + class Listener # :nodoc: + class << self + attr_accessor :report_name_generator + end + + self.report_name_generator = Utils::RSpec.method(:example_to_filename) + + NOTIFICATIONS = %i[ + example_started + example_finished + ].freeze + + def example_started(notification) + return unless profile?(notification.example) + notification.example.metadata[:vernier_collector] = TestProf::Vernier.profile + end + + def example_finished(notification) + return unless profile?(notification.example) + return unless notification.example.metadata[:vernier_collector] + + TestProf::Vernier.dump( + notification.example.metadata[:vernier_collector], + self.class.report_name_generator.call(notification.example) + ) + end + + private + + def profile?(example) + example.metadata.key?(:vernier) + end + end + end +end + +RSpec.configure do |config| + config.before(:suite) do + listener = TestProf::Vernier::Listener.new + + config.reporter.register_listener( + listener, *TestProf::Vernier::Listener::NOTIFICATIONS + ) + end +end + +# Handle boot profiling +RSpec.configure do |config| + config.append_before(:suite) do + TestProf::Vernier.dump(TestProf::Vernier.default_collector, "boot") if TestProf::Vernier.config.boot? + end +end diff --git a/spec/integrations/fixtures/rspec/vernier_fixture.rb b/spec/integrations/fixtures/rspec/vernier_fixture.rb new file mode 100644 index 00000000..d5d71450 --- /dev/null +++ b/spec/integrations/fixtures/rspec/vernier_fixture.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require "test-prof" + +TestProf.configure do |config| + config.output_dir = "../../../../tmp/test_prof" +end + +shared_examples_for "Something" do + it "always passes", :vernier do + expect(true).to eq true + end +end + +describe "One more thing" do + include_examples "Something" +end diff --git a/spec/integrations/profilers_spec.rb b/spec/integrations/profilers_spec.rb index bbd5bb8d..88a0e5b1 100644 --- a/spec/integrations/profilers_spec.rb +++ b/spec/integrations/profilers_spec.rb @@ -4,6 +4,7 @@ begin require "stackprof" require "ruby-prof" + require "vernier" rescue LoadError end @@ -39,6 +40,24 @@ expect(output).to include("StackProf (raw) enabled globally") expect(output).to include("StackProf report generated") + expect(output).to include("StackProf JSON report generated") + expect(output).to include("0 failures") + end + end + + context "vernier" do + specify "per example" do + output = run_rspec("vernier") + + expect(output).to match(/Vernier report generated.+vernier_fixture-rb-1-1/) + expect(output).to include("0 failures") + end + + specify "global" do + output = run_rspec("vernier", env: {"TEST_VERNIER" => "1"}) + + expect(output).to include("Vernier enabled globally") + expect(output).to include("Vernier report generated") expect(output).to include("0 failures") end end From fea6c5c0fe1a0367bcf266b454d99b801e30f8fa Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 14 Nov 2023 21:17:43 -0800 Subject: [PATCH 123/194] docs: sponsor link --- .mdlrc | 2 +- docs/_sidebar.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.mdlrc b/.mdlrc index 77f87fdd..99fa594c 100644 --- a/.mdlrc +++ b/.mdlrc @@ -1 +1 @@ -rules "~MD013", "~MD033", "~MD007" +rules "~MD013", "~MD033", "~MD007", "~MD032" diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 17883bc9..0fba455a 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -2,6 +2,10 @@ * [Getting Started](/getting_started.md) * [Playbook](/playbook.md) + * Profilers * [Ruby profilers](/profilers/ruby_profilers.md) From 91095d4b383eea6d1237bb824be94d31bd51958f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 21 Nov 2023 23:42:09 +0300 Subject: [PATCH 124/194] Bump 1.3.0 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f25df0f6..3371f546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.3.0 (2023-11-21) + - Add Vernier integration. ([@palkan][]) - StackProf uses JSON format by default. ([@palkan][]) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 91605a4a..2fd0fdec 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.2.3" + VERSION = "1.3.0" end From 0a7e82ce941e0cc34eeae54060ef950c726ca4c4 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 22 Nov 2023 18:54:51 +0300 Subject: [PATCH 125/194] docs: update resources - Add TestProf 3 post - Add ZeroGravity case study --- docs/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index efedef32..c5bfb8c7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -56,7 +56,11 @@ TestProf toolbox aims to help you identify bottlenecks in your test suite. It co - [TestProf: a good doctor for slow Ruby tests](https://evilmartians.com/chronicles/testprof-a-good-doctor-for-slow-ruby-tests) -- [TestProf II: Factory therapy for your Ruby tests](https://evilmartians.com/chronicles/testprof-2-factory-therapy-for-your-ruby-tests-rspec-minitest) +- [TestProf II: factory therapy for your Ruby tests](https://evilmartians.com/chronicles/testprof-2-factory-therapy-for-your-ruby-tests-rspec-minitest) + +- [TestProf III: guided and automated Ruby test profiling](https://evilmartians.com/chronicles/test-prof-3-guided-and-automated-ruby-test-profiling) + +- [Rails Testing on Rocket Fuel: How we made our tests 5x faster](https://www.zerogravity.co.uk/blog/ruby-on-rails-slow-tests) - Paris.rb, 2018, "99 Problems of Slow Tests" talk [[video](https://www.youtube.com/watch?v=eDMZS_fkRtk), [slides](https://speakerdeck.com/palkan/paris-dot-rb-2018-99-problems-of-slow-tests)] From f761495316a6be53b458b2c631b0ed0cd4821e31 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 23 Nov 2023 11:22:38 +0100 Subject: [PATCH 126/194] docs: update coggle image --- docs/assets/images/coggle.png | Bin 383801 -> 647696 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/assets/images/coggle.png b/docs/assets/images/coggle.png index b3ffe00b6e71eaa7835f507b1efc4765921a4eea..422071f8dcf3d696cef4fd2f52af67d2c9703b6b 100644 GIT binary patch literal 647696 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 W0DCd01yqpWWA4ezK34^;BV;Qu)@S$ z%g%*x1uCbj$SW$=BUXM^j~Q5fDj90`6coB~aL-G?gNKu!Qq&>mTuAnH_}cJg&St7O zYn~6uE}rfRE~q+oJVK1B?Mwy~Q)PBjULtR=($kNpuOs?KEkG2so0dw=6VL&i(t|ac(JRr zC%>)1{J6Q*BS%V0>o1$4SXUgQz09Fr@EFhVEaEr@m2^~cax&Nzl9JwoW+59AV?f%y zJMJ!l1;)Yo0vcDNfUjRKW0{vNFl8Ipsb_}Z(z|>?J`LgncFJTxLVdXcyho9hvIkH> zfXDwQpz_F0z~CU9FtOVjwh}9ui2d^OH08)PeQ;>Yrz&ZYIf;DU>{XQG0WFGe|2S=v zJBTX2<>aMUNCwammejY>0W){*8YAORHjNC0RHUYvoSZx^B2H6cMfi27;=birH#vHg ztJi`QhD-X?9j-sD5w}B(mad-VsU;HD1f4kOY(>nMh*ptv8sh#{{8NwN9Dm`doPKt zIA)b{f%(}TuIXfQT4=e|oaYbJ>Mn9{UbPLZO&t=@d`W>WMvS%td8kMa7J zDk}Pw4T6(N*G#mTqJjcwOV6JtY+pb!X&)Ly|?b)zh4o<8~#i>5)QxQ)@^*ax#Qz&m-gWtKf~>~@rQGcU$^cY ztOz*7!`fzLYum?)qySQaR|L5om+9$O`NcqF0O#^yZ}MvOsW{y4e-|p9b4IHj4aD)C zoSZ~A`a|{}lrxAK0VI*29|DOP)Y|GVUk>KzVuN6%T(#2yqNBvdb~p>FgT8(((=Z<& zz0LXGS^zstf4|C1DaaJ{G&_eKSWdBMnp$5l z?aHV7lILc53R}Y*w^pdPv==@N5gJNJR19>fP|E_Z{{!T z((s-~XxZg?OjF=&gj;l$N|L_pz_lte@e7ISoZ(Oa6t2Kks0*4CL~a

f*zqn0$-O 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 oK*xhJ-1a#$b!lnB)ejN%y_Eb-@gPqCZ)+F* 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 -AlvTX!Zf;&2L~(-Z%h6L6vJN_ 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%0AY1yW+OEXv>A>y8 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�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%0D^u1*d?z1x~Knn{3^Q4$Xc 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

i%?f{oJp@e3WOh>ynPb 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

X-UaR81@ndC~2xZhSk9la2jGRB$~~r6@T8^ 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

l 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

cXx`?b<-Wv4blzY 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%0Dwhu0?OWzNG) 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 MO7|5@70g2ZAMw^){{R30 From 55629e43a04374eac40e1f9a423f869f6abd9c3d Mon Sep 17 00:00:00 2001 From: uzushino Date: Thu, 7 Dec 2023 00:56:29 +0900 Subject: [PATCH 127/194] FactoryProf results to a JSON file --- lib/test_prof/factory_prof.rb | 3 + lib/test_prof/factory_prof/printers/json.rb | 41 +++++++++++++ spec/integrations/factory_prof_spec.rb | 7 +++ .../factory_prof/printers/json_spec.rb | 57 +++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 lib/test_prof/factory_prof/printers/json.rb create mode 100644 spec/test_prof/factory_prof/printers/json_spec.rb diff --git a/lib/test_prof/factory_prof.rb b/lib/test_prof/factory_prof.rb index 36c4b243..ac129e34 100644 --- a/lib/test_prof/factory_prof.rb +++ b/lib/test_prof/factory_prof.rb @@ -3,6 +3,7 @@ require "test_prof/factory_prof/printers/simple" require "test_prof/factory_prof/printers/flamegraph" require "test_prof/factory_prof/printers/nate_heckler" +require "test_prof/factory_prof/printers/json" require "test_prof/factory_prof/factory_builders/factory_bot" require "test_prof/factory_prof/factory_builders/fabrication" @@ -25,6 +26,8 @@ def initialize Printers::Flamegraph when "nate_heckler" Printers::NateHeckler + when "json" + Printers::Json else Printers::Simple end diff --git a/lib/test_prof/factory_prof/printers/json.rb b/lib/test_prof/factory_prof/printers/json.rb new file mode 100644 index 00000000..04584e71 --- /dev/null +++ b/lib/test_prof/factory_prof/printers/json.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require "test_prof/ext/float_duration" + +module TestProf::FactoryProf + module Printers + module Json # :nodoc: all + class << self + using TestProf::FloatDuration + include TestProf::Logging + + def dump(result, start_time:) + return log(:info, "No factories detected") if result.raw_stats == {} + + outpath = TestProf.artifact_path("test-prof.result.json") + File.write(outpath, convert_stats(result, start_time).to_json) + + log :info, "Profile results to JSON: #{outpath}" + end + + def convert_stats(result, start_time) + total_run_time = TestProf.now - start_time + total_count = result.stats.sum { |stat| stat[:total_count] } + total_top_level_count = result.stats.sum { |stat| stat[:top_level_count] } + total_time = result.stats.sum { |stat| stat[:top_level_time] } + total_uniq_factories = result.stats.map { |stat| stat[:name] }.uniq.count + + { + total_count: total_count, + total_top_level_count: total_top_level_count, + total_time: total_time.duration, + total_run_time: total_run_time.duration, + total_uniq_factories: total_uniq_factories, + + stats: result.stats + } + end + end + end + end +end diff --git a/spec/integrations/factory_prof_spec.rb b/spec/integrations/factory_prof_spec.rb index 727c6a4f..34ad0cbb 100644 --- a/spec/integrations/factory_prof_spec.rb +++ b/spec/integrations/factory_prof_spec.rb @@ -43,6 +43,13 @@ expect(output).to include("FactoryFlame report generated: ") end + specify "with nate printer always enabled and json profiler", :aggregate_failures do + output = run_rspec("factory_prof_with_nate", env: {"FPROF" => "json"}) + + expect(output).to match(/Time spent in factories: \d{2}+:\d{2}\.\d{3} \([\d.]+% of total time\)/) + expect(output).to include("Profile results to JSON: ") + end + context "when no fabrication installed" do specify "simple printer", :aggregate_failures do output = run_rspec("factory_prof_no_fabrication", env: {"FPROF" => "1"}) diff --git a/spec/test_prof/factory_prof/printers/json_spec.rb b/spec/test_prof/factory_prof/printers/json_spec.rb new file mode 100644 index 00000000..6129be44 --- /dev/null +++ b/spec/test_prof/factory_prof/printers/json_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +describe TestProf::FactoryProf::Printers::Json do + let(:stacks) do + stacks = [] + stacks << %i[user account] + stacks << %i[user account] + stacks << %i[post account user account] + stacks << %i[comment post] + stacks << %i[comment user account] + stacks << [:user] + stacks << [:account] + stacks + end + + let(:stats) do + { + user: {name: :user, total_count: 5, total_time: 1.0, top_level_count: 5, top_level_time: 0.1}, + account: {name: :account, total_count: 6, total_time: 2.0, top_level_count: 6, top_level_time: 0.2}, + comment: {name: :comment, total_count: 2, total_time: 3.0, top_level_count: 2, top_level_time: 0.3}, + name: {name: :post, total_count: 2, total_time: 4.0, top_level_count: 0, top_level_time: 0.4} + } + end + + let(:result) { TestProf::FactoryProf::Result.new(stacks, stats) } + + describe "#dump" do + before do + allow(File).to receive(:write) + allow(TestProf).to receive(:artifact_path).and_return("test-prof.result.json") + end + + it "write json" do + described_class.dump(result, start_time: 0) + outpath = TestProf.artifact_path("test-prof.result.json") + expect(File).to have_received(:write).with(outpath, String).once + end + end + + describe "#convert_stats" do + before do + allow(TestProf).to receive(:now).and_return(2.0) + end + + it "calculates factories usage" do + stats = described_class.convert_stats(result, 0.0) + + expect(stats).to include({ + total_count: 15, + total_top_level_count: 13, + total_time: "00:01.000", + total_run_time: "00:02.000", + total_uniq_factories: 4 + }) + end + end + end From 506aaad638c42a1784e9833a77fe32458eda8e41 Mon Sep 17 00:00:00 2001 From: uzushino Date: Thu, 7 Dec 2023 01:04:21 +0900 Subject: [PATCH 128/194] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3371f546..3613c205 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Add support for dumping FactoryProf results in JSON format. ([@uzushino][]) + ## 1.3.0 (2023-11-21) - Add Vernier integration. ([@palkan][]) From 4a2bde16373437887e25ebc10474eb432a83686d Mon Sep 17 00:00:00 2001 From: uzushino Date: Thu, 7 Dec 2023 01:29:58 +0900 Subject: [PATCH 129/194] Fix lint --- .../factory_prof/printers/json_spec.rb | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/spec/test_prof/factory_prof/printers/json_spec.rb b/spec/test_prof/factory_prof/printers/json_spec.rb index 6129be44..8574c219 100644 --- a/spec/test_prof/factory_prof/printers/json_spec.rb +++ b/spec/test_prof/factory_prof/printers/json_spec.rb @@ -1,57 +1,57 @@ # frozen_string_literal: true describe TestProf::FactoryProf::Printers::Json do - let(:stacks) do - stacks = [] - stacks << %i[user account] - stacks << %i[user account] - stacks << %i[post account user account] - stacks << %i[comment post] - stacks << %i[comment user account] - stacks << [:user] - stacks << [:account] - stacks + let(:stacks) do + stacks = [] + stacks << %i[user account] + stacks << %i[user account] + stacks << %i[post account user account] + stacks << %i[comment post] + stacks << %i[comment user account] + stacks << [:user] + stacks << [:account] + stacks + end + + let(:stats) do + { + user: {name: :user, total_count: 5, total_time: 1.0, top_level_count: 5, top_level_time: 0.1}, + account: {name: :account, total_count: 6, total_time: 2.0, top_level_count: 6, top_level_time: 0.2}, + comment: {name: :comment, total_count: 2, total_time: 3.0, top_level_count: 2, top_level_time: 0.3}, + name: {name: :post, total_count: 2, total_time: 4.0, top_level_count: 0, top_level_time: 0.4} + } + end + + let(:result) { TestProf::FactoryProf::Result.new(stacks, stats) } + + describe "#dump" do + before do + allow(File).to receive(:write) + allow(TestProf).to receive(:artifact_path).and_return("test-prof.result.json") end - - let(:stats) do - { - user: {name: :user, total_count: 5, total_time: 1.0, top_level_count: 5, top_level_time: 0.1}, - account: {name: :account, total_count: 6, total_time: 2.0, top_level_count: 6, top_level_time: 0.2}, - comment: {name: :comment, total_count: 2, total_time: 3.0, top_level_count: 2, top_level_time: 0.3}, - name: {name: :post, total_count: 2, total_time: 4.0, top_level_count: 0, top_level_time: 0.4} - } + + it "write json" do + described_class.dump(result, start_time: 0) + outpath = TestProf.artifact_path("test-prof.result.json") + expect(File).to have_received(:write).with(outpath, String).once end - - let(:result) { TestProf::FactoryProf::Result.new(stacks, stats) } - - describe "#dump" do - before do - allow(File).to receive(:write) - allow(TestProf).to receive(:artifact_path).and_return("test-prof.result.json") - end - - it "write json" do - described_class.dump(result, start_time: 0) - outpath = TestProf.artifact_path("test-prof.result.json") - expect(File).to have_received(:write).with(outpath, String).once - end + end + + describe "#convert_stats" do + before do + allow(TestProf).to receive(:now).and_return(2.0) end - - describe "#convert_stats" do - before do - allow(TestProf).to receive(:now).and_return(2.0) - end - - it "calculates factories usage" do - stats = described_class.convert_stats(result, 0.0) - - expect(stats).to include({ - total_count: 15, - total_top_level_count: 13, - total_time: "00:01.000", - total_run_time: "00:02.000", - total_uniq_factories: 4 - }) - end + + it "calculates factories usage" do + stats = described_class.convert_stats(result, 0.0) + + expect(stats).to include({ + total_count: 15, + total_top_level_count: 13, + total_time: "00:01.000", + total_run_time: "00:02.000", + total_uniq_factories: 4 + }) end end +end From 286159215ce06528b81d7c4d24f37282d67da40f Mon Sep 17 00:00:00 2001 From: uzushino Date: Tue, 12 Dec 2023 21:13:48 +0900 Subject: [PATCH 130/194] Update factory_prof.md --- CHANGELOG.md | 1 + docs/profilers/factory_prof.md | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3613c205..a77dc524 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -378,3 +378,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@peret]: https://github.com/peret [@bf4]: https://github.com/bf4 [@Vankiru]: https://github.com/Vankiru +[@uzushino]: https://github.com/uzushino diff --git a/docs/profilers/factory_prof.md b/docs/profilers/factory_prof.md index 510a2702..42990fc6 100644 --- a/docs/profilers/factory_prof.md +++ b/docs/profilers/factory_prof.md @@ -54,6 +54,25 @@ And for every test run see the overall factories usage: [TEST PROF INFO] Time spent in factories: 04:31.222 (54% of total time) ``` +### Exporting profile results to a JSON file + +FactoryProf can save profile results as a JSON file. + +To use this feature, set the `FPROF` environment variable to `json`: + +```sh +FPROF=json rspec + +# or +FPROF=json bundle exec rake test +``` + +Example output: + +``` +[TEST PROF INFO] Profile results to JSON: tmp/test_prof/test-prof.result.json +``` + ## Factory Flamegraph The most useful feature of FactoryProf is the _FactoryFlame_ report. That's the special interpretation of Brendan Gregg's [flame graphs](http://www.brendangregg.com/flamegraphs.html) which allows you to identify _factory cascades_. From 02d8f355c158fb021e58ff1327d624a8299762b6 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 12 Dec 2023 20:09:27 +0300 Subject: [PATCH 131/194] Bump 1.3.1 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a77dc524..223d77e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.3.1 (2023-12-12) + - Add support for dumping FactoryProf results in JSON format. ([@uzushino][]) ## 1.3.0 (2023-11-21) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 2fd0fdec..71d1a0e5 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.3.0" + VERSION = "1.3.1" end From a98edb59dc49924f1bcddb7ecf6e98df86de3aaa Mon Sep 17 00:00:00 2001 From: Lionel <45598644+lioneldebauge@users.noreply.github.com> Date: Thu, 7 Mar 2024 18:38:34 +0100 Subject: [PATCH 132/194] Add Minitest support to TagProf (#283) * Add Minitest support to TagProf * Update docs/profilers/tag_prof.md Co-authored-by: Vladimir Dementyev * Fix CI errors * Fix mdl errors * Return __unknown__ when aboslute path cannot be displayed * Limit to last released rails version in railsmaster.gemfile * Fix rspec bug without limiting rails last stable version in railsmaster.gemfile --------- Co-authored-by: Vladimir Dementyev --- CHANGELOG.md | 2 + docs/profilers/tag_prof.md | 34 ++++- gemfiles/railsmaster.gemfile | 2 +- lib/minitest/test_prof_plugin.rb | 3 + lib/test_prof/tag_prof/minitest.rb | 74 +++++++++++ lib/test_prof/tag_prof/result.rb | 4 +- spec/integrations/factory_doctor_spec.rb | 2 +- .../fixtures/minitest/tag_prof_fixture.rb | 24 ++++ spec/integrations/tag_prof_spec.rb | 118 ++++++++++++++---- spec/support/ar_models.rb | 1 + 10 files changed, 236 insertions(+), 28 deletions(-) create mode 100644 lib/test_prof/tag_prof/minitest.rb create mode 100644 spec/integrations/fixtures/minitest/tag_prof_fixture.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 223d77e0..47e88dd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Add Minitest support for TagProf. ([@lioneldebauge][]) + ## 1.3.1 (2023-12-12) - Add support for dumping FactoryProf results in JSON format. ([@uzushino][]) diff --git a/docs/profilers/tag_prof.md b/docs/profilers/tag_prof.md index 465a3a7e..75659587 100644 --- a/docs/profilers/tag_prof.md +++ b/docs/profilers/tag_prof.md @@ -30,15 +30,47 @@ That's how a report looks like: ## Instructions -TagProf can only be used with RSpec. +TagProf can be used with both RSpec and Minitest (limited support, see below). To activate TagProf use `TAG_PROF` environment variable: +With Rspec: + ```sh # Group by type TAG_PROF=type rspec ``` +With Minitest: + +```sh +# using pure ruby +TAG_PROF=type ruby + +# using Rails built-in task +TAG_PROF=type bin/rails test +``` + +NB: if another value than "type" is used for TAG_PROF environment variable it will be ignored silently in both Minitest and RSpec. + +### Usage specificity with Minitest + +Minitest does not support the usage of tags by default. TagProf therefore groups statistics by direct subdirectories of the root test directory. It assumes root test directory is named either `spec` or `test`. + +When no root test directory can be found the test statistics will not be grouped with other tests. They will be displayed per test with a significant warning message in the report. + +Example: + +```sh +[TEST PROF INFO] TagProf report for type + + type time sql.active_record total %total %time avg + +__unknown__ 00:04.808 00:01.402 42 33.87 54.70 00:00.114 + controller 00:02.855 00:00.921 42 33.87 32.48 00:00.067 + model 00:01.127 00:00.446 40 32.26 12.82 00:00.028 +``` + ## Profiling events You can combine TagProf with [EventProf](./event_prof.md) to track not only the total time spent but also the time spent for the specified activities (through events): diff --git a/gemfiles/railsmaster.gemfile b/gemfiles/railsmaster.gemfile index 175868bd..1335c7c8 100644 --- a/gemfiles/railsmaster.gemfile +++ b/gemfiles/railsmaster.gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" -gem "rails", github: "rails/rails" +gem "rails" gem "fabrication" gem "factory_bot", "~> 5.0" diff --git a/lib/minitest/test_prof_plugin.rb b/lib/minitest/test_prof_plugin.rb index c991f909..30ea1d43 100644 --- a/lib/minitest/test_prof_plugin.rb +++ b/lib/minitest/test_prof_plugin.rb @@ -3,6 +3,7 @@ require "test_prof/event_prof/minitest" require "test_prof/factory_doctor/minitest" require "test_prof/memory_prof/minitest" +require "test_prof/tag_prof/minitest" module Minitest # :nodoc: module TestProf # :nodoc: @@ -16,6 +17,7 @@ def self.configure_options(options = {}) opts[:sample] = true if ENV["SAMPLE"] || ENV["SAMPLE_GROUPS"] opts[:mem_prof_mode] = ENV["TEST_MEM_PROF"] if ENV["TEST_MEM_PROF"] opts[:mem_prof_top_count] = ENV["TEST_MEM_PROF_COUNT"] if ENV["TEST_MEM_PROF_COUNT"] + opts[:tag_prof] = true if ENV["TAG_PROF"] == "type" end end end @@ -50,6 +52,7 @@ def self.plugin_test_prof_init(options) reporter << TestProf::EventProfReporter.new(options[:io], options) if options[:event] reporter << TestProf::FactoryDoctorReporter.new(options[:io], options) if options[:fdoc] reporter << TestProf::MemoryProfReporter.new(options[:io], options) if options[:mem_prof_mode] + reporter << Minitest::TestProf::TagProfReporter.new(options[:io], options) if options[:tag_prof] ::TestProf::MinitestSample.call if options[:sample] end diff --git a/lib/test_prof/tag_prof/minitest.rb b/lib/test_prof/tag_prof/minitest.rb new file mode 100644 index 00000000..6b2b6f46 --- /dev/null +++ b/lib/test_prof/tag_prof/minitest.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module Minitest + module TestProf + class TagProfReporter < BaseReporter # :nodoc: + attr_reader :results + + def initialize(io = $stdout, _options = {}) + super + @results = ::TestProf::TagProf::Result.new("type") + + if event_prof_activated? + require "test_prof/event_prof" + @current_group_id = nil + @events_profiler = configure_profiler + @results = ::TestProf::TagProf::Result.new("type", @events_profiler.events) + end + end + + def prerecord(group, example) + return unless event_prof_activated? + + # enable event profiling + @events_profiler.group_started(true) + end + + def record(result) + results.track(main_folder_path(result), time: result.time, events: fetch_events_data) + @events_profiler.group_started(nil) if event_prof_activated? # reset and disable event profilers + end + + def report + printer = (ENV["TAG_PROF_FORMAT"] == "html") ? ::TestProf::TagProf::Printers::HTML : ::TestProf::TagProf::Printers::Simple + printer.dump(results) + end + + private + + def main_folder_path(result) + return :__unknown__ if absolute_path_from(result).nil? + + absolute_path_from(result) + end + + def absolute_path_from(result) + absolute_path = File.expand_path(result.source_location.first) + absolute_path.slice(/(?<=(?:spec|test)\/)\w*/) + end + + def configure_profiler + ::TestProf::EventProf::CustomEvents.activate_all(tag_prof_event) + ::TestProf::EventProf.build(tag_prof_event) + end + + def event_prof_activated? + return false if tag_prof_event.nil? + + !tag_prof_event.empty? + end + + def tag_prof_event + ENV["TAG_PROF_EVENT"] + end + + def fetch_events_data + return {} unless @events_profiler + + @events_profiler.profilers.map do |profiler| + [profiler.event, profiler.time || 0.0] + end.to_h + end + end + end +end diff --git a/lib/test_prof/tag_prof/result.rb b/lib/test_prof/tag_prof/result.rb index 73c07b08..fa3f708d 100644 --- a/lib/test_prof/tag_prof/result.rb +++ b/lib/test_prof/tag_prof/result.rb @@ -21,8 +21,8 @@ def initialize(tag, events = []) def track(tag, time:, events: {}) data[tag][:count] += 1 data[tag][:time] += time - events.each do |k, v| - data[tag][k] += v + events.each do |event, time| + data[tag][event] += time end end diff --git a/spec/integrations/factory_doctor_spec.rb b/spec/integrations/factory_doctor_spec.rb index 619efc79..5191d961 100644 --- a/spec/integrations/factory_doctor_spec.rb +++ b/spec/integrations/factory_doctor_spec.rb @@ -19,7 +19,7 @@ end it "print message when no bad examples", :aggregate_failures do - output = run_minitest("factory_doctor", env: {"FDOC" => "1", "FDOC_THRESHOLD" => "0", "TESTOPTS" => "--name=test_0005_is_ignored"}) + output = run_minitest("factory_doctor", env: {"FDOC" => "1", "FDOC_THRESHOLD" => "0", "TESTOPTS" => "--name=\"test_0005_is ignored\""}) expect(output).to include("FactoryDoctor enabled") expect(output).to include('FactoryDoctor says: "Looks good to me!"') diff --git a/spec/integrations/fixtures/minitest/tag_prof_fixture.rb b/spec/integrations/fixtures/minitest/tag_prof_fixture.rb new file mode 100644 index 00000000..7ed105fe --- /dev/null +++ b/spec/integrations/fixtures/minitest/tag_prof_fixture.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require "minitest/autorun" +require "active_support" +require "test-prof" + +module Instrumenter + def self.notify(_event, time) + sleep 0.1 + ActiveSupport::Notifications.publish( + "test.event", + 0, + time + ) + end +end + +describe "Test Class" do + it "succeeds" do + Instrumenter.notify "test.event", 100 + assert(true) + end +end diff --git a/spec/integrations/tag_prof_spec.rb b/spec/integrations/tag_prof_spec.rb index 2747620e..61d81a10 100644 --- a/spec/integrations/tag_prof_spec.rb +++ b/spec/integrations/tag_prof_spec.rb @@ -1,36 +1,108 @@ # frozen_string_literal: true describe "TagProf" do - specify "it works", :aggregate_failures do - output = run_rspec("tag_prof", env: {"TAG_PROF" => "type"}) - - expect(output).to include("TagProf report for type") - expect(output).to match(/type\s+time\s+total\s+%total\s+%time\s+avg\n\n/) - expect(output).to match(/fail\s+\d{2}:\d{2}\.\d{3}\s+1\s+/) - expect(output).to match(/pass\s+\d{2}:\d{2}\.\d{3}\s+2\s+/) - expect(output).to match(/__unknown__\s+\d{2}:\d{2}\.\d{3}\s+1\s+/) - end + context "rspec" do + specify "it works", :aggregate_failures do + output = run_rspec("tag_prof", env: {"TAG_PROF" => "type"}) + + expect(output).to include("TagProf report for type") + expect(output).to match(/type\s+time\s+total\s+%total\s+%time\s+avg\n\n/) + expect(output).to match(/fail\s+\d{2}:\d{2}\.\d{3}\s+1\s+/) + expect(output).to match(/pass\s+\d{2}:\d{2}\.\d{3}\s+2\s+/) + expect(output).to match(/__unknown__\s+\d{2}:\d{2}\.\d{3}\s+1\s+/) + end + + specify "html report" do + output = run_rspec("tag_prof", env: {"TAG_PROF" => "type", "TAG_PROF_FORMAT" => "html"}) - specify "html report" do - output = run_rspec("tag_prof", env: {"TAG_PROF" => "type", "TAG_PROF_FORMAT" => "html"}) + expect(output).to include("TagProf report generated:") + + expect(File.exist?("tmp/test_prof/tag-prof.html")).to eq true + end - expect(output).to include("TagProf report generated:") + context "with events" do + specify "it works", :aggregate_failures do + output = run_rspec( + "tag_prof", + env: {"TAG_PROF" => "type", "TAG_PROF_EVENT" => "test.event,test.event2"} + ) - expect(File.exist?("tmp/test_prof/tag-prof.html")).to eq true + expect(output).to include("TagProf report for type") + expect(output).to match(/type\s+time\s+test\.event\s+test.event2\s+total\s+%total\s+%time\s+avg\n\n/) + expect(output).to match(/fail\s+\d{2}:\d{2}\.\d{3}\s+00:23.000\s+00:00.000\s+1\s+/) + expect(output).to match(/pass\s+\d{2}:\d{2}\.\d{3}\s+00:12.420\s+00:14.041\s+2\s+/) + expect(output).to match(/__unknown__\s+\d{2}:\d{2}\.\d{3}\s+00:00.000\s+00:00.000\s+1\s+/) + end + end end - context "with events" do - specify "it works", :aggregate_failures do - output = run_rspec( - "tag_prof", - env: {"TAG_PROF" => "type", "TAG_PROF_EVENT" => "test.event,test.event2"} - ) + context "minitest" do + subject(:output) { run_minitest(path, env: env, chdir: chdir) } + let(:path) { "tag_prof" } + let(:env) { {"TAG_PROF" => "type"} } + let(:chdir) { nil } + it "includes tag prof report" do expect(output).to include("TagProf report for type") - expect(output).to match(/type\s+time\s+test\.event\s+test.event2\s+total\s+%total\s+%time\s+avg\n\n/) - expect(output).to match(/fail\s+\d{2}:\d{2}\.\d{3}\s+00:23.000\s+00:00.000\s+1\s+/) - expect(output).to match(/pass\s+\d{2}:\d{2}\.\d{3}\s+00:12.420\s+00:14.041\s+2\s+/) - expect(output).to match(/__unknown__\s+\d{2}:\d{2}\.\d{3}\s+00:00.000\s+00:00.000\s+1\s+/) + end + + it "includes tag prof report headers" do + expect(output).to match(/type\s+time\s+total\s+%total\s+%time\s+avg\n\n/) + end + + context "when test suite is run from test file directory" do + it "includes total time spent and number of files tested for integrations directory" do + expect(output).to match(/integrations\s+\d{2}:\d{2}\.\d{3}\s+1\s+/) + end + end + + context "when test suite is run from app root directory" do + let(:chdir) { File.expand_path("") } + let(:path) { "spec/integrations/fixtures/minitest/tag_prof" } + + it "includes total time spent and number of files tested for integrations directory" do + expect(output).to match(/integrations\s+\d{2}:\d{2}\.\d{3}\s+1\s+/) + end + end + + context "when test suite is run with event_prof" do + let(:env) { {"TAG_PROF" => "type", "TAG_PROF_EVENT" => "test.event"} } + it "includes event name in tag prof report headers" do + expect(output).to match(/test.event/) + end + + it "includes event time in data reported for integrations directory " do + expect(output).to match(/integrations\s+\d{2}:\d{2}\.\d{3}\s+\d{2}:\d{2}\.\d{3}\s+1\s+/) + end + end + + context "when report format is HTML" do + let(:env) { {"TAG_PROF" => "type", "TAG_PROF_FORMAT" => "html"} } + + it "generates an html report and gives its location" do + output = run_rspec("tag_prof", env: env) + + expect(output).to include("TagProf report generated:") + expect(File.exist?("tmp/test_prof/tag-prof.html")).to eq true + end + end + + context "when root test directory is not named 'test' or 'spec'" do + let(:path) { "tmp/subdirectory_not_found" } + let(:chdir) { File.expand_path("") } + + before do + test_content = File.read("spec/integrations/fixtures/minitest/tag_prof_fixture.rb") + File.write("tmp/subdirectory_not_found_fixture.rb", test_content) + end + + it "reports the statistic for the test result with an explicit error message" do + expect(output).to match(/__unknown__/) + end + + after do + File.delete("tmp/subdirectory_not_found_fixture.rb") + end end end end diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index dced91d3..e3135cb3 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -6,6 +6,7 @@ require "active_record" require "fabrication" require "test_prof" +require "active_support/inflector" require "test_prof/factory_bot" require "activerecord-jdbc-adapter" if defined? JRUBY_VERSION From 23b516f6745be9ef8e8ca5118c4994526f928d22 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 7 Mar 2024 09:40:22 -0800 Subject: [PATCH 133/194] ci: upgrade (add Ruby 3.3, update lint workflow) --- .github/workflows/rspec.yml | 6 +++--- .github/workflows/rubocop.yml | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index dcca708f..d6549b91 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -28,13 +28,13 @@ jobs: gemfile: ["gemfiles/activerecord6.gemfile"] db: ["postgres"] include: - - ruby: 3.2 + - ruby: 3.3 gemfile: "gemfiles/railsmaster.gemfile" db: "mysql" - - ruby: 3.2 + - ruby: 3.3 gemfile: "Gemfile" db: "sqlite" - - ruby: 3.1 + - ruby: 3.2 gemfile: "gemfiles/activerecord7.gemfile" db: "sqlite" multi_db: "true" diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml index 11dc3708..5c9102c6 100644 --- a/.github/workflows/rubocop.yml +++ b/.github/workflows/rubocop.yml @@ -9,12 +9,16 @@ on: jobs: rubocop: runs-on: ubuntu-latest + env: + BUNDLE_JOBS: 4 + BUNDLE_RETRY: 3 + BUNDLE_GEMFILE: "gemfiles/rubocop.gemfile" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: - ruby-version: 2.7 + ruby-version: 3.2 + bundler-cache: true - name: Lint Ruby code with RuboCop run: | - bundle install --gemfile gemfiles/rubocop.gemfile --jobs 4 --retry 3 - bundle exec --gemfile gemfiles/rubocop.gemfile rubocop + bundle exec rubocop From bd7027e1cd58d58cd4f129f5c41012917a6a18c4 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 7 Mar 2024 17:06:36 -0800 Subject: [PATCH 134/194] Bump 1.3.2 --- CHANGELOG.md | 3 +++ lib/test_prof/version.rb | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47e88dd1..80348329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.3.2 (2024-03-08) 🌷 + - Add Minitest support for TagProf. ([@lioneldebauge][]) ## 1.3.1 (2023-12-12) @@ -383,3 +385,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@bf4]: https://github.com/bf4 [@Vankiru]: https://github.com/Vankiru [@uzushino]: https://github.com/uzushino +[@lioneldebauge]: https://github.com/lioneldebauge diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 71d1a0e5..8823e8b5 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.3.1" + VERSION = "1.3.2" end From 6c8f17a48cb12f4638f0f149b497e2854a2b4779 Mon Sep 17 00:00:00 2001 From: Nahuel Garbezza Date: Mon, 15 Apr 2024 19:52:18 -0300 Subject: [PATCH 135/194] refactor: avoid using activesupport's present? method --- lib/test_prof/before_all.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/before_all.rb b/lib/test_prof/before_all.rb index bf30d2fd..c6f561ff 100644 --- a/lib/test_prof/before_all.rb +++ b/lib/test_prof/before_all.rb @@ -66,7 +66,7 @@ def run(scope, metadata) private def filters_apply?(metadata) - return true unless filters.present? && TestProf.rspec? + return true unless filters.is_a?(Hash) && TestProf.rspec? ::RSpec::Core::MetadataFilter.apply?( :all?, From 531a4d1b0f08394ecf445d06953d7780f9c20be2 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 18 Apr 2024 15:24:02 -0700 Subject: [PATCH 136/194] fix: use stable ids in memprof tracker - Drop excess MemProf tests --- lib/test_prof/memory_prof/rspec.rb | 11 +- lib/test_prof/memory_prof/tracker.rb | 24 +-- .../memory_prof/tracker/linked_list.rb | 14 +- .../fixtures/rspec/memory_prof_fixture.rb | 3 +- spec/integrations/memory_prof_rspec_spec.rb | 58 +++---- spec/test_prof/memory_prof/minitest_spec.rb | 68 --------- spec/test_prof/memory_prof/rspec_spec.rb | 123 --------------- .../memory_prof/tracker/linked_list_spec.rb | 143 ------------------ spec/test_prof/memory_prof/tracker_spec.rb | 18 ++- 9 files changed, 58 insertions(+), 404 deletions(-) delete mode 100644 spec/test_prof/memory_prof/minitest_spec.rb delete mode 100644 spec/test_prof/memory_prof/rspec_spec.rb delete mode 100644 spec/test_prof/memory_prof/tracker/linked_list_spec.rb diff --git a/lib/test_prof/memory_prof/rspec.rb b/lib/test_prof/memory_prof/rspec.rb index 08ccb59f..bb6cbcaa 100644 --- a/lib/test_prof/memory_prof/rspec.rb +++ b/lib/test_prof/memory_prof/rspec.rb @@ -16,23 +16,26 @@ def initialize @tracker = MemoryProf.tracker @printer = MemoryProf.printer(tracker) + @current_group = nil + @current_example = nil + @tracker.start end def example_started(notification) - tracker.example_started(example(notification)) + tracker.example_started(notification.example, example(notification)) end def example_finished(notification) - tracker.example_finished(example(notification)) + tracker.example_finished(notification.example) end def example_group_started(notification) - tracker.group_started(group(notification)) + tracker.group_started(notification.group, group(notification)) end def example_group_finished(notification) - tracker.group_finished(group(notification)) + tracker.group_finished(notification.group) end def report diff --git a/lib/test_prof/memory_prof/tracker.rb b/lib/test_prof/memory_prof/tracker.rb index 273b89b4..c90e9f46 100644 --- a/lib/test_prof/memory_prof/tracker.rb +++ b/lib/test_prof/memory_prof/tracker.rb @@ -36,22 +36,26 @@ def finish @total_memory = node.total_memory end - def example_started(example) - list.add_node(example, track) + def example_started(id, example = id) + list.add_node(id, example, track) end - def example_finished(example) - node = list.remove_node(example, track) - examples << {**example, memory: node.total_memory} + def example_finished(id) + node = list.remove_node(id, track) + return unless node + + examples << {**node.item, memory: node.total_memory} end - def group_started(group) - list.add_node(group, track) + def group_started(id, group = id) + list.add_node(id, group, track) end - def group_finished(group) - node = list.remove_node(group, track) - groups << {**group, memory: node.hooks_memory} + def group_finished(id) + node = list.remove_node(id, track) + return unless node + + groups << {**node.item, memory: node.hooks_memory} end end diff --git a/lib/test_prof/memory_prof/tracker/linked_list.rb b/lib/test_prof/memory_prof/tracker/linked_list.rb index 4a68fb5b..34a08771 100644 --- a/lib/test_prof/memory_prof/tracker/linked_list.rb +++ b/lib/test_prof/memory_prof/tracker/linked_list.rb @@ -52,19 +52,20 @@ class LinkedList attr_reader :head def initialize(memory_at_start) - add_node(:total, memory_at_start) + add_node(:total, :total, memory_at_start) end - def add_node(item, memory_at_start) + def add_node(id, item, memory_at_start) @head = LinkedListNode.new( + id: id, item: item, previous: head, memory_at_start: memory_at_start ) end - def remove_node(item, memory_at_finish) - return if head.item != item + def remove_node(id, memory_at_finish) + return if head.id != id head.finish(memory_at_finish) current = head @@ -75,9 +76,10 @@ def remove_node(item, memory_at_finish) end class LinkedListNode - attr_reader :item, :previous, :memory_at_start, :memory_at_finish, :nested_memory + attr_reader :id, :item, :previous, :memory_at_start, :memory_at_finish, :nested_memory - def initialize(item:, memory_at_start:, previous:) + def initialize(id:, item:, memory_at_start:, previous:) + @id = id @item = item @previous = previous diff --git a/spec/integrations/fixtures/rspec/memory_prof_fixture.rb b/spec/integrations/fixtures/rspec/memory_prof_fixture.rb index a8b5a865..23d55bbc 100644 --- a/spec/integrations/fixtures/rspec/memory_prof_fixture.rb +++ b/spec/integrations/fixtures/rspec/memory_prof_fixture.rb @@ -23,8 +23,7 @@ @array = 500.times.map { SecureRandom.hex } end - it "does not allocate anything" do - end + it { 1 } end context "with 1000 allocations" do diff --git a/spec/integrations/memory_prof_rspec_spec.rb b/spec/integrations/memory_prof_rspec_spec.rb index a2ae829e..2b584964 100644 --- a/spec/integrations/memory_prof_rspec_spec.rb +++ b/spec/integrations/memory_prof_rspec_spec.rb @@ -6,74 +6,52 @@ describe "MemoryProf RSpec" do specify "with default options", :aggregate_failures do - output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "test"}) + output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "test", "TEST_MEM_PROF_COUNT" => "3"}) expect(output).to include("MemoryProf results") expect(output).to match(/Final RSS: #{memory_human_regex}/) - expect(output).to include("Top 5 groups (by RSS):") - expect(output).to include("Top 5 examples (by RSS):") - - expect(output).to match(/with 10_000 allocations \(\.\/memory_prof_fixture.rb:39\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/with 1000 allocations \(\.\/memory_prof_fixture.rb:30\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/with 500 allocations \(\.\/memory_prof_fixture.rb:21\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/Groups Allocations \(\.\/memory_prof_fixture.rb:20\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/Examples allocations \(\.\/memory_prof_fixture.rb:6\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - - expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:15\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:11\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:7\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to include("Top 3 groups (by RSS):") + expect(output).to include("Top 3 examples (by RSS):") end specify "in RSS mode", :aggregate_failures do - output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "rss"}) + output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "rss", "TEST_MEM_PROF_COUNT" => "3"}) expect(output).to include("MemoryProf results") expect(output).to match(/Final RSS: #{memory_human_regex}/) - expect(output).to include("Top 5 groups (by RSS):") - expect(output).to include("Top 5 examples (by RSS):") - - expect(output).to match(/with 10_000 allocations \(\.\/memory_prof_fixture.rb:39\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/with 1000 allocations \(\.\/memory_prof_fixture.rb:30\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/with 500 allocations \(\.\/memory_prof_fixture.rb:21\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/Groups Allocations \(\.\/memory_prof_fixture.rb:20\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/Examples allocations \(\.\/memory_prof_fixture.rb:6\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - - expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:15\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:11\) – \+#{memory_human_regex} \(#{percent_regex}\)/) - expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:7\) – \+#{memory_human_regex} \(#{percent_regex}\)/) + expect(output).to include("Top 3 groups (by RSS):") + expect(output).to include("Top 3 examples (by RSS):") end if RUBY_ENGINE != "jruby" specify "in allocations mode", :aggregate_failures do - output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "alloc"}) + output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "alloc", "TEST_MEM_PROF_COUNT" => "3"}) expect(output).to include("MemoryProf results") expect(output).to match(/Total allocations: #{number_regex}/) - expect(output).to include("Top 5 groups (by allocations):") - expect(output).to include("Top 5 examples (by allocations):") + expect(output).to include("Top 3 groups (by allocations):") + expect(output).to include("Top 3 examples (by allocations):") - expect(output).to match(/with 10_000 allocations \(\.\/memory_prof_fixture.rb:39\) – \+#{number_regex} \(#{percent_regex}\)/) - expect(output).to match(/with 1000 allocations \(\.\/memory_prof_fixture.rb:30\) – \+#{number_regex} \(#{percent_regex}\)/) - expect(output).to match(/with 500 allocations \(\.\/memory_prof_fixture.rb:21\) – \+#{number_regex} \(#{percent_regex}\)/) - expect(output).to match(/Groups Allocations \(\.\/memory_prof_fixture.rb:20\) – \+#{number_regex} \(#{percent_regex}\)/) - expect(output).to match(/Examples allocations \(\.\/memory_prof_fixture.rb:6\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 10_000 allocations \(\.\/memory_prof_fixture.rb:\d+\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 1000 allocations \(\.\/memory_prof_fixture.rb:\d+\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/with 500 allocations \(\.\/memory_prof_fixture.rb:\d+\) – \+#{number_regex} \(#{percent_regex}\)/) - expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:15\) – \+#{number_regex} \(#{percent_regex}\)/) - expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:11\) – \+#{number_regex} \(#{percent_regex}\)/) - expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:7\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 10_000 objects \(\.\/memory_prof_fixture.rb:\d+\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 1000 objects \(\.\/memory_prof_fixture.rb:\d+\) – \+#{number_regex} \(#{percent_regex}\)/) + expect(output).to match(/allocates 500 objects \(\.\/memory_prof_fixture.rb:\d+\) – \+#{number_regex} \(#{percent_regex}\)/) end end specify "with top_count", :aggregate_failures do - output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "rss", "TEST_MEM_PROF_COUNT" => "3"}) + output = run_rspec("memory_prof", env: {"TEST_MEM_PROF" => "rss", "TEST_MEM_PROF_COUNT" => "4"}) expect(output).to include("MemoryProf results") expect(output).to match(/Final RSS: #{memory_human_regex}/) - expect(output).to include("Top 3 groups (by RSS):") - expect(output).to include("Top 3 examples (by RSS):") + expect(output).to include("Top 4 groups (by RSS):") + expect(output).to include("Top 4 examples (by RSS):") end end diff --git a/spec/test_prof/memory_prof/minitest_spec.rb b/spec/test_prof/memory_prof/minitest_spec.rb deleted file mode 100644 index 6390f70a..00000000 --- a/spec/test_prof/memory_prof/minitest_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -require "test_prof/memory_prof/minitest" - -describe Minitest::TestProf::MemoryProfReporter do - subject { described_class.new } - - let(:tracker) { subject.tracker } - let(:printer) { subject.printer } - - before do - allow(tracker).to receive(:start) - allow(tracker).to receive(:finish) - allow(tracker).to receive(:example_started) - allow(tracker).to receive(:example_finished) - allow(tracker).to receive(:group_started) - allow(tracker).to receive(:group_finished) - - allow(printer).to receive(:print) - - allow(subject).to receive(:location_with_line_number).and_return("./test/models/reports.rb:57") - end - - describe "#prerecord" do - it "tracks the start of an example" do - subject.prerecord("Report", "test_prepare") - - expect(tracker).to have_received(:example_started).with({ - name: "prepare", - location: "./test/models/reports.rb:57" - }) - end - end - - describe "#record" do - it "tracks the start of an example" do - subject.prerecord("Report", "test_prepare") - subject.record(nil) - - expect(tracker).to have_received(:example_started).with({ - name: "prepare", - location: "./test/models/reports.rb:57" - }) - end - end - - describe "#start" do - it "starts the tracking process" do - subject.start - - expect(tracker).to have_received(:start) - end - end - - describe "#report" do - it "finishes the tracking process" do - subject.report - - expect(tracker).to have_received(:finish) - end - - it "prints the results" do - subject.report - - expect(printer).to have_received(:print) - end - end -end diff --git a/spec/test_prof/memory_prof/rspec_spec.rb b/spec/test_prof/memory_prof/rspec_spec.rb deleted file mode 100644 index ddb8fe64..00000000 --- a/spec/test_prof/memory_prof/rspec_spec.rb +++ /dev/null @@ -1,123 +0,0 @@ -# frozen_string_literal: true - -require "test_prof/memory_prof/rspec" - -describe TestProf::MemoryProf::RSpecListener do - subject { described_class.new } - - let(:tracker) { subject.tracker } - let(:printer) { subject.printer } - - let(:example) do - instance_double( - RSpec::Core::Example, - description: "returns nil", - metadata: {location: "./spec/models/reports_spec.rb:57"} - ) - end - - let(:group) do - double( - RSpec::Core::ExampleGroup, - description: "#publish", - metadata: {location: "./spec/nodels/question_spec.rb:179"} - ) - end - - before do - tracker = instance_double( - TestProf::MemoryProf::Tracker, - start: nil, - finish: nil, - example_started: nil, - example_finished: nil, - group_started: nil, - group_finished: nil - ) - - allow(TestProf::MemoryProf).to receive(:tracker).and_return(tracker) - allow(printer).to receive(:print) - end - - xdescribe "#initialize" do - it "starts the tracking process" do - subject - - expect(tracker).to have_received(:start) - end - end - - describe "#example_started" do - let(:notification) do - RSpec::Core::Notifications::ExampleNotification.send(:new, example) - end - - it "tracks the start of an example" do - subject.example_started(notification) - - expect(tracker).to have_received(:example_started).with({ - name: "returns nil", - location: "./spec/models/reports_spec.rb:57" - }) - end - end - - describe "#example_finished" do - let(:notification) do - RSpec::Core::Notifications::ExampleNotification.send(:new, example) - end - - it "tracks the end of an example" do - subject.example_finished(notification) - - expect(tracker).to have_received(:example_finished).with({ - name: "returns nil", - location: "./spec/models/reports_spec.rb:57" - }) - end - end - - describe "#example_group_started" do - let(:notification) do - RSpec::Core::Notifications::GroupNotification.send(:new, group) - end - - it "tracks the end of an example" do - subject.example_group_started(notification) - - expect(tracker).to have_received(:group_started).with({ - name: "#publish", - location: "./spec/nodels/question_spec.rb:179" - }) - end - end - - describe "#example_group_finished" do - let(:notification) do - RSpec::Core::Notifications::GroupNotification.send(:new, group) - end - - it "tracks the end of an example" do - subject.example_group_finished(notification) - - expect(tracker).to have_received(:group_finished).with({ - name: "#publish", - location: "./spec/nodels/question_spec.rb:179" - }) - end - end - - describe "#report" do - it "finishes the tracking process" do - subject.report - - expect(tracker).to have_received(:finish) - end - - it "prints the results" do - subject.report - - expect(printer).to have_received(:print) - end - end -end diff --git a/spec/test_prof/memory_prof/tracker/linked_list_spec.rb b/spec/test_prof/memory_prof/tracker/linked_list_spec.rb deleted file mode 100644 index 31e1685f..00000000 --- a/spec/test_prof/memory_prof/tracker/linked_list_spec.rb +++ /dev/null @@ -1,143 +0,0 @@ -# frozen_string_literal: true - -describe TestProf::MemoryProf::Tracker::LinkedList do - subject { described_class.new(100) } - - it "initializes a head node" do - expect(subject.head).to have_attributes(item: :total, previous: nil, memory_at_start: 100) - end - - describe "#add_node" do - let(:add_node) { subject.add_node(:item, 200) } - - it "add a new node to the beginning of the list" do - previous = subject.head - add_node - - expect(subject.head).to have_attributes(item: :item, previous: previous, memory_at_start: 200) - end - end - - describe "#remove_node" do - let(:remove_node) { subject.remove_node(:item, 300) } - - before do - subject.add_node(:item, 200) - allow(subject.head).to receive(:finish) - end - - it "finishes the current head node" do - current = subject.head - remove_node - - expect(current).to have_received(:finish).with(300) - end - - it "moves the head to the previous node" do - previous = subject.head.previous - remove_node - - expect(subject.head).to eq(previous) - end - - it "return the current head node" do - current = subject.head - - expect(remove_node).to eq(current) - end - end -end - -describe TestProf::MemoryProf::Tracker::LinkedListNode do - subject do - described_class.new( - item: :item, - memory_at_start: 100, - previous: previous - ) - end - - let(:previous) { nil } - - describe "#total_memory" do - before do - subject.instance_variable_set("@memory_at_start", memory_at_start) - subject.instance_variable_set("@memory_at_finish", memory_at_finish) - end - - context "when memory_at_finish is nil" do - let(:memory_at_start) { 100 } - let(:memory_at_finish) { nil } - - it "returns 0" do - expect(subject.total_memory).to eq(0) - end - end - - context "when memory_at_start > memory_at_finish" do - let(:memory_at_start) { 200 } - let(:memory_at_finish) { 100 } - - it "returns 0" do - expect(subject.total_memory).to eq(0) - end - end - - context "when memory_at_start < memory_at_finish" do - let(:memory_at_start) { 100 } - let(:memory_at_finish) { 200 } - - it "calculates the difference between memory_at_finish and memory_at_start" do - expect(subject.total_memory).to eq(100) - end - end - end - - describe "#hooks_memory" do - before do - subject.instance_variable_set("@memory_at_start", 100) - subject.instance_variable_set("@memory_at_finish", 200) - subject.instance_variable_set("@nested_memory", 50) - end - - it "calculates the difference between total_memory and nested_memory" do - expect(subject.hooks_memory).to eq(50) - end - end - - describe "#finish" do - let(:finish) { subject.finish(200) } - - context "when previous node exists" do - let(:previous) do - described_class.new( - item: :previous, - memory_at_start: 50, - previous: nil - ) - end - - it "sets memory_at_finish" do - finish - - expect(subject.memory_at_finish).to eq(200) - end - - it "updates previous.nested_memory" do - finish - - expect(previous.nested_memory).to eq(100) - end - end - - context "when previous node does not exist" do - let(:previous) { nil } - - it "sets memory_at_finish" do - finish - - expect(subject.memory_at_finish).to eq(200) - end - end - end -end diff --git a/spec/test_prof/memory_prof/tracker_spec.rb b/spec/test_prof/memory_prof/tracker_spec.rb index 2a6f309f..ef9340ea 100644 --- a/spec/test_prof/memory_prof/tracker_spec.rb +++ b/spec/test_prof/memory_prof/tracker_spec.rb @@ -2,6 +2,8 @@ shared_examples "TestProf::MemoryProf::Tracker" do let(:list) { TestProf::MemoryProf::Tracker::LinkedList.new(100) } + let(:example) { double("example") } + let(:group) { double("group") } describe "#start" do it "initializes a linked list" do @@ -25,7 +27,7 @@ end describe "#example_started" do - let(:example_started) { subject.example_started({name: :example}) } + let(:example_started) { subject.example_started(example, {name: :example}) } before do allow(subject).to receive(:track).and_return(200) @@ -35,15 +37,15 @@ it "tracks memory at the start of an example" do example_started - expect(subject.list.head).to have_attributes(item: {name: :example}, memory_at_start: 200) + expect(subject.list.head).to have_attributes(id: example, item: {name: :example}, memory_at_start: 200) end end describe "#example_finished" do - let(:example_finished) { subject.example_finished({name: :example}) } + let(:example_finished) { subject.example_finished(example) } before do - list.add_node({name: :example}, 200) + list.add_node(example, {name: :example}, 200) allow(subject).to receive(:track).and_return(350) allow(subject).to receive(:list).and_return(list) @@ -91,7 +93,7 @@ end describe "#group_started" do - let(:group_started) { subject.group_started({name: :group}) } + let(:group_started) { subject.group_started(group, {name: :group}) } before do allow(subject).to receive(:track).and_return(200) @@ -101,15 +103,15 @@ it "tracks memory at the start of a group" do group_started - expect(subject.list.head).to have_attributes(item: {name: :group}, memory_at_start: 200) + expect(subject.list.head).to have_attributes(id: group, item: {name: :group}, memory_at_start: 200) end end describe "#group_finished" do - let(:group_finished) { subject.group_finished({name: :group}) } + let(:group_finished) { subject.group_finished(group) } before do - list.add_node({name: :group}, 200) + list.add_node(group, {name: :group}, 200) allow(subject).to receive(:track).and_return(350) allow(subject).to receive(:list).and_return(list) From 63977463f404512a63bae291aa433dc2ce24b0b7 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 18 Apr 2024 15:56:56 -0700 Subject: [PATCH 137/194] ci: fix sqlite3 version --- gemfiles/activerecord7.gemfile | 2 +- gemfiles/railsmaster.gemfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gemfiles/activerecord7.gemfile b/gemfiles/activerecord7.gemfile index 89e854cf..6c48e2e9 100644 --- a/gemfiles/activerecord7.gemfile +++ b/gemfiles/activerecord7.gemfile @@ -3,7 +3,7 @@ source 'https://rubygems.org' gem "activerecord", "~> 7.0" gem "factory_bot" gem "fabrication" -gem "sqlite3" +gem "sqlite3", "~> 1.4" gem "sidekiq" gem "timecop" gem "pg" diff --git a/gemfiles/railsmaster.gemfile b/gemfiles/railsmaster.gemfile index 1335c7c8..72b1720a 100644 --- a/gemfiles/railsmaster.gemfile +++ b/gemfiles/railsmaster.gemfile @@ -4,7 +4,7 @@ gem "rails" gem "fabrication" gem "factory_bot", "~> 5.0" -gem "sqlite3", "~> 1.4.0" +gem "sqlite3", "~> 1.4" gem "sidekiq", "~> 4.0" gem "timecop", "~> 0.9.1" gem "pg" From 8e30a1f58587719813bafa70926d34414107a71f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 18 Apr 2024 16:12:18 -0700 Subject: [PATCH 138/194] fix: memprof print 0 rss % --- lib/test_prof/memory_prof/printer.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/test_prof/memory_prof/printer.rb b/lib/test_prof/memory_prof/printer.rb index 987a9bd3..d483b40d 100644 --- a/lib/test_prof/memory_prof/printer.rb +++ b/lib/test_prof/memory_prof/printer.rb @@ -50,6 +50,8 @@ def print_items(items) end def memory_percentage(item) + return 0 if tracker.total_memory.zero? || item[:memory].zero? + (100.0 * item[:memory] / tracker.total_memory).round(2) end From a52da81d5e27e9c949c733b813ca788eca14bd70 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 19 Apr 2024 10:28:26 -0700 Subject: [PATCH 139/194] ci: add release job --- .github/workflows/release.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..b4ff39ee --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,28 @@ +name: Release gems +on: + workflow_dispatch: + push: + tags: + - v* + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch current tag as annotated. See https://github.com/actions/checkout/issues/290 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.2 + bundler-cache: true + - name: Configure RubyGems Credentials + uses: rubygems/configure-rubygems-credentials@main + - name: Publish to RubyGems + run: | + gem install gem-release + gem release From 3593d3ebcfba4002cae6560b6c50236af456daf3 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 19 Apr 2024 10:30:17 -0700 Subject: [PATCH 140/194] Bump 1.3.3 --- CHANGELOG.md | 4 ++++ lib/test_prof/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80348329..20c519c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +## 1.3.3 (2024-04-19) + +- Fix MemProf bugs. ([@palkan][]) + ## 1.3.2 (2024-03-08) 🌷 - Add Minitest support for TagProf. ([@lioneldebauge][]) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 8823e8b5..8f50d81e 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.3.2" + VERSION = "1.3.3" end From 98323b959b2b55b74b897f6009a840d10f84223b Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 29 Apr 2024 15:33:51 -0700 Subject: [PATCH 141/194] docs: use absolute paths for assets --- docs/README.md | 4 ++-- docs/profilers/factory_prof.md | 2 +- docs/profilers/tag_prof.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index c5bfb8c7..0a53f12f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,7 @@ > Ruby tests profiling and optimization toolbox + title="TestProf logo" class="home-logo" src="/assets/images/logo.svg"> TestProf is a collection of different tools to analyze your test suite performance. @@ -32,7 +32,7 @@ TestProf toolbox aims to help you identify bottlenecks in your test suite. It co

diff --git a/docs/profilers/factory_prof.md b/docs/profilers/factory_prof.md index 42990fc6..abdacb73 100644 --- a/docs/profilers/factory_prof.md +++ b/docs/profilers/factory_prof.md @@ -88,7 +88,7 @@ FPROF=flamegraph bundle exec rake test That's how a report looks like: -![](../assets/factory-flame.gif) +![](/assets/factory-flame.gif) How to read this? diff --git a/docs/profilers/tag_prof.md b/docs/profilers/tag_prof.md index 75659587..d3506325 100644 --- a/docs/profilers/tag_prof.md +++ b/docs/profilers/tag_prof.md @@ -26,7 +26,7 @@ TAG_PROF=type TAG_PROF_FORMAT=html bundle exec rspec That's how a report looks like: -![TagProf UI](../assets/tag-prof.gif) +![TagProf UI](/assets/tag-prof.gif) ## Instructions From 95eb0738974b53bf942da270c96c219f1acc22e7 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 30 Apr 2024 09:05:00 -0700 Subject: [PATCH 142/194] fix(docs): use HTML for asset images --- docs/profilers/factory_prof.md | 2 +- docs/profilers/tag_prof.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/profilers/factory_prof.md b/docs/profilers/factory_prof.md index abdacb73..75fe05c6 100644 --- a/docs/profilers/factory_prof.md +++ b/docs/profilers/factory_prof.md @@ -88,7 +88,7 @@ FPROF=flamegraph bundle exec rake test That's how a report looks like: -![](/assets/factory-flame.gif) +TagProf UI How to read this? diff --git a/docs/profilers/tag_prof.md b/docs/profilers/tag_prof.md index d3506325..009290bc 100644 --- a/docs/profilers/tag_prof.md +++ b/docs/profilers/tag_prof.md @@ -26,7 +26,7 @@ TAG_PROF=type TAG_PROF_FORMAT=html bundle exec rspec That's how a report looks like: -![TagProf UI](/assets/tag-prof.gif) +TagProf UI ## Instructions From 0d30e99e62bd01a622bdabebaa74e2837cd7cd61 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 7 May 2024 14:55:47 -0400 Subject: [PATCH 143/194] docs: add helvetic talk to resources --- docs/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/README.md b/docs/README.md index 0a53f12f..680b58c3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -54,6 +54,8 @@ TestProf toolbox aims to help you identify bottlenecks in your test suite. It co ## Resources +- [Profiling Ruby tests with Swiss precision](https://evilmartians.com/events/profiling-ruby-tests-with-swiss-precision-helvetic-ruby) + - [TestProf: a good doctor for slow Ruby tests](https://evilmartians.com/chronicles/testprof-a-good-doctor-for-slow-ruby-tests) - [TestProf II: factory therapy for your Ruby tests](https://evilmartians.com/chronicles/testprof-2-factory-therapy-for-your-ruby-tests-rspec-minitest) From cdf4b829a8462db4615a66b0625b81a11126dbab Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 7 May 2024 14:56:47 -0400 Subject: [PATCH 144/194] docs: add mastodon to users --- docs/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 680b58c3..f830b58d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -47,8 +47,9 @@ TestProf toolbox aims to help you identify bottlenecks in your test suite. It co - [Discourse](https://github.com/discourse/discourse) reduced [~27% of their test suite time](https://twitter.com/samsaffron/status/1125602558024699904) - [Gitlab](https://gitlab.com/gitlab-org/gitlab-ce) reduced [39% of their API tests time](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/14370) -- [CodeTriage](https://github.com/codetriage/codetriage) +- [Mastodon](https://github.com/mastodon/mastodon) - [Dev.to](https://github.com/thepracticaldev/dev.to) +- [CodeTriage](https://github.com/codetriage/codetriage) - [Open Project](https://github.com/opf/openproject) - [...and others](https://github.com/test-prof/test-prof/issues/73) From 545464e5c6207f9d6a8b0ec798f87a8a71f0770b Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 8 May 2024 16:11:42 -0400 Subject: [PATCH 145/194] fix: make minitest sampling work Co-Authored-By: @ericenns --- lib/test_prof/recipes/minitest/sample.rb | 6 ++++-- spec/integrations/fixtures/minitest/sample_fixture.rb | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/test_prof/recipes/minitest/sample.rb b/lib/test_prof/recipes/minitest/sample.rb index e26b6ff5..df4fbcf3 100644 --- a/lib/test_prof/recipes/minitest/sample.rb +++ b/lib/test_prof/recipes/minitest/sample.rb @@ -7,14 +7,16 @@ module MinitestSample CORE_RUNNABLES = [ Minitest::Test, defined?(Minitest::Unit::TestCase) ? Minitest::Unit::TestCase : nil, - Minitest::Spec + defined?(Minitest::Spec) ? Minitest::Spec : nil ].compact.freeze class << self def suites # Make sure that sample contains only _real_ suites Minitest::Runnable.runnables - .reject { |suite| CORE_RUNNABLES.include?(suite) } + .select do |suite| + CORE_RUNNABLES.any? { |kl| suite < kl } && suite.runnable_methods.any? + end end def sample_groups(sample_size) diff --git a/spec/integrations/fixtures/minitest/sample_fixture.rb b/spec/integrations/fixtures/minitest/sample_fixture.rb index dd0bec01..7e823f3f 100644 --- a/spec/integrations/fixtures/minitest/sample_fixture.rb +++ b/spec/integrations/fixtures/minitest/sample_fixture.rb @@ -14,7 +14,10 @@ def test_pass2 end end -class AnotherSomethingTest < Minitest::Test +class CustomTestCase < Minitest::Test +end + +class AnotherSomethingTest < CustomTestCase def test_pass assert true end From 6575956d18e1ec7a65c4e0f610fcadb62302909c Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 8 May 2024 16:44:52 -0400 Subject: [PATCH 146/194] refactor: minitest sampling --- lib/test_prof/recipes/minitest/sample.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/test_prof/recipes/minitest/sample.rb b/lib/test_prof/recipes/minitest/sample.rb index df4fbcf3..ba6a1810 100644 --- a/lib/test_prof/recipes/minitest/sample.rb +++ b/lib/test_prof/recipes/minitest/sample.rb @@ -29,11 +29,18 @@ def sample_examples(sample_size) all_examples = suites.flat_map do |runnable| runnable.runnable_methods.map { |method| [runnable, method] } end - sample = all_examples.sample(sample_size) + + sample = all_examples.sample(sample_size).group_by(&:first) + sample.transform_values! { |v| v.map(&:last) } + # Filter examples by overriding #runnable_methods for all suites suites.each do |runnable| - runnable.define_singleton_method(:runnable_methods) do - super() & sample.select { |ex| ex.first.equal?(runnable) }.map(&:last) + if sample.key?(runnable) + runnable.define_singleton_method(:runnable_methods) do + super() & sample[runnable] + end + else + runnable.define_singleton_method(:runnable_methods) { [] } end end end From 4ffe217d330b533ccb682dc57adc840c1b2f91f1 Mon Sep 17 00:00:00 2001 From: Georgiy Melnikov Date: Thu, 23 May 2024 00:54:01 +0500 Subject: [PATCH 147/194] add threshold config parameter for FactoryProf (#294) * add threshold config parameter for FactoryProf * fix doc * fix threshold logic & fix doc file * remove excess --- CHANGELOG.md | 12 ++++++++++ docs/profilers/factory_prof.md | 22 +++++++++++++++++++ lib/test_prof/factory_prof.rb | 5 +++-- lib/test_prof/factory_prof/printers/json.rb | 2 +- .../factory_prof/printers/nate_heckler.rb | 2 +- lib/test_prof/factory_prof/printers/simple.rb | 4 +++- spec/integrations/factory_prof_spec.rb | 12 ++++++++++ 7 files changed, 54 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20c519c7..4919e627 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ ## master (unreleased) +- FactoryProf: Add threshold configuration parameter. ([@lHydra][]) + +Now you can ignore factories which total number of calls is less than the provided threshold. To do this, specify +the `FPROF_THRESHOLD=30` env var or set it through `FactoryProf` configuration: + +```ruby +TestProf::FactoryProf.configure do |config| + config.threshold = 30 +end +``` + ## 1.3.3 (2024-04-19) - Fix MemProf bugs. ([@palkan][]) @@ -390,3 +401,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@Vankiru]: https://github.com/Vankiru [@uzushino]: https://github.com/uzushino [@lioneldebauge]: https://github.com/lioneldebauge +[@lHydra]: https://github.com/lHydra diff --git a/docs/profilers/factory_prof.md b/docs/profilers/factory_prof.md index 75fe05c6..1aff58ce 100644 --- a/docs/profilers/factory_prof.md +++ b/docs/profilers/factory_prof.md @@ -73,6 +73,28 @@ Example output: [TEST PROF INFO] Profile results to JSON: tmp/test_prof/test-prof.result.json ``` +### Reducing the output + +When running FactoryProf, the output may contain a lot of lines for factories that has been used a few times. +To avoid this and focus on the most important statistics you can specify a threshold value. Then you will be shown the factories whose total number exceeds the threshold. + +To use threshold option set `FPROF_THRESHOLD` environment variable to `N` (where `N` is a threshold number): + +```sh +FPROF=1 FPROF_THRESHOLD=30 rspec + +# or +FPROF=1 FPROF_THRESHOLD=30 bundle exec rake test +``` + +Or you can set the threshold parameter through the `FactoryProf` configuration: + +```ruby +TestProf::FactoryProf.configure do |config| + config.threshold = 30 +end +``` + ## Factory Flamegraph The most useful feature of FactoryProf is the _FactoryFlame_ report. That's the special interpretation of Brendan Gregg's [flame graphs](http://www.brendangregg.com/flamegraphs.html) which allows you to identify _factory cascades_. diff --git a/lib/test_prof/factory_prof.rb b/lib/test_prof/factory_prof.rb index ac129e34..7498bbcd 100644 --- a/lib/test_prof/factory_prof.rb +++ b/lib/test_prof/factory_prof.rb @@ -16,7 +16,7 @@ module FactoryProf # FactoryProf configuration class Configuration - attr_accessor :mode, :printer + attr_accessor :mode, :printer, :threshold def initialize @mode = (ENV["FPROF"] == "flamegraph") ? :flamegraph : :simple @@ -31,6 +31,7 @@ def initialize else Printers::Simple end + @threshold = ENV.fetch("FPROF_THRESHOLD", 0).to_i end # Whether we want to generate flamegraphs @@ -115,7 +116,7 @@ def run def print(started_at) printer = config.printer - printer.dump(result, start_time: started_at) + printer.dump(result, start_time: started_at, threshold: config.threshold) end def start diff --git a/lib/test_prof/factory_prof/printers/json.rb b/lib/test_prof/factory_prof/printers/json.rb index 04584e71..4430e079 100644 --- a/lib/test_prof/factory_prof/printers/json.rb +++ b/lib/test_prof/factory_prof/printers/json.rb @@ -9,7 +9,7 @@ class << self using TestProf::FloatDuration include TestProf::Logging - def dump(result, start_time:) + def dump(result, start_time:, **) return log(:info, "No factories detected") if result.raw_stats == {} outpath = TestProf.artifact_path("test-prof.result.json") diff --git a/lib/test_prof/factory_prof/printers/nate_heckler.rb b/lib/test_prof/factory_prof/printers/nate_heckler.rb index c1ab0d72..bf9d28b6 100644 --- a/lib/test_prof/factory_prof/printers/nate_heckler.rb +++ b/lib/test_prof/factory_prof/printers/nate_heckler.rb @@ -10,7 +10,7 @@ class << self using TestProf::FloatDuration include TestProf::Logging - def dump(result, start_time:) + def dump(result, start_time:, **) return if result.raw_stats == {} total_time = result.stats.sum { |stat| stat[:top_level_time] } diff --git a/lib/test_prof/factory_prof/printers/simple.rb b/lib/test_prof/factory_prof/printers/simple.rb index f85efcd2..ba8eac55 100644 --- a/lib/test_prof/factory_prof/printers/simple.rb +++ b/lib/test_prof/factory_prof/printers/simple.rb @@ -9,7 +9,7 @@ class << self using TestProf::FloatDuration include TestProf::Logging - def dump(result, start_time:) + def dump(result, start_time:, threshold:) return log(:info, "No factories detected") if result.raw_stats == {} msgs = [] @@ -32,6 +32,8 @@ def dump(result, start_time:) MSG result.stats.each do |stat| + next if stat[:total_count] < threshold + time_per_call = stat[:total_time] / stat[:total_count] msgs << format("%8d %11d %13.4fs %17.4fs %18.4fs %18s", stat[:total_count], stat[:top_level_count], stat[:total_time], time_per_call, stat[:top_level_time], stat[:name]) diff --git a/spec/integrations/factory_prof_spec.rb b/spec/integrations/factory_prof_spec.rb index 34ad0cbb..59ea588d 100644 --- a/spec/integrations/factory_prof_spec.rb +++ b/spec/integrations/factory_prof_spec.rb @@ -13,6 +13,18 @@ expect(output).to match(/\s+16\s+8\s+(\d+\.\d{4}s\s+){3}user\n\s+10\s+6\s+\s+(\d+\.\d{4}s\s+){3}post/) end + specify "simple printer with threshold param", :aggregate_failures do + output = run_rspec("factory_prof", env: {"FPROF" => "1", "FPROF_THRESHOLD" => "11"}) + + expect(output).to include("FactoryProf enabled (simple mode)") + + expect(output).to include("Factories usage") + expect(output).to match(/Total: 26\n\s+Total top-level: 14\n\s+Total time: \d{2}+:\d{2}\.\d{3} \(out of \d{2}+:\d{2}\.\d{3}\)\n\s+Total uniq factories: 2/) + expect(output).to match(/total\s+top-level\s+total time\s+time per call\s+top-level time\s+name/) + expect(output).to match(/\s+16\s+8\s+(\d+\.\d{4}s\s+){3}user\n/) + expect(output).not_to match(/\s+10\s+6\s+\s+(\d+\.\d{4}s\s+){3}post/) + end + specify "flamegraph printer" do output = run_rspec("factory_prof", env: {"FPROF" => "flamegraph"}) From 29e6ac805d9b4ca10eee09ec3f226a18cee81c25 Mon Sep 17 00:00:00 2001 From: Georgiy Melnikov Date: Thu, 23 May 2024 06:42:39 +0500 Subject: [PATCH 148/194] add hooks parameter to vernier (#295) * add hooks parameter to vernier * add specs --------- Co-authored-by: Vladimir Dementyev --- CHANGELOG.md | 11 +++++++++++ docs/profilers/ruby_profilers.md | 19 +++++++++++++++++++ lib/test_prof/vernier.rb | 4 +++- spec/integrations/profilers_spec.rb | 9 +++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4919e627..13cb18f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ ## master (unreleased) +- Vernier: Add hooks configuration parameter. ([@lHydra][]) + +Now you can add more insights to the resulting report by adding event markers from Active Support Notifications. +To do this, specify the `TEST_VERNIER_HOOKS=rails` env var or set it through `Vernier` configuration: + +```ruby +TestProf::Vernier.configure do |config| + config.hooks = :rails +end +``` + - FactoryProf: Add threshold configuration parameter. ([@lHydra][]) Now you can ignore factories which total number of calls is less than the provided threshold. To do this, specify diff --git a/docs/profilers/ruby_profilers.md b/docs/profilers/ruby_profilers.md index d52bd6c0..07ed2867 100644 --- a/docs/profilers/ruby_profilers.md +++ b/docs/profilers/ruby_profilers.md @@ -143,6 +143,25 @@ You can also profile your application boot process: TEST_VERNIER=boot bundle exec rspec ./spec/some_spec.rb ``` +### Add markers from Active Support Notifications + +You can add more insights to the resulting report by adding event markers from Active Support Notifications: + +```sh +TEST_VERNIER=1 TEST_VERNIER_HOOKS=rails bundle exec rake test + +# or for RSpec +TEST_VERNIER=1 TEST_VERNIER_HOOKS=rails bundle exec rspec ... +``` + +Or you can set the hooks parameter through the `Vernier` configuration: + +```ruby +TestProf::Vernier.configure do |config| + config.hooks = :rails +end +``` + ## RubyProf Easily integrate the power of [ruby-prof](https://github.com/ruby-prof/ruby-prof) into your test suite. diff --git a/lib/test_prof/vernier.rb b/lib/test_prof/vernier.rb index 6d9667c5..4cac154a 100644 --- a/lib/test_prof/vernier.rb +++ b/lib/test_prof/vernier.rb @@ -19,7 +19,7 @@ module TestProf module Vernier # Vernier configuration class Configuration - attr_accessor :mode, :target, :interval + attr_accessor :mode, :target, :interval, :hooks def initialize @mode = ENV.fetch("TEST_VERNIER_MODE", :wall).to_sym @@ -27,6 +27,7 @@ def initialize sample_interval = ENV["TEST_VERNIER_INTERVAL"].to_i @interval = (sample_interval > 0) ? sample_interval : nil + @hooks = ENV["TEST_VERNIER_HOOKS"]&.split(",")&.map { |hook| hook.strip.to_sym } end def boot? @@ -82,6 +83,7 @@ def profile(name = nil) options = {} options[:interval] = config.interval if config.interval + options[:hooks] = config.hooks if config.hooks if block_given? options[:mode] = config.mode diff --git a/spec/integrations/profilers_spec.rb b/spec/integrations/profilers_spec.rb index 88a0e5b1..9798809c 100644 --- a/spec/integrations/profilers_spec.rb +++ b/spec/integrations/profilers_spec.rb @@ -60,6 +60,15 @@ expect(output).to include("Vernier report generated") expect(output).to include("0 failures") end + + specify "with hooks vernier contains rails events" do + output = run_rspec("vernier", env: {"TEST_VERNIER_HOOKS" => "rails"}) + sample_rails_event = "load_config_initializer.railties" + vernier_report = File.read("tmp/test_prof/vernier-report-wall--vernier_fixture-rb-1-1-.json") + + expect(output).to include("0 failures") + expect(vernier_report).to match(/#{sample_rails_event}/) + end end end From ff763200bf7b6a49bfa549470e704c68971c71d0 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 4 Jun 2024 15:27:05 -0700 Subject: [PATCH 149/194] fix: handle Timecop patching Process.clock_gettime --- .github/workflows/release.yml | 1 - CHANGELOG.md | 2 ++ forspell.dict | 1 + lib/test_prof/core.rb | 25 ++++++++++++++++++++++++- spec/bugs/fixtures/timecop_fixture.rb | 3 ++- spec/bugs/time_patch_handling_spec.rb | 17 +++++++++++++++-- 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b4ff39ee..f1d5b7bf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,6 @@ jobs: - uses: ruby/setup-ruby@v1 with: ruby-version: 3.2 - bundler-cache: true - name: Configure RubyGems Credentials uses: rubygems/configure-rubygems-credentials@main - name: Publish to RubyGems diff --git a/CHANGELOG.md b/CHANGELOG.md index 13cb18f4..01077402 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Support latest Timecop patching `Process.clock_gettime`. ([@palkan][]) + - Vernier: Add hooks configuration parameter. ([@lHydra][]) Now you can add more insights to the resulting report by adding event markers from Active Support Notifications. diff --git a/forspell.dict b/forspell.dict index 946be7c3..40f51b27 100644 --- a/forspell.dict +++ b/forspell.dict @@ -30,3 +30,4 @@ Makar Ermokhin Burkhard Sistovaris +Timecop diff --git a/lib/test_prof/core.rb b/lib/test_prof/core.rb index 921b6e7b..7151ee4e 100644 --- a/lib/test_prof/core.rb +++ b/lib/test_prof/core.rb @@ -6,6 +6,29 @@ require "test_prof/logging" require "test_prof/utils" +# Add an alias for Process.clock_gettime "reserved" for TestProf +# (in case some other tool would like to patch it) +module ::Process + class << self + # Already patched by Timecop + if method_defined?(:clock_gettime_without_mock) + alias_method :clock_gettime_for_test_prof, :clock_gettime_without_mock + else + alias_method :clock_gettime_for_test_prof, :clock_gettime + + def singleton_method_added(method_name) + return super unless method_name == :clock_gettime_without_mock + + define_method(:clock_gettime_for_test_prof) { |*args| clock_gettime_without_mock(*args) } + end + end + end +end + +# Main TestProf module +# +# Contains configuration and common methods + # Ruby applications tests profiling tools. # # Contains tools to analyze factories usage, integrate with Ruby profilers, @@ -54,7 +77,7 @@ def spring? # Returns the current process time def now - Process.clock_gettime(Process::CLOCK_MONOTONIC) + Process.clock_gettime_for_test_prof(Process::CLOCK_MONOTONIC) end # Require gem and shows a custom diff --git a/spec/bugs/fixtures/timecop_fixture.rb b/spec/bugs/fixtures/timecop_fixture.rb index 15353285..251b24bd 100644 --- a/spec/bugs/fixtures/timecop_fixture.rb +++ b/spec/bugs/fixtures/timecop_fixture.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true $LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) -require "timecop" +require "timecop" if ENV.fetch("TIMECOP_ORDER", "before") == "before" require "test-prof" +require "timecop" if ENV.fetch("TIMECOP_ORDER", "before") == "after" Timecop.freeze diff --git a/spec/bugs/time_patch_handling_spec.rb b/spec/bugs/time_patch_handling_spec.rb index 66cbe371..6977a805 100644 --- a/spec/bugs/time_patch_handling_spec.rb +++ b/spec/bugs/time_patch_handling_spec.rb @@ -16,11 +16,24 @@ expect(s + ms).to be > 0 end - specify "works with timecop" do + specify "works with timecop loaded before test-prof" do output = run_rspec( "timecop", chdir: File.join(__dir__, "fixtures"), - env: {"TAG_PROF" => "a"} + env: {"TAG_PROF" => "a", "TIMECOP_ORDER" => "before"} + ) + + matches = output.match(/x\s+\d{2}:(\d{2})\.(\d{3})\s+/) + s, ms = matches[1].to_i, matches[2].to_i + + expect(s + ms).to be > 0 + end + + specify "works with timecop loaded after test-prof" do + output = run_rspec( + "timecop", + chdir: File.join(__dir__, "fixtures"), + env: {"TAG_PROF" => "a", "TIMECOP_ORDER" => "after"} ) matches = output.match(/x\s+\d{2}:(\d{2})\.(\d{3})\s+/) From 228481611f882e5679c65e2d6069809ad714aaf6 Mon Sep 17 00:00:00 2001 From: Georgiy Melnikov Date: Fri, 17 May 2024 21:30:15 +0500 Subject: [PATCH 150/194] add report_duplicates config option for let_it_be --- CHANGELOG.md | 2 + docs/recipes/let_it_be.md | 33 ++++ lib/test_prof/recipes/rspec/let_it_be.rb | 29 +++ .../rspec/let_it_be_nested_fixture.rb | 180 ++++++++++++++++++ spec/integrations/let_it_be_spec.rb | 6 + 5 files changed, 250 insertions(+) create mode 100644 spec/integrations/fixtures/rspec/let_it_be_nested_fixture.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 01077402..7c73e587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - Support latest Timecop patching `Process.clock_gettime`. ([@palkan][]) +- Add support for `report_duplicates` config option for `let_it_be` ([@lHydra][]) + - Vernier: Add hooks configuration parameter. ([@lHydra][]) Now you can add more insights to the resulting report by adding event markers from Active Support Notifications. diff --git a/docs/recipes/let_it_be.md b/docs/recipes/let_it_be.md index 7eaad8c0..e09ae0d7 100644 --- a/docs/recipes/let_it_be.md +++ b/docs/recipes/let_it_be.md @@ -266,3 +266,36 @@ end And then tag contexts/examples with `:let_it_be_frost` to enable this feature. Alternatively, you can specify `freeze` modifier explicitly (`let_it_be(freeze: true)`) or configure an alias. + +## Report duplicates + +Although we suggest using `let_it_be` instead of `let!`, there is one important difference: you can override `let!` definition with the same or nested context, so only the latter one is called; `let_it_be` records could be overridden, but still created. For example: + +```ruby +context "A" do + let!(:user) { create(:user, name: "a") } + let_it_be(:post) { create(:post, title: "A") } + + specify { expect(User.all.pluck(:name)).to eq ["a"] } + specify { expect(Post.all.pluck(:title)).to eq ["A"] } + + context "B" do + let!(:user) { create(:user, name: "b") } + let_it_be(:post) { create(:post, title: "B") } + + specify { expect(User.all.pluck(:name)).to eq ["b"] } + specify { expect(Post.all.pluck(:title)).to eq ["B"] } # fails, because there are two posts + end +end +``` + +So for your convenience, you can configure the behavior when let_it_be is overridden. + +```ruby +TestProf::LetItBe.configure do |config| + config.report_duplicates = :warn # Rspec.warn_with + config.report_duplicates = :raise # Kernel.raise +end +``` + +By default this parameter is disabled. You can configure the behavior that will generate a warning or raise an exception. diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index 00073c9f..f0b1782b 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -7,6 +7,8 @@ module TestProf # Just like `let`, but persist the result for the whole group. # NOTE: Experimental and magical, for more control use `before_all`. module LetItBe + class DuplicationError < StandardError; end + Modifier = Struct.new(:scope, :block) do def call(record, config) block.call(record, config) @@ -32,6 +34,19 @@ def register_modifier(key, on: :let, &block) LetItBe.modifiers[key] = Modifier.new(on, block) end + def report_duplicates=(value) + value = value.to_sym + unless %i[warn raise].include?(value) + raise ArgumentError, "#{value} is not acceptable, acceptable values are :warn or :raise" + end + + @report_duplicates = value + end + + def report_duplicates + @report_duplicates ||= false + end + def default_modifiers @default_modifiers ||= {} end @@ -117,6 +132,8 @@ def let_it_be(identifier, **options, &block) instance_variable_get(:"#{PREFIX}#{identifier}") end + report_duplicates(identifier) if LetItBe.config.report_duplicates + LetItBe.module_for(self).module_eval do define_method(identifier) do # Trying to detect the context @@ -135,6 +152,18 @@ def let_it_be(identifier, **options, &block) let(identifier, &let_accessor) end + private def report_duplicates(identifier) + if instance_methods.include?(identifier) && File.basename(__FILE__) == File.basename(instance_method(identifier).source_location[0]) + error_msg = "let_it_be(:#{identifier}) was redefined in nested group" + + if LetItBe.config.report_duplicates == :warn + ::RSpec.warn_with(error_msg) + else + raise DuplicationError, error_msg + end + end + end + module Freezer # Stoplist to prevent freezing objects and theirs associations that are defined # with `let_it_be`'s `freeze: false` options during deep freezing. diff --git a/spec/integrations/fixtures/rspec/let_it_be_nested_fixture.rb b/spec/integrations/fixtures/rspec/let_it_be_nested_fixture.rb new file mode 100644 index 00000000..57868877 --- /dev/null +++ b/spec/integrations/fixtures/rspec/let_it_be_nested_fixture.rb @@ -0,0 +1,180 @@ +# frozen_string_literal: true + +require_relative "../../../support/ar_models" +require_relative "../../../support/transactional_context" + +require "test_prof/recipes/rspec/let_it_be" + +RSpec.describe "Overriding detection", :transactional do + context "when report_duplicates was set as :raise" do + context "when let_it_be redefined" do + context "when on same nested level" do + it "raises a duplication error" do + expect do + TestProf::LetItBe.configure do |config| + config.report_duplicates = :raise + end + + RSpec.describe "let_it_be on same nested level" do + include TestProf::FactoryBot::Syntax::Methods + + let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user) } + end + end.to raise_error(TestProf::LetItBe::DuplicationError) + end + end + + context "when nested level is 2" do + it "raises a duplication error" do + expect do + TestProf::LetItBe.configure do |config| + config.report_duplicates = :raise + end + + RSpec.describe "let_it_be in nested context" do + include TestProf::FactoryBot::Syntax::Methods + + let_it_be(:user) { create(:user) } + + context "nested context level 2" do + let_it_be(:user) { create(:user) } + end + end + end.to raise_error(TestProf::LetItBe::DuplicationError) + end + end + + context "when nested level is 3" do + it "raises a duplication error" do + expect do + TestProf::LetItBe.configure do |config| + config.report_duplicates = :raise + end + + RSpec.describe "let_it_be in nested context" do + include TestProf::FactoryBot::Syntax::Methods + + let_it_be(:user) { create(:user) } + + context "nested context level 2" do + context "nested context level 3" do + let_it_be(:user) { create(:user) } + end + end + end + end.to raise_error(TestProf::LetItBe::DuplicationError) + end + end + end + + context "when defined let and let_it_be" do + it "does not raise a duplication error" do + expect do + TestProf::LetItBe.configure do |config| + config.report_duplicates = :raise + end + + RSpec.describe "let_it_be and let" do + include TestProf::FactoryBot::Syntax::Methods + + let(:user) { create(:user) } + + context "nested context level 2" do + let_it_be(:user) { create(:user) } + end + end + end.not_to raise_error + end + end + end + + context "when report_duplicates was set as :warn" do + let(:warning_msg) { "let_it_be(:user) was redefined in nested group" } + + before do + allow(::RSpec).to receive(:warn_with).with(warning_msg) + end + + context "when let_it_be redefined" do + context "when on same nested level" do + it "warns a duplication message" do + RSpec.describe "let_it_be on same nested level" do + include TestProf::FactoryBot::Syntax::Methods + + TestProf::LetItBe.configure do |config| + config.report_duplicates = :warn + end + + let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user) } + end.run + + expect(::RSpec).to have_received(:warn_with).with(warning_msg).once + end + end + + context "when nested level is 2" do + it "warns a duplication message" do + RSpec.describe "let_it_be in nested context" do + include TestProf::FactoryBot::Syntax::Methods + + TestProf::LetItBe.configure do |config| + config.report_duplicates = :warn + end + + let_it_be(:user) { create(:user) } + + context "nested context" do + let_it_be(:user) { create(:user) } + end + end.run + + expect(::RSpec).to have_received(:warn_with).with(warning_msg).once + end + end + + context "when nested level is 3" do + it "warns a duplication message" do + RSpec.describe "let_it_be in nested context" do + include TestProf::FactoryBot::Syntax::Methods + + TestProf::LetItBe.configure do |config| + config.report_duplicates = :warn + end + + let_it_be(:user) { create(:user) } + + context "nested context level 2" do + context "nested context level 3" do + let_it_be(:user) { create(:user) } + end + end + end.run + + expect(::RSpec).to have_received(:warn_with).with(warning_msg).once + end + end + end + + context "when defined let and let_it_be" do + it "does not warn a duplication message" do + RSpec.describe "let_it_be and let" do + include TestProf::FactoryBot::Syntax::Methods + + TestProf::LetItBe.configure do |config| + config.report_duplicates = :raise + end + + let(:user) { create(:user) } + + context "nested context level 2" do + let_it_be(:user) { create(:user) } + end + end.run + + expect(::RSpec).not_to have_received(:warn_with) + end + end + end +end diff --git a/spec/integrations/let_it_be_spec.rb b/spec/integrations/let_it_be_spec.rb index 4ecae187..9f522549 100644 --- a/spec/integrations/let_it_be_spec.rb +++ b/spec/integrations/let_it_be_spec.rb @@ -18,4 +18,10 @@ expect(output).to include("0 failures") end + + specify "it detects let_it_be override" do + output = run_rspec("let_it_be_nested") + + expect(output).to include("0 failures") + end end From dcb835c7e6bd3abb82a8b4cb76bfe493a8b90e8b Mon Sep 17 00:00:00 2001 From: Georgiy Melnikov Date: Wed, 5 Jun 2024 18:20:50 +0500 Subject: [PATCH 151/194] remove excess memoization & change setter logic --- lib/test_prof/recipes/rspec/let_it_be.rb | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/lib/test_prof/recipes/rspec/let_it_be.rb b/lib/test_prof/recipes/rspec/let_it_be.rb index f0b1782b..f563346f 100644 --- a/lib/test_prof/recipes/rspec/let_it_be.rb +++ b/lib/test_prof/recipes/rspec/let_it_be.rb @@ -16,6 +16,8 @@ def call(record, config) end class Configuration + attr_accessor :report_duplicates + # Define an alias for `let_it_be` with the predefined options: # # TestProf::LetItBe.configure do |config| @@ -34,19 +36,6 @@ def register_modifier(key, on: :let, &block) LetItBe.modifiers[key] = Modifier.new(on, block) end - def report_duplicates=(value) - value = value.to_sym - unless %i[warn raise].include?(value) - raise ArgumentError, "#{value} is not acceptable, acceptable values are :warn or :raise" - end - - @report_duplicates = value - end - - def report_duplicates - @report_duplicates ||= false - end - def default_modifiers @default_modifiers ||= {} end @@ -155,10 +144,11 @@ def let_it_be(identifier, **options, &block) private def report_duplicates(identifier) if instance_methods.include?(identifier) && File.basename(__FILE__) == File.basename(instance_method(identifier).source_location[0]) error_msg = "let_it_be(:#{identifier}) was redefined in nested group" + report_level = LetItBe.config.report_duplicates.to_sym - if LetItBe.config.report_duplicates == :warn + if report_level == :warn ::RSpec.warn_with(error_msg) - else + elsif report_level == :raise raise DuplicationError, error_msg end end From f1ee78b882935c0e4e3a5f77d66a30429fa42ec3 Mon Sep 17 00:00:00 2001 From: Georgiy Melnikov Date: Sun, 19 May 2024 21:03:48 +0500 Subject: [PATCH 152/194] track traits and overrides with FactoryProf --- CHANGELOG.md | 4 ++ docs/profilers/factory_prof.md | 38 ++++++++-- lib/test_prof/factory_prof.rb | 70 ++++++++++++------- .../factory_prof/fabrication_patch.rb | 8 ++- .../factory_prof/factory_bot_patch.rb | 14 +++- .../factory_builders/fabrication.rb | 4 +- .../factory_builders/factory_bot.rb | 4 +- lib/test_prof/factory_prof/printers/simple.rb | 23 ++++-- spec/integrations/factory_prof_spec.rb | 32 ++++++++- .../factory_prof_with_variations_fixture.rb | 43 ++++++++++++ .../factory_prof/printers/json_spec.rb | 8 +-- spec/test_prof/factory_prof_spec.rb | 23 +++--- 12 files changed, 217 insertions(+), 54 deletions(-) create mode 100644 spec/integrations/fixtures/rspec/factory_prof_with_variations_fixture.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c73e587..0e804723 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Add support for `report_duplicates` config option for `let_it_be` ([@lHydra][]) +- FactoryProf: Add variations information to the FactorProf data in simple mode. Add `variations_limit` configuration parameter. ([@lHydra][]) + +Now you can see common variations (traits and attribute overrides) while collecting data with `FactoryProf` + - Vernier: Add hooks configuration parameter. ([@lHydra][]) Now you can add more insights to the resulting report by adding event markers from Active Support Notifications. diff --git a/docs/profilers/factory_prof.md b/docs/profilers/factory_prof.md index 1aff58ce..1e8b4350 100644 --- a/docs/profilers/factory_prof.md +++ b/docs/profilers/factory_prof.md @@ -12,13 +12,19 @@ Total top-level: 10286 Total time: 04:31.222 (out of 07.16.124) Total uniq factories: 119 - total top-level total time time per call top-level time name - 6091 2715 115.7671s 0.0426s 50.2517s user - 2142 2098 93.3152s 0.0444s 92.1915s post - ... + name total top-level total time time per call top-level time + + user 6091 2715 115.7671s 0.0426s 50.2517s + .admin 123 715 15.7671s 0.0466s 5.2517s + [name,role] 25 11 7.671s 0.0666s 1.2517s + post 2142 2098 93.3152s 0.0444s 92.1915s + .draft[tags] 12 12 9.3152s 0.164s 42.1915s + ... ``` -It shows both the total number of the factory runs and the number of _top-level_ runs, i.e. not during another factory invocation (e.g. when using associations.) +It shows both the total number of the factory and its variations (such as traits, overrides) runs and the number of _top-level_ runs, i.e. not during another factory invocation (e.g. when using associations.) + +In the example above, `.xxx` indicates a trait and `[a,b]` indicates the overrides keys, e.g., `create(:user, :admin)` is an `.admin` variation, while `create(:post, :draft, tags: ["a"])`—`.draft[tags]` It also shows the time spent generating records with factories and the amount of time taken per factory call. @@ -95,6 +101,28 @@ TestProf::FactoryProf.configure do |config| end ``` +### Variations limit config + +When running FactoryProf, the output may contain a variant that is too long, which will distort the output. +To avoid this and focus on the most important statistics you can specify a variations limit value. Then a special ID (`[...]`) will be shown instead of the variant with the number of traits/overrides exceeding the limit. + +To use variations limit parameter set `FPROF_VARIATIONS_LIMIT` environment variable to `N` (where `N` is a limit number): + +```sh +FPROF=1 FPROF_VARIATIONS_LIMIT=5 rspec + +# or +FPROF=1 FPROF_VARIATIONS_LIMIT=5 bundle exec rake test +``` + +Or you can set the limit parameter through the `FactoryProf` configuration: + +```ruby +TestProf::FactoryProf.configure do |config| + config.variations_limit = 5 +end +``` + ## Factory Flamegraph The most useful feature of FactoryProf is the _FactoryFlame_ report. That's the special interpretation of Brendan Gregg's [flame graphs](http://www.brendangregg.com/flamegraphs.html) which allows you to identify _factory cascades_. diff --git a/lib/test_prof/factory_prof.rb b/lib/test_prof/factory_prof.rb index 7498bbcd..3e3e3c54 100644 --- a/lib/test_prof/factory_prof.rb +++ b/lib/test_prof/factory_prof.rb @@ -16,7 +16,7 @@ module FactoryProf # FactoryProf configuration class Configuration - attr_accessor :mode, :printer, :threshold + attr_accessor :mode, :printer, :threshold, :variations_limit def initialize @mode = (ENV["FPROF"] == "flamegraph") ? :flamegraph : :simple @@ -32,6 +32,7 @@ def initialize Printers::Simple end @threshold = ENV.fetch("FPROF_THRESHOLD", 0).to_i + @variations_limit = ENV.fetch("FPROF_VARIATIONS_LIMIT", 2).to_i end # Whether we want to generate flamegraphs @@ -50,8 +51,14 @@ def initialize(stacks, raw_stats) # Returns sorted stats def stats - @stats ||= @raw_stats.values - .sort_by { |el| -el[:total_count] } + @stats ||= @raw_stats.values.sort_by { |el| -el[:total_count] }.map do |stat| + unless stat[:variations].empty? + stat = stat.dup + stat[:variations] = stat[:variations].values.sort_by { |nested_el| -nested_el[:total_count] } + end + + stat + end end def total_count @@ -61,14 +68,6 @@ def total_count def total_time @total_time ||= @raw_stats.values.sum { |v| v[:total_time] } end - - private - - def sorted_stats(key) - @raw_stats.values - .map { |el| [el[:name], el[key]] } - .sort_by { |el| -el[1] } - end end class << self @@ -132,20 +131,19 @@ def result Result.new(@stacks, @stats) end - def track(factory) + def track(factory, variation:) return yield unless running? @depth += 1 @current_stack << factory if config.flamegraph? - @stats[factory][:total_count] += 1 - @stats[factory][:top_level_count] += 1 if @depth == 1 + track_count(@stats[factory]) + track_count(@stats[factory][:variations][variation_name(variation)]) unless variation.empty? t1 = TestProf.now begin yield ensure t2 = TestProf.now - elapsed = t2 - t1 - @stats[factory][:total_time] += elapsed - @stats[factory][:top_level_time] += elapsed if @depth == 1 + track_time(@stats[factory], t1, t2) + track_time(@stats[factory][:variations][variation_name(variation)], t1, t2) unless variation.empty? @depth -= 1 flush_stack if @depth.zero? end @@ -153,21 +151,45 @@ def track(factory) private + def variation_name(variation) + variations_count = variation.to_s.scan(/[\w]+/).size + return "[...]" if variations_count > config.variations_limit + + variation + end + def reset! @stacks = [] if config.flamegraph? @depth = 0 @stats = Hash.new do |h, k| - h[k] = { - name: k, - total_count: 0, - top_level_count: 0, - total_time: 0.0, - top_level_time: 0.0 - } + h[k] = hash_template(k) + h[k][:variations] = Hash.new { |hh, variation_key| hh[variation_key] = hash_template(variation_key) } + h[k] end flush_stack end + def hash_template(name) + { + name: name, + total_count: 0, + top_level_count: 0, + total_time: 0.0, + top_level_time: 0.0 + } + end + + def track_count(factory) + factory[:total_count] += 1 + factory[:top_level_count] += 1 if @depth == 1 + end + + def track_time(factory, t1, t2) + elapsed = t2 - t1 + factory[:total_time] += elapsed + factory[:top_level_time] += elapsed if @depth == 1 + end + def flush_stack return unless config.flamegraph? @stacks << @current_stack unless @current_stack.nil? || @current_stack.empty? diff --git a/lib/test_prof/factory_prof/fabrication_patch.rb b/lib/test_prof/factory_prof/fabrication_patch.rb index 542d3542..5d88c113 100644 --- a/lib/test_prof/factory_prof/fabrication_patch.rb +++ b/lib/test_prof/factory_prof/fabrication_patch.rb @@ -5,7 +5,13 @@ module FactoryProf # Wrap #run method with FactoryProf tracking module FabricationPatch def create(name, overrides = {}) - FactoryBuilders::Fabrication.track(name) { super } + variation = "" + + unless overrides.empty? + variation += overrides.keys.sort.to_s.gsub(/[\\":]/, "") + end + + FactoryBuilders::Fabrication.track(name, variation: variation.to_sym) { super } end end end diff --git a/lib/test_prof/factory_prof/factory_bot_patch.rb b/lib/test_prof/factory_prof/factory_bot_patch.rb index 556eb3c7..6330c86b 100644 --- a/lib/test_prof/factory_prof/factory_bot_patch.rb +++ b/lib/test_prof/factory_prof/factory_bot_patch.rb @@ -5,7 +5,19 @@ module FactoryProf # Wrap #run method with FactoryProf tracking module FactoryBotPatch def run(strategy = @strategy) - FactoryBuilders::FactoryBot.track(strategy, @name) { super } + variation = "" + + if @traits || @overrides + unless @traits.empty? + variation += @traits.sort.join(".").prepend(".") + end + + unless @overrides.empty? + variation += @overrides.keys.sort.to_s.gsub(/[\\":]/, "") + end + end + + FactoryBuilders::FactoryBot.track(strategy, @name, variation: variation.to_sym) { super } end end end diff --git a/lib/test_prof/factory_prof/factory_builders/fabrication.rb b/lib/test_prof/factory_prof/factory_builders/fabrication.rb index 688f68b4..5257f76c 100644 --- a/lib/test_prof/factory_prof/factory_builders/fabrication.rb +++ b/lib/test_prof/factory_prof/factory_builders/fabrication.rb @@ -15,8 +15,8 @@ def self.patch end end - def self.track(factory, &block) - FactoryProf.track(factory, &block) + def self.track(factory, **opts, &block) + FactoryProf.track(factory, **opts, &block) end end end diff --git a/lib/test_prof/factory_prof/factory_builders/factory_bot.rb b/lib/test_prof/factory_prof/factory_builders/factory_bot.rb index b43e3bb7..ae492295 100644 --- a/lib/test_prof/factory_prof/factory_builders/factory_bot.rb +++ b/lib/test_prof/factory_prof/factory_builders/factory_bot.rb @@ -18,9 +18,9 @@ def self.patch defined? TestProf::FactoryBot end - def self.track(strategy, factory, &block) + def self.track(strategy, factory, **opts, &block) return yield unless strategy.create? - FactoryProf.track(factory, &block) + FactoryProf.track(factory, **opts, &block) end end end diff --git a/lib/test_prof/factory_prof/printers/simple.rb b/lib/test_prof/factory_prof/printers/simple.rb index ba8eac55..a8da2969 100644 --- a/lib/test_prof/factory_prof/printers/simple.rb +++ b/lib/test_prof/factory_prof/printers/simple.rb @@ -28,19 +28,34 @@ def dump(result, start_time:, threshold:) Total time: #{total_time.duration} (out of #{total_run_time.duration}) Total uniq factories: #{total_uniq_factories} - total top-level total time time per call top-level time name + name total top-level total time time per call top-level time MSG result.stats.each do |stat| next if stat[:total_count] < threshold - time_per_call = stat[:total_time] / stat[:total_count] - - msgs << format("%8d %11d %13.4fs %17.4fs %18.4fs %18s", stat[:total_count], stat[:top_level_count], stat[:total_time], time_per_call, stat[:top_level_time], stat[:name]) + msgs << format("%-3s%-20s %8d %11d %13.4fs %17.4fs %18.4fs", *format_args(stat)) + # move other variation ("[...]") to the end of the array + sorted_variations = stat[:variations].sort_by.with_index do |variation, i| + (variation[:name] == "[...]") ? stat[:variations].size + 1 : i + end + sorted_variations.each do |variation_stat| + msgs << format("%-5s%-18s %8d %11d %13.4fs %17.4fs %18.4fs", *format_args(variation_stat)) + end end log :info, msgs.join("\n") end + + private + + def format_args(stat) + time_per_call = stat[:total_time] / stat[:total_count] + format_args = [""] + format_args += stat.values_at(:name, :total_count, :top_level_count, :total_time) + format_args << time_per_call + format_args << stat[:top_level_time] + end end end end diff --git a/spec/integrations/factory_prof_spec.rb b/spec/integrations/factory_prof_spec.rb index 59ea588d..8fc59d56 100644 --- a/spec/integrations/factory_prof_spec.rb +++ b/spec/integrations/factory_prof_spec.rb @@ -9,8 +9,36 @@ expect(output).to include("Factories usage") expect(output).to match(/Total: 26\n\s+Total top-level: 14\n\s+Total time: \d{2}+:\d{2}\.\d{3} \(out of \d{2}+:\d{2}\.\d{3}\)\n\s+Total uniq factories: 2/) - expect(output).to match(/total\s+top-level\s+total time\s+time per call\s+top-level time\s+name/) - expect(output).to match(/\s+16\s+8\s+(\d+\.\d{4}s\s+){3}user\n\s+10\s+6\s+\s+(\d+\.\d{4}s\s+){3}post/) + expect(output).to match(/name\s+total\s+top-level\s+total time\s+time per call\s+top-level time/) + expect(output).to match( + / + user\s+16\s+8\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+.with_posts\[name\]\s+1\s+1\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+\[name\]\s+1\s+1\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+post\s+10\s+6\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+\[user\]\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s + /x + ) + end + + specify "simple printer with variations", :aggregate_failures do + output = run_rspec("factory_prof_with_variations", env: {"FPROF" => "1", "FPROF_VARIATIONS_LIMIT" => "2"}) + + expect(output).to include("FactoryProf enabled (simple mode)") + + expect(output).to include("Factories usage") + expect(output).to match(/Total: 25\n\s+Total top-level: 9\n\s+Total time: \d{2}+:\d{2}\.\d{3} \(out of \d{2}+:\d{2}\.\d{3}\)\n\s+Total uniq factories: 2/) + expect(output).to match(/name\s+total\s+top-level\s+total time\s+time per call\s+top-level time/) + expect(output).to match( + / + user\s+15\s+7\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+.traited.with_posts\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+\[name\]\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+\[...\]\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+post\s+10\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+\[text,\suser\]\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s + /x + ) end specify "simple printer with threshold param", :aggregate_failures do diff --git a/spec/integrations/fixtures/rspec/factory_prof_with_variations_fixture.rb b/spec/integrations/fixtures/rspec/factory_prof_with_variations_fixture.rb new file mode 100644 index 00000000..246e8016 --- /dev/null +++ b/spec/integrations/fixtures/rspec/factory_prof_with_variations_fixture.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require_relative "../../../support/ar_models" +require "test-prof" + +TestProf.configure do |config| + config.output_dir = "../../../../tmp/test_prof" +end + +describe "User" do + context "created by factory_bot" do + context "with few traits" do + let!(:user_with_traits) { TestProf::FactoryBot.create(:user, :traited, :with_posts) } + let!(:user_with_same_traits) { TestProf::FactoryBot.create(:user, :with_posts, :traited) } + + it "works" do + expect(true).to eq true + end + end + + context "with many traits" do + let!(:user_over_limit) { TestProf::FactoryBot.create(:user, :with_posts, :traited, :other_trait, tag: "tag") } + let!(:another_user_over_limit) { TestProf::FactoryBot.create(:user, :with_posts, :traited, tag: "some tag") } + + it "works" do + expect(true).to eq true + end + end + end + + context "created by fabrication" do + let!(:user) { Fabricate(:user) } + let!(:another_user_1) { Fabricate(:user, name: "some name") } + let!(:another_user_2) { Fabricate(:user, name: "some name") } + let!(:post) { Fabricate(:post, user: user, text: "some text") } + let!(:post_with_same_overrides) { Fabricate(:post, text: "some text", user: user) } + + it "works" do + expect(true).to eq true + end + end +end diff --git a/spec/test_prof/factory_prof/printers/json_spec.rb b/spec/test_prof/factory_prof/printers/json_spec.rb index 8574c219..5bd8deb9 100644 --- a/spec/test_prof/factory_prof/printers/json_spec.rb +++ b/spec/test_prof/factory_prof/printers/json_spec.rb @@ -15,10 +15,10 @@ let(:stats) do { - user: {name: :user, total_count: 5, total_time: 1.0, top_level_count: 5, top_level_time: 0.1}, - account: {name: :account, total_count: 6, total_time: 2.0, top_level_count: 6, top_level_time: 0.2}, - comment: {name: :comment, total_count: 2, total_time: 3.0, top_level_count: 2, top_level_time: 0.3}, - name: {name: :post, total_count: 2, total_time: 4.0, top_level_count: 0, top_level_time: 0.4} + user: {name: :user, total_count: 5, total_time: 1.0, top_level_count: 5, top_level_time: 0.1, variations: []}, + account: {name: :account, total_count: 6, total_time: 2.0, top_level_count: 6, top_level_time: 0.2, variations: []}, + comment: {name: :comment, total_count: 2, total_time: 3.0, top_level_count: 2, top_level_time: 0.3, variations: []}, + name: {name: :post, total_count: 2, total_time: 4.0, top_level_count: 0, top_level_time: 0.4, variations: []} } end diff --git a/spec/test_prof/factory_prof_spec.rb b/spec/test_prof/factory_prof_spec.rb index 77d2238d..4e761f11 100644 --- a/spec/test_prof/factory_prof_spec.rb +++ b/spec/test_prof/factory_prof_spec.rb @@ -18,6 +18,7 @@ def without_time(xs) xs.map do |x| expect(x.delete(:total_time)).to be_a(Float) expect(x.delete(:top_level_time)).to be_a(Float) + x[:variations] = without_time(x[:variations]) unless x[:variations].nil? x end end @@ -74,13 +75,13 @@ def without_time(xs) ) expect(without_time(result.stats)).to eq( [ - {name: :post, total_count: 1, top_level_count: 1}, - {name: :user, total_count: 1, top_level_count: 0} + {name: :post, total_count: 1, top_level_count: 1, variations: []}, + {name: :user, total_count: 1, top_level_count: 0, variations: []} ] ) end - it "contains many stacks" do + it "contains many stacks with variations" do TestProf::FactoryBot.create_pair(:user) TestProf::FactoryBot.create(:post) TestProf::FactoryBot.create(:user, :with_posts) @@ -95,8 +96,10 @@ def without_time(xs) ) expect(without_time(result.stats)).to eq( [ - {name: :user, total_count: 6, top_level_count: 3}, - {name: :post, total_count: 3, top_level_count: 1} + {name: :user, total_count: 6, top_level_count: 3, variations: [ + {name: :".with_posts", top_level_count: 1, total_count: 1} + ]}, + {name: :post, total_count: 3, top_level_count: 1, variations: []} ] ) end @@ -116,9 +119,9 @@ def without_time(xs) expect(result.stacks.first).to eq([:user]) end - it "contains many stacks" do + it "contains many stacks with variations" do Fabricate.times(2, :user) - Fabricate.create(:post) + Fabricate.create(:post, text: "some text") Fabricate.create(:user) { Fabricate.times(2, :post) } expect(result.stacks.size).to eq 4 @@ -131,8 +134,10 @@ def without_time(xs) ) expect(without_time(result.stats)).to eq( [ - {name: :user, total_count: 6, top_level_count: 3}, - {name: :post, total_count: 3, top_level_count: 1} + {name: :user, total_count: 6, top_level_count: 3, variations: []}, + {name: :post, total_count: 3, top_level_count: 1, variations: [ + {name: :"[text]", top_level_count: 1, total_count: 1} + ]} ] ) end From a7ff4ee5ab711d5fea81bea1335bcf1ad8d42eb7 Mon Sep 17 00:00:00 2001 From: Georgiy Melnikov Date: Mon, 3 Jun 2024 18:36:52 +0500 Subject: [PATCH 153/194] fix spec --- spec/integrations/factory_prof_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/integrations/factory_prof_spec.rb b/spec/integrations/factory_prof_spec.rb index 8fc59d56..0d6867b7 100644 --- a/spec/integrations/factory_prof_spec.rb +++ b/spec/integrations/factory_prof_spec.rb @@ -48,9 +48,9 @@ expect(output).to include("Factories usage") expect(output).to match(/Total: 26\n\s+Total top-level: 14\n\s+Total time: \d{2}+:\d{2}\.\d{3} \(out of \d{2}+:\d{2}\.\d{3}\)\n\s+Total uniq factories: 2/) - expect(output).to match(/total\s+top-level\s+total time\s+time per call\s+top-level time\s+name/) - expect(output).to match(/\s+16\s+8\s+(\d+\.\d{4}s\s+){3}user\n/) - expect(output).not_to match(/\s+10\s+6\s+\s+(\d+\.\d{4}s\s+){3}post/) + expect(output).to match(/name\s+total\s+top-level\s+total time\s+time per call\s+top-level time/) + expect(output).to match(/user\s+16\s+8\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n/) + expect(output).not_to match(/\s+post\s+10\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n/) end specify "flamegraph printer" do From 1fb2ed591a6670b4eb8294a25c2df3641372bc5d Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 5 Jun 2024 10:50:22 -0700 Subject: [PATCH 154/194] make factory_prof variations opt-in --- CHANGELOG.md | 8 +- docs/profilers/factory_prof.md | 90 +++++++++++++------ lib/test_prof/factory_prof.rb | 3 +- .../factory_prof/fabrication_patch.rb | 2 +- .../factory_prof/factory_bot_patch.rb | 14 +-- spec/integrations/factory_prof_spec.rb | 5 +- spec/test_prof/factory_prof_spec.rb | 1 + 7 files changed, 78 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e804723..59dd30ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,13 @@ ## master (unreleased) -- Support latest Timecop patching `Process.clock_gettime`. ([@palkan][]) +- Add variations information to FactorProf reports. ([@lHydra][]) -- Add support for `report_duplicates` config option for `let_it_be` ([@lHydra][]) +Get info on traits/overrides used by running `FPROF=1 FPROF_VARS=1 `. -- FactoryProf: Add variations information to the FactorProf data in simple mode. Add `variations_limit` configuration parameter. ([@lHydra][]) +- Add support for `report_duplicates` config option for `let_it_be` ([@lHydra][]) -Now you can see common variations (traits and attribute overrides) while collecting data with `FactoryProf` +- Support latest Timecop patching `Process.clock_gettime`. ([@palkan][]) - Vernier: Add hooks configuration parameter. ([@lHydra][]) diff --git a/docs/profilers/factory_prof.md b/docs/profilers/factory_prof.md index 1e8b4350..e4a519e4 100644 --- a/docs/profilers/factory_prof.md +++ b/docs/profilers/factory_prof.md @@ -15,16 +15,11 @@ Total uniq factories: 119 name total top-level total time time per call top-level time user 6091 2715 115.7671s 0.0426s 50.2517s - .admin 123 715 15.7671s 0.0466s 5.2517s - [name,role] 25 11 7.671s 0.0666s 1.2517s post 2142 2098 93.3152s 0.0444s 92.1915s - .draft[tags] 12 12 9.3152s 0.164s 42.1915s ... ``` -It shows both the total number of the factory and its variations (such as traits, overrides) runs and the number of _top-level_ runs, i.e. not during another factory invocation (e.g. when using associations.) - -In the example above, `.xxx` indicates a trait and `[a,b]` indicates the overrides keys, e.g., `create(:user, :admin)` is an `.admin` variation, while `create(:post, :draft, tags: ["a"])`—`.draft[tags]` +It shows both the total number of the factory runs and the number of _top-level_ runs, i.e. not during another factory invocation (e.g. when using associations.) It also shows the time spent generating records with factories and the amount of time taken per factory call. @@ -60,6 +55,65 @@ And for every test run see the overall factories usage: [TEST PROF INFO] Time spent in factories: 04:31.222 (54% of total time) ``` +### Variations + +You can also add _variations_ (such as traits, overrides) information to reports by providing the `FPROF_VARS=1` environment variable or enabling it in your code: + +```ruby +TestProf::FactoryProf.configure do |config| + config.include_variations = true +end +``` + +For example: + +```sh +$ FPROF=1 FPROF_VARS=1 bin/rails test + +... + +[TEST PROF INFO] Factories usage + +Total: 15285 +Total top-level: 10286 +Total time: 04:31.222 (out of 07.16.124) +Total uniq factories: 119 + + name total top-level total time time per call top-level time + + user 6091 2715 115.7671s 0.0426s 50.2517s + .admin 123 715 15.7671s 0.0466s 5.2517s + [name,role] 25 11 7.671s 0.0666s 1.2517s + post 2142 2098 93.3152s 0.0444s 92.1915s + .draft[tags] 12 12 9.3152s 0.164s 42.1915s + ... +``` + +In the example above, `.xxx` indicates a trait and `[a,b]` indicates the overrides keys, e.g., `create(:user, :admin)` is an `.admin` variation, while `create(:post, :draft, tags: ["a"])`—`.draft[tags]` + +#### Variations limit config + +When running FactoryProf, the output may contain a variant that is too long, which will distort the output. + +To avoid this and focus on the most important statistics you can specify a variations limit value. Then a special ID (`[...]`) will be shown instead of the variant with the number of traits/overrides exceeding the limit. + +To use variations limit parameter set `FPROF_VARIATIONS_LIMIT` environment variable to `N` (where `N` is a limit number): + +```sh +FPROF=1 FPROF_VARIATIONS_LIMIT=5 rspec + +# or +FPROF=1 FPROF_VARIATIONS_LIMIT=5 bundle exec rake test +``` + +Or you can set the limit parameter through the `FactoryProf` configuration: + +```ruby +TestProf::FactoryProf.configure do |config| + config.variations_limit = 5 +end +``` + ### Exporting profile results to a JSON file FactoryProf can save profile results as a JSON file. @@ -75,7 +129,7 @@ FPROF=json bundle exec rake test Example output: -``` +```sh [TEST PROF INFO] Profile results to JSON: tmp/test_prof/test-prof.result.json ``` @@ -101,28 +155,6 @@ TestProf::FactoryProf.configure do |config| end ``` -### Variations limit config - -When running FactoryProf, the output may contain a variant that is too long, which will distort the output. -To avoid this and focus on the most important statistics you can specify a variations limit value. Then a special ID (`[...]`) will be shown instead of the variant with the number of traits/overrides exceeding the limit. - -To use variations limit parameter set `FPROF_VARIATIONS_LIMIT` environment variable to `N` (where `N` is a limit number): - -```sh -FPROF=1 FPROF_VARIATIONS_LIMIT=5 rspec - -# or -FPROF=1 FPROF_VARIATIONS_LIMIT=5 bundle exec rake test -``` - -Or you can set the limit parameter through the `FactoryProf` configuration: - -```ruby -TestProf::FactoryProf.configure do |config| - config.variations_limit = 5 -end -``` - ## Factory Flamegraph The most useful feature of FactoryProf is the _FactoryFlame_ report. That's the special interpretation of Brendan Gregg's [flame graphs](http://www.brendangregg.com/flamegraphs.html) which allows you to identify _factory cascades_. diff --git a/lib/test_prof/factory_prof.rb b/lib/test_prof/factory_prof.rb index 3e3e3c54..c021770c 100644 --- a/lib/test_prof/factory_prof.rb +++ b/lib/test_prof/factory_prof.rb @@ -16,7 +16,7 @@ module FactoryProf # FactoryProf configuration class Configuration - attr_accessor :mode, :printer, :threshold, :variations_limit + attr_accessor :mode, :printer, :threshold, :include_variations, :variations_limit def initialize @mode = (ENV["FPROF"] == "flamegraph") ? :flamegraph : :simple @@ -32,6 +32,7 @@ def initialize Printers::Simple end @threshold = ENV.fetch("FPROF_THRESHOLD", 0).to_i + @include_variations = ENV["FPROF_VARS"] == "1" @variations_limit = ENV.fetch("FPROF_VARIATIONS_LIMIT", 2).to_i end diff --git a/lib/test_prof/factory_prof/fabrication_patch.rb b/lib/test_prof/factory_prof/fabrication_patch.rb index 5d88c113..e4d2a2f0 100644 --- a/lib/test_prof/factory_prof/fabrication_patch.rb +++ b/lib/test_prof/factory_prof/fabrication_patch.rb @@ -7,7 +7,7 @@ module FabricationPatch def create(name, overrides = {}) variation = "" - unless overrides.empty? + if FactoryProf.config.include_variations && !overrides.empty? variation += overrides.keys.sort.to_s.gsub(/[\\":]/, "") end diff --git a/lib/test_prof/factory_prof/factory_bot_patch.rb b/lib/test_prof/factory_prof/factory_bot_patch.rb index 6330c86b..3db291a9 100644 --- a/lib/test_prof/factory_prof/factory_bot_patch.rb +++ b/lib/test_prof/factory_prof/factory_bot_patch.rb @@ -7,13 +7,15 @@ module FactoryBotPatch def run(strategy = @strategy) variation = "" - if @traits || @overrides - unless @traits.empty? - variation += @traits.sort.join(".").prepend(".") - end + if FactoryProf.config.include_variations + if @traits || @overrides + unless @traits.empty? + variation += @traits.sort.join(".").prepend(".") + end - unless @overrides.empty? - variation += @overrides.keys.sort.to_s.gsub(/[\\":]/, "") + unless @overrides.empty? + variation += @overrides.keys.sort.to_s.gsub(/[\\":]/, "") + end end end diff --git a/spec/integrations/factory_prof_spec.rb b/spec/integrations/factory_prof_spec.rb index 0d6867b7..44ba8b73 100644 --- a/spec/integrations/factory_prof_spec.rb +++ b/spec/integrations/factory_prof_spec.rb @@ -13,16 +13,13 @@ expect(output).to match( / user\s+16\s+8\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n - \s+.with_posts\[name\]\s+1\s+1\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n - \s+\[name\]\s+1\s+1\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n \s+post\s+10\s+6\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n - \s+\[user\]\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s /x ) end specify "simple printer with variations", :aggregate_failures do - output = run_rspec("factory_prof_with_variations", env: {"FPROF" => "1", "FPROF_VARIATIONS_LIMIT" => "2"}) + output = run_rspec("factory_prof_with_variations", env: {"FPROF" => "1", "FPROF_VARS" => "1", "FPROF_VARIATIONS_LIMIT" => "2"}) expect(output).to include("FactoryProf enabled (simple mode)") diff --git a/spec/test_prof/factory_prof_spec.rb b/spec/test_prof/factory_prof_spec.rb index 4e761f11..efd39958 100644 --- a/spec/test_prof/factory_prof_spec.rb +++ b/spec/test_prof/factory_prof_spec.rb @@ -5,6 +5,7 @@ TestProf::FactoryProf.configure do |config| # turn on stacks collection config.mode = :flamegraph + config.include_variations = true end describe TestProf::FactoryProf, :transactional do From ac88eb8d646ee1d731457cd3c8116698a34456da Mon Sep 17 00:00:00 2001 From: John Kelly Date: Wed, 8 Feb 2023 11:03:20 +0000 Subject: [PATCH 155/194] Add FactoryBot.get_factory_default --- docs/recipes/factory_default.md | 4 +++- lib/test_prof/factory_default.rb | 14 ++++++++++---- spec/test_prof/factory_default_spec.rb | 13 +++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index 1310a9fa..2230a2c4 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -94,7 +94,7 @@ In your `spec_helper.rb`: require "test_prof/recipes/rspec/factory_default" ``` -This adds two new methods to FactoryBot: +This adds three new methods to FactoryBot: - `FactoryBot#set_factory_default(factory, object)` – use the `object` as default for associations built with `factory` @@ -108,6 +108,8 @@ before { FactoryBot.set_factory_default(:user, user) } - `FactoryBot#create_default(factory, *args)` – is a shortcut for `create` + `set_factory_default`. +- `FactoryBot#get_factory_default(factory, *args)` – retrieves the default value for `factory` + **IMPORTANT:** Defaults are **cleaned up after each example** by default (i.e., when using `test_prof/recipes/rspec/factory_default`). ### Using with `before_all` / `let_it_be` diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 64ce7ab5..e303b07c 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -168,6 +168,10 @@ def set_factory_default(name, obj, preserve_traits: FactoryDefault.config.preser ) end + def get_factory_default(name, *args) + FactoryDefault.get(name, traits = args, overrides = args.extract_options!, write_stats = false) + end + def skip_factory_default(&block) FactoryDefault.disable!(&block) end @@ -236,7 +240,7 @@ def register(name, obj, **options) obj end - def get(name, traits = nil, overrides = nil) + def get(name, traits = nil, overrides = nil, write_stats = true) return unless enabled? record = store[name] @@ -248,7 +252,7 @@ def get(name, traits = nil, overrides = nil) traits = nil end - stats[name][:miss] += 1 + stats[name][:miss] += 1 if write_stats if traits && !traits.empty? && record[:preserve_traits] return @@ -263,8 +267,10 @@ def get(name, traits = nil, overrides = nil) end end - stats[name][:miss] -= 1 - stats[name][:hit] += 1 + if write_stats + stats[name][:miss] -= 1 + stats[name][:hit] += 1 + end if record[:context] && (record[:context] != :example) object.refind diff --git a/spec/test_prof/factory_default_spec.rb b/spec/test_prof/factory_default_spec.rb index e25d0f0e..6fedcc13 100644 --- a/spec/test_prof/factory_default_spec.rb +++ b/spec/test_prof/factory_default_spec.rb @@ -26,23 +26,29 @@ it "re-uses the same default record" do post = TestProf::FactoryBot.create(:post) + expect(TestProf::FactoryBot.get_factory_default(:user)).to eq user expect(post.user).to eq user end it "re-uses default record independently of traits" do post = TestProf::FactoryBot.create(:post, :with_traited_user) + expect(TestProf::FactoryBot.get_factory_default(:user)).to eq user expect(post.user).to eq user end it "re-uses default record independently of attributes" do post = TestProf::FactoryBot.create(:post, :with_tagged_user) + expect(TestProf::FactoryBot.get_factory_default(:user)).to eq user expect(post.user).to eq user end specify ".disable!(&block)" do post = TestProf::FactoryBot.skip_factory_default { TestProf::FactoryBot.create(:post) } + + # get_factory_default should ignore disabled + expect(TestProf::FactoryBot.get_factory_default(:user)).to eq user expect(post.user).not_to eq(user) end @@ -53,7 +59,10 @@ post = TestProf::FactoryBot.create_default(:post) post_traited = TestProf::FactoryBot.create(:post, :with_traited_user) + expect(TestProf::FactoryBot.get_factory_default(:post).user).to eq user expect(post.user).to eq user + + expect(TestProf::FactoryBot.get_factory_default(:post, :with_traited_user)).to eq nil expect(post_traited.user).not_to eq user end @@ -64,7 +73,9 @@ post = TestProf::FactoryBot.create_default(:post) post_traited = TestProf::FactoryBot.create(:post, :with_traited_user) + expect(TestProf::FactoryBot.get_factory_default(:post).user).to eq user expect(post.user).to eq user + expect(TestProf::FactoryBot.get_factory_default(:user, :traited)).to eq traited_user expect(post_traited.user).to eq traited_user end end @@ -76,6 +87,7 @@ it "ignores default when explicit attributes don't match" do post = TestProf::FactoryBot.create(:post, :with_tagged_user) + expect(TestProf::FactoryBot.get_factory_default(:user, tag: "some tag")).to eq nil expect(post.user).not_to eq user end @@ -84,6 +96,7 @@ post = TestProf::FactoryBot.create(:post, :with_tagged_user) + expect(TestProf::FactoryBot.get_factory_default(:user, tag: "some tag")).to eq user expect(post.user).to eq user end end From 7b2356c5fb22c382974fb8fe9e9fec5b927bb434 Mon Sep 17 00:00:00 2001 From: John Kelly Date: Wed, 8 Feb 2023 17:42:47 +0000 Subject: [PATCH 156/194] Fixes --- lib/test_prof/factory_default.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index e303b07c..a0dba42c 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -169,7 +169,7 @@ def set_factory_default(name, obj, preserve_traits: FactoryDefault.config.preser end def get_factory_default(name, *args) - FactoryDefault.get(name, traits = args, overrides = args.extract_options!, write_stats = false) + FactoryDefault.get(name, args, args.extract_options!, false) end def skip_factory_default(&block) @@ -268,8 +268,8 @@ def get(name, traits = nil, overrides = nil, write_stats = true) end if write_stats - stats[name][:miss] -= 1 - stats[name][:hit] += 1 + stats[name][:miss] -= 1 + stats[name][:hit] += 1 end if record[:context] && (record[:context] != :example) From f29ef968ee6635e8cc72e194f897b30f706aedf5 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 5 Jun 2024 11:31:45 -0700 Subject: [PATCH 157/194] Improve set_factory_default/get_factory_default --- CHANGELOG.md | 3 +++ docs/recipes/factory_default.md | 19 +++++++++++++++---- lib/test_prof/factory_default.rb | 13 +++++++------ .../factory_default/factory_bot_patch.rb | 2 +- spec/test_prof/factory_default_spec.rb | 6 +++++- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59dd30ff..c1db8e35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- FactoryDefault: Add `#get_factory_default`. [[@john-h-k][]] + - Add variations information to FactorProf reports. ([@lHydra][]) Get info on traits/overrides used by running `FPROF=1 FPROF_VARS=1 `. @@ -421,3 +423,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@uzushino]: https://github.com/uzushino [@lioneldebauge]: https://github.com/lioneldebauge [@lHydra]: https://github.com/lHydra +[@john-h-k]: https://github.com/john-h-k diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index 2230a2c4..ee798908 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -94,9 +94,9 @@ In your `spec_helper.rb`: require "test_prof/recipes/rspec/factory_default" ``` -This adds three new methods to FactoryBot: +This adds the following methods to FactoryBot: -- `FactoryBot#set_factory_default(factory, object)` – use the `object` as default for associations built with `factory` +- `FactoryBot#set_factory_default(factory, object)` – use the `object` as default for associations built with `factory`. Example: @@ -104,11 +104,22 @@ Example: let(:user) { create(:user) } before { FactoryBot.set_factory_default(:user, user) } + +# You can also set the default factory with traits +FactoryBot.set_factory_default([:user, :amdin], admin) + +# Or (since v1.4) +FactoryBot.set_factory_default(:user, :amdin, admin) ``` -- `FactoryBot#create_default(factory, *args)` – is a shortcut for `create` + `set_factory_default`. +- `FactoryBot#create_default(...)` – is a shortcut for `create` + `set_factory_default`. -- `FactoryBot#get_factory_default(factory, *args)` – retrieves the default value for `factory` +- `FactoryBot#get_factory_default(factory)` – retrieves the default value for `factory` (since v1.4). + +```rb +# This method also supports traits +admin = FactoryBot.get_factory_default(:user, :amdin) +``` **IMPORTANT:** Defaults are **cleaned up after each example** by default (i.e., when using `test_prof/recipes/rspec/factory_default`). diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index a0dba42c..6fd91dd0 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -159,7 +159,8 @@ def create_default(name, *args, &block) set_factory_default(name, obj, **default_options) end - def set_factory_default(name, obj, preserve_traits: FactoryDefault.config.preserve_traits, preserve_attributes: FactoryDefault.config.preserve_attributes, **other) + def set_factory_default(*name, obj, preserve_traits: FactoryDefault.config.preserve_traits, preserve_attributes: FactoryDefault.config.preserve_attributes, **other) + name = name.first if name.size == 1 FactoryDefault.register( name, obj, preserve_traits: preserve_traits, @@ -168,8 +169,8 @@ def set_factory_default(name, obj, preserve_traits: FactoryDefault.config.preser ) end - def get_factory_default(name, *args) - FactoryDefault.get(name, args, args.extract_options!, false) + def get_factory_default(name, *traits, **overrides) + FactoryDefault.get(name, traits, overrides, skip_stats: true) end def skip_factory_default(&block) @@ -240,7 +241,7 @@ def register(name, obj, **options) obj end - def get(name, traits = nil, overrides = nil, write_stats = true) + def get(name, traits = nil, overrides = nil, skip_stats: false) return unless enabled? record = store[name] @@ -252,7 +253,7 @@ def get(name, traits = nil, overrides = nil, write_stats = true) traits = nil end - stats[name][:miss] += 1 if write_stats + stats[name][:miss] += 1 unless skip_stats if traits && !traits.empty? && record[:preserve_traits] return @@ -267,7 +268,7 @@ def get(name, traits = nil, overrides = nil, write_stats = true) end end - if write_stats + unless skip_stats stats[name][:miss] -= 1 stats[name][:hit] += 1 end diff --git a/lib/test_prof/factory_default/factory_bot_patch.rb b/lib/test_prof/factory_default/factory_bot_patch.rb index 32d83991..b14b5898 100644 --- a/lib/test_prof/factory_default/factory_bot_patch.rb +++ b/lib/test_prof/factory_default/factory_bot_patch.rb @@ -12,7 +12,7 @@ module RunnerExt module StrategyExt def association(runner) - FactoryDefault.get(runner.name, runner.traits, runner.overrides) || + FactoryDefault.get(runner.name, runner.traits, runner.overrides, **{}) || FactoryDefault.profiler.instrument(runner.name, runner.traits, runner.overrides) { super } end end diff --git a/spec/test_prof/factory_default_spec.rb b/spec/test_prof/factory_default_spec.rb index 6fedcc13..cd1e3880 100644 --- a/spec/test_prof/factory_default_spec.rb +++ b/spec/test_prof/factory_default_spec.rb @@ -35,6 +35,7 @@ expect(TestProf::FactoryBot.get_factory_default(:user)).to eq user expect(post.user).to eq user + expect(TestProf::FactoryBot.get_factory_default(:user, :traited)).to eq user end it "re-uses default record independently of attributes" do @@ -67,7 +68,10 @@ end context "when has default with the trait" do - let!(:traited_user) { TestProf::FactoryBot.create_default(:user, :traited) } + let!(:traited_user) do + user = TestProf::FactoryBot.create(:user, :traited) + TestProf::FactoryBot.set_factory_default(:user, :traited, user) + end it "re-uses default record for this trait" do post = TestProf::FactoryBot.create_default(:post) From f4353b98b0e54b8ddd6e855f4a64d8045b901c27 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 5 Jun 2024 14:10:29 -0700 Subject: [PATCH 158/194] chore: drop Ruby <2.7 and Rails <6 support --- .github/workflows/rspec.yml | 6 ------ CHANGELOG.md | 2 ++ README.md | 4 ++-- gemfiles/activerecord5.gemfile | 12 ------------ lib/test_prof/event_prof/monitor.rb | 13 +++---------- test-prof.gemspec | 2 +- 6 files changed, 8 insertions(+), 31 deletions(-) delete mode 100644 gemfiles/activerecord5.gemfile diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index d6549b91..ae5bf99b 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -55,12 +55,6 @@ jobs: - ruby: 2.7 gemfile: "gemfiles/activerecord60.gemfile" db: "postgres" - - ruby: 2.6 - gemfile: "gemfiles/activerecord5.gemfile" - db: "sqlite-file" - - ruby: 2.5 - gemfile: "gemfiles/activerecord5.gemfile" - db: "sqlite" services: postgres: image: postgres:latest diff --git a/CHANGELOG.md b/CHANGELOG.md index c1db8e35..55793f6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Drop support for **Ruby <2.7** and **Rails <6**. + - FactoryDefault: Add `#get_factory_default`. [[@john-h-k][]] - Add variations information to FactorProf reports. ([@lHydra][]) diff --git a/README.md b/README.md index ba30224f..6774ef87 100644 --- a/README.md +++ b/README.md @@ -83,9 +83,9 @@ And that's it) Supported Ruby versions: -- Ruby (MRI) >= 2.5.0 (**NOTE:** for Ruby 2.2 use TestProf < 0.7.0, Ruby 2.3 use TestProf ~> 0.7.0, Ruby 2.4 use TestProf <0.12.0) +- Ruby (MRI) >= 2.7.0 (**NOTE:** for Ruby 2.2 use TestProf < 0.7.0, Ruby 2.3 use TestProf ~> 0.7.0, Ruby 2.4 use TestProf <0.12.0, Ruby 2.5-2.6 use TestProf < 1.3) -- JRuby >= 9.1.0.0 (**NOTE:** refinements-dependent features might require 9.2.7+) +- JRuby >= 9.3.0 Supported RSpec version (for RSpec features only): >= 3.5.0 (for older RSpec versions use TestProf < 0.8.0). diff --git a/gemfiles/activerecord5.gemfile b/gemfiles/activerecord5.gemfile deleted file mode 100644 index 0803da34..00000000 --- a/gemfiles/activerecord5.gemfile +++ /dev/null @@ -1,12 +0,0 @@ -source 'https://rubygems.org' - -gem "activerecord", "~> 5.0" -gem "activerecord-import" -gem "factory_bot", "~> 5.0" -gem "fabrication" -gem "sqlite3", "~> 1.4" -gem "sidekiq", "~> 6.0" -gem "timecop", "~> 0.9.1" -gem "pg" - -gemspec path: '..' diff --git a/lib/test_prof/event_prof/monitor.rb b/lib/test_prof/event_prof/monitor.rb index afa932e4..3a811670 100644 --- a/lib/test_prof/event_prof/monitor.rb +++ b/lib/test_prof/event_prof/monitor.rb @@ -48,16 +48,9 @@ def call(mod, event, *mids, guard: nil, top_level: false) patch = Module.new do mids.each do |mid| - if RUBY_VERSION >= "2.7.0" - define_method(mid) do |*args, **kwargs, &block| - next super(*args, **kwargs, &block) unless guard.nil? || instance_exec(*args, **kwargs, &guard) - tracker.track { super(*args, **kwargs, &block) } - end - else - define_method(mid) do |*args, &block| - next super(*args, &block) unless guard.nil? || instance_exec(*args, &guard) - tracker.track { super(*args, &block) } - end + define_method(mid) do |*args, **kwargs, &block| + next super(*args, **kwargs, &block) unless guard.nil? || instance_exec(*args, **kwargs, &guard) + tracker.track { super(*args, **kwargs, &block) } end end end diff --git a/test-prof.gemspec b/test-prof.gemspec index d6b20e54..f17018a2 100644 --- a/test-prof.gemspec +++ b/test-prof.gemspec @@ -31,7 +31,7 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] - spec.required_ruby_version = ">= 2.5.0" + spec.required_ruby_version = ">= 2.7.0" spec.add_development_dependency "bundler", ">= 1.16" spec.add_development_dependency "rake", "~> 13.0" From 58f38d0676350f7407ecf7d33e98a0be3bfa5293 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 6 Jun 2024 09:08:07 -0700 Subject: [PATCH 159/194] tests: test database state after before_all --- spec/integrations/fixtures/rspec/before_all_fixture.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/integrations/fixtures/rspec/before_all_fixture.rb b/spec/integrations/fixtures/rspec/before_all_fixture.rb index 9f3f330d..d9123e75 100644 --- a/spec/integrations/fixtures/rspec/before_all_fixture.rb +++ b/spec/integrations/fixtures/rspec/before_all_fixture.rb @@ -78,6 +78,10 @@ specify { expect(User.count).to eq 1 } end + + context "after before_all with thread the database must be clean" do + specify { expect(User.count).to eq 0 } + end end describe "User", :transactional, :with_user do From 8fe54fae98f103015a252f9c86fde3f87ab27ee7 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 6 Jun 2024 09:28:01 -0700 Subject: [PATCH 160/194] tests: add before_all + fixtures + threads examples --- spec/integrations/before_all_spec.rb | 2 +- .../rspec/before_all_rails_fixtures_fixture.rb | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/spec/integrations/before_all_spec.rb b/spec/integrations/before_all_spec.rb index af352c09..b00caf6d 100644 --- a/spec/integrations/before_all_spec.rb +++ b/spec/integrations/before_all_spec.rb @@ -31,7 +31,7 @@ it "works with Rails fixtures" do output = run_rspec("before_all_rails_fixtures", success: true) - expect(output).to include("3 examples, 0 failures") + expect(output).to include("examples, 0 failures") end specify "database connection" do diff --git a/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb b/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb index abeed370..5e7d61c4 100644 --- a/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb +++ b/spec/integrations/fixtures/rspec/before_all_rails_fixtures_fixture.rb @@ -51,4 +51,20 @@ expect(Post.count).to eq 0 end end + + context "before_all with thread" do + before_all do + Thread.new do + TestProf::FactoryBot.create(:user, tag: :thread) + end.join + end + + specify { expect(User.find_by(tag: :thread)).to be_a(User) } + + specify { expect(User.count).to eq 2 } + end + + context "after before_all with thread the database must be clean" do + specify { expect(User.count).to eq 1 } + end end From c390478394a0f0e422c1e9ae3aa736998455e1d5 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 6 Jun 2024 10:03:51 -0700 Subject: [PATCH 161/194] chore: ActiveRecord 7.2 compatibility --- .github/workflows/rspec.yml | 3 + gemfiles/activerecord72.gemfile | 11 ++ gemfiles/railsmaster.gemfile | 4 +- .../before_all/adapters/active_record.rb | 134 ++++++++++++------ lib/test_prof/factory_bot.rb | 2 + .../before_all/adapters/active_record_spec.rb | 2 +- 6 files changed, 107 insertions(+), 49 deletions(-) create mode 100644 gemfiles/activerecord72.gemfile diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ae5bf99b..b476f68e 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -34,6 +34,9 @@ jobs: - ruby: 3.3 gemfile: "Gemfile" db: "sqlite" + - ruby: 3.3 + gemfile: "gemfiles/activerecord72.gemfile" + db: "sqlite-file" - ruby: 3.2 gemfile: "gemfiles/activerecord7.gemfile" db: "sqlite" diff --git a/gemfiles/activerecord72.gemfile b/gemfiles/activerecord72.gemfile new file mode 100644 index 00000000..80304143 --- /dev/null +++ b/gemfiles/activerecord72.gemfile @@ -0,0 +1,11 @@ +source 'https://rubygems.org' + +gem "rails", "7.2.0.beta2" +gem "factory_bot" +gem "fabrication" +gem "sqlite3", "~> 2.0" +gem "sidekiq" +gem "timecop" +gem "pg" + +gemspec path: '..' diff --git a/gemfiles/railsmaster.gemfile b/gemfiles/railsmaster.gemfile index 72b1720a..99d31498 100644 --- a/gemfiles/railsmaster.gemfile +++ b/gemfiles/railsmaster.gemfile @@ -1,10 +1,10 @@ source "https://rubygems.org" -gem "rails" +gem "rails", github: "rails/rails", branch: "main" gem "fabrication" gem "factory_bot", "~> 5.0" -gem "sqlite3", "~> 1.4" +gem "sqlite3", "~> 2.0" gem "sidekiq", "~> 4.0" gem "timecop", "~> 0.9.1" gem "pg" diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 7079c7ee..daa8a171 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -8,44 +8,86 @@ module ActiveRecord POOL_ARGS = ((::ActiveRecord::VERSION::MAJOR > 6) ? [:writing] : []).freeze class << self - def all_connections - @all_connections ||= if ::ActiveRecord::Base.respond_to? :connects_to - ::ActiveRecord::Base.connection_handler.connection_pool_list(*POOL_ARGS).filter_map { |pool| - begin - pool.connection - rescue *pool_connection_errors => error - log_pool_connection_error(pool, error) - nil + if ::ActiveRecord::Base.connection.pool.respond_to?(:pin_connection!) + ::ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(Module.new do + # FIXME: Why `@pinned_connection = nil; super` doesn't work? + def pin_connection!(lock_thread) # :nodoc: + # raise "There is already a pinned connection" if @pinned_connection + + @pinned_connection = connection_lease&.connection || checkout + # Any leased connection must be in @connections otherwise + # some methods like #connected? won't behave correctly + unless @connections.include?(@pinned_connection) + @connections << @pinned_connection end - } - else - Array.wrap(::ActiveRecord::Base.connection) + + @pinned_connection.lock_thread = ActiveSupport::IsolatedExecutionState.context if lock_thread + @pinned_connection.verify! # eagerly validate the connection + @pinned_connection.begin_transaction joinable: false, _lazy: false + end + end) + + def begin_transaction + ::ActiveRecord::Base.connection_handler.connection_pool_list(*POOL_ARGS).each do |pool| + pool.pin_connection!(true) + end end - end - def pool_connection_errors - @pool_connection_errors ||= [] - end + def rollback_transaction + ::ActiveRecord::Base.connection_handler.connection_pool_list(*POOL_ARGS).each do |pool| + # If it has pinned connection, we must unpin it; + # if it has been already unpinned, just rollback + next pool.unpin_connection! if pool.instance_variable_get(:@pinned_connection) - def log_pool_connection_error(pool, error) - warn "Could not connect to pool #{pool.connection_class.name}. #{error.class}: #{error.message}" - end + connection = pool.lease_connection + if connection.open_transactions.zero? + warn "!!! before_all transaction has been already rollbacked and " \ + "could work incorrectly" + next + end + connection.rollback_transaction + end + end + else + def all_connections + @all_connections ||= if ::ActiveRecord::Base.respond_to? :connects_to + ::ActiveRecord::Base.connection_handler.connection_pool_list(*POOL_ARGS).filter_map { |pool| + begin + pool.connection + rescue *pool_connection_errors => error + log_pool_connection_error(pool, error) + nil + end + } + else + Array.wrap(::ActiveRecord::Base.connection) + end + end - def begin_transaction - @all_connections = nil - all_connections.each do |connection| - connection.begin_transaction(joinable: false) + def pool_connection_errors + @pool_connection_errors ||= [] + end + + def log_pool_connection_error(pool, error) + warn "Could not connect to pool #{pool.connection_class.name}. #{error.class}: #{error.message}" + end + + def begin_transaction + @all_connections = nil + all_connections.each do |connection| + connection.begin_transaction(joinable: false) + end end - end - def rollback_transaction - all_connections.each do |connection| - if connection.open_transactions.zero? - warn "!!! before_all transaction has been already rollbacked and " \ - "could work incorrectly" - next + def rollback_transaction + all_connections.each do |connection| + if connection.open_transactions.zero? + warn "!!! before_all transaction has been already rollbacked and " \ + "could work incorrectly" + next + end + connection.rollback_transaction end - connection.rollback_transaction end end @@ -67,23 +109,23 @@ def setup_fixtures(test_object) end end - # avoid instance variable collisions with cats - PREFIX_RESTORE_LOCK_THREAD = "@😺" - - configure do |config| - # Make sure ActiveRecord uses locked thread. - # It only gets locked in `before` / `setup` hook, - # thus using thread in `before_all` (e.g. ActiveJob async adapter) - # might lead to leaking connections - config.before(:begin) do - next unless ::ActiveRecord::Base.connection.pool.respond_to?(:lock_thread=) - instance_variable_set("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread", ::ActiveRecord::Base.connection.pool.instance_variable_get(:@lock_thread)) unless instance_variable_defined? "#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread" - ::ActiveRecord::Base.connection.pool.lock_thread = true - end + unless ::ActiveRecord::Base.connection.pool.respond_to?(:pin_connection!) + # avoid instance variable collisions with cats + PREFIX_RESTORE_LOCK_THREAD = "@😺" - config.after(:rollback) do - next unless ::ActiveRecord::Base.connection.pool.respond_to?(:lock_thread=) - ::ActiveRecord::Base.connection.pool.lock_thread = instance_variable_get("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread") + configure do |config| + # Make sure ActiveRecord uses locked thread. + # It only gets locked in `before` / `setup` hook, + # thus using thread in `before_all` (e.g. ActiveJob async adapter) + # might lead to leaking connections + config.before(:begin) do + instance_variable_set("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread", ::ActiveRecord::Base.connection.pool.instance_variable_get(:@lock_thread)) unless instance_variable_defined? "#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread" + ::ActiveRecord::Base.connection.pool.lock_thread = true + end + + config.after(:rollback) do + ::ActiveRecord::Base.connection.pool.lock_thread = instance_variable_get("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread") + end end end end diff --git a/lib/test_prof/factory_bot.rb b/lib/test_prof/factory_bot.rb index 2a6946aa..7723c6ae 100644 --- a/lib/test_prof/factory_bot.rb +++ b/lib/test_prof/factory_bot.rb @@ -3,6 +3,8 @@ module TestProf # :nodoc: all FACTORY_GIRL_NAMES = {"factory_bot" => "::FactoryBot", "factory_girl" => "::FactoryGirl"}.freeze + TestProf.require("active_support/inflector") + FACTORY_GIRL_NAMES.find do |name, cname| TestProf.require(name) do TestProf::FactoryBot = Object.const_get(cname) diff --git a/spec/test_prof/before_all/adapters/active_record_spec.rb b/spec/test_prof/before_all/adapters/active_record_spec.rb index f2b85df8..64f7b70a 100644 --- a/spec/test_prof/before_all/adapters/active_record_spec.rb +++ b/spec/test_prof/before_all/adapters/active_record_spec.rb @@ -18,7 +18,7 @@ def self.configure subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.begin_transaction } it "calls begin_transaction on all available connections" do - expect(connection).to receive(:begin_transaction).with(joinable: false) + expect(connection).to receive(:begin_transaction).with(a_hash_including(joinable: false)) subject end From 2209fd7d863c884649b833eaf22b288cd3fe499e Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Sat, 8 Jun 2024 11:24:45 -0700 Subject: [PATCH 162/194] chore: upgrade before_all to use upcoming pinning API See https://github.com/rails/rails/pull/50999#issuecomment-2150906497 --- .../before_all/adapters/active_record.rb | 34 +---------- .../before_all/adapters/active_record_spec.rb | 60 ++++++++++++------- 2 files changed, 41 insertions(+), 53 deletions(-) diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index daa8a171..5b249db3 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -9,43 +9,15 @@ module ActiveRecord class << self if ::ActiveRecord::Base.connection.pool.respond_to?(:pin_connection!) - ::ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(Module.new do - # FIXME: Why `@pinned_connection = nil; super` doesn't work? - def pin_connection!(lock_thread) # :nodoc: - # raise "There is already a pinned connection" if @pinned_connection - - @pinned_connection = connection_lease&.connection || checkout - # Any leased connection must be in @connections otherwise - # some methods like #connected? won't behave correctly - unless @connections.include?(@pinned_connection) - @connections << @pinned_connection - end - - @pinned_connection.lock_thread = ActiveSupport::IsolatedExecutionState.context if lock_thread - @pinned_connection.verify! # eagerly validate the connection - @pinned_connection.begin_transaction joinable: false, _lazy: false - end - end) - def begin_transaction - ::ActiveRecord::Base.connection_handler.connection_pool_list(*POOL_ARGS).each do |pool| + ::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).each do |pool| pool.pin_connection!(true) end end def rollback_transaction - ::ActiveRecord::Base.connection_handler.connection_pool_list(*POOL_ARGS).each do |pool| - # If it has pinned connection, we must unpin it; - # if it has been already unpinned, just rollback - next pool.unpin_connection! if pool.instance_variable_get(:@pinned_connection) - - connection = pool.lease_connection - if connection.open_transactions.zero? - warn "!!! before_all transaction has been already rollbacked and " \ - "could work incorrectly" - next - end - connection.rollback_transaction + ::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).each do |pool| + pool.unpin_connection! end end else diff --git a/spec/test_prof/before_all/adapters/active_record_spec.rb b/spec/test_prof/before_all/adapters/active_record_spec.rb index 64f7b70a..705fe5e0 100644 --- a/spec/test_prof/before_all/adapters/active_record_spec.rb +++ b/spec/test_prof/before_all/adapters/active_record_spec.rb @@ -11,44 +11,60 @@ def self.configure describe TestProf::BeforeAll::Adapters::ActiveRecord do context "when using single database", skip: (multi_db? ? "Using multiple databases" : nil) do - let(:connection_pool) { ApplicationRecord } + let(:connection_pool) { ApplicationRecord.connection_pool } let(:connection) { connection_pool.connection } describe ".begin_transaction" do subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.begin_transaction } - it "calls begin_transaction on all available connections" do - expect(connection).to receive(:begin_transaction).with(a_hash_including(joinable: false)) + if ::ActiveRecord::Base.connection.pool.respond_to?(:pin_connection!) + it "calls pin_connection! on all available connections" do + expect(connection_pool).to receive(:pin_connection!).with(true) - subject + subject + end + else + it "calls begin_transaction on all available connections" do + expect(connection).to receive(:begin_transaction).with(a_hash_including(joinable: false)) + + subject + end end end describe ".rollback_transaction" do subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.rollback_transaction } - context "when not all connections have started a transaction" do - before do - # Ensure no transactions are open due to randomization of specs - connection.rollback_transaction unless connection.open_transactions.zero? - end + if ::ActiveRecord::Base.connection.pool.respond_to?(:pin_connection!) + it "calls unpin_connection! on all available connections" do + expect(connection_pool).to receive(:unpin_connection!) - it "warns when connection does not have open transaction" do - expect { subject }.to output( - /!!! before_all transaction has been already rollbacked and could work incorrectly\n/ - ).to_stderr + subject end - end - - context "when the connection is a transaction" do - before do - connection.begin_transaction - allow(connection).to receive(:rollback_transaction).and_call_original + else + context "when not all connections have started a transaction" do + before do + # Ensure no transactions are open due to randomization of specs + connection.rollback_transaction unless connection.open_transactions.zero? + end + + it "warns when connection does not have open transaction" do + expect { subject }.to output( + /!!! before_all transaction has been already rollbacked and could work incorrectly\n/ + ).to_stderr + end end - it "calls rollback_transaction on all available connections" do - subject - expect(connection).to have_received(:rollback_transaction) + context "when the connection is a transaction" do + before do + connection.begin_transaction + allow(connection).to receive(:rollback_transaction).and_call_original + end + + it "calls rollback_transaction on all available connections" do + subject + expect(connection).to have_received(:rollback_transaction) + end end end end From 78880bae013afb3eb57b3fb850a6c3c7670b9715 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Sat, 8 Jun 2024 12:27:37 -0700 Subject: [PATCH 163/194] ci: test Rails 7.2 against stable branch for now --- gemfiles/activerecord72.gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gemfiles/activerecord72.gemfile b/gemfiles/activerecord72.gemfile index 80304143..bc7e7243 100644 --- a/gemfiles/activerecord72.gemfile +++ b/gemfiles/activerecord72.gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem "rails", "7.2.0.beta2" +gem "rails", github: "rails/rails", branch: "7-2-stable" gem "factory_bot" gem "fabrication" gem "sqlite3", "~> 2.0" From 1b762042ea1fcf0f7ebbb0f829a2b57efeae452a Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 13 Jun 2024 16:35:04 -0700 Subject: [PATCH 164/194] Bump 1.4.0.rc.1 --- lib/test_prof/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 8f50d81e..3419e5fd 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.3.3" + VERSION = "1.4.0.rc.1" end From b891e72de01efde9e099c538ed79f665dfc9655f Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 28 Jun 2024 17:29:37 -0700 Subject: [PATCH 165/194] style: fix new rubocop offense --- lib/test_prof/recipes/minitest/before_all.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/recipes/minitest/before_all.rb b/lib/test_prof/recipes/minitest/before_all.rb index 25bb1d47..5d88449f 100644 --- a/lib/test_prof/recipes/minitest/before_all.rb +++ b/lib/test_prof/recipes/minitest/before_all.rb @@ -114,7 +114,7 @@ def included(base) base.singleton_class.prepend(Module.new do def parallelize(workers: :number_of_processors, with: :processes) # super.parallelize returns nil when no parallelization is set up - if super(workers: workers, with: with).nil? + if super.nil? return end From 0259a76d2242a63d01556100ee208d29eaf1429c Mon Sep 17 00:00:00 2001 From: Ivan Naumov <6850463+iwdt@users.noreply.github.com> Date: Sun, 14 Jul 2024 23:31:53 +0300 Subject: [PATCH 166/194] Fixed typo in documentation about factory default --- docs/recipes/factory_default.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index ee798908..8eae2647 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -106,10 +106,10 @@ let(:user) { create(:user) } before { FactoryBot.set_factory_default(:user, user) } # You can also set the default factory with traits -FactoryBot.set_factory_default([:user, :amdin], admin) +FactoryBot.set_factory_default([:user, :admin], admin) # Or (since v1.4) -FactoryBot.set_factory_default(:user, :amdin, admin) +FactoryBot.set_factory_default(:user, :admin, admin) ``` - `FactoryBot#create_default(...)` – is a shortcut for `create` + `set_factory_default`. @@ -118,7 +118,7 @@ FactoryBot.set_factory_default(:user, :amdin, admin) ```rb # This method also supports traits -admin = FactoryBot.get_factory_default(:user, :amdin) +admin = FactoryBot.get_factory_default(:user, :admin) ``` **IMPORTANT:** Defaults are **cleaned up after each example** by default (i.e., when using `test_prof/recipes/rspec/factory_default`). From 9ab4368f09a777ced33e2a755036d7efa36bb86e Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 23 Jul 2024 09:12:57 +0300 Subject: [PATCH 167/194] feat: factory default for fabrication --- CHANGELOG.md | 2 + docs/recipes/factory_default.md | 26 ++++++-- lib/test_prof/factory_default.rb | 45 ++----------- .../factory_default/fabrication_patch.rb | 60 +++++++++++++++++ .../factory_default/factory_bot_patch.rb | 65 ++++++++++++++++--- spec/integrations/factory_default_spec.rb | 16 +++++ .../factory_default_fabrication_fixture.rb | 61 +++++++++++++++++ spec/support/ar_models.rb | 4 ++ 8 files changed, 224 insertions(+), 55 deletions(-) create mode 100644 lib/test_prof/factory_default/fabrication_patch.rb create mode 100644 spec/integrations/fixtures/rspec/factory_default_fabrication_fixture.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 55793f6c..67050b58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- FactoryDefault: add Fabrication support. ([@palkan][]) + - Drop support for **Ruby <2.7** and **Rails <6**. - FactoryDefault: Add `#get_factory_default`. [[@john-h-k][]] diff --git a/docs/recipes/factory_default.md b/docs/recipes/factory_default.md index 8eae2647..832db42e 100644 --- a/docs/recipes/factory_default.md +++ b/docs/recipes/factory_default.md @@ -2,8 +2,6 @@ _FactoryDefault_ aims to help you cope with _factory cascades_ (see [FactoryProf](../profilers/factory_prof.md)) by reusing associated records. -**NOTE**. Only works with FactoryGirl/FactoryBot. - It can be very useful when you're working on a typical SaaS application (or other hierarchical data). Consider an example. Assume we have the following factories: @@ -28,6 +26,19 @@ factory :task do end ``` +Or in case of Fabrication: + +```ruby +Fabricator(:account) do +end + +Fabricator(:user) do + account +end + +# etc. +``` + And we want to test the `Task` model: ```ruby @@ -94,9 +105,9 @@ In your `spec_helper.rb`: require "test_prof/recipes/rspec/factory_default" ``` -This adds the following methods to FactoryBot: +This adds the following methods to FactoryBot and/or Fabrication: -- `FactoryBot#set_factory_default(factory, object)` – use the `object` as default for associations built with `factory`. +- `FactoryBot#set_factory_default(factory, object)` / `Fabricate.set_fabricate_default(factory, object)` – use the `object` as default for associations built with `factory`. Example: @@ -110,11 +121,14 @@ FactoryBot.set_factory_default([:user, :admin], admin) # Or (since v1.4) FactoryBot.set_factory_default(:user, :admin, admin) + +# You can also register a default record for specific attribute overrides +Fabricate.set_fabricate_default(:post, post, state: "draft") ``` -- `FactoryBot#create_default(...)` – is a shortcut for `create` + `set_factory_default`. +- `FactoryBot#create_default(...)` / `Fabricate.create_default(...)` – is a shortcut for `create` + `set_factory_default`. -- `FactoryBot#get_factory_default(factory)` – retrieves the default value for `factory` (since v1.4). +- `FactoryBot#get_factory_default(factory)` / `Fabricate.get_fabricate_default(factory)` – retrieves the default value for `factory` (since v1.4). ```rb # This method also supports traits diff --git a/lib/test_prof/factory_default.rb b/lib/test_prof/factory_default.rb index 6fd91dd0..4ade23c7 100644 --- a/lib/test_prof/factory_default.rb +++ b/lib/test_prof/factory_default.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true require "test_prof/core" -require "test_prof/factory_bot" + require "test_prof/factory_default/factory_bot_patch" +require "test_prof/factory_default/fabrication_patch" + require "test_prof/ext/float_duration" require "test_prof/ext/active_record_refind" if defined?(::ActiveRecord::Base) @@ -144,40 +146,6 @@ def print_report end end - module DefaultSyntax # :nodoc: - def create_default(name, *args, &block) - options = args.extract_options! - default_options = {} - default_options[:preserve_traits] = options.delete(:preserve_traits) if options.key?(:preserve_traits) - default_options[:preserve_attributes] = options.delete(:preserve_attributes) if options.key?(:preserve_attributes) - - obj = TestProf::FactoryBot.create(name, *args, options, &block) - - # Factory with traits - name = [name, *args] if args.any? - - set_factory_default(name, obj, **default_options) - end - - def set_factory_default(*name, obj, preserve_traits: FactoryDefault.config.preserve_traits, preserve_attributes: FactoryDefault.config.preserve_attributes, **other) - name = name.first if name.size == 1 - FactoryDefault.register( - name, obj, - preserve_traits: preserve_traits, - preserve_attributes: preserve_attributes, - **other - ) - end - - def get_factory_default(name, *traits, **overrides) - FactoryDefault.get(name, traits, overrides, skip_stats: true) - end - - def skip_factory_default(&block) - FactoryDefault.disable!(&block) - end - end - class Configuration attr_accessor :preserve_traits, :preserve_attributes, :report_summary, :report_stats, @@ -202,11 +170,8 @@ class << self attr_reader :stats, :profiler def init - TestProf::FactoryBot::Syntax::Methods.include DefaultSyntax - TestProf::FactoryBot.extend DefaultSyntax - TestProf::FactoryBot::Strategy::Create.prepend StrategyExt - TestProf::FactoryBot::Strategy::Build.prepend StrategyExt - TestProf::FactoryBot::Strategy::Stub.prepend StrategyExt + FactoryBotPatch.patch + FabricationPatch.patch @profiler = config.profiling_enabled? ? Profiler.new : NoopProfiler.new @enabled = ENV["FACTORY_DEFAULT_DISABLED"] != "1" diff --git a/lib/test_prof/factory_default/fabrication_patch.rb b/lib/test_prof/factory_default/fabrication_patch.rb new file mode 100644 index 00000000..d55cf0e4 --- /dev/null +++ b/lib/test_prof/factory_default/fabrication_patch.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module TestProf + module FactoryDefault # :nodoc: all + module FabricationPatch + module DefaultExt + def create_default(name, overrides = {}, &block) + obj = ::Fabricate.create(name, overrides, &block) + set_fabricate_default(name, obj) + end + + def set_fabricate_default(name, obj, **opts) + FactoryDefault.register( + name, obj, + preserve_attributes: FactoryDefault.config.preserve_attributes, + preserve_traits: FactoryDefault.config.preserve_traits, + **opts + ) + end + + def get_fabricate_default(name, **overrides) + FactoryDefault.get(name, nil, overrides, skip_stats: true) + end + + def skip_fabricate_default(&block) + FactoryDefault.disable!(&block) + end + + def create(name, overrides = {}, &block) + self.fabrication_depth += 1 + # We do not support defaults for objects created with attribute blocks + return super if block + + return super if fabrication_depth < 2 + + FactoryDefault.get(name, nil, overrides, **{}) || + FactoryDefault.profiler.instrument(name, nil, overrides) { super } + ensure + self.fabrication_depth -= 1 + end + + private + + def fabrication_depth + Thread.current[:_fab_depth_] ||= 0 + end + + def fabrication_depth=(value) + Thread.current[:_fab_depth_] = value + end + end + + def self.patch + TestProf.require "fabrication" do + ::Fabricate.singleton_class.prepend(DefaultExt) + end + end + end + end +end diff --git a/lib/test_prof/factory_default/factory_bot_patch.rb b/lib/test_prof/factory_default/factory_bot_patch.rb index b14b5898..faac66a1 100644 --- a/lib/test_prof/factory_default/factory_bot_patch.rb +++ b/lib/test_prof/factory_default/factory_bot_patch.rb @@ -2,18 +2,65 @@ module TestProf module FactoryDefault # :nodoc: all - module RunnerExt - refine TestProf::FactoryBot::FactoryRunner do - attr_reader :name, :traits, :overrides + module FactoryBotPatch + module RunnerExt + refine TestProf::FactoryBot::FactoryRunner do + attr_reader :name, :traits, :overrides + end + end + + using RunnerExt + + module StrategyExt + def association(runner) + FactoryDefault.get(runner.name, runner.traits, runner.overrides, **{}) || + FactoryDefault.profiler.instrument(runner.name, runner.traits, runner.overrides) { super } + end + end + + module SyntaxExt + def create_default(name, *args, &block) + options = args.extract_options! + default_options = {} + default_options[:preserve_traits] = options.delete(:preserve_traits) if options.key?(:preserve_traits) + default_options[:preserve_attributes] = options.delete(:preserve_attributes) if options.key?(:preserve_attributes) + + obj = TestProf::FactoryBot.create(name, *args, options, &block) + + # Factory with traits + name = [name, *args] if args.any? + + set_factory_default(name, obj, **default_options) + end + + def set_factory_default(*name, obj, preserve_traits: FactoryDefault.config.preserve_traits, preserve_attributes: FactoryDefault.config.preserve_attributes, **other) + name = name.first if name.size == 1 + FactoryDefault.register( + name, obj, + preserve_traits: preserve_traits, + preserve_attributes: preserve_attributes, + **other + ) + end + + def get_factory_default(name, *traits, **overrides) + FactoryDefault.get(name, traits, overrides, skip_stats: true) + end + + def skip_factory_default(&block) + FactoryDefault.disable!(&block) + end end - end - using RunnerExt + def self.patch + require "test_prof/factory_bot" + return unless defined?(TestProf::FactoryBot) - module StrategyExt - def association(runner) - FactoryDefault.get(runner.name, runner.traits, runner.overrides, **{}) || - FactoryDefault.profiler.instrument(runner.name, runner.traits, runner.overrides) { super } + TestProf::FactoryBot::Syntax::Methods.include SyntaxExt + TestProf::FactoryBot.extend SyntaxExt + TestProf::FactoryBot::Strategy::Create.prepend StrategyExt + TestProf::FactoryBot::Strategy::Build.prepend StrategyExt + TestProf::FactoryBot::Strategy::Stub.prepend StrategyExt end end end diff --git a/spec/integrations/factory_default_spec.rb b/spec/integrations/factory_default_spec.rb index 1e1e2760..bf87f960 100644 --- a/spec/integrations/factory_default_spec.rb +++ b/spec/integrations/factory_default_spec.rb @@ -8,6 +8,12 @@ expect(output).to include("0 failures") end + specify "fabrication" do + output = run_rspec("factory_default_fabrication") + + expect(output).to include("0 failures") + end + specify "let_it_be integration" do output = run_rspec("factory_default_let_it_be") @@ -24,6 +30,16 @@ expect(output).to match(/user\s+11\s+3/) end + specify "fabrication stats" do + output = run_rspec("factory_default_fabrication", env: {"FACTORY_DEFAULT_STATS" => "1"}) + + expect(output).to include("0 failures") + + expect(output).to include("FactoryDefault summary: hit=7 miss=1") + expect(output).to match(/factory\s+hit\s+miss\n\n/) + expect(output).to match(/user\s+7\s+1/) + end + specify "analyze" do output = run_rspec( "factory_default_analyze", diff --git a/spec/integrations/fixtures/rspec/factory_default_fabrication_fixture.rb b/spec/integrations/fixtures/rspec/factory_default_fabrication_fixture.rb new file mode 100644 index 00000000..0ea22fef --- /dev/null +++ b/spec/integrations/fixtures/rspec/factory_default_fabrication_fixture.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require_relative "../../../support/ar_models" +require_relative "../../../support/transactional_context" +require "test_prof/recipes/rspec/factory_default" + +TestProf::FactoryDefault.configure do |config| + config.preserve_attributes = true +end + +describe "Post" do + let(:user) { Fabricate.create_default(:user) } + let(:post) { Fabricate(:post) } + + it "creates post with the same user" do + user + expect { post }.not_to change(User, :count) + expect(post.user).to eq user + end + + it "creates associated user if no default" do + expect { post }.to change(User, :count).by(1) + end + + it "creates new user if not an association" do + user + expect { Fabricate(:user) }.to change(User, :count).by(1) + end + + it "works with many records" do + user + expect { Fabricate.times(5, :post) }.not_to change(User, :count) + expect(user.posts.count).to eq 5 + end + + it "works with specified user" do + user + user2 = Fabricate(:user) + post = Fabricate(:post, user: user2) + expect(post.user).to eq user2 + end + + context "with redefined user" do + let(:user2) { Fabricate(:user) } + + before { Fabricate.set_fabricate_default(:user, user2) } + + it "uses redefined default" do + expect(post.user).to eq user2 + end + end + + context "with overrides" do + before { user } + + it "creates new record if overrides do not match" do + expect { Fabricate(:alice_post) }.to change(User, :count).by(1) + end + end +end diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index e3135cb3..f605a3ef 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -214,3 +214,7 @@ class Post < ApplicationRecord text { sequence(:text) { |n| "Post ##{n}}" } } user end + +Fabricator(:alice_post, from: :post) do + user { Fabricate(:user, name: "Alice") } +end From 1a2edc5983d86508da3951c261a6982e68cce19d Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 23 Jul 2024 10:06:07 +0300 Subject: [PATCH 168/194] Bump 1.4.0.rc.2 --- lib/test_prof/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 3419e5fd..617ea2fc 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.4.0.rc.1" + VERSION = "1.4.0.rc.2" end From 0e7968b976b907a01cfac587321d36a485d98d52 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 25 Jul 2024 12:38:48 +0300 Subject: [PATCH 169/194] feat: add tps profiler --- CHANGELOG.md | 2 + lib/test_prof.rb | 1 + lib/test_prof/tps_prof.rb | 46 ++++++++++++++ lib/test_prof/tps_prof/profiler.rb | 55 ++++++++++++++++ lib/test_prof/tps_prof/reporter/text.rb | 48 ++++++++++++++ lib/test_prof/tps_prof/rspec.rb | 63 +++++++++++++++++++ .../fixtures/rspec/tps_prof_fixture.rb | 30 +++++++++ spec/integrations/tps_prof_spec.rb | 15 +++++ 8 files changed, 260 insertions(+) create mode 100644 lib/test_prof/tps_prof.rb create mode 100644 lib/test_prof/tps_prof/profiler.rb create mode 100644 lib/test_prof/tps_prof/reporter/text.rb create mode 100644 lib/test_prof/tps_prof/rspec.rb create mode 100644 spec/integrations/fixtures/rspec/tps_prof_fixture.rb create mode 100644 spec/integrations/tps_prof_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 67050b58..c64caa6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Add new TPS (tests per second) profiler. ([@palkan][]) + - FactoryDefault: add Fabrication support. ([@palkan][]) - Drop support for **Ruby <2.7** and **Rails <6**. diff --git a/lib/test_prof.rb b/lib/test_prof.rb index acb766c3..cff6fb40 100644 --- a/lib/test_prof.rb +++ b/lib/test_prof.rb @@ -12,5 +12,6 @@ require "test_prof/memory_prof" require "test_prof/rspec_stamp" require "test_prof/tag_prof" +require "test_prof/tps_prof" require "test_prof/rspec_dissect" if TestProf.rspec? require "test_prof/factory_all_stub" diff --git a/lib/test_prof/tps_prof.rb b/lib/test_prof/tps_prof.rb new file mode 100644 index 00000000..79c733f4 --- /dev/null +++ b/lib/test_prof/tps_prof.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require "test_prof/tps_prof/profiler" +require "test_prof/tps_prof/reporter/text" + +module TestProf + # TPSProf shows top-N example group based on their tests-per-second value. + # + # Example: + # + # TPS_PROF=10 rspec ... + # + module TPSProf + class Configuration + attr_accessor :top_count, :threshold, :reporter + + def initialize + @top_count = ENV["TPS_PROF"].to_i + @top_count = 10 if @top_count == 1 + @threshold = ENV.fetch("TPS_PROF_MIN", 10).to_i + @reporter = resolve_reporter(ENV["TPS_PROF_FORMAT"]) + end + + private + + def resolve_reporter(format) + # TODO: support other formats + TPSProf::Reporter::Text.new + end + end + + class << self + def config + @config ||= Configuration.new + end + + def configure + yield config + end + end + end +end + +require "test_prof/tps_prof/rspec" if TestProf.rspec? +# TODO: Minitest support +# require "test_prof/tps_prof/minitest" if TestProf.minitest? diff --git a/lib/test_prof/tps_prof/profiler.rb b/lib/test_prof/tps_prof/profiler.rb new file mode 100644 index 00000000..11f720ec --- /dev/null +++ b/lib/test_prof/tps_prof/profiler.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "test_prof/utils/sized_ordered_set" + +module TestProf + module TPSProf + class Profiler + attr_reader :top_count, :groups, :total_count, :total_time, :threshold + + def initialize(top_count, threshold: 10) + @threshold = threshold + @top_count = top_count + @total_count = 0 + @total_time = 0.0 + @groups = Utils::SizedOrderedSet.new(top_count, sort_by: :tps) + end + + def group_started(id) + @current_group = id + @examples_count = 0 + @examples_time = 0.0 + @group_started_at = TestProf.now + end + + def group_finished(id) + return unless @examples_count >= threshold + + # Context-time + group_time = (TestProf.now - @group_started_at) - @examples_time + run_time = @examples_time + group_time + + groups << { + id: id, + run_time: run_time, + group_time: group_time, + count: @examples_count, + tps: -(@examples_count / run_time).round(2) + } + end + + def example_started(id) + @example_started_at = TestProf.now + end + + def example_finished(id) + @examples_count += 1 + @total_count += 1 + + time = (TestProf.now - @example_started_at) + @examples_time += time + @total_time += time + end + end + end +end diff --git a/lib/test_prof/tps_prof/reporter/text.rb b/lib/test_prof/tps_prof/reporter/text.rb new file mode 100644 index 00000000..559c184a --- /dev/null +++ b/lib/test_prof/tps_prof/reporter/text.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require "test_prof/ext/float_duration" +require "test_prof/ext/string_truncate" + +module TestProf + module TPSProf + module Reporter + class Text + include Logging + using FloatDuration + using StringTruncate + + def print(profiler) + groups = profiler.groups + + total_tps = (profiler.total_count / profiler.total_time).round(2) + + msgs = [] + + msgs << + <<~MSG + Total TPS (tests per second): #{total_tps} + + Top #{profiler.top_count} slowest suites by TPS (tests per second) (min examples per group: #{profiler.threshold}): + + MSG + + groups.each do |group| + description = group[:id].top_level_description + location = group[:id].metadata[:location] + time = group[:run_time] + group_time = group[:group_time] + count = group[:count] + tps = -group[:tps] + + msgs << + <<~GROUP + #{description.truncate} (#{location}) – #{tps} TPS (#{time.duration} / #{count}), group time: #{group_time.duration} + GROUP + end + + log :info, msgs.join + end + end + end + end +end diff --git a/lib/test_prof/tps_prof/rspec.rb b/lib/test_prof/tps_prof/rspec.rb new file mode 100644 index 00000000..457dd223 --- /dev/null +++ b/lib/test_prof/tps_prof/rspec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module TestProf + module TPSProf + class RSpecListener # :nodoc: + include Logging + + NOTIFICATIONS = %i[ + example_group_started + example_group_finished + example_started + example_finished + ].freeze + + attr_reader :reporter, :profiler + + def initialize + @profiler = Profiler.new(TPSProf.config.top_count, threshold: TPSProf.config.threshold) + @reporter = TPSProf.config.reporter + + log :info, "TPSProf enabled (top-#{TPSProf.config.top_count})" + end + + def example_group_started(notification) + return unless notification.group.top_level? + profiler.group_started notification.group + end + + def example_group_finished(notification) + return unless notification.group.top_level? + profiler.group_finished notification.group + end + + def example_started(notification) + profiler.example_started notification.example + end + + def example_finished(notification) + profiler.example_finished notification.example + end + + def print + reporter.print(profiler) + end + end + end +end + +# Register TPSProf listener +TestProf.activate("TPS_PROF") do + RSpec.configure do |config| + listener = nil + + config.before(:suite) do + listener = TestProf::TPSProf::RSpecListener.new + config.reporter.register_listener( + listener, *TestProf::TPSProf::RSpecListener::NOTIFICATIONS + ) + end + + config.after(:suite) { listener&.print } + end +end diff --git a/spec/integrations/fixtures/rspec/tps_prof_fixture.rb b/spec/integrations/fixtures/rspec/tps_prof_fixture.rb new file mode 100644 index 00000000..931688eb --- /dev/null +++ b/spec/integrations/fixtures/rspec/tps_prof_fixture.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../../../../../lib", __FILE__) +require "active_support" +require "test-prof" + +describe "Something" do + it "sleeps a bit" do + sleep 0.12 + expect(true).to eq true + end + + it "sleeps a bit more" do + sleep 0.43 + expect(true).to eq true + end +end + +describe "Another something" do + before(:all) { sleep 1.3 } + + it "do nothing" do + expect(true).to eq true + end + + it "sleeps too long" do + sleep 1.2 + expect(true).to eq true + end +end diff --git a/spec/integrations/tps_prof_spec.rb b/spec/integrations/tps_prof_spec.rb new file mode 100644 index 00000000..9ab0b4d7 --- /dev/null +++ b/spec/integrations/tps_prof_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +describe "TPSProf" do + context "RSpec" do + specify "with default options", :aggregate_failures do + output = run_rspec("tps_prof", env: {"TPS_PROF" => "1", "TPS_PROF_MIN" => "2"}) + + expect(output).to include("TPSProf enabled (top-10)") + expect(output).to match(/Total TPS \(tests per second\): 2\.\d+/) + + expect(output).to match(/Another something \(\.\/tps_prof_fixture\.rb:\d+\) – 0\.\d+ TPS \(00:\d{2}\.\d{3} \/ 2\), group time: 00:01\.\d{3}/) + expect(output).to match(/Something \(\.\/tps_prof_fixture\.rb:\d+\) – 3\.\d+ TPS \(00:\d{2}\.\d{3} \/ 2\), group time: 00:\d{2}\.\d{3}/) + end + end +end From e7302166a7824f98387c34b29c43151e288ad35e Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 25 Jul 2024 16:02:23 +0300 Subject: [PATCH 170/194] fix: ensure factory_bot is required in factory_default patch --- .../factory_default/factory_bot_patch.rb | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/test_prof/factory_default/factory_bot_patch.rb b/lib/test_prof/factory_default/factory_bot_patch.rb index faac66a1..b185b2bc 100644 --- a/lib/test_prof/factory_default/factory_bot_patch.rb +++ b/lib/test_prof/factory_default/factory_bot_patch.rb @@ -1,15 +1,19 @@ # frozen_string_literal: true +require "test_prof/factory_bot" + module TestProf module FactoryDefault # :nodoc: all module FactoryBotPatch - module RunnerExt - refine TestProf::FactoryBot::FactoryRunner do - attr_reader :name, :traits, :overrides + if defined?(TestProf::FactoryBot::FactoryRunner) + module RunnerExt + refine TestProf::FactoryBot::FactoryRunner do + attr_reader :name, :traits, :overrides + end end - end - using RunnerExt + using RunnerExt + end module StrategyExt def association(runner) @@ -53,7 +57,6 @@ def skip_factory_default(&block) end def self.patch - require "test_prof/factory_bot" return unless defined?(TestProf::FactoryBot) TestProf::FactoryBot::Syntax::Methods.include SyntaxExt From 1eebcbbb6c192fe5e79046c6bd692731b3925148 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 25 Jul 2024 18:29:17 +0300 Subject: [PATCH 171/194] Bump 1.4.0.rc.3 --- lib/test_prof/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 617ea2fc..c27d0802 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.4.0.rc.2" + VERSION = "1.4.0.rc.3" end From ab7c9aaa9b37ef343c66633fab78ebdb22b4c52b Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 26 Jul 2024 12:30:26 +0300 Subject: [PATCH 172/194] feat: add no boot profiling mode for RubyProf --- docs/profilers/ruby_profilers.md | 16 ++++++++++++++ lib/test_prof/ruby_prof.rb | 27 ++++++++++++++++++------ lib/test_prof/ruby_prof/rspec_no_boot.rb | 15 +++++++++++++ spec/integrations/profilers_spec.rb | 8 +++++++ 4 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 lib/test_prof/ruby_prof/rspec_no_boot.rb diff --git a/docs/profilers/ruby_profilers.md b/docs/profilers/ruby_profilers.md index 07ed2867..e23a8c16 100644 --- a/docs/profilers/ruby_profilers.md +++ b/docs/profilers/ruby_profilers.md @@ -194,6 +194,22 @@ At the end of the test run, you will see the message from Test Prof including pa [TEST PROF INFO] RubyProf report generated: tmp/test_prof/ruby-prof-report-flat-wall-total.txt ``` +#### Skipping test suite boot + +**NOTE:** RSpec only. + +It could be usefule to exclude the application boot and tests load from the RubyProf report to analyze only tests being executed (so you don't have `Kernel#require` being one of the top slowest methods). + +For that, specify the `TEST_RUBY_PROF_BOOT=false` (or "0", or "f") env variable: + +```sh +$ TEST_RUBY_PROF=1 TEST_RUBY_PROF_BOOT=0 bundle exec rspec ... + +[TEST PROF] RubyProf enabled for examples + +... +``` + ### Profiling individual examples with RubyProf TestProf provides a built-in shared context for RSpec to profile examples individually: diff --git a/lib/test_prof/ruby_prof.rb b/lib/test_prof/ruby_prof.rb index 51f3a713..a99b4f18 100644 --- a/lib/test_prof/ruby_prof.rb +++ b/lib/test_prof/ruby_prof.rb @@ -48,12 +48,13 @@ class Configuration attr_accessor :printer, :mode, :min_percent, :include_threads, :exclude_common_methods, :test_prof_exclusions_enabled, - :custom_exclusions + :custom_exclusions, :skip_boot def initialize @printer = ENV["TEST_RUBY_PROF"].to_sym if PRINTERS.key?(ENV["TEST_RUBY_PROF"]) @printer ||= ENV.fetch("TEST_RUBY_PROF_PRINTER", :flat).to_sym @mode = ENV.fetch("TEST_RUBY_PROF_MODE", :wall).to_s + @skip_boot = %w[0 false f].include?(ENV["TEST_RUBY_PROF_BOOT"]) @min_percent = 1 @include_threads = false @exclude_common_methods = true @@ -65,6 +66,10 @@ def include_threads? include_threads == true end + def skip_boot? + skip_boot == true + end + def exclude_common_methods? exclude_common_methods == true end @@ -166,23 +171,21 @@ def configure # # Use this method to profile the whole run. def run - report = profile + report = profile(locked: true) return unless report - @locked = true - log :info, "RubyProf enabled globally" at_exit { report.dump("total") } end - def profile + def profile(locked: false) if locked? log :warn, <<~MSG RubyProf is activated globally, you cannot generate per-example report. - Make sure you haven't set the TEST_RUBY_PROF environmental variable. + Make sure you haven not set the TEST_RUBY_PROF environmental variable. MSG return end @@ -212,6 +215,8 @@ def profile profiler.start + @locked = true if locked + Report.new(profiler) end @@ -282,5 +287,13 @@ def exclude_common_methods(profiler) # Hook to run RubyProf globally TestProf.activate("TEST_RUBY_PROF") do - TestProf::RubyProf.run + if TestProf::RubyProf.config.skip_boot? + if TestProf.rspec? + require "test_prof/ruby_prof/rspec_no_boot" + else + TestProf.log :warn, "RubyProf tests profiling w/o test suite boot is only supported in RSpec" + end + else + TestProf::RubyProf.run + end end diff --git a/lib/test_prof/ruby_prof/rspec_no_boot.rb b/lib/test_prof/ruby_prof/rspec_no_boot.rb new file mode 100644 index 00000000..0066e01a --- /dev/null +++ b/lib/test_prof/ruby_prof/rspec_no_boot.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +RSpec.configure do |config| + report = nil + + config.append_before(:suite) do + report = TestProf::RubyProf.profile(locked: true) + + TestProf.log :info, "RubyProf enabled for examples" + end + + config.after(:suite) do + report&.dump("examples") + end +end diff --git a/spec/integrations/profilers_spec.rb b/spec/integrations/profilers_spec.rb index 9798809c..3319b48f 100644 --- a/spec/integrations/profilers_spec.rb +++ b/spec/integrations/profilers_spec.rb @@ -25,6 +25,14 @@ expect(output).to include("RubyProf report generated") expect(output).to include("0 failures") end + + specify "examples only" do + output = run_rspec("ruby_prof", env: {"TEST_RUBY_PROF" => "1", "TEST_RUBY_PROF_BOOT" => "0"}) + + expect(output).to include("RubyProf enabled for examples") + expect(output).to include("RubyProf report generated") + expect(output).to include("0 failures") + end end context "stackprof" do From 643ac6a2f1e8ed391972ae67dfa88f7e3fa691eb Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 26 Jul 2024 13:51:34 +0300 Subject: [PATCH 173/194] fix(factory_prof): consider threshold for variations; add empty variation --- docs/profilers/factory_prof.md | 14 ++++++++------ lib/test_prof/factory_prof.rb | 9 +++++++-- lib/test_prof/factory_prof/fabrication_patch.rb | 2 +- lib/test_prof/factory_prof/factory_bot_patch.rb | 2 +- lib/test_prof/factory_prof/printers/simple.rb | 2 ++ spec/integrations/factory_prof_spec.rb | 2 ++ spec/test_prof/factory_prof_spec.rb | 16 +++++++++++++--- 7 files changed, 34 insertions(+), 13 deletions(-) diff --git a/docs/profilers/factory_prof.md b/docs/profilers/factory_prof.md index e4a519e4..21707286 100644 --- a/docs/profilers/factory_prof.md +++ b/docs/profilers/factory_prof.md @@ -81,15 +81,17 @@ Total uniq factories: 119 name total top-level total time time per call top-level time - user 6091 2715 115.7671s 0.0426s 50.2517s - .admin 123 715 15.7671s 0.0466s 5.2517s - [name,role] 25 11 7.671s 0.0666s 1.2517s - post 2142 2098 93.3152s 0.0444s 92.1915s - .draft[tags] 12 12 9.3152s 0.164s 42.1915s + user 6091 2715 115.7671s 0.0426s 50.251s + - 5243 1989 84.231s 0.0412s 34.321s + .admin 823 715 15.767s 0.0466s 5.257s + [name,role] 25 11 7.671s 0.0666s 1.257s + post 2142 2098 93.315s 0.0444s 92.191s + _ 2130 2086 87.685s 0.0412s 88.191s + .draft[tags] 12 12 9.315s 0.164s 42.115s ... ``` -In the example above, `.xxx` indicates a trait and `[a,b]` indicates the overrides keys, e.g., `create(:user, :admin)` is an `.admin` variation, while `create(:post, :draft, tags: ["a"])`—`.draft[tags]` +In the example above, `-` indicates a factory without traits or overrides (e.g., `create(:user)`), `.xxx` indicates a trait and `[a,b]` indicates the overrides keys, e.g., `create(:user, :admin)` is an `.admin` variation, while `create(:post, :draft, tags: ["a"])`—`.draft[tags]` #### Variations limit config diff --git a/lib/test_prof/factory_prof.rb b/lib/test_prof/factory_prof.rb index c021770c..55abf001 100644 --- a/lib/test_prof/factory_prof.rb +++ b/lib/test_prof/factory_prof.rb @@ -40,6 +40,10 @@ def initialize def flamegraph? @mode == :flamegraph end + + def include_variations? + @include_variations == true + end end class Result # :nodoc: @@ -137,14 +141,14 @@ def track(factory, variation:) @depth += 1 @current_stack << factory if config.flamegraph? track_count(@stats[factory]) - track_count(@stats[factory][:variations][variation_name(variation)]) unless variation.empty? + track_count(@stats[factory][:variations][variation_name(variation)]) if config.include_variations? t1 = TestProf.now begin yield ensure t2 = TestProf.now track_time(@stats[factory], t1, t2) - track_time(@stats[factory][:variations][variation_name(variation)], t1, t2) unless variation.empty? + track_time(@stats[factory][:variations][variation_name(variation)], t1, t2) if config.include_variations? @depth -= 1 flush_stack if @depth.zero? end @@ -153,6 +157,7 @@ def track(factory, variation:) private def variation_name(variation) + return "-" if variation.empty? variations_count = variation.to_s.scan(/[\w]+/).size return "[...]" if variations_count > config.variations_limit diff --git a/lib/test_prof/factory_prof/fabrication_patch.rb b/lib/test_prof/factory_prof/fabrication_patch.rb index e4d2a2f0..9c4c7d1b 100644 --- a/lib/test_prof/factory_prof/fabrication_patch.rb +++ b/lib/test_prof/factory_prof/fabrication_patch.rb @@ -7,7 +7,7 @@ module FabricationPatch def create(name, overrides = {}) variation = "" - if FactoryProf.config.include_variations && !overrides.empty? + if FactoryProf.config.include_variations? && !overrides.empty? variation += overrides.keys.sort.to_s.gsub(/[\\":]/, "") end diff --git a/lib/test_prof/factory_prof/factory_bot_patch.rb b/lib/test_prof/factory_prof/factory_bot_patch.rb index 3db291a9..d2b02414 100644 --- a/lib/test_prof/factory_prof/factory_bot_patch.rb +++ b/lib/test_prof/factory_prof/factory_bot_patch.rb @@ -7,7 +7,7 @@ module FactoryBotPatch def run(strategy = @strategy) variation = "" - if FactoryProf.config.include_variations + if FactoryProf.config.include_variations? if @traits || @overrides unless @traits.empty? variation += @traits.sort.join(".").prepend(".") diff --git a/lib/test_prof/factory_prof/printers/simple.rb b/lib/test_prof/factory_prof/printers/simple.rb index a8da2969..8ffac516 100644 --- a/lib/test_prof/factory_prof/printers/simple.rb +++ b/lib/test_prof/factory_prof/printers/simple.rb @@ -40,6 +40,8 @@ def dump(result, start_time:, threshold:) (variation[:name] == "[...]") ? stat[:variations].size + 1 : i end sorted_variations.each do |variation_stat| + next if variation_stat[:total_count] < threshold + msgs << format("%-5s%-18s %8d %11d %13.4fs %17.4fs %18.4fs", *format_args(variation_stat)) end end diff --git a/spec/integrations/factory_prof_spec.rb b/spec/integrations/factory_prof_spec.rb index 44ba8b73..c980ba5d 100644 --- a/spec/integrations/factory_prof_spec.rb +++ b/spec/integrations/factory_prof_spec.rb @@ -29,10 +29,12 @@ expect(output).to match( / user\s+15\s+7\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+-\s+9\s+1\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n \s+.traited.with_posts\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n \s+\[name\]\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n \s+\[...\]\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n \s+post\s+10\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n + \s+-\s+8\s+0\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s\n \s+\[text,\suser\]\s+2\s+2\s+(\d+\.\d{4}s\s+){2}\d+\.\d{4}s /x ) diff --git a/spec/test_prof/factory_prof_spec.rb b/spec/test_prof/factory_prof_spec.rb index efd39958..477c1c3a 100644 --- a/spec/test_prof/factory_prof_spec.rb +++ b/spec/test_prof/factory_prof_spec.rb @@ -5,13 +5,15 @@ TestProf::FactoryProf.configure do |config| # turn on stacks collection config.mode = :flamegraph - config.include_variations = true + config.include_variations = false end describe TestProf::FactoryProf, :transactional do before { described_class.start } after { described_class.stop } + after { TestProf::FactoryProf.config.include_variations = false } + # Ensure meta-queries have been performed before(:all) { User.first } @@ -83,6 +85,8 @@ def without_time(xs) end it "contains many stacks with variations" do + TestProf::FactoryProf.config.include_variations = true + TestProf::FactoryBot.create_pair(:user) TestProf::FactoryBot.create(:post) TestProf::FactoryBot.create(:user, :with_posts) @@ -98,9 +102,12 @@ def without_time(xs) expect(without_time(result.stats)).to eq( [ {name: :user, total_count: 6, top_level_count: 3, variations: [ + {name: "-", top_level_count: 2, total_count: 5}, {name: :".with_posts", top_level_count: 1, total_count: 1} ]}, - {name: :post, total_count: 3, top_level_count: 1, variations: []} + {name: :post, total_count: 3, top_level_count: 1, variations: [ + {name: "-", top_level_count: 1, total_count: 3} + ]} ] ) end @@ -121,6 +128,8 @@ def without_time(xs) end it "contains many stacks with variations" do + TestProf::FactoryProf.config.include_variations = true + Fabricate.times(2, :user) Fabricate.create(:post, text: "some text") Fabricate.create(:user) { Fabricate.times(2, :post) } @@ -135,8 +144,9 @@ def without_time(xs) ) expect(without_time(result.stats)).to eq( [ - {name: :user, total_count: 6, top_level_count: 3, variations: []}, + {name: :user, total_count: 6, top_level_count: 3, variations: [{name: "-", top_level_count: 3, total_count: 6}]}, {name: :post, total_count: 3, top_level_count: 1, variations: [ + {name: "-", top_level_count: 0, total_count: 2}, {name: :"[text]", top_level_count: 1, total_count: 1} ]} ] From 065ca2465118769a1a809dac66ff57f07562691d Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 26 Jul 2024 14:10:56 +0300 Subject: [PATCH 174/194] Bump 1.4.0.rc.4 --- lib/test_prof/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index c27d0802..d263a972 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.4.0.rc.3" + VERSION = "1.4.0.rc.4" end From b42880710fce0ec31d037b366baa4292d06ae624 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 1 Aug 2024 17:15:02 +0300 Subject: [PATCH 175/194] feat(any_fixture): refind by default, disable cache when clean --- CHANGELOG.md | 2 ++ docs/recipes/any_fixture.md | 32 ++++++++----------- lib/test_prof/any_fixture.rb | 18 +++++++++-- lib/test_prof/any_fixture/dsl.rb | 20 +++++++++++- lib/test_prof/recipes/rspec/any_fixture.rb | 8 +++++ .../fixtures/rspec/any_fixture_fixture.rb | 5 +-- 6 files changed, 62 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c64caa6b..a8ae3ba0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- AnyFixture: Disable fixtures cache within _clean fixture_ context. Automatically _refind_ records when using `#fixture`. ([@palkan][]) + - Add new TPS (tests per second) profiler. ([@palkan][]) - FactoryDefault: add Fabrication support. ([@palkan][]) diff --git a/docs/recipes/any_fixture.md b/docs/recipes/any_fixture.md index a6c19ff7..06ba0182 100644 --- a/docs/recipes/any_fixture.md +++ b/docs/recipes/any_fixture.md @@ -28,11 +28,8 @@ RSpec.shared_context "account", account: true do end end - # Use .register here to track the usage stats (see below) - let(:account) { TestProf::AnyFixture.register(:account) } - - # Or hard-reload object if there is chance of in-place modification - let(:account) { Account.find(TestProf::AnyFixture.register(:account).id) } + # Use .cached to retrieve the fixiture record + let(:account) { TestProf::AnyFixture.cached(:account) } end # You can enhance the existing database cleaning. Posts will be deleted before fixtures reset @@ -96,7 +93,7 @@ require "test_prof/any_fixture/dsl" using TestProf::AnyFixture::DSL # and then you can use `fixture` method (which is just an alias for `TestProf::AnyFixture.register`) -before(:all) { fixture(:account) } +before(:all) { fixture(:account) { create(:account) } } # You can also use it to fetch the record (instead of storing it in instance variable) let(:account) { fixture(:account) } @@ -106,20 +103,14 @@ before_fixtures_reset { Post.delete_all } after_fixtures_reset { Post.delete_all } ``` -## `ActiveRecord#refind` - -TestProf also provides an extension to _hard-reload_ ActiveRecord objects: +Note that the `#fixture` method also _refinds_ Active Record objects on read, i.e., the following two expressions works similarly: ```ruby -# instead of -let(:account) { Account.find(fixture(:account).id) } - -# load refinement -require "test_prof/ext/active_record_refind" +let(:account) { fixture(:account) } -using TestProf::Ext::ActiveRecordRefind +# similar to -let(:account) { fixture(:account).refind } +let(:account) { Account.find(TestProf::AnyFixture.cached(:account).id) } ``` ## Temporary disable fixtures @@ -139,9 +130,14 @@ context "global state", :with_clean_fixture do end ``` -How does it work? It wraps the example group into a transaction (using [`before_all`](./before_all.md)) and calls `TestProf::AnyFixture.clean` before running the examples. +How does it work? It wraps the example group into a transaction (using [`before_all`](./before_all.md)) and calls `TestProf::AnyFixture.clean` and `TestProf::AnyFixture.disable!` before running the examples and then call `TestProf::AnyFixture.enable!` at the context exit. The `disable!`/`enable!` method toggle the cache state. That makes it possible to re-use blocks passed during registration like there is no AnyFixture: + +```ruby +# Here we create a new account if AnyFixture is disabled +let(:account) { fixture(:account) { create(:account) } } +``` -Thus, this context is a little bit _heavy_. Try to avoid such situations and write specs independent of the global state. +Reseting fixtures (i.e., delete data from the affected tables) can be _heavy_. Try to avoid such situations and write specs independent of the global state. ## Usage report diff --git a/lib/test_prof/any_fixture.rb b/lib/test_prof/any_fixture.rb index 9e792d25..f486cff1 100644 --- a/lib/test_prof/any_fixture.rb +++ b/lib/test_prof/any_fixture.rb @@ -108,14 +108,18 @@ def register(id) cached(id) do raise "No fixture named #{id} has been registered" unless block_given? + next yield if @disabled + ActiveSupport::Notifications.subscribed(method(:subscriber), "sql.active_record") do yield end end end - def cached(id) - cache.fetch(id) { yield } + def cached(id, &block) + return (block_given? ? yield : nil) if @disabled + + cache.fetch(id, &block) end # Create and register new SQL dump. @@ -174,6 +178,14 @@ def reset callbacks.clear end + def disable! + @disabled = true + end + + def enable! + @disabled = false + end + def before_fixtures_reset(&block) callbacks[:before_fixtures_reset] << block end @@ -266,5 +278,7 @@ def disable_referential_integrity connection.disable_referential_integrity { yield } end end + + enable! end end diff --git a/lib/test_prof/any_fixture/dsl.rb b/lib/test_prof/any_fixture/dsl.rb index 81cc44a7..cea7a004 100644 --- a/lib/test_prof/any_fixture/dsl.rb +++ b/lib/test_prof/any_fixture/dsl.rb @@ -1,5 +1,10 @@ # frozen_string_literal: true +if defined?(::ActiveRecord::Base) + require "test_prof/ext/active_record_refind" + using TestProf::Ext::ActiveRecordRefind +end + module TestProf module AnyFixture # Adds "global" `fixture`, `before_fixtures_reset` and `after_fixtures_reset` methods (through refinement) @@ -9,7 +14,20 @@ module DSL # - Rails added `Kernel.prepend` in 6.1: https://github.com/rails/rails/commit/3124007bd674dcdc9c3b5c6b2964dfb7a1a0733c refine ::Object do def fixture(id, &block) - ::TestProf::AnyFixture.register(:"#{id}", &block) + id = :"#{id}" + record = ::TestProf::AnyFixture.cached(id) + + return ::TestProf::AnyFixture.register(id, &block) unless record + + return record.refind if record.is_a?(::ActiveRecord::Base) + + if record.respond_to?(:to_ary) + return record.map do |rec| + rec.is_a?(::ActiveRecord::Base) ? rec.refind : rec + end + end + + record end def before_fixtures_reset(&block) diff --git a/lib/test_prof/recipes/rspec/any_fixture.rb b/lib/test_prof/recipes/rspec/any_fixture.rb index 307e3dfe..a97e6172 100644 --- a/lib/test_prof/recipes/rspec/any_fixture.rb +++ b/lib/test_prof/recipes/rspec/any_fixture.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true require "test_prof/any_fixture" +require "test_prof/any_fixture/dsl" +require "test_prof/ext/active_record_refind" + require "test_prof/recipes/rspec/before_all" RSpec.shared_context "any_fixture:clean" do @@ -8,6 +11,11 @@ before_all do TestProf::AnyFixture.clean + TestProf::AnyFixture.disable! + end + + after(:all) do + TestProf::AnyFixture.enable! end end diff --git a/spec/integrations/fixtures/rspec/any_fixture_fixture.rb b/spec/integrations/fixtures/rspec/any_fixture_fixture.rb index a28c03cd..398321d0 100644 --- a/spec/integrations/fixtures/rspec/any_fixture_fixture.rb +++ b/spec/integrations/fixtures/rspec/any_fixture_fixture.rb @@ -5,7 +5,6 @@ require_relative "../../../support/transactional_context" require "test_prof/recipes/rspec/any_fixture" -require "test_prof/any_fixture/dsl" using TestProf::AnyFixture::DSL shared_context "user", user: true do @@ -15,7 +14,8 @@ end end - let(:user) { User.find(fixture(:user).id) } + let(:user) { fixture(:user) } + let(:a_user) { fixture(:user) { TestProf::FactoryBot.create(:user) } } end describe "User", :user do @@ -27,6 +27,7 @@ context "with clean fixture", :transactional do specify "no users", :with_clean_fixture do expect(User.count).to eq 0 + expect { a_user }.to change(User, :count).by(1) end end end From 18c04336593af115772408095739fb58f8ad61d5 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Thu, 1 Aug 2024 18:42:03 +0300 Subject: [PATCH 176/194] forspell: refind --- forspell.dict | 1 + 1 file changed, 1 insertion(+) diff --git a/forspell.dict b/forspell.dict index 40f51b27..5e80eec8 100644 --- a/forspell.dict +++ b/forspell.dict @@ -31,3 +31,4 @@ Ermokhin Burkhard Sistovaris Timecop +refind From 3b4c463ce528283f4547d1045789fcf0b98ee4f6 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 7 Aug 2024 11:40:18 +0300 Subject: [PATCH 177/194] docs: add RailsConf workshop links --- docs/README.md | 2 ++ docs/playbook.md | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index f830b58d..ec5387a8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -55,6 +55,8 @@ TestProf toolbox aims to help you identify bottlenecks in your test suite. It co ## Resources +- [From slow to go: Rails test profiling hands-on](https://evilmartians.com/events/from-slow-to-go-rails-test-profiling-hands-on-railsconf-2024) + - [Profiling Ruby tests with Swiss precision](https://evilmartians.com/events/profiling-ruby-tests-with-swiss-precision-helvetic-ruby) - [TestProf: a good doctor for slow Ruby tests](https://evilmartians.com/chronicles/testprof-a-good-doctor-for-slow-ruby-tests) diff --git a/docs/playbook.md b/docs/playbook.md index 6dbb9dac..cc1b827b 100644 --- a/docs/playbook.md +++ b/docs/playbook.md @@ -4,11 +4,13 @@ This document aims to help you get started with profiling test suites and answer **NOTE**: This document assumes you're working with a Ruby on Rails application and RSpec testing framework. The ideas can easily be translated into other frameworks. +> 📼 Check out also the ["From slow to go" RailsConf 2024 workshop recording](https://evilmartians.com/events/from-slow-to-go-rails-test-profiling-hands-on-railsconf-2024) to see this playbook in action. + ## Step 0. Configuration basics Low-hanging configuration fruits: -- Disable logging in tests—it's useless. If you really need it, use our [logging utils](./recipes/logging.md). +- Disable logging\* in tests—it's useless. If you really need it, use our [logging utils](./recipes/logging.md). ```ruby config.logger = ActiveSupport::TaggedLogging.new(Logger.new(nil)) @@ -17,15 +19,19 @@ config.log_level = :fatal - Disable coverage and built-in profiling by default. Use env var to enable it (e.g., `COVERAGE=true`) +\* Modern SSD hard drives make the overhead of file-based logging almost negligible. Still, we recommend disabling logging to make sure tests are not affected in any environment (e.g., Docker on MacOS). + ## Step 1. General profiling -It helps to identify not-so-low hanging fruits. We recommend using [StackProf](./profilers/stack_prof.md), so you must install it first (if not yet): +It helps to identify not-so-low hanging fruits. We recommend using [StackProf](./profilers/ruby_profilers.md#stack_prof) or [Vernier](./profilers/ruby_profilers.md#vernier), so you must install them first (if not yet): ```sh bundle add stackprof +# or +bundle add vernier ``` -Configure Test Prof to generate JSON profiles by default: +Configure TestProf to generate JSON profiles by default: ```ruby TestProf::StackProf.configure do |config| @@ -46,7 +52,7 @@ TEST_STACK_PROF=boot rspec ./spec/some_spec.rb What to look for? Some examples: - No [Bootsnap](https://github.com/Shopify/bootsnap) used or not configured to cache everything (e.g., YAML files) -- Slow Rails initializers that are not needed in tests. +- Slow Rails initializers that are not needed in tests. Vernier's Rails hooks feature is especially useful in analyzing Rails initializers. ### Step 1.2. Sampling tests profiling From d4d8bab4257d1110d012317cc29891dcec674f4b Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 12 Aug 2024 21:32:03 +0300 Subject: [PATCH 178/194] Bump 1.4.0 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8ae3ba0..4f8b3e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.4.0 (2024-08-12) + - AnyFixture: Disable fixtures cache within _clean fixture_ context. Automatically _refind_ records when using `#fixture`. ([@palkan][]) - Add new TPS (tests per second) profiler. ([@palkan][]) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index d263a972..7ea58bb5 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.4.0.rc.4" + VERSION = "1.4.0" end From bc95266be7d78395c8bcd5e000133cf0ddf52b55 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 12 Aug 2024 23:01:02 +0300 Subject: [PATCH 179/194] fix: isolator integration --- Gemfile | 2 +- gemfiles/activerecord7.gemfile | 2 +- lib/test_prof/before_all/isolator.rb | 21 ++++++--------------- spec/support/transactional_context.rb | 4 ++-- 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/Gemfile b/Gemfile index a3510cb9..34fc8820 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,7 @@ if File.exist?(local_gemfile) eval_gemfile(local_gemfile) # rubocop:disable Security/Eval else platform :mri do - gem "sqlite3", "~> 1.4" + gem "sqlite3", "~> 2.0" end platform :jruby do diff --git a/gemfiles/activerecord7.gemfile b/gemfiles/activerecord7.gemfile index 6c48e2e9..6762f26f 100644 --- a/gemfiles/activerecord7.gemfile +++ b/gemfiles/activerecord7.gemfile @@ -3,7 +3,7 @@ source 'https://rubygems.org' gem "activerecord", "~> 7.0" gem "factory_bot" gem "fabrication" -gem "sqlite3", "~> 1.4" +gem "sqlite3", "~> 2.0" gem "sidekiq" gem "timecop" gem "pg" diff --git a/lib/test_prof/before_all/isolator.rb b/lib/test_prof/before_all/isolator.rb index f6a27fdc..66e7d827 100644 --- a/lib/test_prof/before_all/isolator.rb +++ b/lib/test_prof/before_all/isolator.rb @@ -1,20 +1,11 @@ # frozen_string_literal: true -module TestProf - module BeforeAll - # Disable Isolator within before_all blocks - module Isolator - def begin_transaction(*) - ::Isolator.transactions_threshold += 1 - super - end +TestProf::BeforeAll.configure do |config| + config.before(:begin) do + ::Isolator.incr_thresholds! + end - def rollback_transaction(*) - super - ::Isolator.transactions_threshold -= 1 - end - end + config.after(:rollback) do + ::Isolator.decr_thresholds! end end - -TestProf::BeforeAll.singleton_class.prepend(TestProf::BeforeAll::Isolator) diff --git a/spec/support/transactional_context.rb b/spec/support/transactional_context.rb index 8e12b86a..19b6afcc 100644 --- a/spec/support/transactional_context.rb +++ b/spec/support/transactional_context.rb @@ -5,11 +5,11 @@ shared_context "transactional", transactional: true do prepend_before(:each) do ActiveRecord::Base.connection.begin_transaction(joinable: false) - Isolator.transactions_threshold += 1 if defined?(Isolator) + ::Isolator.incr_thresholds! if defined?(::Isolator) end append_after(:each) do - Isolator.transactions_threshold -= 1 if defined?(Isolator) + ::Isolator.decr_thresholds! if defined?(::Isolator) ActiveRecord::Base.connection.rollback_transaction unless ActiveRecord::Base.connection.open_transactions.zero? end From f9b5743ecab3d270cf3e07d080241e0552fbf3ec Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 12 Aug 2024 23:20:30 +0300 Subject: [PATCH 180/194] fix: multi db before_all tests --- .../before_all/adapters/active_record_spec.rb | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/spec/test_prof/before_all/adapters/active_record_spec.rb b/spec/test_prof/before_all/adapters/active_record_spec.rb index 705fe5e0..d020823f 100644 --- a/spec/test_prof/before_all/adapters/active_record_spec.rb +++ b/spec/test_prof/before_all/adapters/active_record_spec.rb @@ -79,8 +79,8 @@ def self.configure subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.begin_transaction } it "calls begin_transaction on all available connections" do - expect(connection_1).to receive(:begin_transaction).with(joinable: false) - expect(connection_2).to receive(:begin_transaction).with(joinable: false) + expect(connection_1).to receive(:begin_transaction).with(a_hash_including(joinable: false)) + expect(connection_2).to receive(:begin_transaction).with(a_hash_including(joinable: false)) subject end @@ -89,32 +89,41 @@ def self.configure describe ".rollback_transaction" do subject { ::TestProf::BeforeAll::Adapters::ActiveRecord.rollback_transaction } - context "when not all connections have started a transaction" do - before do - # Ensure no transactions are open due to randomization of specs - connection_1.rollback_transaction unless connection_1.open_transactions.zero? - connection_2.rollback_transaction unless connection_2.open_transactions.zero? - connection_2.begin_transaction - end + if ::ActiveRecord::Base.connection.pool.respond_to?(:pin_connection!) + it "calls #unpin_connection! on each connection" do + expect(connection_pool_list.first.connection_pool).to receive(:unpin_connection!) + expect(connection_pool_list.last.connection_pool).to receive(:unpin_connection!) - it "warns when connection does not have open transaction" do - expect { subject }.to output( - /!!! before_all transaction has been already rollbacked and could work incorrectly\n/ - ).to_stderr + subject end - end + else + context "when not all connections have started a transaction" do + before do + # Ensure no transactions are open due to randomization of specs + connection_1.rollback_transaction unless connection_1.open_transactions.zero? + connection_2.rollback_transaction unless connection_2.open_transactions.zero? + connection_2.begin_transaction + end - context "when the connection is a transaction" do - before do - connection_1.begin_transaction - connection_2.begin_transaction + it "warns when connection does not have open transaction" do + expect { subject }.to output( + /!!! before_all transaction has been already rollbacked and could work incorrectly\n/ + ).to_stderr + end end - it "calls rollback_transaction on all available connections" do - expect(connection_1).to receive(:rollback_transaction) - expect(connection_2).to receive(:rollback_transaction) + context "when the connection is a transaction" do + before do + connection_1.begin_transaction + connection_2.begin_transaction + end - subject + it "calls rollback_transaction on all available connections" do + expect(connection_1).to receive(:rollback_transaction) + expect(connection_2).to receive(:rollback_transaction) + + subject + end end end end From 2b1e7452160a7b4aa6a234a44c24ec36158fa7d8 Mon Sep 17 00:00:00 2001 From: Matt Culpepper Date: Thu, 22 Aug 2024 21:17:59 -0500 Subject: [PATCH 181/194] Typo (EVEN_PROF_STAMP => EVENT_PROF_STAMP) --- docs/playbook.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/playbook.md b/docs/playbook.md index cc1b827b..d3ae5c49 100644 --- a/docs/playbook.md +++ b/docs/playbook.md @@ -150,7 +150,7 @@ Now, we can narrow our scope further to the top 10 files from the generated repo **TIP:** In RSpec, you can mark the slowest examples with a custom tag automatically using the following command: ```sh -EVENT_PROF=factory.create EVEN_PROF_STAMP=slow:factory bin/rspec spec/models +EVENT_PROF=factory.create EVENT_PROF_STAMP=slow:factory bin/rspec spec/models ``` ## Step 4. Factories usage From 87858b7e758dfa73f4345c039be4c4711f0a717a Mon Sep 17 00:00:00 2001 From: devinburnette Date: Tue, 20 Aug 2024 11:33:56 -0400 Subject: [PATCH 182/194] fix: dont load active record connection in dry-run --- CHANGELOG.md | 3 + Gemfile | 1 - lib/test_prof/before_all.rb | 23 +++-- lib/test_prof/version.rb | 2 +- spec/test_prof/before_all_spec.rb | 134 ++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 9 deletions(-) create mode 100644 spec/test_prof/before_all_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f8b3e68..0de2d47d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## master (unreleased) +## 1.4.1 (2024-08-20) +- Skips loading the ActiveRecord adapter for runs where RSpec --dry-run mode is enabled. ([@devinburnette][]) + ## 1.4.0 (2024-08-12) - AnyFixture: Disable fixtures cache within _clean fixture_ context. Automatically _refind_ records when using `#fixture`. ([@palkan][]) diff --git a/Gemfile b/Gemfile index 34fc8820..bf1e674a 100644 --- a/Gemfile +++ b/Gemfile @@ -16,7 +16,6 @@ else platform :jruby do gem "activerecord-jdbcsqlite3-adapter" - gem "activerecord", "~> 7.0" end gem "activerecord", "~> 7.0" diff --git a/lib/test_prof/before_all.rb b/lib/test_prof/before_all.rb index c6f561ff..00097d88 100644 --- a/lib/test_prof/before_all.rb +++ b/lib/test_prof/before_all.rb @@ -15,7 +15,11 @@ def initialize end class << self - attr_accessor :adapter + attr_writer :adapter + + def adapter + @adapter ||= default_adapter + end def begin_transaction(scope = nil, metadata = []) raise AdapterMissing if adapter.nil? @@ -47,6 +51,17 @@ def config def configure yield config end + + private + + def default_adapter + if defined?(::ActiveRecord::Base) + return if TestProf.rspec? && ::RSpec.configuration.dry_run? + + require "test_prof/before_all/adapters/active_record" + Adapters::ActiveRecord + end + end end class HookEntry # :nodoc: @@ -138,12 +153,6 @@ def validate_hook_type!(type) end end -if defined?(::ActiveRecord::Base) - require "test_prof/before_all/adapters/active_record" - - TestProf::BeforeAll.adapter = TestProf::BeforeAll::Adapters::ActiveRecord -end - if defined?(::Isolator) require "test_prof/before_all/isolator" end diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index 7ea58bb5..d8f54211 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.4.0" + VERSION = "1.4.1" end diff --git a/spec/test_prof/before_all_spec.rb b/spec/test_prof/before_all_spec.rb new file mode 100644 index 00000000..26754b91 --- /dev/null +++ b/spec/test_prof/before_all_spec.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +require "test_prof/before_all" + +RSpec.describe TestProf::BeforeAll do + let(:adapter) { double("Adapter") } + + before do + described_class.adapter = adapter + end + + describe ".adapter" do + context "when adapter is set" do + it "returns the adapter" do + expect(described_class.adapter).to eq(adapter) + end + end + + context "when adapter is not set" do + before do + described_class.adapter = nil + end + + context "when dry run mode is not enabled" do + before do + allow(TestProf).to receive(:rspec?).and_return(false) + allow(RSpec.configuration).to receive(:dry_run?).and_return(false) + end + + it "returns the ActiveRecord adapter" do + expect(described_class.adapter).to eq(TestProf::BeforeAll::Adapters::ActiveRecord) + end + end + + context "when dry run mode is enabled" do + before do + allow(TestProf).to receive(:rspec?).and_return(true) + allow(RSpec.configuration).to receive(:dry_run?).and_return(true) + end + + it "returns nil" do + expect(described_class.adapter).to eq(nil) + end + end + end + end + + describe ".begin_transaction" do + it "calls begin_transaction on adapter" do + allow(adapter).to receive(:begin_transaction) + expect(adapter).to receive(:begin_transaction) + + described_class.begin_transaction {} + end + end + + describe ".rollback_transaction" do + it "calls rollback_transaction on adapter" do + allow(adapter).to receive(:rollback_transaction) + expect(adapter).to receive(:rollback_transaction) + + described_class.rollback_transaction {} + end + end + + describe ".setup_fixtures" do + context "when adapter supports setup_fixtures" do + it "calls setup_fixtures on adapter" do + test_object = double("TestObject") + allow(adapter).to receive(:setup_fixtures) + expect(adapter).to receive(:setup_fixtures).with(test_object) + + described_class.setup_fixtures(test_object) + end + end + + context "when adapter does not support setup_fixtures" do + it "raises ArgumentError" do + allow(adapter).to receive(:respond_to?).with(:setup_fixtures).and_return(false) + + expect { described_class.setup_fixtures(double("TestObject")) }.to raise_error(ArgumentError, "Current adapter doesn't support #setup_fixtures") + end + end + end +end + +describe TestProf::BeforeAll::Configuration do + let(:config) { described_class.new } + + describe "#before" do + it "adds a before hook to the specified type" do + block = proc {} + config.before(:begin, &block) + + expect(config.instance_variable_get(:@hooks)[:begin].before.map(&:block)).to include(block) + end + + it "raises an error for invalid hook type" do + expect { config.before(:invalid_type) {} }.to raise_error(ArgumentError, "Unknown hook type: invalid_type. Valid types: begin, rollback") + end + end + + describe "#after" do + it "adds an after hook to the specified type" do + block = proc {} + config.after(:rollback, &block) + + expect(config.instance_variable_get(:@hooks)[:rollback].after.map(&:block)).to include(block) + end + + it "raises an error for invalid hook type" do + expect { config.after(:invalid_type) {} }.to raise_error(ArgumentError, "Unknown hook type: invalid_type. Valid types: begin, rollback") + end + end + + describe "#run_hooks" do + it "runs all before and after hooks for the specified type" do + block_before = proc {} + block_after = proc {} + + config.before(:begin, &block_before) + config.after(:begin, &block_after) + + expect(block_before).to receive(:call).once + expect(block_after).to receive(:call).once + + config.run_hooks(:begin) {} + end + + it "raises an error for invalid hook type" do + expect { config.run_hooks(:invalid_type) {} }.to raise_error(ArgumentError, "Unknown hook type: invalid_type. Valid types: begin, rollback") + end + end +end From 07f6204b1cc10ad8b351418416362d49725eb766 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 23 Aug 2024 11:19:30 +0300 Subject: [PATCH 183/194] tests: add dry-run integration test --- CHANGELOG.md | 4 +- lib/test_prof/before_all.rb | 18 ++++++++- lib/test_prof/core.rb | 4 ++ spec/integrations/before_all_spec.rb | 6 +++ spec/support/ar_models.rb | 56 ++++++++++++++-------------- spec/test_prof/before_all_spec.rb | 24 +++++------- 6 files changed, 68 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0de2d47d..7a81928d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ## master (unreleased) -## 1.4.1 (2024-08-20) +## 1.4.1 (2024-08-23) + - Skips loading the ActiveRecord adapter for runs where RSpec --dry-run mode is enabled. ([@devinburnette][]) ## 1.4.0 (2024-08-12) @@ -437,3 +438,4 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md) [@lioneldebauge]: https://github.com/lioneldebauge [@lHydra]: https://github.com/lHydra [@john-h-k]: https://github.com/john-h-k +[@devinburnette]: https://github.com/devinburnette diff --git a/lib/test_prof/before_all.rb b/lib/test_prof/before_all.rb index 00097d88..0d148067 100644 --- a/lib/test_prof/before_all.rb +++ b/lib/test_prof/before_all.rb @@ -14,6 +14,20 @@ def initialize end end + # Used in dry-run mode + class NoopAdapter + class << self + def begin_transaction(...) + end + + def rollback_transaction(...) + end + + def setup_fixtures(...) + end + end + end + class << self attr_writer :adapter @@ -55,9 +69,9 @@ def configure private def default_adapter - if defined?(::ActiveRecord::Base) - return if TestProf.rspec? && ::RSpec.configuration.dry_run? + return NoopAdapter if TestProf.dry_run? + if defined?(::ActiveRecord::Base) require "test_prof/before_all/adapters/active_record" Adapters::ActiveRecord end diff --git a/lib/test_prof/core.rb b/lib/test_prof/core.rb index 7151ee4e..4c258e67 100644 --- a/lib/test_prof/core.rb +++ b/lib/test_prof/core.rb @@ -75,6 +75,10 @@ def spring? defined?(::Spring::Application) && (disabled.nil? || disabled.empty? || disabled == "0") end + def dry_run? + rspec? && ::RSpec.configuration.dry_run? + end + # Returns the current process time def now Process.clock_gettime_for_test_prof(Process::CLOCK_MONOTONIC) diff --git a/spec/integrations/before_all_spec.rb b/spec/integrations/before_all_spec.rb index b00caf6d..c29a2e6d 100644 --- a/spec/integrations/before_all_spec.rb +++ b/spec/integrations/before_all_spec.rb @@ -39,6 +39,12 @@ expect(output).to include("0 failures") end + + specify "dry-run" do + output = run_rspec("before_all", options: "--dry-run", env: {"DRY_RUN" => "true", "DB" => "postgres", "DATABASE_URL" => "postgres://bla-bla-host/test_prof_test"}) + + expect(output).to include("0 failures") + end end context "Minitest" do diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index f605a3ef..5dbfa438 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -75,8 +75,8 @@ class Comment < CommentsRecord belongs_to :user, dependent: :destroy end - ApplicationRecord.establish_connection - CommentsRecord.establish_connection + ApplicationRecord.establish_connection unless ENV["DRY_RUN"] == "true" + CommentsRecord.establish_connection unless ENV["DRY_RUN"] == "true" else ActiveRecord::Base.configurations = {test: DB_CONFIG} class ApplicationRecord < ActiveRecord::Base @@ -87,40 +87,42 @@ class Comment < ApplicationRecord belongs_to :user, dependent: :destroy end - ActiveRecord::Base.establish_connection(**DB_CONFIG) + ActiveRecord::Base.establish_connection(**DB_CONFIG) unless ENV["DRY_RUN"] == "true" end -# #truncate_tables is not supported in older Rails, let's just ignore the failures -ActiveRecord::Base.connection.truncate_tables(*ActiveRecord::Base.connection.tables) rescue nil # rubocop:disable Style/RescueModifier +unless ENV["DRY_RUN"] == "true" + # #truncate_tables is not supported in older Rails, let's just ignore the failures + ActiveRecord::Base.connection.truncate_tables(*ActiveRecord::Base.connection.tables) rescue nil # rubocop:disable Style/RescueModifier -ActiveRecord::Schema.define do - using_pg = ActiveRecord::Base.connection.adapter_name == "PostgreSQL" + ActiveRecord::Schema.define do + using_pg = ActiveRecord::Base.connection.adapter_name == "PostgreSQL" - enable_extension "pgcrypto" if using_pg + enable_extension "pgcrypto" if using_pg - create_table :users, id: (using_pg ? :uuid : :bigint), if_not_exists: true do |t| - t.string :name - t.string :tag - end + create_table :users, id: (using_pg ? :uuid : :bigint), if_not_exists: true do |t| + t.string :name + t.string :tag + end - create_table :posts, if_not_exists: true do |t| - t.text :text - if using_pg - t.uuid :user_id - else - t.bigint :user_id + create_table :posts, if_not_exists: true do |t| + t.text :text + if using_pg + t.uuid :user_id + else + t.bigint :user_id + end + t.foreign_key :users + t.timestamps end - t.foreign_key :users - t.timestamps end -end -ActiveRecord::Base.establish_connection DB_CONFIG_COMMENTS if multi_db? -ActiveRecord::Schema.define do - create_table :comments, if_not_exists: true do |t| - t.string :post_id # String because it could be a UUID - t.string :user_id # String because it could be a UUID - t.string :comment + ActiveRecord::Base.establish_connection DB_CONFIG_COMMENTS if multi_db? + ActiveRecord::Schema.define do + create_table :comments, if_not_exists: true do |t| + t.string :post_id # String because it could be a UUID + t.string :user_id # String because it could be a UUID + t.string :comment + end end end diff --git a/spec/test_prof/before_all_spec.rb b/spec/test_prof/before_all_spec.rb index 26754b91..4e3c1348 100644 --- a/spec/test_prof/before_all_spec.rb +++ b/spec/test_prof/before_all_spec.rb @@ -21,25 +21,21 @@ described_class.adapter = nil end - context "when dry run mode is not enabled" do - before do - allow(TestProf).to receive(:rspec?).and_return(false) - allow(RSpec.configuration).to receive(:dry_run?).and_return(false) - end + let(:dry_run) { false } - it "returns the ActiveRecord adapter" do - expect(described_class.adapter).to eq(TestProf::BeforeAll::Adapters::ActiveRecord) - end + before do + allow(TestProf).to receive(:dry_run?).and_return(dry_run) + end + + it "returns the ActiveRecord adapter" do + expect(described_class.adapter).to eq(TestProf::BeforeAll::Adapters::ActiveRecord) end context "when dry run mode is enabled" do - before do - allow(TestProf).to receive(:rspec?).and_return(true) - allow(RSpec.configuration).to receive(:dry_run?).and_return(true) - end + let(:dry_run) { true } - it "returns nil" do - expect(described_class.adapter).to eq(nil) + it "returns NoopAdapter" do + expect(described_class.adapter).to eq(TestProf::BeforeAll::NoopAdapter) end end end From 56bf28eda402328542a8541ced7164da122039b9 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 23 Aug 2024 11:19:45 +0300 Subject: [PATCH 184/194] style: use 2.7 in .rubocop.yml --- .rubocop.yml | 2 +- lib/test_prof/cops/rspec/aggregate_examples.rb | 4 ++-- lib/test_prof/cops/rspec/aggregate_examples/its.rb | 2 +- lib/test_prof/ext/string_truncate.rb | 2 +- lib/test_prof/rspec_stamp/parser.rb | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 40b38d41..7e947b63 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -13,7 +13,7 @@ AllCops: - 'gemfiles/**/*' DisplayCopNames: true SuggestExtensions: false - TargetRubyVersion: 2.5 + TargetRubyVersion: 2.7 Standard/BlockSingleLineBraces: Enabled: false diff --git a/lib/test_prof/cops/rspec/aggregate_examples.rb b/lib/test_prof/cops/rspec/aggregate_examples.rb index 78837544..51784ee0 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples.rb @@ -123,7 +123,7 @@ class AggregateExamples < ::RuboCop::Cop::Cop def on_block(node) example_group_with_several_examples(node) do |all_examples| example_clusters(all_examples).each do |_, examples| - examples[1..-1].each do |example| + examples[1..].each do |example| add_offense(example, location: :expression, message: message_for(example, examples[0])) @@ -141,7 +141,7 @@ def autocorrect(example_node) range = range_for_replace(examples) replacement = aggregated_example(examples, metadata) corrector.replace(range, replacement) - examples[1..-1].map { |example| drop_example(corrector, example) } + examples[1..].map { |example| drop_example(corrector, example) } end end end diff --git a/lib/test_prof/cops/rspec/aggregate_examples/its.rb b/lib/test_prof/cops/rspec/aggregate_examples/its.rb index 3377689e..47176b94 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/its.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/its.rb @@ -64,7 +64,7 @@ def example_metadata(example) return super unless its?(example.send_node) # First parameter to `its` is not metadata. - example.send_node.arguments[1..-1] + example.send_node.arguments[1..] end def its?(node) diff --git a/lib/test_prof/ext/string_truncate.rb b/lib/test_prof/ext/string_truncate.rb index 7972e438..2953be88 100644 --- a/lib/test_prof/ext/string_truncate.rb +++ b/lib/test_prof/ext/string_truncate.rb @@ -12,7 +12,7 @@ def truncate(limit = 30) head = ((limit - 3) / 2) tail = head + 3 - limit - "#{self[0..(head - 1)]}...#{self[tail..-1]}" + "#{self[0..(head - 1)]}...#{self[tail..]}" end end end diff --git a/lib/test_prof/rspec_stamp/parser.rb b/lib/test_prof/rspec_stamp/parser.rb index 1f1f7442..3a1d01b8 100644 --- a/lib/test_prof/rspec_stamp/parser.rb +++ b/lib/test_prof/rspec_stamp/parser.rb @@ -143,7 +143,7 @@ def parse_const(expr) elsif expr.first == :@const expr[1] elsif expr.first == :const_path_ref - expr[1..-1].map(&method(:parse_const)).join("::") + expr[1..].map(&method(:parse_const)).join("::") end end end From e6a3483c9af03ce685999554e7630afa8a391010 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 3 Sep 2024 18:40:56 +0300 Subject: [PATCH 185/194] fix: ignore scopes in #refind Fixes #306 --- CHANGELOG.md | 2 ++ lib/test_prof/ext/active_record_refind.rb | 2 +- spec/test_prof/ext/active_record_refind_spec.rb | 12 ++++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a81928d..0368cc7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Ignore default scopes in `ActiveRecord::Base#refind`. ([@palkan][]) + ## 1.4.1 (2024-08-23) - Skips loading the ActiveRecord adapter for runs where RSpec --dry-run mode is enabled. ([@devinburnette][]) diff --git a/lib/test_prof/ext/active_record_refind.rb b/lib/test_prof/ext/active_record_refind.rb index fbc2d9cc..d1ff4970 100644 --- a/lib/test_prof/ext/active_record_refind.rb +++ b/lib/test_prof/ext/active_record_refind.rb @@ -12,7 +12,7 @@ module ActiveRecordRefind # # We need it to make sure that the state is clean. def refind - self.class.find(send(self.class.primary_key)) + self.class.unscoped.find(send(self.class.primary_key)) end end end diff --git a/spec/test_prof/ext/active_record_refind_spec.rb b/spec/test_prof/ext/active_record_refind_spec.rb index cf29ba55..80931868 100644 --- a/spec/test_prof/ext/active_record_refind_spec.rb +++ b/spec/test_prof/ext/active_record_refind_spec.rb @@ -17,5 +17,17 @@ expect(ruser).not_to be_equal user expect(ruser.posts.first.text).to eq "clean" end + + it "ignores default scopes" do + scoped_post_class = Class.new(Post) do + default_scope { where.not(text: "dirty") } + end + + post = scoped_post_class.create!(text: "dirty") + + rpost = post.refind + + expect(rpost.text).to eq "dirty" + end end end From 7d180511bf19ae7ef2817c438e4dd62e8ccec417 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 3 Sep 2024 21:14:35 +0300 Subject: [PATCH 186/194] fix(ci): use latest factory_bot with rails master --- gemfiles/railsmaster.gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gemfiles/railsmaster.gemfile b/gemfiles/railsmaster.gemfile index 99d31498..2f1f53cf 100644 --- a/gemfiles/railsmaster.gemfile +++ b/gemfiles/railsmaster.gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" gem "rails", github: "rails/rails", branch: "main" gem "fabrication" -gem "factory_bot", "~> 5.0" +gem "factory_bot", "~> 6" gem "sqlite3", "~> 2.0" gem "sidekiq", "~> 4.0" gem "timecop", "~> 0.9.1" From d722d9f7d3c63bb7aaf54f33ee1267fded688043 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 3 Sep 2024 21:24:35 +0300 Subject: [PATCH 187/194] fix: active_support vs. factory_bot --- lib/test_prof/factory_bot.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_prof/factory_bot.rb b/lib/test_prof/factory_bot.rb index 7723c6ae..f3875961 100644 --- a/lib/test_prof/factory_bot.rb +++ b/lib/test_prof/factory_bot.rb @@ -3,7 +3,7 @@ module TestProf # :nodoc: all FACTORY_GIRL_NAMES = {"factory_bot" => "::FactoryBot", "factory_girl" => "::FactoryGirl"}.freeze - TestProf.require("active_support/inflector") + TestProf.require("active_support") FACTORY_GIRL_NAMES.find do |name, cname| TestProf.require(name) do From 830e4540826f3d70ee4d7e045ae8ac64ba7eb2f8 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 3 Sep 2024 21:39:49 +0300 Subject: [PATCH 188/194] Bump 1.4.2 --- CHANGELOG.md | 2 ++ lib/test_prof/version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0368cc7a..5d459f29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 1.4.2 (2024-09-03) 🗓️ + - Ignore default scopes in `ActiveRecord::Base#refind`. ([@palkan][]) ## 1.4.1 (2024-08-23) diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index d8f54211..db521262 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.4.1" + VERSION = "1.4.2" end From 83971c9860f61ae71cb7290e9ce5a098834769d9 Mon Sep 17 00:00:00 2001 From: aseroff Date: Tue, 15 Oct 2024 15:47:08 -0500 Subject: [PATCH 189/194] Migrates to rubocop v1 see https://github.com/rubocop/rubocop/blob/6b30b0323e5e6ca83067631f6cf2cbc13b6a8f92/docs/modules/ROOT/pages/v1_upgrade_notes.adoc#L12 --- .../cops/rspec/aggregate_examples.rb | 30 ++++++++----------- .../cops/rspec/aggregate_examples/its.rb | 2 +- .../aggregate_examples/line_range_helpers.rb | 2 +- .../matchers_with_side_effects.rb | 2 +- .../aggregate_examples/metadata_helpers.rb | 2 +- .../rspec/aggregate_examples/node_matchers.rb | 2 +- lib/test_prof/factory_doctor.rb | 3 +- 7 files changed, 18 insertions(+), 25 deletions(-) diff --git a/lib/test_prof/cops/rspec/aggregate_examples.rb b/lib/test_prof/cops/rspec/aggregate_examples.rb index 51784ee0..f6fcdd8f 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples.rb @@ -108,7 +108,8 @@ module RSpec # expect(number).to be_odd # end # - class AggregateExamples < ::RuboCop::Cop::Cop + class AggregateExamples < ::RuboCop::Cop::Base + extend AutoCorrector include LineRangeHelpers include MetadataHelpers include NodeMatchers @@ -123,29 +124,22 @@ class AggregateExamples < ::RuboCop::Cop::Cop def on_block(node) example_group_with_several_examples(node) do |all_examples| example_clusters(all_examples).each do |_, examples| - examples[1..].each do |example| + examples.drop(1).each do |example| add_offense(example, - location: :expression, - message: message_for(example, examples[0])) + message: message_for(example, examples[0])) do |corrector| + clusters = example_clusters_for_autocorrect(example) + clusters.each do |metadata, examples| + range = range_for_replace(examples) + replacement = aggregated_example(examples, metadata) + corrector.replace(range, replacement) + examples.drop(1).map { |example| drop_example(corrector, example) } + end + end end end end end - def autocorrect(example_node) - clusters = example_clusters_for_autocorrect(example_node) - return if clusters.empty? - - lambda do |corrector| - clusters.each do |metadata, examples| - range = range_for_replace(examples) - replacement = aggregated_example(examples, metadata) - corrector.replace(range, replacement) - examples[1..].map { |example| drop_example(corrector, example) } - end - end - end - private # Clusters of examples in the same example group, on the same nesting diff --git a/lib/test_prof/cops/rspec/aggregate_examples/its.rb b/lib/test_prof/cops/rspec/aggregate_examples/its.rb index 47176b94..979f618f 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/its.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/its.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module RSpec - class AggregateExamples < ::RuboCop::Cop::Cop + class AggregateExamples < ::RuboCop::Cop::Base # @example `its` # # # Supports regular `its` call with an attribute/method name, diff --git a/lib/test_prof/cops/rspec/aggregate_examples/line_range_helpers.rb b/lib/test_prof/cops/rspec/aggregate_examples/line_range_helpers.rb index dc14a30e..ca37e10d 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/line_range_helpers.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/line_range_helpers.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module RSpec - class AggregateExamples < ::RuboCop::Cop::Cop + class AggregateExamples < ::RuboCop::Cop::Base # @internal Support methods for keeping newlines around examples. module LineRangeHelpers include RangeHelp diff --git a/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb b/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb index 21af5b5f..0540bc04 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb @@ -5,7 +5,7 @@ module RuboCop module Cop module RSpec - class AggregateExamples < ::RuboCop::Cop::Cop + class AggregateExamples < ::RuboCop::Cop::Base # When aggregated, the expectations will fail when not supposed to or # have a risk of not failing when expected to. One example is # `validate_presence_of :comment` as it leaves an empty comment after diff --git a/lib/test_prof/cops/rspec/aggregate_examples/metadata_helpers.rb b/lib/test_prof/cops/rspec/aggregate_examples/metadata_helpers.rb index 25b0c80d..291c0251 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/metadata_helpers.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/metadata_helpers.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module RSpec - class AggregateExamples < ::RuboCop::Cop::Cop + class AggregateExamples < ::RuboCop::Cop::Base # @internal # Support methods for example metadata. # Examples with similar metadata are grouped. diff --git a/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb b/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb index 40e77e63..1faa2b77 100644 --- a/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb +++ b/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb @@ -5,7 +5,7 @@ module RuboCop module Cop module RSpec - class AggregateExamples < ::RuboCop::Cop::Cop + class AggregateExamples < ::RuboCop::Cop::Base # @internal # Node matchers and searchers. module NodeMatchers diff --git a/lib/test_prof/factory_doctor.rb b/lib/test_prof/factory_doctor.rb index 9c564f28..1d4c1f23 100644 --- a/lib/test_prof/factory_doctor.rb +++ b/lib/test_prof/factory_doctor.rb @@ -105,10 +105,9 @@ def result # Do not analyze code within the block def ignore @ignored = true - res = yield + yield ensure @ignored = false - res end def ignore! From 95d3c7ffc763d077eac7b309703454a2eeb23f3f Mon Sep 17 00:00:00 2001 From: aseroff Date: Tue, 15 Oct 2024 15:55:41 -0500 Subject: [PATCH 190/194] changelog entry, revert change made to get rubocop to pass --- CHANGELOG.md | 2 ++ lib/test_prof/factory_doctor.rb | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d459f29..761716a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Updates Rubocop::Cop code to comply with most modern API. ([@aseroff][]) + ## 1.4.2 (2024-09-03) 🗓️ - Ignore default scopes in `ActiveRecord::Base#refind`. ([@palkan][]) diff --git a/lib/test_prof/factory_doctor.rb b/lib/test_prof/factory_doctor.rb index 1d4c1f23..9c564f28 100644 --- a/lib/test_prof/factory_doctor.rb +++ b/lib/test_prof/factory_doctor.rb @@ -105,9 +105,10 @@ def result # Do not analyze code within the block def ignore @ignored = true - yield + res = yield ensure @ignored = false + res end def ignore! From b19f5b981ff62d76cd3add01c88b1f299e7da049 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 23 Oct 2024 20:50:19 +0900 Subject: [PATCH 191/194] style: rubocop --- lib/test_prof/factory_doctor.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/test_prof/factory_doctor.rb b/lib/test_prof/factory_doctor.rb index 9c564f28..1d4c1f23 100644 --- a/lib/test_prof/factory_doctor.rb +++ b/lib/test_prof/factory_doctor.rb @@ -105,10 +105,9 @@ def result # Do not analyze code within the block def ignore @ignored = true - res = yield + yield ensure @ignored = false - res end def ignore! From deb2a04f440b8595d5e4d9cc85e2a3815e290155 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Mon, 2 Dec 2024 13:14:27 -0800 Subject: [PATCH 192/194] backers: @Jwaterhouse052 Thanks! --- BACKERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BACKERS.md b/BACKERS.md index f5260794..25793878 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -10,3 +10,4 @@ - [Makar Ermokhin](https://github.com/Earendil95) - [Burkhard Vogel-Kreykenbohm](https://github.com/bvogel) - [Charles Sistovaris](https://github.com/charly) +- [@Jwaterhouse052](https://github.com/Jwaterhouse052) From c73b64d9b5b4fd63360e92c47f1a331ee9850276 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Fri, 13 Dec 2024 16:46:34 -0800 Subject: [PATCH 193/194] fix: handle new connection pools in before_all Ref #310 --- .github/workflows/rspec.yml | 11 ++- Gemfile | 1 + gemfiles/activerecord8.gemfile | 11 +++ lib/test_prof/any_fixture/dump.rb | 2 +- .../before_all/adapters/active_record.rb | 21 +++++ lib/test_prof/recipes/minitest/before_all.rb | 2 +- .../before_all_any_fixture_multidb_spec.rb | 13 +++ .../before_all_any_fixture_multidb_fixture.rb | 79 +++++++++++++++++++ spec/support/ar_models.rb | 9 ++- 9 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 gemfiles/activerecord8.gemfile create mode 100644 spec/bugs/before_all_any_fixture_multidb_spec.rb create mode 100644 spec/bugs/fixtures/before_all_any_fixture_multidb_fixture.rb diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index b476f68e..89842def 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -24,10 +24,14 @@ jobs: strategy: fail-fast: false matrix: - ruby: [2.7] - gemfile: ["gemfiles/activerecord6.gemfile"] + ruby: [3.3] + gemfile: ["gemfiles/activerecord8.gemfile"] db: ["postgres"] include: + - ruby: 3.3 + gemfile: "gemfiles/activerecord8.gemfile" + db: "postgres" + multi_db: "true" - ruby: 3.3 gemfile: "gemfiles/railsmaster.gemfile" db: "mysql" @@ -39,7 +43,7 @@ jobs: db: "sqlite-file" - ruby: 3.2 gemfile: "gemfiles/activerecord7.gemfile" - db: "sqlite" + db: "sqlite-file" multi_db: "true" - ruby: 3.1 gemfile: "gemfiles/activerecord7.gemfile" @@ -95,4 +99,3 @@ jobs: - name: Run RSpec run: | bundle exec rspec --force-color - diff --git a/Gemfile b/Gemfile index bf1e674a..ef7699aa 100644 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,7 @@ else gem "activerecord-jdbcsqlite3-adapter" end + gem "pg" gem "activerecord", "~> 7.0" gem "actionview" gem "actionpack" diff --git a/gemfiles/activerecord8.gemfile b/gemfiles/activerecord8.gemfile new file mode 100644 index 00000000..9e5a056b --- /dev/null +++ b/gemfiles/activerecord8.gemfile @@ -0,0 +1,11 @@ +source 'https://rubygems.org' + +gem "activerecord", "~> 8.0" +gem "factory_bot" +gem "fabrication" +gem "sqlite3", "~> 2.0" +gem "sidekiq" +gem "timecop" +gem "pg" + +gemspec path: '..' diff --git a/lib/test_prof/any_fixture/dump.rb b/lib/test_prof/any_fixture/dump.rb index 7dc037ac..82d33cc2 100644 --- a/lib/test_prof/any_fixture/dump.rb +++ b/lib/test_prof/any_fixture/dump.rb @@ -69,7 +69,7 @@ def finish(_event, _id, payload) end def commit - return unless defined?(:@file) + return unless instance_variable_defined?(:@file) file.close diff --git a/lib/test_prof/before_all/adapters/active_record.rb b/lib/test_prof/before_all/adapters/active_record.rb index 5b249db3..cdf90f34 100644 --- a/lib/test_prof/before_all/adapters/active_record.rb +++ b/lib/test_prof/before_all/adapters/active_record.rb @@ -10,6 +10,7 @@ module ActiveRecord class << self if ::ActiveRecord::Base.connection.pool.respond_to?(:pin_connection!) def begin_transaction + subscribe! ::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).each do |pool| pool.pin_connection!(true) end @@ -19,6 +20,26 @@ def rollback_transaction ::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).each do |pool| pool.unpin_connection! end + unsubscribe! + end + + def subscribe! + Thread.current[:before_all_connection_subscriber] = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload| + connection_name = payload[:connection_name] if payload.key?(:connection_name) + shard = payload[:shard] if payload.key?(:shard) + next unless connection_name + + pool = ::ActiveRecord::Base.connection_handler.retrieve_connection_pool(connection_name, shard: shard) + next unless pool && pool.role == :writing + + pool.pin_connection!(true) + end + end + + def unsubscribe! + return unless Thread.current[:before_all_connection_subscriber] + ActiveSupport::Notifications.unsubscribe(Thread.current[:before_all_connection_subscriber]) + Thread.current[:before_all_connection_subscriber] = nil end else def all_connections diff --git a/lib/test_prof/recipes/minitest/before_all.rb b/lib/test_prof/recipes/minitest/before_all.rb index 5d88449f..da43b85b 100644 --- a/lib/test_prof/recipes/minitest/before_all.rb +++ b/lib/test_prof/recipes/minitest/before_all.rb @@ -104,7 +104,7 @@ def included(base) if base.respond_to?(:parallelize_teardown) base.parallelize_teardown do last_klass = ::Minitest.previous_klass - if last_klass&.respond_to?(:parallelized) && last_klass&.parallelized + if last_klass&.respond_to?(:parallelized) && last_klass.parallelized last_klass.before_all_executor&.deactivate! end end diff --git a/spec/bugs/before_all_any_fixture_multidb_spec.rb b/spec/bugs/before_all_any_fixture_multidb_spec.rb new file mode 100644 index 00000000..a57e176f --- /dev/null +++ b/spec/bugs/before_all_any_fixture_multidb_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# https://github.com/test-prof/test-prof/issues/310 +describe "before_all + any_fixture + multidb", type: :integration do + specify "works" do + output = run_rspec( + "before_all_any_fixture_multidb", + chdir: File.join(__dir__, "fixtures") + ) + + expect(output).to include("0 failures") + end +end diff --git a/spec/bugs/fixtures/before_all_any_fixture_multidb_fixture.rb b/spec/bugs/fixtures/before_all_any_fixture_multidb_fixture.rb new file mode 100644 index 00000000..6ee710b0 --- /dev/null +++ b/spec/bugs/fixtures/before_all_any_fixture_multidb_fixture.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +require "action_controller/railtie" +require "action_view/railtie" +require "active_record/railtie" +require "rspec/rails" + +require_relative "../../support/ar_models" + +RSpec.configure do |config| + config.fixture_path = File.join(__dir__, "fixtures") + config.use_transactional_fixtures = true +end + +require "test_prof/recipes/rspec/before_all" +require "test_prof/recipes/rspec/let_it_be" +require "test_prof/recipes/rspec/any_fixture" + +RSpec.configure do |config| + config.include TestProf::FactoryBot::Syntax::Methods + + config.before(:suite) do + TestProf::AnyFixture.register(:user) { TestProf::FactoryBot.create(:user) } + end +end + +# ActiveSupport::Notifications.subscribe("transaction.active_record") do |event| +# puts "[TRANSACTION] #{event.payload[:outcome].upcase} #{event.payload[:connection].inspect} from: #{caller_locations.find { |l| l.to_s.include?(Rails.root.to_s) }&.to_s}" +# end + +# TestProf::BeforeAll.configure do |config| +# config.before(:begin) do +# puts "[BEFORE_ALL] connection pools #{::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).map(&:inspect)}" +# end + +# config.before(:rollback) do +# puts "[BEFORE_ALL] connection pools before unpin_connection! #{::ActiveRecord::Base.connection_handler.connection_pool_list(:writing).map(&:inspect)}" +# end +# end + +describe "let_it_be vs lazy multi db" do + let_it_be(:user) { TestProf::FactoryBot.create(:user) } + + # Loading an AR class with a custom DB configuration + # triggers a new connection pool creation that hasn't been tracked by + # before_all... + let!(:dual_comments_class) do + Class.new(ApplicationRecord) do + def self.name + "DualCommentsRecord" + end + + self.abstract_class = true + + connects_to database: {writing: :comments, reading: :primary} if multi_db? + end.then do |record_class| + Class.new(record_class) do + self.table_name = "comments" + + belongs_to :user, dependent: :destroy + end + end + end + + specify do + expect(User.count).to eq 2 + + dual_comments_class.create!(user: user, comment: "Hello!") + end + + specify do + expect(TestProf::FactoryBot.create(:comment)).to be_present + expect(Comment.count).to eq 1 + end + + context "with clean fixture", :with_clean_fixture do + specify { expect(User.count).to eq 0 } + end +end diff --git a/spec/support/ar_models.rb b/spec/support/ar_models.rb index 5dbfa438..586f75da 100644 --- a/spec/support/ar_models.rb +++ b/spec/support/ar_models.rb @@ -57,12 +57,12 @@ def multi_db? db_comments_path = File.join(TestProf.config.output_dir, "testdb_comments.sqlite") FileUtils.rm(db_comments_path) if File.file?(db_comments_path) DB_CONFIG_COMMENTS = {adapter: "sqlite3", database: db_comments_path} - ActiveRecord::Base.configurations = {test: {comments: DB_CONFIG_COMMENTS, posts: DB_CONFIG}} + ActiveRecord::Base.configurations = {test: {primary: DB_CONFIG, comments: DB_CONFIG_COMMENTS}} class ApplicationRecord < ActiveRecord::Base self.abstract_class = true - connects_to database: {writing: :posts, reading: :posts} + connects_to database: {writing: :primary, reading: :primary} end class CommentsRecord < ApplicationRecord @@ -126,6 +126,11 @@ class Comment < ApplicationRecord end end +if multi_db? + ActiveRecord::Base.establish_connection + CommentsRecord.establish_connection DB_CONFIG_COMMENTS +end + ActiveRecord::Base.logger = if ENV["DEBUG"] Logger.new($stdout) From dc3a0f6efe22dafa9e5c787540e2608fb5d3c4aa Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Wed, 18 Dec 2024 14:02:14 -0800 Subject: [PATCH 194/194] Bump 1.4.3 --- CHANGELOG.md | 4 ++++ lib/test_prof/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 761716a5..aafea41c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +## 1.4.3 (2024-12-18) + +- Fix handling new (lazy) connection pools in `before_all`. ([@palkan][]) + - Updates Rubocop::Cop code to comply with most modern API. ([@aseroff][]) ## 1.4.2 (2024-09-03) 🗓️ diff --git a/lib/test_prof/version.rb b/lib/test_prof/version.rb index db521262..1c7df1c0 100644 --- a/lib/test_prof/version.rb +++ b/lib/test_prof/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module TestProf - VERSION = "1.4.2" + VERSION = "1.4.3" end

- TestProf map + TestProf map