dockerspec icon indicating copy to clipboard operation
dockerspec copied to clipboard

How could I run multiple containers from single docker-compose.yml definition?

Open onnimonni opened this issue 5 years ago • 2 comments

Dockerspec Version

0.5.0

Ruby Version

2.5.3

Platform Details

MacOS

Scenario

Steps to Reproduce

handler.rb

require 'json'
 def hello(event:, context:)
  { statusCode: 200, body: JSON.generate('Hello Ruby!') }
end

def check_environment(event:, context:)
  { statusCode: 200, body: ENV.inspect }
end

docker-compose.yml:

version: '3'
services:
  # Closely replicated lambda environment
  lambda:
    image: lambci/lambda:ruby2.5
    volumes:
      # Mount whole project
      - .:/var/task
    networks:
      default:

  # Local mocked services
  ## AWS S3
  s3:
    image: scality/s3server
    ports:
      - 8000
    networks:
      default:
        aliases:
          - bucket.local-s3

networks:
  default:

spec/lambda_spec.rb:

require 'dockerspec/serverspec'

COMPOSE_YML = File.expand_path(File.join(__FILE__, "../../docker-compose.yml"))
raise(Exception, "Missing docker-compose file: #{COMPOSE_YML}") unless File.exists? COMPOSE_YML

describe docker_compose(COMPOSE_YML) do
  describe 'Running docker-compose.yml with services' do
    # Start mocked s3 server
    its_container(:s3, family: 'debian') do
      its(:stdout, retry: 60) { should include 'Server is listening' }
      describe process('node') do
        it { should be_running }
      end
    end

    its_container(:lambda) do
      describe command('handler.hello'), retry: 1 do # disable retries here
        its(:stdout) { should include 'Hello Ruby!' }
        its(:stderr) { should eq '' }
      end

      describe command('handler.check_environment', environment: { HELLO: 'RUBY'}), retry: 1 do # disable retries here
        its(:stdout) { should include '"HELLO"=>"RUBY"' }
        its(:stderr) { should eq '' }
      end
    end
  end
end

Expected Result

I know that this doesn't work. I'm willing to contribute on this feature but I'm in need of feedback.

How would you enhance this gem so that I could do multiple runs like these:

$ docker-compose run --rm lambda handler.hello
$ docker-compose run --rm -e HELLO=RUBY lambda handler.check_environment

Actual Result

Currently it just fails because the lambda container stops immediately:

$ bundle exec rspec spec/lambda_spec.rb

Serverspec on file: "......../docker-compose.yml"
  Running docker-compose.yml with services
    "lambda" container
      Command "handler.hello"
        stdout
          example at ./spec/lambda_spec.rb:18 (FAILED - 1)
Failures:

  1) Serverspec on file: "........../docker-compose.yml" Running docker-compose.yml with services "lambda" container Command "handler.hello" stdout
     Failure/Error: its(:stdout) { should include 'Hello Ruby!' }
     Docker::Error::ConflictError:
       Container d6aa793121d1357fbf7ab12e018a925d1208c96ca427b94a4ecf87d63ac5900d is not running

So the current way runs something similiar to docker-compose exec service-name. I would want to use something like this docker-compose --rm run service-name multiple times.

I know you must be busy but I would want to support this feature financially as well.

onnimonni avatar Dec 02 '18 17:12 onnimonni

Something like this would be awesome:

with_service(:lambda) do
  describe run(command: 'handler.hello'), retry: 1 do # disable retries here
    its(:stdout) { should include 'Hello Ruby!' }
    its(:stderr) { should eq '' }
  end

  describe run(command: 'handler.check_environment', environment: { HELLO: 'RUBY'}), retry: 1 do # disable retries here
    its(:stdout) { should include '"HELLO"=>"RUBY"' }
    its(:stderr) { should eq '' }
  end
end

Which would run something similiar to:

$ docker-compose run --rm lambda handler.hello
$ docker-compose run -e HELLO=RUBY --rm lambda handler.check_enviroment

onnimonni avatar Dec 02 '18 17:12 onnimonni

And I already did initial support for docker-compose.yml version 3 into docker-compose-api gem: https://github.com/mauricioklein/docker-compose-api/pulls

I'm just not sure how to pass the contexts correctly inside dockerspec.

onnimonni avatar Dec 02 '18 17:12 onnimonni