serverpec использует неправильный контейнер - PullRequest
1 голос
/ 08 апреля 2019

У меня есть 2 файла спецификаций, которые используют разные образы докеров и, следовательно, предполагают запуск отдельных и разных контейнеров докеров для запуска примеров.

В приведенных ниже фрагментах я использую гем serverspec для проверки своих контейнеров

спецификация / 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

спецификация / 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 Ответ

1 голос
/ 09 апреля 2019

Я нашел способ решить проблему, хотя и довольно хакерский.Ключ к этой проблеме лежит в том, как контейнер, наконец, освобождается .Если больше нет ссылок, указывающих на экземпляр Docker, будет выполнен сбор мусора, а контейнер уничтожен и удален.Однако экземпляр объекта хранится в переменной уровня класса как одиночный элемент в базовом классе .Мне кажется, что единственный способ «сбросить» specinfra - это вызвать метод clear, унаследованный от класса Docker.

В конце концов, следующая проблема решена, и используется правильный классдля запуска каждой спецификации.

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

Было бы здорово знать, что есть лучший способ получить доступ к этим методам, не полагаясь на метод, не раскрытый в геме serverspec.

...