test-kitchen 0.7.0 → 1.0.0.alpha.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/.travis.yml +11 -0
- data/.yardopts +3 -0
- data/Gemfile +13 -0
- data/Guardfile +11 -0
- data/LICENSE +15 -0
- data/README.md +131 -0
- data/Rakefile +69 -0
- data/bin/kitchen +9 -4
- data/features/cli.feature +17 -0
- data/features/cli_init.feature +156 -0
- data/features/support/env.rb +14 -0
- data/lib/kitchen/busser.rb +166 -0
- data/lib/kitchen/chef_data_uploader.rb +156 -0
- data/lib/kitchen/cli.rb +540 -0
- data/lib/kitchen/collection.rb +55 -0
- data/lib/kitchen/color.rb +46 -0
- data/lib/kitchen/config.rb +223 -0
- data/lib/kitchen/driver/base.rb +180 -0
- data/lib/kitchen/driver/dummy.rb +81 -0
- data/lib/kitchen/driver/ssh_base.rb +192 -0
- data/lib/kitchen/driver.rb +42 -0
- data/lib/kitchen/errors.rb +52 -0
- data/lib/kitchen/instance.rb +327 -0
- data/lib/kitchen/instance_actor.rb +42 -0
- data/lib/kitchen/loader/yaml.rb +105 -0
- data/lib/kitchen/logger.rb +145 -0
- data/{cookbooks/test-kitchen/libraries/helpers.rb → lib/kitchen/logging.rb} +13 -9
- data/lib/kitchen/manager.rb +45 -0
- data/lib/kitchen/metadata_chopper.rb +52 -0
- data/lib/kitchen/platform.rb +61 -0
- data/lib/kitchen/rake_tasks.rb +59 -0
- data/lib/kitchen/shell_out.rb +65 -0
- data/lib/kitchen/state_file.rb +88 -0
- data/lib/kitchen/suite.rb +76 -0
- data/lib/kitchen/thor_tasks.rb +62 -0
- data/lib/kitchen/util.rb +79 -0
- data/{cookbooks/test-kitchen/recipes/erlang.rb → lib/kitchen/version.rb} +9 -6
- data/lib/kitchen.rb +98 -0
- data/lib/vendor/hash_recursive_merge.rb +74 -0
- data/spec/kitchen/collection_spec.rb +80 -0
- data/spec/kitchen/color_spec.rb +54 -0
- data/spec/kitchen/config_spec.rb +201 -0
- data/spec/kitchen/driver/dummy_spec.rb +191 -0
- data/spec/kitchen/instance_spec.rb +162 -0
- data/spec/kitchen/loader/yaml_spec.rb +243 -0
- data/spec/kitchen/platform_spec.rb +48 -0
- data/spec/kitchen/state_file_spec.rb +122 -0
- data/spec/kitchen/suite_spec.rb +64 -0
- data/spec/spec_helper.rb +47 -0
- data/templates/plugin/driver.rb.erb +23 -0
- data/templates/plugin/license_apachev2.erb +15 -0
- data/templates/plugin/license_gplv2.erb +18 -0
- data/templates/plugin/license_gplv3.erb +16 -0
- data/templates/plugin/license_mit.erb +22 -0
- data/templates/plugin/license_reserved.erb +5 -0
- data/templates/plugin/version.rb.erb +12 -0
- data/test-kitchen.gemspec +44 -0
- metadata +290 -82
- data/config/Cheffile +0 -47
- data/config/Kitchenfile +0 -39
- data/config/Vagrantfile +0 -114
- data/cookbooks/test-kitchen/attributes/default.rb +0 -25
- data/cookbooks/test-kitchen/metadata.rb +0 -27
- data/cookbooks/test-kitchen/recipes/chef.rb +0 -19
- data/cookbooks/test-kitchen/recipes/compat.rb +0 -39
- data/cookbooks/test-kitchen/recipes/default.rb +0 -51
- data/cookbooks/test-kitchen/recipes/ruby.rb +0 -29
- data/lib/test-kitchen/cli/destroy.rb +0 -36
- data/lib/test-kitchen/cli/init.rb +0 -37
- data/lib/test-kitchen/cli/platform_list.rb +0 -37
- data/lib/test-kitchen/cli/project_info.rb +0 -44
- data/lib/test-kitchen/cli/ssh.rb +0 -36
- data/lib/test-kitchen/cli/status.rb +0 -36
- data/lib/test-kitchen/cli/test.rb +0 -68
- data/lib/test-kitchen/cli.rb +0 -282
- data/lib/test-kitchen/dsl.rb +0 -63
- data/lib/test-kitchen/environment.rb +0 -166
- data/lib/test-kitchen/platform.rb +0 -79
- data/lib/test-kitchen/project/base.rb +0 -159
- data/lib/test-kitchen/project/cookbook.rb +0 -97
- data/lib/test-kitchen/project/cookbook_copy.rb +0 -58
- data/lib/test-kitchen/project/ruby.rb +0 -37
- data/lib/test-kitchen/project/supported_platforms.rb +0 -75
- data/lib/test-kitchen/project.rb +0 -23
- data/lib/test-kitchen/runner/base.rb +0 -154
- data/lib/test-kitchen/runner/openstack/dsl.rb +0 -39
- data/lib/test-kitchen/runner/openstack/environment.rb +0 -141
- data/lib/test-kitchen/runner/openstack.rb +0 -147
- data/lib/test-kitchen/runner/vagrant.rb +0 -95
- data/lib/test-kitchen/runner.rb +0 -21
- data/lib/test-kitchen/scaffold.rb +0 -88
- data/lib/test-kitchen/ui.rb +0 -73
- data/lib/test-kitchen/version.rb +0 -21
- data/lib/test-kitchen.rb +0 -34
@@ -0,0 +1,201 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012, Fletcher Nichol
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require_relative '../spec_helper'
|
20
|
+
|
21
|
+
require 'kitchen'
|
22
|
+
require 'kitchen/logging'
|
23
|
+
require 'kitchen/collection'
|
24
|
+
require 'kitchen/config'
|
25
|
+
require 'kitchen/driver'
|
26
|
+
require 'kitchen/instance'
|
27
|
+
require 'kitchen/platform'
|
28
|
+
require 'kitchen/suite'
|
29
|
+
require 'kitchen/util'
|
30
|
+
|
31
|
+
module Kitchen
|
32
|
+
|
33
|
+
class DummyLoader
|
34
|
+
|
35
|
+
def read
|
36
|
+
@data || Hash.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def data=(hash)
|
40
|
+
@data = hash
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe Kitchen::Config do
|
46
|
+
|
47
|
+
let(:loader) { Kitchen::DummyLoader.new }
|
48
|
+
let(:config) { Kitchen::Config.new(:loader => loader) }
|
49
|
+
|
50
|
+
before do
|
51
|
+
FakeFS.activate!
|
52
|
+
FileUtils.mkdir_p("/tmp")
|
53
|
+
end
|
54
|
+
|
55
|
+
after do
|
56
|
+
FakeFS.deactivate!
|
57
|
+
FakeFS::FileSystem.clear
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#platforms" do
|
61
|
+
|
62
|
+
it "returns platforms loaded from a kitchen.yml" do
|
63
|
+
stub_data!({ :platforms => [{ :name => 'one' }, { :name => 'two' }] })
|
64
|
+
|
65
|
+
config.platforms.size.must_equal 2
|
66
|
+
config.platforms[0].name.must_equal 'one'
|
67
|
+
config.platforms[1].name.must_equal 'two'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns an empty Array if no platforms are given" do
|
71
|
+
stub_data!({})
|
72
|
+
|
73
|
+
config.platforms.must_equal []
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#suites" do
|
78
|
+
|
79
|
+
it "returns suites loaded from a kitchen.yml" do
|
80
|
+
stub_data!({ :suites => [
|
81
|
+
{ :name => 'one', :run_list => [] },
|
82
|
+
{ :name => 'two', :run_list => [] },
|
83
|
+
] })
|
84
|
+
|
85
|
+
config.suites.size.must_equal 2
|
86
|
+
config.suites[0].name.must_equal 'one'
|
87
|
+
config.suites[1].name.must_equal 'two'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns an empty Array if no suites are given" do
|
91
|
+
stub_data!({})
|
92
|
+
|
93
|
+
config.suites.must_equal []
|
94
|
+
end
|
95
|
+
|
96
|
+
it "returns a suite with nil for data_bags_path by default" do
|
97
|
+
stub_data!({ :suites => [{ :name => 'one', :run_list => [] }] })
|
98
|
+
config.suites.first.data_bags_path.must_be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it "retuns a suite with a common data_bags_path set" do
|
102
|
+
stub_data!({ :suites => [{ :name => 'one', :run_list => [] }] })
|
103
|
+
config.test_base_path = "/tmp/base"
|
104
|
+
FileUtils.mkdir_p "/tmp/base/data_bags"
|
105
|
+
|
106
|
+
config.suites.first.data_bags_path.must_equal "/tmp/base/data_bags"
|
107
|
+
end
|
108
|
+
|
109
|
+
it "retuns a suite with a suite-specific data_bags_path set" do
|
110
|
+
stub_data!({ :suites => [{ :name => 'cool', :run_list => [] }] })
|
111
|
+
config.test_base_path = "/tmp/base"
|
112
|
+
FileUtils.mkdir_p "/tmp/base/cool/data_bags"
|
113
|
+
config.suites.first.data_bags_path.must_equal "/tmp/base/cool/data_bags"
|
114
|
+
end
|
115
|
+
|
116
|
+
it "returns a suite with nil for roles_path by default" do
|
117
|
+
stub_data!({ :suites => [{ :name => 'one', :run_list => [] }] })
|
118
|
+
config.suites.first.roles_path.must_be_nil
|
119
|
+
end
|
120
|
+
|
121
|
+
it "returns a suite with a common roles_path set" do
|
122
|
+
stub_data!({ :suites => [{ :name => 'one', :run_list => [] }] })
|
123
|
+
config.test_base_path = "/tmp/base"
|
124
|
+
FileUtils.mkdir_p "/tmp/base/roles"
|
125
|
+
config.suites.first.roles_path.must_equal "/tmp/base/roles"
|
126
|
+
end
|
127
|
+
|
128
|
+
it "returns a suite with a suite-specific roles_path set" do
|
129
|
+
stub_data!({ :suites => [{ :name => 'mysuite', :run_list => [] }] })
|
130
|
+
config.test_base_path = "/tmp/base"
|
131
|
+
FileUtils.mkdir_p "/tmp/base/mysuite/roles"
|
132
|
+
config.suites.first.roles_path.must_equal "/tmp/base/mysuite/roles"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "#instances" do
|
137
|
+
|
138
|
+
it "returns instances loaded from a kitchen.yml" do
|
139
|
+
stub_data!({
|
140
|
+
:platforms => [
|
141
|
+
{ :name => 'p1' },
|
142
|
+
{ :name => 'p2' },
|
143
|
+
],
|
144
|
+
:suites => [
|
145
|
+
{ :name => 's1', :run_list => [] },
|
146
|
+
{ :name => 's2', :run_list => [] },
|
147
|
+
{ :name => 's3', :run_list => [], :excludes => ['p1'] }
|
148
|
+
]
|
149
|
+
})
|
150
|
+
config.instances.size.must_equal 5
|
151
|
+
config.instances.map { |i| i.name }.must_equal %w{s1-p1 s1-p2 s2-p1 s2-p2 s3-p2}
|
152
|
+
end
|
153
|
+
|
154
|
+
it "returns an instance containing a driver instance" do
|
155
|
+
stub_data!({
|
156
|
+
:platforms => [{ :name => 'platform', :driver_plugin => 'dummy' }],
|
157
|
+
:suites => [{ :name => 'suite', :run_list => [] }]
|
158
|
+
})
|
159
|
+
config.instances.first.driver.must_be_instance_of Kitchen::Driver::Dummy
|
160
|
+
end
|
161
|
+
|
162
|
+
it "returns an instance with a driver initialized with kitchen_root" do
|
163
|
+
config.kitchen_root = "/tmp"
|
164
|
+
stub_data!({
|
165
|
+
:platforms => [{ :name => 'platform', :driver_plugin => 'dummy' }],
|
166
|
+
:suites => [{ :name => 'suite', :run_list => [] }]
|
167
|
+
})
|
168
|
+
config.instances.first.driver[:kitchen_root].must_equal "/tmp"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "returns an instance with a driver initialized with passed in config" do
|
172
|
+
stub_data!({
|
173
|
+
:platforms => [
|
174
|
+
{ :name => 'platform', :driver_plugin => 'dummy',
|
175
|
+
:driver_config => { :foo => 'bar' }
|
176
|
+
}
|
177
|
+
],
|
178
|
+
:suites => [{ :name => 'suite', :run_list => [] }]
|
179
|
+
})
|
180
|
+
config.instances.first.driver[:foo].must_equal "bar"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "#log_level" do
|
185
|
+
|
186
|
+
it "returns a default log_level of info" do
|
187
|
+
config.log_level.must_equal :info
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns an overridden log_level" do
|
191
|
+
config.log_level = :error
|
192
|
+
config.log_level.must_equal :error
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def stub_data!(hash)
|
199
|
+
loader.data = hash
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012, Fletcher Nichol
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require_relative '../../spec_helper'
|
20
|
+
require 'logger'
|
21
|
+
require 'stringio'
|
22
|
+
|
23
|
+
require 'kitchen/driver/dummy'
|
24
|
+
|
25
|
+
describe Kitchen::Driver::Dummy do
|
26
|
+
|
27
|
+
let(:logged_output) { StringIO.new }
|
28
|
+
let(:logger) { Logger.new(logged_output) }
|
29
|
+
let(:config) { Hash.new }
|
30
|
+
let(:state) { Hash.new }
|
31
|
+
|
32
|
+
let(:instance) do
|
33
|
+
stub(:name => "coolbeans", :logger => logger, :to_str => "instance")
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:driver) do
|
37
|
+
d = Kitchen::Driver::Dummy.new(config)
|
38
|
+
d.instance = instance
|
39
|
+
d
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "default_config" do
|
43
|
+
|
44
|
+
it "sets :sleep to 0 by default" do
|
45
|
+
driver[:sleep].must_equal 0
|
46
|
+
end
|
47
|
+
|
48
|
+
it "sets :random_failure to false by default" do
|
49
|
+
driver[:random_failure].must_equal false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#create" do
|
54
|
+
|
55
|
+
it "sets :my_id to a unique value as an example" do
|
56
|
+
driver.create(state)
|
57
|
+
|
58
|
+
state[:my_id].must_match /^coolbeans-/
|
59
|
+
end
|
60
|
+
|
61
|
+
it "calls sleep if :sleep value is greater than 0" do
|
62
|
+
config[:sleep] = 12.5
|
63
|
+
driver.expects(:sleep).with(12.5).returns(true)
|
64
|
+
|
65
|
+
driver.create(state)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "randomly raises ActionFailed if :random_failure is set" do
|
69
|
+
config[:random_failure] = true
|
70
|
+
driver.stubs(:randomly_fail?).returns(true)
|
71
|
+
|
72
|
+
proc { driver.create(state) }.must_raise Kitchen::ActionFailed
|
73
|
+
end
|
74
|
+
|
75
|
+
it "will only raise ActionFailed if :random_failure is set" do
|
76
|
+
config[:random_failure] = true
|
77
|
+
|
78
|
+
begin
|
79
|
+
driver.create(state)
|
80
|
+
rescue Kitchen::ActionFailed => ex
|
81
|
+
# If exception is anything other than Kitchen::ActionFailed, this spec
|
82
|
+
# will fail
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "logs a create event to INFO" do
|
87
|
+
driver.create(state)
|
88
|
+
|
89
|
+
logged_output.string.must_match /^.+ INFO .+ \[Dummy\] Create on .+$/
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#converge" do
|
94
|
+
|
95
|
+
it "calls sleep if :sleep value is greater than 0" do
|
96
|
+
config[:sleep] = 12.5
|
97
|
+
driver.expects(:sleep).with(12.5).returns(true)
|
98
|
+
|
99
|
+
driver.create(state)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "randomly raises ActionFailed if :random_failure is set" do
|
103
|
+
config[:random_failure] = true
|
104
|
+
driver.stubs(:randomly_fail?).returns(true)
|
105
|
+
|
106
|
+
proc { driver.converge(state) }.must_raise Kitchen::ActionFailed
|
107
|
+
end
|
108
|
+
|
109
|
+
it "logs a converge event to INFO" do
|
110
|
+
driver.converge(state)
|
111
|
+
|
112
|
+
logged_output.string.must_match /^.+ INFO .+ \[Dummy\] Converge on .+$/
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#setup" do
|
117
|
+
|
118
|
+
it "calls sleep if :sleep value is greater than 0" do
|
119
|
+
config[:sleep] = 12.5
|
120
|
+
driver.expects(:sleep).with(12.5).returns(true)
|
121
|
+
|
122
|
+
driver.setup(state)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "randomly raises ActionFailed if :random_failure is set" do
|
126
|
+
config[:random_failure] = true
|
127
|
+
driver.stubs(:randomly_fail?).returns(true)
|
128
|
+
|
129
|
+
proc { driver.setup(state) }.must_raise Kitchen::ActionFailed
|
130
|
+
end
|
131
|
+
|
132
|
+
it "logs a setup event to INFO" do
|
133
|
+
driver.setup(state)
|
134
|
+
|
135
|
+
logged_output.string.must_match /^.+ INFO .+ \[Dummy\] Setup on .+$/
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "#verify" do
|
140
|
+
|
141
|
+
it "calls sleep if :sleep value is greater than 0" do
|
142
|
+
config[:sleep] = 12.5
|
143
|
+
driver.expects(:sleep).with(12.5).returns(true)
|
144
|
+
|
145
|
+
driver.verify(state)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "randomly raises ActionFailed if :random_failure is set" do
|
149
|
+
config[:random_failure] = true
|
150
|
+
driver.stubs(:randomly_fail?).returns(true)
|
151
|
+
|
152
|
+
proc { driver.verify(state) }.must_raise Kitchen::ActionFailed
|
153
|
+
end
|
154
|
+
|
155
|
+
it "logs a verify event to INFO" do
|
156
|
+
driver.verify(state)
|
157
|
+
|
158
|
+
logged_output.string.must_match /^.+ INFO .+ \[Dummy\] Verify on .+$/
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "#destroy" do
|
163
|
+
|
164
|
+
it "removes :my_id from the state hash" do
|
165
|
+
state[:my_id] = "90210"
|
166
|
+
driver.destroy(state)
|
167
|
+
|
168
|
+
state[:my_id].must_be_nil
|
169
|
+
end
|
170
|
+
|
171
|
+
it "calls sleep if :sleep value is greater than 0" do
|
172
|
+
config[:sleep] = 12.5
|
173
|
+
driver.expects(:sleep).with(12.5).returns(true)
|
174
|
+
|
175
|
+
driver.verify(state)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "randomly raises ActionFailed if :random_failure is set" do
|
179
|
+
config[:random_failure] = true
|
180
|
+
driver.stubs(:randomly_fail?).returns(true)
|
181
|
+
|
182
|
+
proc { driver.destroy(state) }.must_raise Kitchen::ActionFailed
|
183
|
+
end
|
184
|
+
|
185
|
+
it "logs a destroy event to INFO" do
|
186
|
+
driver.destroy(state)
|
187
|
+
|
188
|
+
logged_output.string.must_match /^.+ INFO .+ \[Dummy\] Destroy on .+$/
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012, Fletcher Nichol
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require_relative '../spec_helper'
|
20
|
+
require 'logger'
|
21
|
+
require 'stringio'
|
22
|
+
|
23
|
+
require 'kitchen/logging'
|
24
|
+
require 'kitchen/instance'
|
25
|
+
require 'kitchen/driver'
|
26
|
+
require 'kitchen/driver/dummy'
|
27
|
+
require 'kitchen/platform'
|
28
|
+
require 'kitchen/suite'
|
29
|
+
|
30
|
+
describe Kitchen::Instance do
|
31
|
+
|
32
|
+
let(:suite) do
|
33
|
+
Kitchen::Suite.new({ :name => 'suite',
|
34
|
+
:run_list => 'suite_list', :attributes => { :s => 'ss' } })
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:platform) do
|
38
|
+
Kitchen::Platform.new({ :name => 'platform',
|
39
|
+
:run_list => 'platform_list', :attributes => { :p => 'pp' } })
|
40
|
+
end
|
41
|
+
|
42
|
+
let(:driver) { Kitchen::Driver::Dummy.new({}) }
|
43
|
+
|
44
|
+
let(:opts) do
|
45
|
+
{ :suite => suite, :platform => platform, :driver => driver }
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:instance) { Kitchen::Instance.new(opts) }
|
49
|
+
|
50
|
+
before do
|
51
|
+
Celluloid.logger = Logger.new(StringIO.new)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "raises an ArgumentError if suite is missing" do
|
55
|
+
opts.delete(:suite)
|
56
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
57
|
+
end
|
58
|
+
|
59
|
+
it "raises an ArgumentError if platform is missing" do
|
60
|
+
opts.delete(:platform)
|
61
|
+
proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
|
62
|
+
end
|
63
|
+
|
64
|
+
it "returns suite" do
|
65
|
+
instance.suite.must_equal suite
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns platform" do
|
69
|
+
instance.platform.must_equal platform
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#name" do
|
73
|
+
|
74
|
+
def combo(suite_name, platform_name)
|
75
|
+
opts[:suite] = Kitchen::Suite.new(
|
76
|
+
:name => suite_name, :run_list => []
|
77
|
+
)
|
78
|
+
opts[:platform] = Kitchen::Platform.new(
|
79
|
+
:name => platform_name
|
80
|
+
)
|
81
|
+
Kitchen::Instance.new(opts)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "combines the suite and platform names with a dash" do
|
85
|
+
combo('suite', 'platform').name.must_equal "suite-platform"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "squashes periods" do
|
89
|
+
combo('suite.ness', 'platform').name.must_equal "suiteness-platform"
|
90
|
+
combo('suite', 'platform.s').name.must_equal "suite-platforms"
|
91
|
+
combo('s.s.', '.p.p').name.must_equal "ss-pp"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "transforms underscores to dashes" do
|
95
|
+
combo('suite_ness', 'platform').name.must_equal "suite-ness-platform"
|
96
|
+
combo('suite', 'platform-s').name.must_equal "suite-platform-s"
|
97
|
+
combo('_s__s_', 'pp_').name.must_equal "-s--s--pp-"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#run_list" do
|
102
|
+
|
103
|
+
def combo(suite_list, platform_list)
|
104
|
+
opts[:suite] = Kitchen::Suite.new(
|
105
|
+
:name => 'suite', :run_list => suite_list
|
106
|
+
)
|
107
|
+
opts[:platform] = Kitchen::Platform.new(
|
108
|
+
:name => 'platform', :run_list => platform_list
|
109
|
+
)
|
110
|
+
Kitchen::Instance.new(opts)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "combines the platform then suite run_lists" do
|
114
|
+
combo(%w{s1 s2}, %w{p1 p2}).run_list.must_equal %w{p1 p2 s1 s2}
|
115
|
+
end
|
116
|
+
|
117
|
+
it "uses the suite run_list only when platform run_list is empty" do
|
118
|
+
combo(%w{sa sb}, nil).run_list.must_equal %w{sa sb}
|
119
|
+
end
|
120
|
+
|
121
|
+
it "returns an emtpy Array if both run_lists are empty" do
|
122
|
+
combo([], nil).run_list.must_equal []
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#attributes" do
|
127
|
+
|
128
|
+
def combo(suite_attrs, platform_attrs)
|
129
|
+
opts[:suite] = Kitchen::Suite.new(
|
130
|
+
:name => 'suite', :run_list => [], :attributes => suite_attrs
|
131
|
+
)
|
132
|
+
opts[:platform] = Kitchen::Platform.new(
|
133
|
+
:name => 'platform', :attributes => platform_attrs
|
134
|
+
)
|
135
|
+
Kitchen::Instance.new(opts)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "merges suite and platform hashes together" do
|
139
|
+
combo(
|
140
|
+
{ :suite => { :s1 => 'sv1' } },
|
141
|
+
{ :suite => { :p1 => 'pv1' }, :platform => 'pp' }
|
142
|
+
).attributes.must_equal({
|
143
|
+
:suite => { :s1 => 'sv1', :p1 => 'pv1' },
|
144
|
+
:platform => 'pp'
|
145
|
+
})
|
146
|
+
end
|
147
|
+
|
148
|
+
it "merges suite values over platform values" do
|
149
|
+
combo(
|
150
|
+
{ :common => { :c1 => 'xxx' } },
|
151
|
+
{ :common => { :c1 => 'cv1', :c2 => 'cv2' } },
|
152
|
+
).attributes.must_equal({
|
153
|
+
:common => { :c1 => 'xxx', :c2 => 'cv2' }
|
154
|
+
})
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "#dna combines attributes with the run_list" do
|
159
|
+
instance.dna.must_equal({ :s => 'ss', :p => 'pp',
|
160
|
+
:run_list => ['platform_list', 'suite_list'] })
|
161
|
+
end
|
162
|
+
end
|