使用错误容器的serverspec

时间:2019-04-07 21:28:00

标签: ruby docker rspec serverspec

我有2个spec文件,它们使用不同的docker映像,因此应该启动不同的docker容器来运行示例。

在下面的代码段中,我正在使用serverspec gem来测试我的容器

spec / dockerfile / ember_spec.rb

require 'spec_helper'
require 'shared_examples/release'

describe 'ember' do
  before(:all) do
    @image = Docker::Image.build_from_dir(image_path('ember'))

    set :os, family: :alpine
    set :backend, :docker
    set :docker_image, @image.id
    set :docker_container_create_options, { 'Entrypoint' => ['/bin/sh'] }
  end

  describe command('ember version') do
    its(:stdout) { should contain 'ember-cli: 3.3.0' }
    its(:stdout) { should contain 'node: 10.10.0' }
  end

  include_examples 'os release', 'Alpine Linux'
end

spec / dockerfile / gerbv_spec.rb

require 'spec_helper'
require 'shared_examples/release'

describe 'gerbv' do
  before(:all) do
    @image = Docker::Image.build_from_dir(image_path('gerbv'))

    set :os, family: :debian
    set :backend, :docker
    set :docker_image, @image.id
    set :docker_container_create_options, { 'Entrypoint' => ['/bin/sh'] }
  end

  describe package('gerbv') do
    it { should be_installed }
  end

  include_examples 'os release', 'Ubuntu 18.04'
end

但是,在运行bundle exec rspec时,很明显,同一容器用于运行每个规范文件。我已经通过在每个示例之前打印出正在运行的容器来确认这一点。当然,这会导致其中一个文件的规范失败(以秒为准)。

使用bundle exec rspec path/to/file独立运行文件时,所有规格都会通过。

在运行一个文件中的示例并为另一组示例创建新的容器之后,是否有任何方法可以迫使容器旋转?

1 个答案:

答案 0 :(得分:1)

我找到了一种解决问题的方法,尽管它很笨拙。该问题的关键在于容器最终如何released。当不再有任何指向Docker实例的引用时,将对其进行垃圾回收,并杀死并删除该容器。但是,对象实例在base class中作为单例保存在类级别的变量中。在我看来,“重置” specinfra的唯一方法是调用在clear类上继承的Docker方法。

最后,以下内容解决了该问题,并且使用正确的类来运行每个规范。

after(:all) {
  Specinfra.backend.class.clear
}

很高兴知道有一种更好的方法可以访问此方法,而不必依赖未通过serverspec gem公开的方法。