Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Spec involving Mutex passes in 3.8 but fails in 3.9 #1327

Closed
johann-koebbe-vericity opened this issue Apr 26, 2020 · 4 comments
Closed

Spec involving Mutex passes in 3.8 but fails in 3.9 #1327

johann-koebbe-vericity opened this issue Apr 26, 2020 · 4 comments

Comments

@johann-koebbe-vericity
Copy link

Subject of the issue

This comes from a project that hasn't been updated in a few years, but I was recently bringing into the modern day. A spec involving the use of Mutex.new passes in 3.8 but fails in 3.9. I believe it is related to the change in rspec-mocks 3.9 that improves thread safety by using Mutex.

Your environment

  • Ruby version: ruby 2.7.0p0 (currently, but experienced in 2.5 and 2.6 as well)
  • rspec-mocks version: 3.8.2 (working), 3.9.1 (failing)

Steps to reproduce

class Mootex
  def mootex
    @mootex ||= Mutex.new
  end
end

RSpec.describe Mootex do
  describe 'memoization' do
    subject { described_class.new }

    it 'creates a mootex when one is not available' do
      subject.instance_variable_set('@mootex', nil)
      expect(Mutex).to receive(:new)
      subject.mootex
    end

    it 'does not create a mootex when one is available' do
      subject.instance_variable_set('@mootex', 'mootex')
      expect(Mutex).not_to receive(:new)
      subject.mootex
    end
  end
end

Expected behavior

Both specs should pass.

Actual behavior

  1) Mootex memoization creates a mootex when one is not available
     Failure/Error: @mootex ||= Mutex.new

     NoMethodError:
       undefined method `synchronize' for #<Object:0x0000000002376430>
@pirj
Copy link
Member

pirj commented Apr 26, 2020

I guess there's some overlap with Support::Mutex.new, but making expectations on ::Mutex doesn't change the situation. 🤔

@JonRowe
Copy link
Member

JonRowe commented Apr 26, 2020

This happens because we use Mutex when it is available to make mocks threadsafe, there is no real Support::Mutex except on 1.8.7, but we've done this by simply assigning the class to the constant.

See rspec/rspec-support#411

@JonRowe
Copy link
Member

JonRowe commented Apr 26, 2020

Closing here now, as the fix is over in rspec-support, however as a work around you could add and_call_original to generate mutexes.

@JonRowe JonRowe closed this as completed Apr 26, 2020
@johann-koebbe-vericity
Copy link
Author

@JonRowe Thanks for the quick reply/fix! I tried

    it 'creates a mootex when one is not available' do
      subject.instance_variable_set('@mootex', nil)
      expect(Mutex).to receive(:new).and_call_original
      subject.mootex
    end

but got the same error. It's not a big deal, though, since you already have a fix in place. I'll just leave the project pinned at 3.8.x until the fix hits the wild.

Many thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants