require 'test_helper' class TestResquePluginsStatus < Minitest::Test describe "Resque::Plugins::Status" do before do Resque.redis.flushall end describe ".create" do describe "not inline" do before do @uuid = WorkingJob.create('num' => 100) end it "add the job to the queue" do assert_equal 1, Resque.size(:statused) end it "set the queued object to the current class" do job = Resque.pop(:statused) assert_equal @uuid, job['args'].first assert_equal "WorkingJob", job['class'] end it "add the uuid to the statuses" do assert_includes Resque::Plugins::Status::Hash.status_ids, @uuid end it "return a UUID" do assert_match(/^\w{32}$/, @uuid) end end describe "inline" do before do Resque.stubs(:inline?).returns(true) end it "not queue a job" do @uuid = WorkingJob.create('num' => 100) assert_equal 0, Resque.size(:statused) end it "call perform" do WorkingJob.any_instance.expects(:perform).once @uuid = WorkingJob.create('num' => 100) end end end describe ".create with a failing before_enqueue hook" do before do @size = Resque.size(:statused) @status_ids_size = Resque::Plugins::Status::Hash.status_ids.length @res = NeverQueuedJob.create(:num => 100) end it "return nil" do assert_equal nil, @res end it "not create a status" do assert_equal @size, Resque.size(:statused) end it "not add the uuid to the statuses" do assert_equal @status_ids_size, Resque::Plugins::Status::Hash.status_ids.length end end describe ".scheduled" do before do @job_args = {'num' => 100} @uuid = WorkingJob.scheduled(:queue_name, WorkingJob, @job_args) end it "create the job with the provided arguments" do job = Resque.pop(:queue_name) assert_equal @job_args, job['args'].last end end describe ".enqueue" do it "delegate to enqueue_to, filling in the queue from the class" do @uuid = BasicJob.enqueue(WorkingJob, :num => 100) @payload = Resque.pop(:statused) assert_equal "WorkingJob", @payload['class'] end end describe ".enqueue_to" do before do @uuid = BasicJob.enqueue_to(:new_queue, WorkingJob, :num => 100) @payload = Resque.pop(:new_queue) end it "add the job with the specific class to the queue" do assert_equal "WorkingJob", @payload['class'] end it "add the arguments to the options hash" do assert_equal @uuid, @payload['args'].first end it "add the uuid to the statuses" do assert_includes Resque::Plugins::Status::Hash.status_ids, @uuid end it "return UUID" do assert_match(/^\w{32}$/, @uuid) end end describe ".dequeue" do before do @uuid1 = BasicJob.enqueue(WorkingJob, :num => 100) @uuid2 = BasicJob.enqueue(WorkingJob, :num => 100) end it "dequeue the job with the uuid from the correct queue" do size = Resque.size(:statused) BasicJob.dequeue(WorkingJob, @uuid2) assert_equal size-1, Resque.size(:statused) end it "not dequeue any jobs with different uuids for same class name" do BasicJob.dequeue(WorkingJob, @uuid2) assert_equal @uuid1, Resque.pop(:statused)['args'].first end end describe ".perform" do let(:expectation) { } before do expectation @uuid = WorkingJob.create(:num => 100) @payload = Resque.pop(:statused) @performed = WorkingJob.perform(*@payload['args']) end it "load load a new instance of the klass" do assert @performed.is_a?(WorkingJob) end it "set the uuid" do assert_equal @uuid, @performed.uuid end it "set the status" do assert @performed.status.is_a?(Resque::Plugins::Status::Hash) assert_equal 'WorkingJob({"num"=>100})', @performed.status.name end describe "before" do let(:expectation) { WorkingJob.any_instance.expects(:perform).once } it("call perform on the inherited class") {} end end describe "manually failing a job" do before do @uuid = FailureJob.create(:num => 100) @payload = Resque.pop(:statused) @performed = FailureJob.perform(*@payload['args']) end it "load load a new instance of the klass" do assert @performed.is_a?(FailureJob) end it "set the uuid" do assert_equal @uuid, @performed.uuid end it "set the status" do assert @performed.status.is_a?(Resque::Plugins::Status::Hash) assert_equal 'FailureJob({"num"=>100})', @performed.status.name end it "be failed" do assert_match(/failure/, @performed.status.message) assert @performed.status.failed? end end describe "killing a job" do before do @uuid = KillableJob.create(:num => 100) @payload = Resque.pop(:statused) Resque::Plugins::Status::Hash.kill(@uuid) assert_includes Resque::Plugins::Status::Hash.kill_ids, @uuid @performed = KillableJob.perform(*@payload['args']) @status = Resque::Plugins::Status::Hash.get(@uuid) end it "set the status to killed" do assert @status.killed? assert !@status.completed? end it "only perform iterations up to kill" do assert_equal 1, Resque.redis.get("#{@uuid}:iterations").to_i end it "not persist the kill key" do refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid end end describe "killing all jobs" do before do @uuid1 = KillableJob.create(:num => 100) @uuid2 = KillableJob.create(:num => 100) Resque::Plugins::Status::Hash.killall assert_includes Resque::Plugins::Status::Hash.kill_ids, @uuid1 assert_includes Resque::Plugins::Status::Hash.kill_ids, @uuid2 @payload1 = Resque.pop(:statused) @payload2 = Resque.pop(:statused) @performed = KillableJob.perform(*@payload1['args']) @performed = KillableJob.perform(*@payload2['args']) @status1, @status2 = Resque::Plugins::Status::Hash.mget([@uuid1, @uuid2]) end it "set the status to killed" do assert @status1.killed? assert !@status1.completed? assert @status2.killed? assert !@status2.completed? end it "only perform iterations up to kill" do assert_equal 1, Resque.redis.get("#{@uuid1}:iterations").to_i assert_equal 1, Resque.redis.get("#{@uuid2}:iterations").to_i end it "not persist the kill key" do refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid1 refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid2 end end describe "invoking killall jobs to kill a range" do before do @uuid1 = KillableJob.create(:num => 100) @uuid2 = KillableJob.create(:num => 100) Resque::Plugins::Status::Hash.killall(0,0) # only @uuid2 it be killed refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid1 assert_includes Resque::Plugins::Status::Hash.kill_ids, @uuid2 @payload1 = Resque.pop(:statused) @payload2 = Resque.pop(:statused) @performed = KillableJob.perform(*@payload1['args']) @performed = KillableJob.perform(*@payload2['args']) @status1, @status2 = Resque::Plugins::Status::Hash.mget([@uuid1, @uuid2]) end it "set the status to killed" do assert !@status1.killed? assert @status1.completed? assert @status2.killed? assert !@status2.completed? end it "only perform iterations up to kill" do assert_equal 100, Resque.redis.get("#{@uuid1}:iterations").to_i assert_equal 1, Resque.redis.get("#{@uuid2}:iterations").to_i end it "not persist the kill key" do refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid1 refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid2 end end describe "with an invoked job" do before do @job = WorkingJob.new('123', {'num' => 100}) end describe "#at" do before do @job.at(50, 100, "At 50%") end it "calculate percent" do assert_equal 50, @job.status.pct_complete end it "set status" do assert @job.status.working? end it "save message" do assert_equal "At 50%", @job.status.message end end describe "#failed" do before do @job.failed("OOOOPS!") end it "set status" do assert @job.status.failed? end it "set message" do assert_equal "OOOOPS!", @job.status.message end end describe "#completed" do before do @job.completed end it "set status" do assert @job.status.completed? end it "set message" do assert_match(/complete/i, @job.status.message) end end describe "#safe_perform!" do before do @job = ErrorJob.new("123") assert_raises(RuntimeError) do @job.safe_perform! end end it "set status as failed" do assert @job.status.failed? end end end end end