调试Rspec Postgres锁定

use*_*314 11 postgresql rspec ruby-on-rails

我正在尝试测试一个使用的应用程序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
Run Code Online (Sandbox Code Playgroud)

我不知道如何解释.我90%确定问题是由于这个gem以及它在每个请求中引起的额外数据库活动,因为当我恢复到之前的,不那么密集的身份验证时,所有问题都会消失.我还通过给予postgres一些额外的时间来处理违规测试,从而使事情得到控制:

after :each do
  sleep 2
end
Run Code Online (Sandbox Code Playgroud)

这适用于除一个之外的所有情况,这需要在之前超时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
Run Code Online (Sandbox Code Playgroud)

对我来说,再次指向数据库问题.

还有什么我可以做的来追踪/控制这些错误吗?我应该研究一下任何rspec设置?

Dav*_*mpy 0

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

尝试这样的事情:

  context 'when both records get updated in one job', non_parallel do
    it { is_expected.to eq 2 }
  end
Run Code Online (Sandbox Code Playgroud)

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

  rspec --tag non_parallel
Run Code Online (Sandbox Code Playgroud)

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

当然,使用这个创可贴时要小心。识别代码中的非竞争安全总是更好,因为这种竞争可能在现实世界中发生。