I have a set of Test::Unit tests for a Rails application. It was developed on OS X under Ruby 1.8.6, Rails 2.3.4.
I’m also using thoughtbot-shoulda 2.10.2.
I’m using standard Rails fixtures, not factories.
I’ve checked out the project onto a CentOS Linux 5 workstation for another developer to work on. He’s running Ruby 1.8.7.
(The app is running on CentOS Linux 5 in production, and it’s working fine there.)
On my coworker’s CentOS dev machine, all of the unit tests are passing.
However, most, but not all, of the functional tests are erroring out. I’ve isolated one test (removing all the others from the project) to narrow down the troubleshooting scope.
context 'on DELETE to :destroy' do
setup {
delete(:destroy, { :id => addresses(:mary_publics_address).id }, stans_id)
}
should 'delete the address' do
assert Address.find(:all, :conditions => {
:id => addresses(:mary_publics_address).id
} ).blank?
end
should 'delete the addresses phone numbers' do
assert PhoneNumber.find(:all, :conditions => {
:id => phone_numbers(:mary_publics_phone_number).id
} ).blank?
end
end
The error we’re getting is…
[abc@abc contactdb]$ rake test:functionals --trace
(in /home/abc/projects/contactdb)
[ ... ]
/usr/local/ruby_187/bin/ruby -I"lib:test" "/home/abc/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/addresses_controller_test.rb"
Loaded suite /home/abc/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.E
Finished in 0.426749 seconds.
1) Error:
test: on DELETE to :destroy should delete the addresses phone numbers. (AddressesControllerTest):
ActiveRecord::RecordNotFound: Couldn't find Address with ID=1254595889
/test/functional/addresses_controller_test.rb:107:in `__bind_1255114457_160068'
/usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:369:in `call'
/usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:369:in `run_current_setup_blocks'
/usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:368:in `each'
/usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:368:in `run_current_setup_blocks'
/usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:350:in `test: on DELETE to :destroy should delete the addresses phone numbers. '
2 tests, 1 assertions, 0 failures, 1 errors
rake aborted!
Command failed with status (1): [/usr/local/ruby_187/bin/ruby -I"lib:test" ...]
I think the key mystery is why it can’t find the Address with that ID.
Another factor is that when I comment out this block, the remaining test passes.
should 'delete the addresses phone numbers' do
assert PhoneNumber.find(:all, :conditions => {
:id => phone_numbers(:mary_publics_phone_number).id
} ).blank?
end
Anyone seen this before?
Troubleshooting suggestions?
One thing to realize about
Hashes in Ruby is that they don’t retain ordering. I’ve had problems before that change the hash ordering depending on what code is loaded in memory — even adding aputs "foo"somewhere would make a bug go away because I didn’t realize the ordering of theHashmade a difference somewhere deep in the code. (Note:Hashdoes retain ordering in 1.9.1, specificly because of problems like that, if I were to guess.) This is consistent with what you say about how commenting out code makes other code pass. Since most fixtures are read in usingYAMLasHashes, it’s reasonable to think this might be a cause. Finding someplace thatHashordering (i.e. in something likeeach) makes a difference may or may not make sense in your case. If nothing else, it’s something to keep in mind.Have you tried using
Fixtures.identify(:mary_publics_phone_number)instead ofphone_numbers(:mary_publics_phone_number).id? (See also: Fixtures documentation.) Another thing to keep in mind: you may not have unique fixture names. I’d check for duplicates, just in case. I know a lot of people who just copy and paste fixtures because they don’t know aboutYAML‘s ability to give default values. In the process, they might forget to change the fixture’s name. Example:Another issue I’ve had when moving from OS X to Linux is subtle differences in the Ruby version. (Even if both report 1.8.6, keep in mind that the patchlevel matters.) It used to be the case that the Red Hat version of Ruby had a memory leak in the garbage collector that required us to restart long running processes on occasion. (Before we realized what was going on, it created some hard to find bugs as they wouldn’t happen for a long time.) Since CentOS is related to Red Hat (basically the same as RHEL), I could imagine other version differences causing issues. I know OS X never had the memory leak problem I described, which made it even harder to narrow the bug down. As far as differences go between 1.8.6 and 1.8.7, you’ll have to refer to the change logs. Be aware that the version of Ruby built from source and the packaged version could behave differently — I think the memory leak problem was introduced by whoever packaged Ruby.
Those are only a few possible causes. Please report back with what you find!