调试Rspec Postgres锁定



我正在尝试测试一个使用gem devise_token_auth的应用程序,它基本上在几乎每个请求上都包括几个额外的DB读/写(用于验证和更新用户访问令牌)。

除了测试包含几个额外数据库读/写的控制器操作外,一切都很正常。在这些情况下,终端锁定,我被迫通过活动监视器终止ruby进程。

有时我会收到这样的错误消息:

ruby /Users/evan/.rvm/gems/ruby-2.1.1/bin/rspec spec/controllers/api/v1/messages_controller_spec.rb(1245,0x7fff792bf310) malloc: *** error for object 0x7ff15fb73c00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

我不知道该怎么解释。我敢肯定90%的问题是由于这个gem和它在每个请求上引起的额外DB活动造成的,因为当我恢复到以前的、强度较低的身份验证时,所有问题都会消失。我还通过给postgres一些额外的时间进行违规测试来控制局面:

after :each do
  sleep 2
end

这适用于除一种情况外的所有情况,这种情况需要在expect之前超时,否则会抛出以下错误:

Failure/Error: expect(@user1.received_messages.first.read?).to eq true
     ActiveRecord::StatementInvalid:
       PG::UnableToSend: another command is already in progress
       : SELECT  "messages".* FROM "messages"  WHERE "messages"."receiver_id" = $1  ORDER BY "messages"."id" ASC LIMIT 1

对我来说,这再次指向DB问题。

我还能做些什么来追踪/控制这些错误吗?我应该调查任何rspec设置吗?

如果您正在运行并行rspec任务,则可能会触发此操作。当我们遇到这样的问题时,我们使用标记强制这些测试在CI中的rspec的单个非并行实例中运行。

试试这样的东西:

  context 'when both records get updated in one job', non_parallel do
    it { is_expected.to eq 2 }
  end

然后在non_parallel标记上单独调用rspec:

  rspec --tag non_parallel

为了提高性能,您的大部分测试(未标记为non_parallel)仍然可以在CI解决方案(例如Jenkins)中并行运行。

当然,使用这个创可贴要小心。最好在代码中识别出不安全的种族,因为种族可能发生在现实世界中。

最新更新