serverspec 使用了错误的容器
serverspec using wrong container
我有 2 个规范文件使用不同的 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
然而,当 运行ning bundle exec rspec
时,很明显 运行 每个规范文件都使用同一个容器。我已经通过在每个示例之前打印出 运行ning 容器来确认这一点。这当然会导致其中一个文件的规范失败(以 运行 秒为准)。
当文件 运行 独立使用 bundle exec rspec path/to/file
时,所有规格都通过。
在一个文件中的示例具有 运行 并为另一组示例创建新容器后,是否有任何方法可以强制停止容器?
我找到了解决问题的方法,尽管是一个很老套的方法。这个问题的关键在于容器最终如何released. When there are no longer any references pointing to the Docker
instance it will be garbage collected and the container killed and deleted. However the object instance is held in a class level variable as a singleton in the base class。在我看来,"reset" specinfra 的唯一方法是调用在 Docker
class.
上继承的 clear
方法
最后,以下解决了问题,正确的 class 被用于 运行 每个规格。
after(:all) {
Specinfra.backend.class.clear
}
很高兴知道有更好的方法来访问此方法,而不必依赖未通过 serverspec
gem.
公开的方法
我有 2 个规范文件使用不同的 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
然而,当 运行ning bundle exec rspec
时,很明显 运行 每个规范文件都使用同一个容器。我已经通过在每个示例之前打印出 运行ning 容器来确认这一点。这当然会导致其中一个文件的规范失败(以 运行 秒为准)。
当文件 运行 独立使用 bundle exec rspec path/to/file
时,所有规格都通过。
在一个文件中的示例具有 运行 并为另一组示例创建新容器后,是否有任何方法可以强制停止容器?
我找到了解决问题的方法,尽管是一个很老套的方法。这个问题的关键在于容器最终如何released. When there are no longer any references pointing to the Docker
instance it will be garbage collected and the container killed and deleted. However the object instance is held in a class level variable as a singleton in the base class。在我看来,"reset" specinfra 的唯一方法是调用在 Docker
class.
clear
方法
最后,以下解决了问题,正确的 class 被用于 运行 每个规格。
after(:all) {
Specinfra.backend.class.clear
}
很高兴知道有更好的方法来访问此方法,而不必依赖未通过 serverspec
gem.