diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8075373be6..e2e4abbb52 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -297,3 +297,26 @@ jobs: bundle install --local || bundle install bundle exec rake compile -- --${{matrix.sys}}-system-libraries bundle exec rake test + + memcheck: + continue-on-error: true # this is experimental! + strategy: + fail-fast: false + matrix: + sys: ["disable"] + ruby: ["3.0"] + runs-on: ubuntu-latest + container: + image: ghcr.io/sparklemotion/nokogiri-test:mri-${{matrix.ruby}} + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - uses: actions/cache@v2 + if: matrix.sys == 'disable' + with: + path: ports + key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}} + - run: bundle install --local || bundle install + - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries + - run: bundle exec rake test:memcheck diff --git a/nokogiri.gemspec b/nokogiri.gemspec index d9c6896195..7ce50c1790 100644 --- a/nokogiri.gemspec +++ b/nokogiri.gemspec @@ -334,6 +334,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency("rubocop-performance", "~> 1.11") spec.add_development_dependency("rubocop-rake", "~> 0.6") spec.add_development_dependency("rubocop-shopify", "~> 2.3") + spec.add_development_dependency("ruby_memcheck", "~> 1.0") spec.add_development_dependency("simplecov", "~> 0.20") spec.extensions << "ext/nokogiri/extconf.rb" diff --git a/rakelib/test.rake b/rakelib/test.rake index d191968355..19a7bd2bc3 100644 --- a/rakelib/test.rake +++ b/rakelib/test.rake @@ -1,6 +1,7 @@ # frozen_string_literal: true require "rake/testtask" +require "ruby_memcheck" # # much of this was ripped out of hoe-debugging @@ -15,6 +16,11 @@ class ValgrindTestTask < Rake::TestTask "--error-exitcode=#{ERROR_EXITCODE}", "--gen-suppressions=all",] + RubyMemcheck.config( + binary_name: "nokogiri", + valgrind_generate_suppressions: true, + ) + def ruby(*args, **options, &block) valgrind_options = check_for_suppression_file(VALGRIND_OPTIONS) command = "ulimit -s unlimited && valgrind #{valgrind_options.join(" ")} #{RUBY} #{args.join(" ")}" @@ -96,4 +102,8 @@ namespace "test" do LldbTestTask.new("lldb") do |t| nokogiri_test_task_configuration(t) end + + RubyMemcheck::TestTask.new("memcheck") do |t| + nokogiri_test_task_configuration(t) + end end diff --git a/test/helper.rb b/test/helper.rb index a1b29acb72..224525200b 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -12,6 +12,10 @@ # - "stress" - run tests with GC.stress set to true # - NOKOGIRI_GC: read more in test/test_memory_leak.rb # + +# make sure we do one final major before the process exits (for valgrind) +at_exit { GC.start(full_mark: true) } unless ::RUBY_PLATFORM == "java" + require "simplecov" SimpleCov.start do add_filter "/test/"