Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 测试轨道的轨道状况,然后进行清理_Ruby On Rails_Ruby_Multithreading_Race Condition_Minitest - Fatal编程技术网

Ruby on rails 测试轨道的轨道状况,然后进行清理

Ruby on rails 测试轨道的轨道状况,然后进行清理,ruby-on-rails,ruby,multithreading,race-condition,minitest,Ruby On Rails,Ruby,Multithreading,Race Condition,Minitest,我正在尝试测试我的部分代码是否符合比赛条件。我遇到的问题与唯一性验证有关,事实证明,在rails中,唯一性验证并不安全。我相信我能够解决这个问题,但我不确定如何测试我的解决方案 我最接近的是以下内容(灵感来源:): 上面的代码结构与我的完全相同,但是模型已经变得更加通用 测试本身似乎工作正常。但是,测试中创建的密钥不会在测试之后删除。我正在使用DatabaseCleaner,我尝试了所有不同的策略。此外,有时我会遇到常量键的循环依赖性问题。不知道为什么,但我猜这是因为ruby不要求线程安全 有更

我正在尝试测试我的部分代码是否符合比赛条件。我遇到的问题与唯一性验证有关,事实证明,在rails中,唯一性验证并不安全。我相信我能够解决这个问题,但我不确定如何测试我的解决方案

我最接近的是以下内容(灵感来源:):

上面的代码结构与我的完全相同,但是模型已经变得更加通用

测试本身似乎工作正常。但是,测试中创建的密钥不会在测试之后删除。我正在使用DatabaseCleaner,我尝试了所有不同的策略。此外,有时我会遇到常量键的循环依赖性问题。不知道为什么,但我猜这是因为ruby不要求线程安全

有更好的办法解决我的问题吗?如上所述,我在这方面遇到了一些不同的问题,我觉得这应该是一个足够普遍的问题,应该存在良好的测试标准。

以下几点:

1) 可能是我的无知,但“应该等待”这句话对我来说似乎是错误的。一些更像是
的东西,而你应该等待做
似乎更像你想要的。您还调用了
pod.save
,这似乎没有什么意义,所以我猜这不是您正在使用的代码

2) 我希望数据库清理器能够工作,因为我认为如果使用“截断”策略,它将在测试运行时遍历并截断每个表。我疯狂的猜测是,您已经将它配置为只运行集成测试,这是一个单元测试,或者类似的东西。如果不是这样,请尝试在测试结束时调用
DatabaseCleaner.truncate
(或者以显式方式执行),看看是否有效

3) 在数据库中使用唯一索引可以解决这个问题吗?这样就完全不需要进行此测试,因为您只需要信任您的数据库。当您得到一个非唯一值时,您可以在代码中以非验证的方式处理它。速度也快得多,因为您不必每次保存时都进行额外的sql调用

4) 无法从给出的信息中了解为什么会出现循环依赖性问题。我以前就遇到过这个问题,并且做了一个
将调用者
放在文件的顶部来尝试诊断。

1)循环只是一个丑陋的黑客,以确保所有线程同时启动。关于“pod.save”你是对的,我编辑了它以匹配我的示例。2) 我得试一下。我想我配置它在每次测试后进行清理,但您可能是正确的。3) 是的,这就是我正在使用的解决方案。你是对的,我可以相信DB会正确处理它。不过,我还有一些其他的场景可能更难解决,所以测试比赛条件的一般方法还是不错的。
test "Can't create duplicate keys with same value and keyboard" do
  assert_equal(5, ActiveRecord::Base.connection.pool.size)
  begin
    concurrency_level = 4
    keyboard = create :keyboard
    should_wait = true

    statuses = {}

    threads = Array.new(concurrency_level) do |i|
      Thread.new do
        true while should_wait
        begin
          # Unique validation for key values exists scoped to keyboard
          key = keyboard.keys.new(value: 'a')
          statuses[i] = key.save
        rescue ActiveRecord::RecordNotUnique
          statuses[i] = false
        end
      end
    end
    should_wait = false
    threads.each(&:join)

    assert_equal(1, keyboard.keys.count)
    assert_equal(1, statuses.count { |_k, v| v })
    assert_equal(3, statuses.count { |_k, v| !v })
  ensure
    ActiveRecord::Base.connection_pool.disconnect!
  end
end