foodtaster 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/README.md +11 -5
- data/foodtaster.gemspec +1 -0
- data/lib/foodtaster/client.rb +57 -17
- data/lib/foodtaster/config.rb +5 -1
- data/lib/foodtaster/rspec/dsl_methods.rb +8 -4
- data/lib/foodtaster/rspec/example_methods.rb +10 -0
- data/lib/foodtaster/rspec/matchers/file_matcher.rb +16 -2
- data/lib/foodtaster/rspec_run.rb +45 -37
- data/lib/foodtaster/server_process.rb +39 -0
- data/lib/foodtaster/version.rb +1 -1
- data/lib/foodtaster/vm.rb +15 -5
- data/lib/foodtaster.rb +4 -3
- metadata +11 -8
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Foodtæster
|
2
2
|
|
3
3
|
Foodtaster is a library for testing your Chef code with RSpec. Specs
|
4
4
|
are actually executed on VirtualBox machine(s) managed by
|
@@ -36,13 +36,13 @@ describe "nginx::default" do
|
|
36
36
|
vm0.should open_page("http://localhost/")
|
37
37
|
|
38
38
|
vm0.should have_file("/etc/init.d/nginx")
|
39
|
-
vm0.should have_file("/etc/nginx/nginx.conf").with_content(/gzip on/)
|
39
|
+
vm0.should have_file("/etc/nginx/nginx.conf").with_content(/gzip on/).with_mode(0644)
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should have valid nginx config" do
|
43
43
|
result = vm0.execute("nginx -t")
|
44
44
|
|
45
|
-
result.should
|
45
|
+
result.should be_successful
|
46
46
|
result.stdout.should include("/etc/nginx/nginx.conf syntax is ok")
|
47
47
|
end
|
48
48
|
end
|
@@ -52,7 +52,9 @@ end
|
|
52
52
|
|
53
53
|
First, install Vagrant for your system following [official
|
54
54
|
instructions](http://docs.vagrantup.com/v2/installation/index.html).
|
55
|
-
Then, install two plugins:
|
55
|
+
Then, install two Vagrant plugins:
|
56
|
+
[sahara](http://github.com/jedi4ever/sahara) and
|
57
|
+
[vagrant-foodtaster-server](http://github.com/mlapshin/vagrant-foodtaster-server):
|
56
58
|
|
57
59
|
vagrant plugin install sahara
|
58
60
|
vagrant plugin install vagrant-foodtaster-server
|
@@ -61,6 +63,10 @@ That's all, you are ready to go.
|
|
61
63
|
|
62
64
|
## Usage
|
63
65
|
|
66
|
+
Check out [foodtaster-example
|
67
|
+
repository](http://github.com/mlapshin/foodtaster-example) or
|
68
|
+
follow this instructions.
|
69
|
+
|
64
70
|
In your Chef repository, create a basic Gemfile:
|
65
71
|
|
66
72
|
source 'https://rubygems.org/'
|
@@ -101,4 +107,4 @@ You are ready to write cookbook specs. Run them as usual with command:
|
|
101
107
|
## License
|
102
108
|
|
103
109
|
Foodtaster is distributed under [MIT
|
104
|
-
License](http://raw.github.com/mlapshin/foodtaster/master/LICENSE).
|
110
|
+
License](http://raw.github.com/mlapshin/foodtaster/master/LICENSE).
|
data/foodtaster.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.description = %q{RSpec for Chef cookbooks run on Vagrant}
|
12
12
|
gem.summary = %q{Foodtaster is a library for testing your Chef code with RSpec.}
|
13
13
|
gem.homepage = "http://github.com/mlapshin/foodtaster"
|
14
|
+
gem.license = 'MIT'
|
14
15
|
|
15
16
|
gem.files = `git ls-files`.split($/)
|
16
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
data/lib/foodtaster/client.rb
CHANGED
@@ -2,29 +2,69 @@ require 'drb'
|
|
2
2
|
|
3
3
|
module Foodtaster
|
4
4
|
class Client
|
5
|
-
|
6
|
-
# start local service to be able to redirect stdout & stderr
|
7
|
-
# to client
|
8
|
-
DRb.start_service("druby://localhost:0")
|
9
|
-
@v = DRbObject.new_with_uri("druby://localhost:#{drb_port}")
|
5
|
+
MAX_ATTEMPTS = 20
|
10
6
|
|
11
|
-
|
12
|
-
|
7
|
+
def self.connect(drb_port, server_process = nil)
|
8
|
+
attempt_index = 1
|
9
|
+
begin
|
10
|
+
sleep 0.2
|
11
|
+
client = Foodtaster::Client.new(drb_port)
|
12
|
+
rescue DRb::DRbConnError => e
|
13
|
+
Foodtaster.logger.debug "DRb connection failed (attempt #{attempt_index}/#{MAX_ATTEMPTS}): #{e.message}"
|
14
|
+
attempt_index += 1
|
15
|
+
retry if attempt_index <= MAX_ATTEMPTS && (server_process.nil? || server_process.alive?)
|
16
|
+
end
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
if client
|
19
|
+
Foodtaster.logger.debug "DRb connection established"
|
20
|
+
else
|
21
|
+
Foodtaster.logger.debug "Can't connect to Foodtaster DRb Server"
|
18
22
|
end
|
23
|
+
|
24
|
+
client
|
19
25
|
end
|
20
26
|
|
21
|
-
|
27
|
+
[:vm_defined?, :prepare_vm, :rollback_vm,
|
28
|
+
:run_chef_on_vm, :execute_command_on_vm,
|
29
|
+
:shutdown_vm].each do |method_name|
|
30
|
+
define_method method_name do |*args|
|
31
|
+
begin
|
32
|
+
@v.send(method_name, *args)
|
33
|
+
rescue DRb::DRbUnknownError => e
|
34
|
+
message = "Folowing exception was raised on server:\n#{e.unknown.buf}"
|
35
|
+
Foodtaster.logger.fatal(message)
|
36
|
+
raise e
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
22
40
|
|
23
|
-
|
24
|
-
$stdout.extend DRbUndumped
|
25
|
-
$stderr.extend DRbUndumped
|
41
|
+
private
|
26
42
|
|
27
|
-
|
28
|
-
|
43
|
+
def initialize(drb_port)
|
44
|
+
# start local service to be able to redirect stdout & stderr
|
45
|
+
# to client
|
46
|
+
DRb.start_service("druby://localhost:0")
|
47
|
+
@v = DRbObject.new_with_uri("druby://localhost:#{drb_port}")
|
48
|
+
|
49
|
+
init
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def init
|
55
|
+
$stdout.extend DRbUndumped
|
56
|
+
$stderr.extend DRbUndumped
|
57
|
+
|
58
|
+
@v.redirect_stdstreams($stdout, $stderr)
|
59
|
+
check_version
|
60
|
+
end
|
61
|
+
|
62
|
+
def check_version
|
63
|
+
server_version = @v.version
|
64
|
+
|
65
|
+
if server_version != Foodtaster::VERSION
|
66
|
+
Foodtaster.logger.warn "Warning: Foodtaster DRb Server version doesn't match Foodtaster Gem version.\n\nDRb Server version: #{server_version}\nFoodtaster Gem version: #{Foodtaster::VERSION}\n"
|
67
|
+
end
|
68
|
+
end
|
29
69
|
end
|
30
70
|
end
|
data/lib/foodtaster/config.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Foodtaster
|
2
2
|
class Config
|
3
|
-
%w(log_level drb_port vagrant_binary
|
3
|
+
%w(log_level drb_port vagrant_binary shutdown_vms
|
4
|
+
skip_rollback start_server).each do |attr|
|
4
5
|
attr_accessor attr.to_sym
|
5
6
|
end
|
6
7
|
|
@@ -8,6 +9,9 @@ module Foodtaster
|
|
8
9
|
@log_level = :info
|
9
10
|
@drb_port = 35672
|
10
11
|
@vagrant_binary = 'vagrant'
|
12
|
+
@shutdown_vms = false
|
13
|
+
@skip_rollback = false
|
14
|
+
@start_server = true
|
11
15
|
end
|
12
16
|
|
13
17
|
def self.default
|
@@ -1,18 +1,22 @@
|
|
1
1
|
module Foodtaster
|
2
2
|
module RSpec
|
3
3
|
module DslMethods
|
4
|
-
def
|
4
|
+
def require_vm(vm_name)
|
5
5
|
Foodtaster::RSpecRun.current.require_vm(vm_name)
|
6
6
|
|
7
|
-
|
7
|
+
let(vm_name) { get_vm(vm_name) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def run_chef_on(vm_name, options = {}, &block)
|
11
|
+
require_vm(vm_name)
|
12
|
+
skip_rollback = Foodtaster.config.skip_rollback || options[:skip_rollback]
|
8
13
|
|
9
14
|
before(:all) do
|
10
15
|
vm = get_vm(vm_name)
|
11
16
|
vm.rollback unless skip_rollback
|
17
|
+
|
12
18
|
run_chef_on(vm_name, &block)
|
13
19
|
end
|
14
|
-
|
15
|
-
let(vm_name) { get_vm(vm_name) }
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -7,10 +7,20 @@ module Foodtaster
|
|
7
7
|
|
8
8
|
def run_chef_on(vm_name, &block)
|
9
9
|
chef_config = ChefConfig.new.tap{ |conf| block.call(conf) }.to_hash
|
10
|
+
@previous_chef_config = chef_config
|
11
|
+
|
10
12
|
vm = get_vm(vm_name)
|
11
13
|
vm.run_chef(chef_config)
|
12
14
|
end
|
13
15
|
|
16
|
+
def rerun_chef_on(vm_name)
|
17
|
+
raise RuntimeError, "No previous Chef run was made" unless @previous_chef_config
|
18
|
+
vm = get_vm(vm_name)
|
19
|
+
vm.run_chef(@previous_chef_config)
|
20
|
+
end
|
21
|
+
|
22
|
+
alias :repeat_chef_run :rerun_chef_on
|
23
|
+
|
14
24
|
private
|
15
25
|
|
16
26
|
class ChefConfig
|
@@ -28,6 +28,12 @@ module Foodtaster
|
|
28
28
|
@results[:owner] = (@actual_owner.to_s == @owner.to_s)
|
29
29
|
end
|
30
30
|
|
31
|
+
if @mode
|
32
|
+
@actual_mode = vm.execute("sudo stat #{@path} -c \"%a\"").stdout.chomp
|
33
|
+
|
34
|
+
@results[:mode] = (@actual_mode == @mode.to_s(8))
|
35
|
+
end
|
36
|
+
|
31
37
|
@results.values.all?
|
32
38
|
end
|
33
39
|
|
@@ -43,10 +49,17 @@ module Foodtaster
|
|
43
49
|
self
|
44
50
|
end
|
45
51
|
|
52
|
+
def with_mode(mode)
|
53
|
+
@mode = mode
|
54
|
+
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
46
58
|
def failure_message_for_should
|
47
59
|
["expected that #{@vm.name} should have file '#{@path}'",
|
48
60
|
@content && !@results[:content] && "with content #{@content.inspect}, but actual content is:\n#{@actual_content.inspect}\n",
|
49
|
-
@owner && !@results[:owner] && "with owner #{@owner}, but actual owner is #{@actual_owner}"
|
61
|
+
@owner && !@results[:owner] && "with owner #{@owner}, but actual owner is #{@actual_owner}",
|
62
|
+
@mode && !@results[:mode] && "with mode #{@mode.to_s(8)}(octal), but actual mode is #{@actual_mode}(octal)"].delete_if { |a| !a }.join(" ")
|
50
63
|
end
|
51
64
|
|
52
65
|
def failure_message_for_should_not
|
@@ -56,7 +69,8 @@ module Foodtaster
|
|
56
69
|
def description
|
57
70
|
["have file '#{@path}'",
|
58
71
|
@content && "with content #{@content.inspect}",
|
59
|
-
@owner && "with owner #{@owner}"
|
72
|
+
@owner && "with owner #{@owner}",
|
73
|
+
@mode && "with mode #{@mode}"].delete_if { |a| !a }.join(" ")
|
60
74
|
end
|
61
75
|
end
|
62
76
|
|
data/lib/foodtaster/rspec_run.rb
CHANGED
@@ -5,7 +5,8 @@ module Foodtaster
|
|
5
5
|
def initialize
|
6
6
|
@required_vm_names = Set.new
|
7
7
|
@client = nil
|
8
|
-
@
|
8
|
+
@server_process = nil
|
9
|
+
@stopped = false
|
9
10
|
end
|
10
11
|
|
11
12
|
def require_vm(vm_name)
|
@@ -21,15 +22,28 @@ module Foodtaster
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def start
|
24
|
-
|
25
|
-
|
26
|
-
Foodtaster.logger.debug "Starting Foodtaster specs run"
|
25
|
+
setup_signal_handlers
|
27
26
|
start_server_and_connect_client
|
28
|
-
|
27
|
+
|
28
|
+
if (@server_process.nil? || @server_process.alive?) && @client
|
29
|
+
prepare_required_vms
|
30
|
+
else
|
31
|
+
if @server_process
|
32
|
+
Foodtaster.logger.fatal "Failed to start Foodtaster DRb Server:\n\n#{@server_process.output}"
|
33
|
+
else
|
34
|
+
Foodtaster.logger.fatal "Failed to connect to Foodtaster DRb Server"
|
35
|
+
end
|
36
|
+
|
37
|
+
exit 1
|
38
|
+
end
|
29
39
|
end
|
30
40
|
|
31
41
|
def stop
|
42
|
+
return if @stopped
|
43
|
+
|
44
|
+
@stopped = true
|
32
45
|
puts "" # newline after rspec output
|
46
|
+
shutdown_required_vms if Foodtaster.config.shutdown_vms
|
33
47
|
terminate_server
|
34
48
|
end
|
35
49
|
|
@@ -47,51 +61,45 @@ module Foodtaster
|
|
47
61
|
|
48
62
|
private
|
49
63
|
|
64
|
+
def setup_signal_handlers
|
65
|
+
terminator = proc {
|
66
|
+
self.stop
|
67
|
+
exit 1
|
68
|
+
}
|
69
|
+
|
70
|
+
trap("INT", &terminator)
|
71
|
+
trap("TERM", &terminator)
|
72
|
+
|
73
|
+
at_exit do
|
74
|
+
self.stop
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
50
78
|
def prepare_required_vms
|
51
79
|
self.required_vm_names.each { |vm_name| get_vm(vm_name).prepare }
|
52
80
|
end
|
53
81
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
82
|
+
def shutdown_required_vms
|
83
|
+
self.required_vm_names.each { |vm_name| get_vm(vm_name).shutdown }
|
84
|
+
end
|
57
85
|
|
58
|
-
|
59
|
-
Foodtaster.
|
86
|
+
def start_server_and_connect_client
|
87
|
+
drb_port = Foodtaster.config.drb_port
|
60
88
|
|
89
|
+
start_server(drb_port) if Foodtaster.config.start_server
|
61
90
|
connect_client(drb_port)
|
62
91
|
end
|
63
92
|
|
64
|
-
def
|
65
|
-
|
66
|
-
begin
|
67
|
-
sleep 0.2
|
68
|
-
@client = Foodtaster::Client.new(drb_port)
|
69
|
-
rescue DRb::DRbConnError => e
|
70
|
-
Foodtaster.logger.debug "DRb connection failed: #{e.message}"
|
71
|
-
retry_count += 1
|
72
|
-
retry if retry_count < 10
|
73
|
-
end
|
74
|
-
|
75
|
-
if @client.nil?
|
76
|
-
server_output = File.read("/tmp/vagrant-foodtaster-server-output.txt")
|
77
|
-
|
78
|
-
Foodtaster.logger.fatal "Cannot start or connect to Foodtaster DRb server."
|
79
|
-
Foodtaster.logger.fatal "Server output:\n#{server_output}\n"
|
80
|
-
|
81
|
-
exit 1
|
82
|
-
else
|
83
|
-
Foodtaster.logger.debug "DRb connection established"
|
84
|
-
end
|
93
|
+
def start_server(drb_port)
|
94
|
+
@server_process = Foodtaster::ServerProcess.new(drb_port)
|
85
95
|
end
|
86
96
|
|
87
97
|
def terminate_server
|
88
|
-
|
98
|
+
@server_process && @server_process.terminate
|
99
|
+
end
|
89
100
|
|
90
|
-
|
91
|
-
|
92
|
-
Process.wait(-pgid)
|
93
|
-
Foodtaster.logger.debug "Terminated foodtaster-server process"
|
94
|
-
end
|
101
|
+
def connect_client(drb_port)
|
102
|
+
@client = Foodtaster::Client.connect(drb_port, @server_process)
|
95
103
|
end
|
96
104
|
end
|
97
105
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Foodtaster
|
4
|
+
class ServerProcess
|
5
|
+
def initialize(drb_port)
|
6
|
+
Foodtaster.logger.debug "Starting Foodtaster specs run"
|
7
|
+
|
8
|
+
vagrant_binary = Foodtaster.config.vagrant_binary
|
9
|
+
|
10
|
+
_, @pipe_out, thread = Open3.popen2("#{vagrant_binary} foodtaster-server #{drb_port}",
|
11
|
+
pgroup: true, err: [:child, :out])
|
12
|
+
|
13
|
+
@pid = thread.pid
|
14
|
+
@pgid = Process.getpgid(@pid)
|
15
|
+
|
16
|
+
Foodtaster.logger.debug "Started foodtaster-server on port #{drb_port} with PID #{@pid}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def output
|
20
|
+
@pipe_out.read
|
21
|
+
end
|
22
|
+
|
23
|
+
def alive?
|
24
|
+
Process.kill(0, @pid) == 1 rescue false
|
25
|
+
end
|
26
|
+
|
27
|
+
def terminate
|
28
|
+
if alive?
|
29
|
+
@pipe_out.close
|
30
|
+
|
31
|
+
if @pgid > 0
|
32
|
+
Process.kill("TERM", -@pgid)
|
33
|
+
Process.waitpid(-@pgid) rescue nil
|
34
|
+
Foodtaster.logger.debug "Terminated Foodtaster DRb Server process"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/foodtaster/version.rb
CHANGED
data/lib/foodtaster/vm.rb
CHANGED
@@ -6,8 +6,8 @@ module Foodtaster
|
|
6
6
|
attr_reader :exit_status
|
7
7
|
|
8
8
|
def initialize(hash)
|
9
|
-
@stderr = hash[:stderr]
|
10
|
-
@stdout = hash[:stdout]
|
9
|
+
@stderr = hash[:stderr].to_s
|
10
|
+
@stdout = hash[:stdout].to_s
|
11
11
|
@exit_status = hash[:exit_status]
|
12
12
|
end
|
13
13
|
|
@@ -32,8 +32,13 @@ module Foodtaster
|
|
32
32
|
@client.prepare_vm(name)
|
33
33
|
end
|
34
34
|
|
35
|
+
def shutdown
|
36
|
+
Foodtaster.logger.debug "#{name}: Shutting down VM"
|
37
|
+
@client.shutdown_vm(name)
|
38
|
+
end
|
39
|
+
|
35
40
|
def rollback
|
36
|
-
Foodtaster.logger.info "#{name}:
|
41
|
+
Foodtaster.logger.info "#{name}: Rolling back VM"
|
37
42
|
@client.rollback_vm(name)
|
38
43
|
end
|
39
44
|
|
@@ -42,12 +47,17 @@ module Foodtaster
|
|
42
47
|
exec_result_hash = @client.execute_command_on_vm(name, command)
|
43
48
|
|
44
49
|
Foodtaster.logger.debug "#{name}: Finished with #{exec_result_hash[:exit_status]}"
|
45
|
-
Foodtaster.logger.debug "#{name}: STDOUT: #{exec_result_hash[:stdout].chomp}"
|
46
|
-
Foodtaster.logger.debug "#{name}: STDERR: #{exec_result_hash[:stderr].chomp}"
|
50
|
+
Foodtaster.logger.debug "#{name}: STDOUT: #{exec_result_hash[:stdout].to_s.chomp}"
|
51
|
+
Foodtaster.logger.debug "#{name}: STDERR: #{exec_result_hash[:stderr].to_s.chomp}"
|
47
52
|
|
48
53
|
ExecResult.new(exec_result_hash)
|
49
54
|
end
|
50
55
|
|
56
|
+
def execute_as(user, command)
|
57
|
+
cmd = %Q[sudo su -l #{user} -c "#{command}"]
|
58
|
+
self.execute cmd
|
59
|
+
end
|
60
|
+
|
51
61
|
def run_chef(config)
|
52
62
|
Foodtaster.logger.info "#{name}: Running Chef with Run List #{config[:run_list].join(', ')}"
|
53
63
|
Foodtaster.logger.debug "#{name}: with JSON: #{config[:json].inspect}"
|
data/lib/foodtaster.rb
CHANGED
@@ -4,9 +4,10 @@ require 'foodtaster/rspec'
|
|
4
4
|
require 'logger'
|
5
5
|
|
6
6
|
module Foodtaster
|
7
|
-
autoload :Client,
|
8
|
-
autoload :
|
9
|
-
autoload :
|
7
|
+
autoload :Client, 'foodtaster/client'
|
8
|
+
autoload :ServerProcess, 'foodtaster/server_process'
|
9
|
+
autoload :Vm, 'foodtaster/vm'
|
10
|
+
autoload :RSpecRun, 'foodtaster/rspec_run'
|
10
11
|
|
11
12
|
class << self
|
12
13
|
def logger
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foodtaster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
5
4
|
prerelease:
|
5
|
+
version: 0.0.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mike Lapshin
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
+
prerelease: false
|
16
|
+
type: :runtime
|
15
17
|
name: rspec
|
16
|
-
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
19
|
none: false
|
18
20
|
requirements:
|
19
21
|
- - ! '>='
|
20
22
|
- !ruby/object:Gem::Version
|
21
23
|
version: 2.10.0
|
22
|
-
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
27
|
- - ! '>='
|
@@ -51,10 +51,12 @@ files:
|
|
51
51
|
- lib/foodtaster/rspec/matchers/simple_matchers.rb
|
52
52
|
- lib/foodtaster/rspec/matchers/user_matcher.rb
|
53
53
|
- lib/foodtaster/rspec_run.rb
|
54
|
+
- lib/foodtaster/server_process.rb
|
54
55
|
- lib/foodtaster/version.rb
|
55
56
|
- lib/foodtaster/vm.rb
|
56
57
|
homepage: http://github.com/mlapshin/foodtaster
|
57
|
-
licenses:
|
58
|
+
licenses:
|
59
|
+
- MIT
|
58
60
|
post_install_message:
|
59
61
|
rdoc_options: []
|
60
62
|
require_paths:
|
@@ -73,8 +75,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
75
|
version: '0'
|
74
76
|
requirements: []
|
75
77
|
rubyforge_project:
|
76
|
-
rubygems_version: 1.8.
|
78
|
+
rubygems_version: 1.8.25
|
77
79
|
signing_key:
|
78
80
|
specification_version: 3
|
79
81
|
summary: Foodtaster is a library for testing your Chef code with RSpec.
|
80
82
|
test_files: []
|
83
|
+
has_rdoc:
|