When I run the test, I write the following error in the console:
undefined method `split' for nil:NilClass (NoMethodError)
/Users/denis/.rvm/gems/ruby-2.1.1/gems/run_loop 1.2.6/lib/run_loop/sim_control.rb:866:in `block in sim_details'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/run_loop-1.2.6/lib/run_loop/sim_control.rb:863:in `each'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/run_loop-1.2.6/lib/run_loop/sim_control.rb:863:in `sim_details'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/run_loop-1.2.6/lib/run_loop/sim_control.rb:290:in `enable_accessibility_on_sims'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/run_loop-1.2.6/lib/run_loop/core.rb:214:in `run_with_options'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/run_loop-1.2.6/lib/run_loop/core.rb:792:in `run'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/calabash-cucumber-0.12.2/lib/calabash-cucumber/launcher.rb:755:in `block in new_run_loop'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/calabash-cucumber-0.12.2/lib/calabash-cucumber/launcher.rb:753:in `times'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/calabash-cucumber-0.12.2/lib/calabash-cucumber/launcher.rb:753:in `new_run_loop'
/Users/denis/.rvm/gems/ruby-2.1.1/gems/calabash-cucumber-0.12.2/lib/calabash-cucumber/launcher.rb:624:in `relaunch'
/Users/denis/Documents/calabash-test-ios/x-platform-example/features/ios/support/01_launch.rb:27:in `Before'
The test itself is an example from here. Here is the code for one of the errors:
def sim_details(primary_key)
unless xcode_version_gte_6?
raise RuntimeError, 'this method is only available on Xcode >= 6'
end
allowed = [:udid, :launch_name]
unless allowed.include? primary_key
raise ArgumentError, "expected '#{primary_key}' to be one of '#{allowed}'"
end
hash = {}
xctools.instruments(:sims).each do |elm|
launch_name = elm[/\A.+\((\d\.\d(\.\d)? Simulator\))/, 0]
udid = elm[XCODE_6_SIM_UDID_REGEX,0]
sdk_version = elm[/(\d\.\d(\.\d)? Simulator)/, 0].split(' ').first
value =
{
:launch_name => launch_name,
:udid => udid,
:sdk_version => RunLoop::Version.new(sdk_version)
}
if primary_key == :udid
key = udid
else
key = launch_name
end
hash[key] = value
end
hash
end
Run this command: bundle exec cucumber -p ios DEVICE_TARGET="6D45E1...6513"
Can anyone come across?
Does the DEVICE_TARGET UUID actually exist in the list of available simulators?
instruments -s will show you the devices. Switching Xcode versions and not rebooting or restarting the CoreSimulator service can result in the simulator not being found.
Looks like this code sdk_version = elm[/(\d\.\d(\.\d)? Simulator)/, 0] is not returning anything. It seems that you are expecting it to return a string. I would debug in that area.
The error is telling you that your selection is resulting in a nil object which of course has no class, and also as such has no .split method. As a result trying to invoke the .split method is giving you the error that the thing you have there, does not have a .split method defined.
I am a beginner programmer in Ruby and Ruby on Rails , I'm trying to run a rake command in my task , but when I do the following happens:
rake daily_tasks:process_api
rake aborted!
ActiveRecord::AssociationTypeMismatch: Estado(#47392639701120) expected, got NilClass(#47392580444120)
/home/thiagoamaralr/Desktop/proponente-master-4f8a3b2ddb02a90b2c173cf31383505018d02dd/app/services/create_programa_api.rb:21:in `call'
/home/thiagoamaralr/Desktop/proponente-master-74f8a3b2ddb02a90b2c173cf31383505018d02dd/lib/tasks/daily_tasks.rake:7:in `block (3 levels) in <top (required)>'
/home/thiagoamaralr/Desktop/proponente-master-74f8a3b2ddb02a90b2c173cf31383505018d02dd/lib/tasks/daily_tasks.rake:5:in `each'
/home/thiagoamaralr/Desktop/proponente-master-74f8a3b2ddb02a90b2c173cf31383505018d02dd/lib/tasks/daily_tasks.rake:5:in `block (2 levels) in <top (required)>'
Tasks: TOP => daily_tasks:process_api
(See full trace by running task with --trace)
Follow the task I'm trying to run:
namespace :daily_tasks do
desc "Process the day to day tasks"
task process_api: :environment do
SiconvApi::Programa.find.each do |programa|
if programa.data_inicio_recebimento_propostas && (programa.data_inicio_recebimento_propostas.to_date >= Date.parse("2015/06/01"))
CreateProgramaApi.call(SiconvApi::Serializers::Programa.new(programa))
end
end
end
end
And this is content create_programa_api.rb:
class CreateProgramaApi
def self.call(programa_api)
params = programa_api.to_h
params[:orgao] = Orgao.where("lower(name) = ?", programa_api[:orgao][:nome].mb_chars.downcase).first_or_create(name: programa_api[:orgao][:nome])
params[:orgao_vinculado] = Orgao.where("lower(name) = ?", programa_api[:orgao_vinculado][:nome].mb_chars.downcase).first_or_create(name: programa_api[:orgao_vinculado][:nome])
params[:orgao_executor] = Orgao.where("lower(name) = ?", programa_api[:orgao_executor][:nome].mb_chars.downcase).first_or_create(name: programa_api[:orgao_executor][:nome])
params[:estados] = []
if programa_api[:estados].size == 27
params[:estados] << Estado.find_by(sigla: 'Todos')
else
programa_api[:estados].each do |e|
params[:estados] << Estado.find_by(sigla: e)
end
end
params[:atendes] = [Atende.where("lower(name) = ?", programa_api[:atende_a].mb_chars.downcase).first_or_create(name: programa_api[:atende_a])] if programa_api[:atende_a]
params.delete(:atende_a)
programa = Programa.find_by(codigo: programa_api[:codigo])
if programa
programa.update(params)
else
Programa.create! params
end
end
end
Thanks for your attention!
You have nil object in params[:estados], and Rails can't save this association.
Easiest way to remove them is to call params[:estados].compact! after line 14
This block of code is your problem:
params[:estados] = []
if programa_api[:estados].size == 27
params[:estados] << Estado.find_by(sigla: 'Todos')
else
programa_api[:estados].each do |e|
params[:estados] << Estado.find_by(sigla: e)
end
end
If no record is found, the #find_by returns nil. This is why you are getting the error:
ActiveRecord::AssociationTypeMismatch: Estado(#47392639701120) expected, got NilClass
When calling Programa.create!(params).
One solution would be to call params[:estados].compact! after the if statement (this is using Array#compact! to remove any nil values).
Or, you could instead write that section of code like this:
params[:estados] = Estadio.where(
sigla: (programa_api[:estados].size == 27 ? 'Todos' : programa_api[:estados])
)
With this code, there is no longer a need to call compact! since we already end up with an empty array if no records are found (i.e. there are no nil values).
Note that the behaviour here isn't quite the same - what happens if there are multiple Estado records with the sigla equal to one of programa_api[:estados] or 'Todos'? Previously you were only fetching the "first" such record, whereas now you'd be fetching all of them. This may not be an issue (or may even be the correct behaviour!!) - it's just something to be aware of, at least.
I'm writing an Rails 4.2.0 application where I need to deliver emails. I've been advised Que gem for managing background jobs. I've done everything as in installation and usage is listed here.
Also I've specified in application.rb these lines:
# For https://github.com/chanks/que
config.active_record.schema_format = :sql
config.active_job.queue_adapter = :que
My job looks like this send_welcome_message.rb :
class SendWelcomeEmail < Que::Job
# Default settings for this job. These are optional - without them, jobs
# will default to priority 100 and run immediately.
#priority = 10
#run_at = proc { 1.minute.from_now }
def run(user_id, options)
#user = User.find(user_id)
UserMailer.welcome_email(#user).deliver_now
# Destroy the job.
destroy
end
end
After running the rails s command my console is populated with these messages:
{
"lib":"que",
"hostname":"...",
"pid":13938,
"thread":69925811873800,
"event":"job_unavailable"
}
And when I enqueue my job like this in controller
SendWelcomeEmail.enqueue 20, priority: 100
and refresh the page, I get the following errors all the time ( despite I can send messages is sync manner without using que ):
{
"lib":"que",
"hostname":"...",
"pid":13938,
"thread":69925811873800,
"event":"job_errored",
"error":{
"class":"ArgumentError",
"message":"wrong number of arguments (1 for 2)"
},
"job":{
"queue":"",
"priority":100,
"run_at":"2015-06-22T01:59:45.187+03:00",
"job_id":11,
"job_class":"SendWelcomeEmail",
"args":[
20
],
"error_count":2
}
}
And when I open rails console in the second terminal and enter there Que.worker_states (it's written here and should return information about every worker in the system) I get [].
I think that I have no workers spawned. Am I right? And how to fix it?
UPDATE
Found error in que log:
wrong number of arguments (1 for 2)
/home/username/train/project/app/jobs/send_welcome_email.rb:8:in `run'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/job.rb:15:in `_run'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/job.rb:99:in `block in work'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/adapters/active_record.rb:5:in `block in checkout'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:292:in `with_connection'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/adapters/active_record.rb:34:in `checkout_activerecord_adapter'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/adapters/active_record.rb:5:in `checkout'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/job.rb:82:in `work'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/worker.rb:78:in `block in work_loop'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/worker.rb:73:in `loop'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/worker.rb:73:in `work_loop'
/home/username/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/que-0.10.0/lib/que/worker.rb:17:in `block in initialize'
Line 8 is:
def run(user_id, options)
SOLUTION
Now its' working. I've deleted the adapter configuration from application.rb and in place of
SendWelcomeEmail.enqueue 20, priority: 100
wrote
#user = User.find(20)
SendWelcomeEmail.enqueue #user.id, :priority => 100
Now it's works. Funny thing in the second variant the same values are passed to the function. Still error message said that run obtained only 1 argument - 20.
Reading the que gem, it looks like the enqueue method treats priority keyword as a special case: https://github.com/chanks/que/blob/master/lib/que/job.rb#L31
So, your run method is only passed the first argument. The priority keyword gets swallowed by que.
Changing your run method to
def run(user_id)
should fix your issue.
I'm upgrading a Rails 4.0 app to Rails 4.2. All the tests passed prior to the upgrade. However, I am now getting several errors (but no failures). This is the output of one of the tests:
Run options: --seed 30437
# Running:
E
Finished in 1.738307s, 0.5753 runs/s, 0.0000 assertions/s.
/opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.1/lib/action_dispatch/testing/assertions/routing.rb:171:in `method_missing': private method `location' called for #<[MyTestClass]:0xb46557c> (NoMethodError)
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.1/lib/action_dispatch/testing/integration.rb:397:in `method_missing'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest/test.rb:265:in `block in to_s'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest/test.rb:264:in `map'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest/test.rb:264:in `to_s'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:580:in `%'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:580:in `block in aggregated_results'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:579:in `each'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:579:in `each_with_index'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:579:in `each'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:579:in `map'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:579:in `aggregated_results'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:566:in `report'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:638:in `each'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:638:in `report'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:134:in `run'
from /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/minitest-5.6.0/lib/minitest.rb:56:in `block in autorun'
I can't seem to find anything in my code that could be causing this error. Looking at some of the files mentioned in the stacktrace, it looks like it is erroring while trying to generate a failure message. (Double fail...)
What is the cause of this error?
Edit:
The first line of my test is s = login(:user). If I place a return before that line, the test passes, but if I place it after that line, I still get the error. The login function is defined in my test_helper.rb as follows:
def login(user)
open_session do |sess|
u = users(user)
sess.extend(MySession)
sess.get "/users/sign_in"
sess.assert_response :success
sess.post_via_redirect "/users/sign_in",
user: {
email: u.email,
password: "<password>"
}
assert_equal '/', sess.path
assert_equal "Signed in successfully.", sess.flash[:notice]
end
end
The module MySession contains a few helper methods.
Edit 2:
I opened a rails console session, required my test class, and did MyTestClass.private_methods. This was the output:
=> [:initialize, :_stash_object_in_method, :_superclass_delegating_accessor, :included, :extended, :prepended, :method_added, :method_removed, :method_undefined, :initialize_copy, :attr, :attr_reader, :attr_writer, :attr_accessor, :initialize_clone, :remove_const, :using, :remove_method, :undef_method, :alias_method, :public, :protected, :private, :define_method, :attr_internal_ivar_name, :attr_internal_define, :DelegateClass, :Digest, :timeout, :default_src_encoding, :Nokogiri, :irb_binding, :create_fixtures, :load, :require, :initialize_dup, :sprintf, :format, :Integer, :Float, :String, :Array, :Hash, :warn, :raise, :fail, :global_variables, :__method__, :__callee__, :__dir__, :eval, :local_variables, :iterator?, :block_given?, :catch, :throw, :loop, :respond_to_missing?, :trace_var, :untrace_var, :at_exit, :syscall, :open, :printf, :print, :putc, :puts, :gets, :readline, :select, :readlines, :p, :srand, :rand, :trap, :require_relative, :proc, :lambda, :binding, :caller, :caller_locations, :exec, :fork, :exit!, :system, :spawn, :sleep, :exit, :abort, :Rational, :Complex, :set_trace_func, :gem_original_require, :Pathname, :URI, :rubygems_require, :BigDecimal, :j, :jj, :JSON, :not_implemented, :y, :open_uri_original_open, :pp, :singleton_method_added, :singleton_method_removed, :singleton_method_undefined, :method_missing]
Edit 3:
I opened a rails console session, required my test class, and did test = MyTestClass.new and then test.private_methods. This time, the output did contain :location. This app does have a Location model, and this output appeared in between several other of the app's models, so I suspect that is the problem. The question is now: why do my test classes have private methods named after my app's models? How can I fix or work around this problem? (Obviously I could rename the Location model, but I'd prefer to avoid that, if possible.)
Did the location method change from public to private on whatever class you're calling it on between Rails 4.0 and 4.2?
Maybe I'm misunderstanding, but the error seems pretty straightforward. Somewhere (in your code, or maybe a gem you rely on that's changed versions as well) a method called location is being called which is private. The stack track shows you where it's happening, so take a look at that code and see what's going on.
Might also be helpful to see the test code, but the stack trace is pointing you to the source from which you can trace back what's going on.
I looked through the code on github as well and can't find anything. Any chance you defined a method called location on MyTestClass that overrides the one in MiniTest::Test ? Also, if you go into your console and simply require the MyTestClass, and call .private_methods on it (or rather an instance of it), does :location indeed show up in the list? Any include statements anywhere that you can find in your code that might be bringing in a location method into MyTestClass?
It looks like this question/answer might provide a way to track down where these methods are coming from.
Using the .method and .source_location methods from #jefflunt's link, I was able to find the cause of the problem. When I did test.method(:location).source_location from the rails console, I got this output:
=> ["/opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/fixtures.rb", 885]
When I looked up that line in that file, I found a method that defines private accessor methods for each fixture. Since I had fixtures defined for my Location model, that was the cause of this problem.
Since I don't see another way around this problem (aside from perhaps ditching fixtures, which I'm not ready to put time into just yet), I'll be renaming my Location model.
I mitigate the low success rate of a particular operation by running multiple threads and waiting for the first one to return with a valid answer. I've created a minimal example below:
THREADS = [] if !defined?(THREADS)
def threadtest
THREADS.clear
queue, mutex, result = Queue.new, Mutex.new, nil
10.times do |i|
THREADS << Thread.new do
counted = (10e6 + rand(10e6)).to_i.times { } # randomize computation time
num = rand(8) # succeed only 1/8 of the time
#mutex.synchronize do # even if wrapped in mutex
# print "#{User.last.inspect}\n" # deadlocks below if uncommented
#end
queue << [num, counted, i]
end
end
10.times do |i|
result, counted, num = queue.pop # deadlocks here
if result.zero?
puts "#{i}: #{num} succeeds after #{counted} counts"
break
elsif num.present?
puts "#{i}: #{num} failed with #{result} after #{counted} counts"
end
end
THREADS.each(&:exit)
return result
end
30.times { threadtest } # deadlock happens on "high load"
The error looks like:
fatal: deadlock detected
from /usr/lib/ruby/1.9.1/thread.rb:189:in `sleep'
from /usr/lib/ruby/1.9.1/thread.rb:189:in `block in pop'
from <internal:prelude>:10:in `synchronize'
from /usr/lib/ruby/1.9.1/thread.rb:184:in `pop'
from (irb):38:in `block in threadtest'
from (irb):37:in `times'
from (irb):37:in `threadtest'
from (irb):53:in `block in irb_binding'
from (irb):53:in `times'
from (irb):53
from /usr/local/bin/irb:12:in `<main>'
I've tried many variations in an attempt to prevent the deadlock, all to no avail. I can detail some of the experimentations I've done so far if requested. I do have one more idea that I've been avoiding due to the amount of refactoring it'd require in my application.
Is it simply the case that ActiveRecord can't be accessed via multiple threads?
I'll update with a few more details as I think of them.
'deadlock detected' error in rails is the the closest related question I found, but it's got no answers.
I had the same error and had to add the
gem 'net-ssh-gateway'
in the file Gemfile.lock, because the version that was bundled didn't work with the installed ruby. Seems like the dependency wasn't resolved any more in the newer ruby version.