调试 Rspec Postgres 锁定

Posted

技术标签:

【中文标题】调试 Rspec Postgres 锁定【英文标题】:Debugging Rspec Postgres lockups 【发布时间】:2014-11-14 01:54:17 【问题描述】:

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

一切正常,除了在测试包含几个额外数据库读/写的控制器操作时。在这些情况下,终端锁定,我不得不通过活动监视器终止 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 以及它在每个请求上导致的额外数据库活动,因为当我恢复到以前的、不那么密集的身份验证时,所有问题都消失了。我还通过给 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

对我来说,这又指向了数据库问题。

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

【问题讨论】:

从那以后你有没有发现任何线索?我们在 Cucumber 上遇到了类似的问题。 不,删除了导致问题的库 您确定一次只运行一个 RSpec 进程吗?此问题是否同时出现在功能和模型规范中? 【参考方案1】:

如果您正在运行并行 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)中并行运行以提高性能。

当然,使用这种创可贴时要小心。在你的代码中找出不安全的地方总是更好的,因为这种竞争可能发生在现实世界中。

【讨论】:

以上是关于调试 Rspec Postgres 锁定的主要内容,如果未能解决你的问题,请参考以下文章

RSpec 测试失败 - 使用显示套接字但缺少锁定文件

如何使用 pry 调试器检查 rspec 变量

postgres服务之加密

Json 类型列元素更新 - Postgres

使用 Postgres 函数作为 ActiveRecord 模型

致命:连接到 postgres 时用户“postgres”的密码验证失败