serverspec использует неправильный контейнер

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

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

спец/докерфайл/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

спец/докерфайл/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, все спецификации проходят.

Есть ли способ принудительно завершить работу контейнера после запуска примеров в одном файле и создания нового контейнера для другого набора примеров?


person tomasbasham    schedule 07.04.2019    source источник
comment
Что такое set? (Я не думаю, что это стандартная вещь rspec?) Вы действительно хотите каждый раз создавать новый образ и требовать, чтобы ваши тесты запускались от имени пользователя root?   -  person David Maze    schedule 08.04.2019
comment
Я считаю, что set происходит от драгоценного камня serverspec. Я отредактирую вопрос, чтобы сделать это более ясным. Мне сейчас все равно, будет ли образ строиться каждый раз. Я рефакторинг это позже. Более важно, чтобы работал правильный контейнер.   -  person tomasbasham    schedule 08.04.2019
comment
Я бы рекомендовал связывать тесты с изображениями через Rakefile вместо bundle exec rspec, чтобы вы могли создавать надежные пользовательские команды для своих файлов спецификаций. Это шаблонный способ и с Serverspec.   -  person Matt Schuchard    schedule 08.04.2019


Ответы (1)


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

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

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

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

person tomasbasham    schedule 08.04.2019
comment
Здесь, здесь. Хорошее решение, сэр. - person Hemm K; 09.04.2019