mirror of
https://github.com/inspec/inspec
synced 2024-11-24 05:33:17 +00:00
37ad8f9531
Instead of having RSpec re-run its world multiple times, run it only once with all tests. Which leaves us with one more thing to solve: we want to start tests as soon as the container is up and they are set up. At the moment, the containers come up and are set up concurrently, including test registry, but the tests themselves are in simple sequence. Signed-off-by: Dominik Richter <dominik.richter@gmail.com>
94 lines
2.1 KiB
Ruby
94 lines
2.1 KiB
Ruby
# encoding: utf-8
|
|
|
|
require 'docker'
|
|
require 'yaml'
|
|
require 'concurrent'
|
|
require_relative '../lib/vulcano'
|
|
|
|
tests = ARGV
|
|
if tests.empty?
|
|
puts 'Nothing to do.'
|
|
exit 0
|
|
end
|
|
|
|
class DockerTester
|
|
def initialize(tests)
|
|
@tests = tests
|
|
@images = docker_images_by_tag
|
|
@conf = tests_conf
|
|
end
|
|
|
|
def run
|
|
puts ['Running tests:', @tests].flatten.join("\n- ")
|
|
puts ''
|
|
# test all images
|
|
promises = @conf['images'].map { |n|
|
|
Concurrent::Promise.new {
|
|
container = prepare_image(n)
|
|
runner = test_container(container.id)
|
|
[container, runner]
|
|
}.execute
|
|
}
|
|
|
|
sleep(0.1) until promises.all?(&:fulfilled?)
|
|
|
|
runner = promises[0].value[1]
|
|
ok = runner.run
|
|
|
|
done = promises.map do |promise|
|
|
promise.then { |c, _| stop_container(c) }
|
|
end
|
|
sleep(0.1) until done.all?(&:fulfilled?)
|
|
|
|
ok or fail 'Test failures'
|
|
end
|
|
|
|
def docker_images_by_tag
|
|
# get all docker image tags
|
|
images = {}
|
|
Docker::Image.all.map do |img|
|
|
Array(img.info['RepoTags']).each do |tag|
|
|
images[tag] = img
|
|
end
|
|
end
|
|
images
|
|
end
|
|
|
|
def tests_conf
|
|
# get the test configuration
|
|
conf_path = File.join(File.dirname(__FILE__), '..', '.tests.yaml')
|
|
fail "Can't find tests config in #{conf_path}" unless File.file?(conf_path)
|
|
YAML.load(File.read(conf_path))
|
|
end
|
|
|
|
def test_container(container_id)
|
|
puts "--> run test on docker #{container_id}"
|
|
opts = { 'target' => "docker://#{container_id}" }
|
|
runner = Vulcano::Runner.new(nil, opts)
|
|
runner.add_tests(@tests)
|
|
runner
|
|
end
|
|
|
|
def prepare_image(name)
|
|
dname = "docker-#{name}:latest"
|
|
image = @images[dname]
|
|
fail "Can't find docker image #{dname}" if image.nil?
|
|
|
|
puts "--> start docker #{name}"
|
|
container = Docker::Container.create(
|
|
'Cmd' => ['/bin/bash'],
|
|
'Image' => image.id,
|
|
'OpenStdin' => true,
|
|
)
|
|
container.start
|
|
container
|
|
end
|
|
|
|
def stop_container(container)
|
|
puts "--> killrm docker #{container.id}"
|
|
container.kill
|
|
container.delete(force: true)
|
|
end
|
|
end
|
|
|
|
DockerTester.new(tests).run
|