Skip to content

Commit

Permalink
* Refactor specs
Browse files Browse the repository at this point in the history
  • Loading branch information
simonswine committed Dec 2, 2014
1 parent 78e388a commit fcbc657
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 63 deletions.
2 changes: 2 additions & 0 deletions lib/php_fpm_docker/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def self.log_dir_path
def initialize
@name = 'php_fpm_docker'
@longname = 'PHP FPM Docker Wrapper'
@launchers = []
end

def start
Expand All @@ -41,6 +42,7 @@ def start

# init
l = Launcher.new php_name, self
@launchers << l

# run daemon
self.pid = l.run
Expand Down
14 changes: 11 additions & 3 deletions lib/php_fpm_docker/docker_container.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,22 @@ def method_missing(sym, *args, &block)
end
end

def create(cmd, opts = {})
def create(opts = {})
opts = { 'Cmd' => opts } if opts.is_a? Array

fail(
ArgumentError,
'Argument has to be a hash or array of strings'
) if opts.nil?

my_opts = options
my_opts.merge! opts

fail(ArgumentError, "cmd is no array: #{cmd}") unless cmd.is_a? Array
fail(ArgumentError, "cmd is no array: #{my_opts['Cmd']}") \
unless my_opts['Cmd'].is_a? Array

# ensure there are only strings
my_opts['Cmd'] = cmd.map(&:to_s)
my_opts['Cmd'] = my_opts['Cmd'].map(&:to_s)

@container = Docker::Container.create(my_opts)
logger.debug do
Expand Down
3 changes: 2 additions & 1 deletion lib/php_fpm_docker/docker_image.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# coding: utf-8
require 'docker'
require 'php_fpm_docker/logging'
require 'php_fpm_docker/docker_container'

module PhpFpmDocker
# Wraps the docker connection
Expand Down Expand Up @@ -91,7 +92,7 @@ def detect_find_path(sym)
private

def detect_fetch
output = cmd(['/bin/sh', '-c', detect_cmd])
output = cmd('Cmd' => ['/bin/sh', '-c', detect_cmd])
output[:stdout].split("\n")
end

Expand Down
14 changes: 11 additions & 3 deletions lib/php_fpm_docker/launcher.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# coding: utf-8
require 'pathname'
require 'php_fpm_docker/config_parser'
require 'php_fpm_docker/docker_image'
require 'php_fpm_docker/logging'

module PhpFpmDocker
Expand All @@ -13,6 +14,8 @@ class Launcher # rubocop:disable ClassLength
def initialize(name, app) # rubocop:disable MethodLength
@name = name
@app = app

# Set log file for all sub objects
Application.log_path = Application.log_dir_path.join("#{@name}")
end

Expand Down Expand Up @@ -120,9 +123,14 @@ def pools_action(pools, pools_hashes, action)
begin
pool[:object].send(action)
rescue => e
logger.warn(pool[:object].to_s) do
logger.warn do
"Failed to #{action}: #{e.message}"
end
e.backtrace.each do |line|
logger.debug do
line
end
end
end
end
else
Expand Down Expand Up @@ -185,11 +193,11 @@ def pools_config

def config
@config ||= ConfigParser.new(config_path)
@config.config
@config.config['global']
end

def docker_image
@docker_image ||= docker_image_get
@docker_image ||= DockerImage.new(config['image_name'])
end
end
end
4 changes: 2 additions & 2 deletions lib/php_fpm_docker/pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def gid
# Build the spawn command
def spawn_command
[
@launcher.spawn_cmd_path,
@launcher.docker_image.spawn_fcgi_path,
'-s', @config['listen'],
'-U', listen_uid.to_s,
'-G', listen_gid.to_s,
Expand All @@ -134,7 +134,7 @@ def php_command

end

[@launcher.php_cmd_path] + admin_options
[@launcher.docker_image.php_path] + admin_options
end

def container
Expand Down
52 changes: 46 additions & 6 deletions spec/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ def dbl_launcher_options
:bind_mounts => ['/mnt/bind'],
:web_path => '/var/webpath',
:docker_image => dbl_docker_image,
:spawn_cmd_path => '/usr/bin/fcgi-bin',
:php_cmd_path => '/usr/bin/php',
}
end

Expand All @@ -74,6 +72,8 @@ def dbl_docker_image
return @dbl_docker_image unless @dbl_docker_image.nil?
@dbl_docker_image = instance_double('PhpFpmDocker::DockerImage',
:create => nil,
:spawn_fcgi_path => '/usr/bin/fcgi-bin',
:php_path => '/usr/bin/php',
)
@dbl_docker_image
end
Expand All @@ -95,11 +95,49 @@ def dbl_logger
@dbl_logger ||= logger
end

def dbl_docker_api_image
return @dbl_docker_api_image unless @dbl_docker_api_image.nil?
d = @dbl_docker_api_image = double(Docker::Image)
allow(Docker::Image).to receive(:get) do |name|
double(name,
:id => "id_#{name}"
)
end
d
end

def dbl_docker_api_container
return @dbl_docker_api_container unless @dbl_docker_api_container.nil?
allow(Docker::Container).to receive(:create) do |*create_args|
name = create_args.first['name'] || 'unknown'
c = instance_double(
Docker::Container,
:id => name
)
allow(c).to receive(:start) do |*start_args|
@docker_api_containers[name][:start_args] = start_args
end
@docker_api_containers = {} if @docker_api_containers.nil?
@docker_api_containers[name] = {
:object => c,
:create_args => create_args,
}
c
end
end

def mock_docker_api
dbl_docker_api_image
dbl_docker_api_container
end

def mock_users
allow(Etc).to receive(:getpwnam) do |user|
uid = @users.select do |key, value|
result = @users.select do |key, value|
value == user
end.first.first.to_i
end
raise "User #{user} not found" if result.length < 1
uid = result.first.first.to_i
d = double(user)
allow(d).to receive(:uid).and_return(uid)
d
Expand All @@ -108,9 +146,11 @@ def mock_users

def mock_groups
allow(Etc).to receive(:getgrnam) do |group|
gid = @groups.select do |key, value|
result = @groups.select do |key, value|
value == group
end.first.first.to_i
end
raise "Group #{group} not found" if result.length < 1
gid = result.first.first.to_i
d = double(group)
allow(d).to receive(:gid).and_return(gid)
d
Expand Down
106 changes: 101 additions & 5 deletions spec/integration/application_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,37 @@ module PhpFpmDocker
dir: Pathname.new(Dir.mktmpdir)
}

# Mock docker api
mock_docker_api

# Mock users
@users = {
1001 => 'user1',
1002 => 'user2',
2001 => 'luser1',
2002 => 'luser2',
}
mock_users

@groups = {}
@users.each do |key,value|
@groups[key] = value.sub('user','group')
end
mock_groups

# Mock path detection
allow_any_instance_of(DockerImage).to receive(:detect_output).and_return([
'spawn_fcgi_path=/spawn_fcgi_path',
'php_path=/php_path',
'PHP 5.6.3 (cgi-fcgi) (built: Nov 17 2014 14:14:17)',
])

# Mock log dir
@options[:log_dir] = @options[:dir].join 'log'
allow(Application).to receive(:log_dir_path).and_return(@options[:log_dir])
allow(Application).to receive(:log_path).and_return(STDOUT)
allow(Application).to receive(:log_path).and_return(Pathname.new(
File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'tmp', 'rspec.log'))
))

# Wrap creation of Launchers
allow(Launcher).to receive(:new).and_wrap_original do |m, *args|
Expand Down Expand Up @@ -49,10 +76,79 @@ module PhpFpmDocker
@options[:pools] = 2
create_config @options
end
describe '#run' do
it 'starts containers' do
puts @options[:dir]
method(['launcher1','start'])
describe 'init.d script' do
let(:start) do
expect{start_method}.to output.to_stdout
start_method
end
let(:start_method) do
allow(a_i).to receive(:exit).with(0)
a_i.run(['launcher1','start'])
end

context 'one launcher' do
context 'start' do
let(:method) do
start
end
it 'should return successful return value' do
expect(a_i).to receive(:exit).with(0)
method
end
context 'starts two containers' do
before(:example) do
method
end
it 'should be started' do
expect(@docker_api_containers.keys).to contain_exactly(
match(/web1_/),
match(/web2_/)
)
end
it 'should get the correct bind_mounts' do
matching = [
match(%r{^/var/lib/php5-fpm(:|$)}),
match(%r{^/var/www/web[0-9]+domain\.com(:|$)}),
]
@docker_api_containers.each do |key,value|
expect(value[:start_args].first['Binds']).to contain_exactly(
*matching
)
expect(value[:create_args].first['Volumes'].keys).to contain_exactly(
*matching
)
end
end
it 'should get the correct command' do
@docker_api_containers.each do |key,value|
command = value[:create_args].first['Cmd']
expect(command.join(' ')).to match(/-M 0660/)
expect(command.join(' ')).to match(%r{/spawn_fcgi_path.+--.+/php_path})
['u','U','g','G'].each do |char|
expect(command.join(' ')).to match(/-U [0-9]+/)
end
end
end
end
end
context 'start and stop' do
let(:method) do
start
end
let(:launchers) do
inst_get(:@launchers)
end
it 'should return successful return value' do
expect(a_i).to receive(:exit).with(0)
method

# Loop containers
@docker_api_containers.each do |key,value|
expect(value[:object]).to receive(:delete).with(hash_including(:force => true))
end
launchers.first.stop_pools
end
end
end
end
end
Expand Down
6 changes: 6 additions & 0 deletions spec/integration/docker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ module PhpFpmDocker
DockerImage.new @image_name
end
describe 'docker_integration' do
before(:example) do
# Mock log dir
allow(Application).to receive(:log_path).and_return(Pathname.new(
File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'tmp', 'rspec.log'))
))
end
describe DockerImage do
let(:a_i) do
image
Expand Down
8 changes: 7 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
require 'coveralls'
require 'helper'
require 'simplecov'
require 'coveralls'

Coveralls.wear! do
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
Coveralls::SimpleCov::Formatter,
SimpleCov::Formatter::HTMLFormatter,
]
SimpleCov.start do
add_filter 'spec/'
end

Expand Down

0 comments on commit fcbc657

Please sign in to comment.