Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

"Undefined method" errors when running locally or in CI environment (Jenkins on Ubuntu) #174

Closed
damonatbrightroll opened this Issue · 25 comments

9 participants

damonatbrightroll Jason Draper Thibaud Guillaume-Gentil davidjoliver Marko Anastasov Cade Truitt kev_the_dev Paulo Henrique Lopes Ribeiro Gabe Berke-Williams
damonatbrightroll

I also filed this at thoughtbot/shoulda#224, but realized this may be a more appropriate location for it.

When running any of rspec, rake spec, bundle exec rspec, or bundle exec rake spec on my MacBook Pro, I see errors like this when running specs en masse:

$ rspec
....F.FFF.........F.FF..F.FFFFFF.....FF.FFF....F.FFF.....F.FFF......F.FF....F.F...........FFF.FFFF.......FFFFFF.........FF.FF.....F.FFFF.......F.FF.....FFFFF........F.FF..FF.FF.......FFF.FF.....F.FF.....F.FF......F....FF.FFFFF.......FFF....FFFFFF.....

Failures:

  1) Activation associations 
     Failure/Error: it { should belong_to(:line_item) }
     NoMethodError:
       undefined method `belong_to' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_1:0x007fcf9e4b94f0>
     # ./spec/models/activation_spec.rb:7:in `block (3 levels) in <top (required)>'

  2) Activation validations 
     Failure/Error: it { should validate_presence_of(:line_item_id) }
     NoMethodError:
       undefined method `validate_presence_of' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2:0x007fcf9e5f0d00>
     # ./spec/models/activation_spec.rb:15:in `block (3 levels) in <top (required)>'

  3) Activation validations 
     Failure/Error: it { should validate_presence_of(:msg_id) }
     NoMethodError:
       undefined method `validate_presence_of' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2:0x007fcf9e5ee438>
     # ./spec/models/activation_spec.rb:17:in `block (3 levels) in <top (required)>'

  4) Activation validations 
     Failure/Error: it { should ensure_length_of(:msg_id).is_at_most(Activation::MAXIMUM_LENGTH_OF_MSG_ID) }
     NoMethodError:
       undefined method `ensure_length_of' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2:0x007fcf9e5f3b68>
     # ./spec/models/activation_spec.rb:18:in `block (3 levels) in <top (required)>'

etc. The errors seem only to occur against shoulda-style specs. However, I can run individual RSpec files without incident, e.g.,:

$ rspec spec/models/activation_spec.rb 
..............

Top 10 slowest examples (0.03596 seconds, 94.2% of total time):
  Activation associations 
    0.01183 seconds ./spec/models/activation_spec.rb:7
  Activation validations 
    0.00784 seconds ./spec/models/activation_spec.rb:15
  Activation validations should be valid
    0.00515 seconds ./spec/models/activation_spec.rb:11
  Activation validations 
    0.00318 seconds ./spec/models/activation_spec.rb:18
  Activation validations 
    0.00314 seconds ./spec/models/activation_spec.rb:17
  Activation attributes 
    0.00215 seconds ./spec/models/activation_spec.rb:30
  Activation defaults status 
    0.00084 seconds ./spec/models/activation_spec.rb:24
  Activation attributes 
    0.0007 seconds ./spec/models/activation_spec.rb:30
  Activation attributes 
    0.00056 seconds ./spec/models/activation_spec.rb:30
  Activation attributes 
    0.00056 seconds ./spec/models/activation_spec.rb:30

Finished in 0.03919 seconds
14 examples, 0 failures

Here is my Gemfile:

source 'http://rubygems.org'
source 'http://gems.btrll.com'

gem 'rails', '3.2.8'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem 'brxutils'
gem 'mysql2'
gem 'state_machine'

# squeel grants additional ActiveRecord querying goodness without needing to embed SQL in code.
gem 'squeel'

# safe_attributes lets us overcome some legacy column names (e.g., 'errors') that collide with standard Rails-generated
# method names.
gem 'safe_attributes'

# strong_parameters gem should be used to prepare for Rails 4.0.
# See http://weblog.rubyonrails.org/2012/3/21/strong-parameters/
gem 'strong_parameters'

gem 'jquery-rails'
gem 'ar_query_builder', '1.0.1'

gem 'umsclient', '>= 0.4.1', :require => 'umsclient/frameworks/warden'

# used to integrate with other web services
gem 'rest_request', '2.10.1'

# used for role-based authorization
gem 'cancan'

# used for authentication
gem 'rails_warden'

# templating gem for json-based responses
gem 'rabl'

# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# To use Jbuilder templates for JSON
# gem 'jbuilder'

# Use unicorn as the app server
# gem 'unicorn'

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'

gem 'rq_request'
gem 'rq_client', '3.9.1'

gem 'redis'

# Used for stats collection with Graphite
gem 'statsd-ruby', '~> 0.4.0', github: 'jeremy/statsd-ruby', :require => 'statsd'

# needed for BrightRoll's build/deployment system
gem 'brpkg'

# solr support for full-text searching
gem 'sunspot_rails'

# used together with apache/nginx to serve rails applications
gem 'passenger', '3.0.13'

group :test do
  # factory_girl_rails makes it easy to create factories for unit tests.
  gem 'factory_girl_rails'

  # shoulda-matchers provides simpler syntax than vanilla RSpec in some cases.
  gem 'shoulda-matchers', '>= 1.4.0'

  # simplecov provides code coverage report in coverage/index.html.
  gem 'simplecov', :require => false

  # Allow to use/mock solr in tests
  gem 'sunspot-rails-tester'
end

group :development, :test do
  gem 'rspec-rails'

  # local solr server for development env
  gem 'sunspot_solr'

  # used by solr to show indexing progress
  gem 'progress_bar'

  # pretty-formats tables in console
  gem 'hirb'
end

More info:

$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin12.1.0]
$ rails --version
Rails 3.2.8

What's particularly troublesome is that I've got another project with basically the exact same Gemfile (the latter was used as a template for the former) and I've never seen this problem until now.

More information, after running with rspec -b:

Failures:

  1) Activation associations 
     Failure/Error: it { should belong_to(:line_item) }
     NoMethodError:
       undefined method `belong_to' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_1:0x007fc284896928>
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.11.3/lib/rspec/matchers/method_missing.rb:9:in `method_missing'
     # ./spec/models/activation_spec.rb:7:in `block (3 levels) in <top (required)>'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:113:in `instance_eval'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:113:in `block in run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:253:in `with_around_each_hooks'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:110:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:378:in `block in run_examples'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:374:in `map'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:374:in `run_examples'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:360:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `block in run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `map'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `map'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `block in run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/reporter.rb:34:in `report'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:25:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:69:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:8:in `block in autorun'

I am also seeing this in our (Jenkins) CI environment.

Jason Draper
Admin

Can you post your spec_helper as well? I can't see why this issue would occur so I'm hoping that can provide some insight.

damonatbrightroll
require 'simplecov'
SimpleCov.start 'rails'

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'shoulda/matchers'
Dir[File.dirname(__FILE__) + "/spec_helpers/*.rb"].each {|file| require file }

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

DUMMY_ORG_ID = 12345
DUMMY_VALUE = 'some random string'
EMPTY_STRING = ''

RSpec.configure do |config|
  # ## Mock Framework
  #
  # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
  #
  # config.mock_with :mocha
  # config.mock_with :flexmock
  # config.mock_with :rr
  config.mock_with :rspec

  config.include(ControllerMacros, :type => :controller)

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = true

  # If true, the base class of anonymous controllers will be inferred
  # automatically. This will be the default behavior in future versions of
  # rspec-rails.
  config.infer_base_class_for_anonymous_controllers = false

  # FactoryGirl configuration:
  config.include FactoryGirl::Syntax::Methods

  # From https://makandracards.com/makandra/950-speed-up-rspec-by-deferring-garbage-collection
  config.before(:all) do
    DeferredGarbageCollection.start
  end
  config.after(:all) do
    DeferredGarbageCollection.reconsider
  end

  # Sunspot configuration (mock session)
  $original_sunspot_session = Sunspot.session
  config.before do
    Sunspot.session = Sunspot::Rails::StubSessionProxy.new($original_sunspot_session)
  end

  # Sunspot configuration: add ':solr => true' rspec metadata to allow example groups that use this metadata flag
  # to  use the original sunspot session
  config.before :each, :solr => true do
    Sunspot::Rails::Tester.start_original_sunspot_session
    Sunspot.session = $original_sunspot_session
    Sunspot.remove_all!
  end

  config.before(:suite) do
    # From http://robots.thoughtbot.com/post/21719164760/factorygirl-3-2-so-awesome-it-needs-to-be-released
    ActiveSupport::Notifications.subscribe('factory_girl.run_factory') do |name, start, finish, id, payload|
      execution_time_in_seconds = finish - start

      if execution_time_in_seconds >= 0.5
        $stderr.puts "Slow factory: #{payload[:name]} using strategy #{payload[:strategy]}"
      end
    end
  end
end
damonatbrightroll

Here is an entire spec file as well, if that helps. Line numbers of failing tests have changed somewhat from what I pasted above, but the checks are the same.

require 'spec_helper'

describe Activation do
  let(:activation) { Activation.new(:line_item_id => 1, :msg_id => DUMMY_VALUE, :status => Activation::Status::PENDING) }

  describe 'associations' do
    it { should belong_to(:line_item) }
  end

  describe 'validations' do
    it 'should be valid' do
      activation.should be_valid
    end

    it { should validate_presence_of(:line_item_id) }

    it { should validate_presence_of(:msg_id) }
    it { should ensure_length_of(:msg_id).is_at_most(Activation::MAXIMUM_LENGTH_OF_MSG_ID) }

    it { should ensure_inclusion_of(:status).in_array(Activation::Status.values) }
  end

  describe 'defaults' do
    subject { activation }

    its(:status) { should == Activation::Status::PENDING }
  end

  describe 'attributes' do
    [:id, :line_item_id, :msg_id, :status, :errors_text, :warnings_text, :created_at,
     :updated_at].each do |expected_attribute|
      it { should respond_to(expected_attribute) }
    end
  end
end
Jason Draper
Admin

@damonatbrightroll - can you send me an email : draper-at-thoughtbot-dot-com

Thibaud Guillaume-Gentil

We also get this issue on the Semaphore CI, have you been able to fix it? Thanks!

damonatbrightroll

No luck as yet. @drapergeek had two suggestions for us:

  1. Remove simplecov.
  2. Disable "require 'shoulda/matchers'" from our spec_helper.rb.

The former had no effect. The latter immediately broke the build in environments that had otherwise been working. Continuing to investigate, but for now we are disabling all shoulda-related specs until we can resolve this.

damonatbrightroll

@thibaudgg Can you please post your files as I did above so we can compare notes? If you can also paste the platform(s) on which you're building, that would be useful as well.

Thibaud Guillaume-Gentil

Removing the branch and re-adding it seems to have done the trick on Semaphore CI.

@damonatbrightroll We doesn't do anything special in our config, we just have gem 'shoulda-watcher in your Gemfile in test group.

damonatbrightroll

@thibaudgg What do you mean by "removing the branch and re-adding it?" In git or something else?

Thibaud Guillaume-Gentil

@damonatbrightroll it's a feature of Semaphore CI, not in GIt.

davidjoliver

I'm using Jenkins and I'm seeing this as well. @damonatbrightroll any word yet? @thibaudgg I wonder if there is an equivalent...measure one can take within Jenkins...(?)

damonatbrightroll

@davidjoliver: No progress yet, unfortunately. Various shoulda tests remain commented out or replaced with (more verbose) vanilla RSpec for now, particularly should have_many, should have_one, should belong_to, should ensure_inclusion_of, should ensure_length_of, should accept_nested_attributes_for, should validate_presence_of, should validate_uniqueness_of, and possibly one or two others I'm forgetting offhand.

Marko Anastasov

Just to clarify what @thibaudgg mentioned - removing the branch and re-adding it on Semaphore technically means that a repo (together with the cached bundle) is deleted and cloned again. So I think there's some randomness going on.

Jason Draper
Admin

Unfortunately I have not been able to replicate this. If possible I would like to see someone create a bare bones project to replicate this issue. If a failure could be seem without using CI that would also be helpful even if we have to be specific about the OS and setup. Without being able to duplicate the issue my hands are somewhat tied at the moment.

damonatbrightroll

I am on vacation this week but will take a stab at it next week.

damonatbrightroll

I've tried but haven't been able to create a barebones project that demonstrates the bad behavior on my MBP. Anyone else able to do so?

Cade Truitt

I just ran into this issue yesterday, so I was determined to figure out what was going on. I'm not sure if the root cause of your problem is the same as mine, but I was able to create a bare bones project that replicates the issue: https://github.com/cade/shoulda-matchers-goes-boom

Instructions are in the README for how to reproduce and artificially 'fix' the problem. Hope this helps.

kev_the_dev

+1 for any progress?

damonatbrightroll

Post-Thanksgiving bump.

Bruno Alvares da Costa brunoadacosta referenced this issue in DevInSantos/devinsantos-events
Closed

shoulda-matchers não está funcionando #1

Paulo Henrique Lopes Ribeiro

I had this same problem a while ago on a rack project. I solved it by stoping loading shoulda-matchers at Gemfile and loading it inside spec_helper.rb

Gemfile

  gem 'shoulda-matchers', :require => false

spec_helper.rb

  require 'shoulda-matchers'

Hope this helps.

damonatbrightroll

@plribeiro3000 Tried that to no avail.

damonatbrightroll

This seems to be fixed by the merge to master resulting from thoughtbot/shoulda#221 (comment).

Gabe Berke-Williams
Admin

Fantastic! I'll close this then.

Gabe Berke-Williams gabebw closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.