test-kitchen 1.0.0.alpha.7 → 1.0.0.beta.1

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.
@@ -0,0 +1,123 @@
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'
24
+
25
+ module Kitchen
26
+
27
+ module Driver
28
+
29
+ class StaticDefaults < Base
30
+
31
+ default_config :beans, "kidney"
32
+ default_config :tunables, { 'flimflam' => 'positate' }
33
+ end
34
+
35
+ class ComputedDefaults < Base
36
+
37
+ default_config :beans, "kidney"
38
+ default_config :fetch_command, "curl"
39
+ default_config :beans_url do |driver|
40
+ "http://gim.me/#{driver[:beans]}"
41
+ end
42
+ default_config :command do |driver|
43
+ "#{driver[:fetch_command]} #{driver[:beans_url]}"
44
+ end
45
+ default_config :fetch_url do |driver|
46
+ "http://gim.me/beans-for/#{driver.instance.name}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ describe Kitchen::Driver::Base do
53
+
54
+ let(:logged_output) { StringIO.new }
55
+ let(:logger) { Logger.new(logged_output) }
56
+ let(:config) { Hash.new }
57
+ let(:state) { Hash.new }
58
+
59
+ let(:instance) do
60
+ stub(:name => "coolbeans", :logger => logger, :to_str => "instance")
61
+ end
62
+
63
+ describe "user config" do
64
+
65
+ let(:driver) do
66
+ d = Kitchen::Driver::Base.new(config)
67
+ d.instance = instance
68
+ d
69
+ end
70
+
71
+ it "injects config into driver" do
72
+ config[:fruit] = %w{apples oranges}
73
+ config[:cool_enough] = true
74
+
75
+ driver[:fruit].must_equal ['apples', 'oranges']
76
+ driver[:cool_enough].must_equal true
77
+ end
78
+ end
79
+
80
+ describe "static default config" do
81
+
82
+ let(:driver) do
83
+ d = Kitchen::Driver::StaticDefaults.new(config)
84
+ d.instance = instance
85
+ d
86
+ end
87
+
88
+ it "uses default config" do
89
+ driver[:beans].must_equal "kidney"
90
+ driver[:tunables]['flimflam'].must_equal 'positate'
91
+ end
92
+
93
+ it "uses user config over default config" do
94
+ config[:beans] = "pinto"
95
+
96
+ driver[:beans].must_equal "pinto"
97
+ end
98
+ end
99
+
100
+ describe "computed default config" do
101
+
102
+ let(:driver) do
103
+ d = Kitchen::Driver::ComputedDefaults.new(config)
104
+ d.instance = instance
105
+ d
106
+ end
107
+
108
+ it "uses computed config" do
109
+ driver[:beans_url].must_equal "http://gim.me/kidney"
110
+ driver[:command].must_equal "curl http://gim.me/kidney"
111
+ end
112
+
113
+ it "has access to instance object" do
114
+ driver[:fetch_url].must_equal "http://gim.me/beans-for/coolbeans"
115
+ end
116
+
117
+ it "uses user config over default config" do
118
+ config[:command] = "echo listentome"
119
+
120
+ driver[:command].must_equal "echo listentome"
121
+ end
122
+ end
123
+ end
@@ -98,65 +98,72 @@ describe Kitchen::Instance do
98
98
  end
99
99
  end
100
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 []
101
+ describe 'Cheflike' do
102
+
103
+ describe "#run_list" do
104
+
105
+ def combo(suite_list, platform_list)
106
+ opts[:suite] = Kitchen::Suite.new(
107
+ :name => 'suite', :run_list => suite_list
108
+ ).extend(Kitchen::Suite::Cheflike)
109
+ opts[:platform] = Kitchen::Platform.new(
110
+ :name => 'platform', :run_list => platform_list
111
+ ).extend(Kitchen::Platform::Cheflike)
112
+ Kitchen::Instance.new(opts).extend(Kitchen::Instance::Cheflike)
113
+ end
114
+
115
+ it "combines the platform then suite run_lists" do
116
+ combo(%w{s1 s2}, %w{p1 p2}).run_list.must_equal %w{p1 p2 s1 s2}
117
+ end
118
+
119
+ it "uses the suite run_list only when platform run_list is empty" do
120
+ combo(%w{sa sb}, nil).run_list.must_equal %w{sa sb}
121
+ end
122
+
123
+ it "returns an emtpy Array if both run_lists are empty" do
124
+ combo([], nil).run_list.must_equal []
125
+ end
123
126
  end
124
- end
125
-
126
- describe "#attributes" do
127
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)
128
+ describe "#attributes" do
129
+
130
+ def combo(suite_attrs, platform_attrs)
131
+ opts[:suite] = Kitchen::Suite.new(
132
+ :name => 'suite', :run_list => [], :attributes => suite_attrs
133
+ ).extend(Kitchen::Suite::Cheflike)
134
+ opts[:platform] = Kitchen::Platform.new(
135
+ :name => 'platform', :attributes => platform_attrs
136
+ ).extend(Kitchen::Platform::Cheflike)
137
+ Kitchen::Instance.new(opts).extend(Kitchen::Instance::Cheflike)
138
+ end
139
+
140
+ it "merges suite and platform hashes together" do
141
+ combo(
142
+ { :suite => { :s1 => 'sv1' } },
143
+ { :suite => { :p1 => 'pv1' }, :platform => 'pp' }
144
+ ).attributes.must_equal({
145
+ :suite => { :s1 => 'sv1', :p1 => 'pv1' },
146
+ :platform => 'pp'
147
+ })
148
+ end
149
+
150
+ it "merges suite values over platform values" do
151
+ combo(
152
+ { :common => { :c1 => 'xxx' } },
153
+ { :common => { :c1 => 'cv1', :c2 => 'cv2' } },
154
+ ).attributes.must_equal({
155
+ :common => { :c1 => 'xxx', :c2 => 'cv2' }
156
+ })
157
+ end
136
158
  end
137
159
 
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
160
+ it "#dna combines attributes with the run_list" do
161
+ instance.extend(Kitchen::Instance::Cheflike)
162
+ instance.platform.extend(Kitchen::Platform::Cheflike)
163
+ instance.suite.extend(Kitchen::Suite::Cheflike)
147
164
 
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
- })
165
+ instance.dna.must_equal({ :s => 'ss', :p => 'pp',
166
+ :run_list => ['platform_list', 'suite_list'] })
155
167
  end
156
168
  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
169
  end
@@ -31,18 +31,25 @@ describe Kitchen::Platform do
31
31
  proc { Kitchen::Platform.new(opts) }.must_raise Kitchen::ClientError
32
32
  end
33
33
 
34
- it "returns an empty Array given no run_list" do
35
- platform.run_list.must_equal []
36
- end
37
-
38
- it "returns an empty Hash given no attributes" do
39
- platform.attributes.must_equal Hash.new
40
- end
41
-
42
- it "returns attributes from constructor" do
43
- opts.merge!({ :run_list => ['a', 'b'], :attributes => { :c => 'd' } })
44
- platform.name.must_equal 'plata'
45
- platform.run_list.must_equal ['a', 'b']
46
- platform.attributes.must_equal({ :c => 'd' })
34
+ describe 'Cheflike' do
35
+
36
+ let(:platform) do
37
+ Kitchen::Platform.new(opts).extend(Kitchen::Platform::Cheflike)
38
+ end
39
+
40
+ it "returns an empty Array given no run_list" do
41
+ platform.run_list.must_equal []
42
+ end
43
+
44
+ it "returns an empty Hash given no attributes" do
45
+ platform.attributes.must_equal Hash.new
46
+ end
47
+
48
+ it "returns attributes from constructor" do
49
+ opts.merge!({ :run_list => ['a', 'b'], :attributes => { :c => 'd' } })
50
+ platform.name.must_equal 'plata'
51
+ platform.run_list.must_equal ['a', 'b']
52
+ platform.attributes.must_equal({ :c => 'd' })
53
+ end
47
54
  end
48
55
  end
@@ -31,39 +31,45 @@ describe Kitchen::Suite do
31
31
  proc { Kitchen::Suite.new(opts) }.must_raise Kitchen::ClientError
32
32
  end
33
33
 
34
- it "raises an ArgumentError if run_list is missing" do
35
- opts.delete(:run_list)
36
- proc { Kitchen::Suite.new(opts) }.must_raise Kitchen::ClientError
37
- end
34
+ describe 'Cheflike' do
38
35
 
39
- it "returns an empty Hash given no attributes" do
40
- suite.attributes.must_equal Hash.new
41
- end
36
+ let(:suite) { Kitchen::Suite.new(opts).extend(Kitchen::Suite::Cheflike) }
42
37
 
43
- it "returns an empty Array given no excludes" do
44
- suite.excludes.must_equal Array.new
45
- end
38
+ it "returns an empty Hash given no attributes" do
39
+ suite.attributes.must_equal Hash.new
40
+ end
46
41
 
47
- it "returns nil given no data_bags_path" do
48
- suite.data_bags_path.must_be_nil
49
- end
42
+ it "returns an empty Array given no excludes" do
43
+ suite.excludes.must_equal Array.new
44
+ end
50
45
 
51
- it "returns nil given no roles_path" do
52
- suite.roles_path.must_be_nil
53
- end
46
+ it "returns nil given no data_bags_path" do
47
+ suite.data_bags_path.must_be_nil
48
+ end
54
49
 
55
- it "returns nil given no encrypted_data_bag_secret_key_path" do
56
- suite.encrypted_data_bag_secret_key_path.must_be_nil
57
- end
50
+ it "returns nil given no roles_path" do
51
+ suite.roles_path.must_be_nil
52
+ end
53
+
54
+ it "returns nil given no nodes_path" do
55
+ suite.nodes_path.must_be_nil
56
+ end
57
+
58
+ it "returns nil given no encrypted_data_bag_secret_key_path" do
59
+ suite.encrypted_data_bag_secret_key_path.must_be_nil
60
+ end
58
61
 
59
- it "returns attributes from constructor" do
60
- opts.merge!({ :attributes => { :a => 'b' }, :data_bags_path => 'crazy',
61
- :roles_path => 'town', :encrypted_data_bag_secret_key_path => 'secret' })
62
- suite.name.must_equal 'suitezy'
63
- suite.run_list.must_equal ['doowah']
64
- suite.attributes.must_equal({ :a => 'b' })
65
- suite.data_bags_path.must_equal 'crazy'
66
- suite.roles_path.must_equal 'town'
67
- suite.encrypted_data_bag_secret_key_path.must_equal 'secret'
62
+ it "returns attributes from constructor" do
63
+ opts.merge!({ :attributes => { :a => 'b' }, :data_bags_path => 'crazy',
64
+ :roles_path => 'town', :nodes_path => 'woowoo',
65
+ :encrypted_data_bag_secret_key_path => 'secret' })
66
+ suite.name.must_equal 'suitezy'
67
+ suite.run_list.must_equal ['doowah']
68
+ suite.attributes.must_equal({ :a => 'b' })
69
+ suite.data_bags_path.must_equal 'crazy'
70
+ suite.roles_path.must_equal 'town'
71
+ suite.nodes_path.must_equal 'woowoo'
72
+ suite.encrypted_data_bag_secret_key_path.must_equal 'secret'
73
+ end
68
74
  end
69
75
  end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+ #
4
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
5
+ #
6
+ # Copyright (C) 2013, Fletcher Nichol
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+
20
+ require 'rubygems'
21
+ require 'chef'
22
+ require 'chef/application/client'
23
+ require 'chef_zero/server'
24
+ require 'chef_fs/chef_fs_data_store'
25
+ require 'chef_fs/config'
26
+ require 'tmpdir'
27
+
28
+ client = Chef::Application::Client.new
29
+ client.reconfigure
30
+
31
+ data_store = ChefFS::ChefFSDataStore.new(
32
+ ChefFS::Config.new(Chef::Config).local_fs
33
+ )
34
+
35
+ server_opts = {
36
+ :host => "127.0.0.1",
37
+ :port => 8889,
38
+ :generate_real_keys => false,
39
+ :data_store => data_store
40
+ }
41
+
42
+ Chef::Log.info("Starting Chef Zero server in background")
43
+ server = ChefZero::Server.new(server_opts)
44
+ server.start_background
45
+ at_exit do
46
+ Chef::Log.info("Shutting down Chef Zero server")
47
+ server.stop
48
+ end
49
+
50
+ Dir.mktmpdir do |tmpdir|
51
+ File.open(File.join(tmpdir, "validation.pem"), "wb") do |f|
52
+ f.write(server.gen_key_pair.first)
53
+ end
54
+ Chef::Config[:validation_key] = File.join(tmpdir, "validation.pem")
55
+ Chef::Config[:client_key] = File.join(tmpdir, "client.pem")
56
+ Chef::Config[:chef_server_url] = server.url
57
+ client.setup_application
58
+ client.run_application
59
+ end
@@ -7,19 +7,19 @@ platforms:
7
7
  - name: ubuntu-12.04
8
8
  driver_config:
9
9
  box: opscode-ubuntu-12.04
10
- box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box
10
+ box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box
11
11
  - name: ubuntu-10.04
12
12
  driver_config:
13
13
  box: opscode-ubuntu-10.04
14
- box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-10.04_provisionerless.box
14
+ box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-10.04_provisionerless.box
15
15
  - name: centos-6.4
16
16
  driver_config:
17
17
  box: opscode-centos-6.4
18
- box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_centos-6.4_provisionerless.box
18
+ box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_centos-6.4_provisionerless.box
19
19
  - name: centos-5.9
20
20
  driver_config:
21
21
  box: opscode-centos-5.9
22
- box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_centos-5.9_provisionerless.box
22
+ box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_centos-5.9_provisionerless.box
23
23
 
24
24
  suites:
25
25
  - name: default