chef 12.2.1-x86-mingw32 → 12.3.0.rc.0-x86-mingw32

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/ext/win32-eventlog/Rakefile +10 -6
  3. data/lib/chef.rb +1 -0
  4. data/lib/chef/application/apply.rb +5 -0
  5. data/lib/chef/application/client.rb +10 -0
  6. data/lib/chef/application/knife.rb +5 -1
  7. data/lib/chef/application/solo.rb +5 -0
  8. data/lib/chef/chef_class.rb +130 -0
  9. data/lib/chef/client.rb +15 -7
  10. data/lib/chef/config.rb +13 -0
  11. data/lib/chef/event_loggers/windows_eventlog.rb +11 -5
  12. data/lib/chef/http.rb +13 -3
  13. data/lib/chef/http/basic_client.rb +21 -4
  14. data/lib/chef/http/socketless_chef_zero_client.rb +207 -0
  15. data/lib/chef/knife.rb +3 -0
  16. data/lib/chef/knife/bootstrap.rb +1 -1
  17. data/lib/chef/knife/core/status_presenter.rb +12 -11
  18. data/lib/chef/knife/ssh.rb +3 -1
  19. data/lib/chef/knife/status.rb +32 -7
  20. data/lib/chef/local_mode.rb +13 -3
  21. data/lib/chef/mixin/provides.rb +32 -0
  22. data/lib/chef/platform/provider_priority_map.rb +16 -7
  23. data/lib/chef/platform/resource_priority_map.rb +37 -0
  24. data/lib/chef/policy_builder/expand_node_object.rb +14 -0
  25. data/lib/chef/policy_builder/policyfile.rb +0 -1
  26. data/lib/chef/provider.rb +5 -20
  27. data/lib/chef/provider/package/rubygems.rb +4 -1
  28. data/lib/chef/provider/service/macosx.rb +66 -30
  29. data/lib/chef/provider_resolver.rb +10 -5
  30. data/lib/chef/resource.rb +5 -39
  31. data/lib/chef/resource/gem_package.rb +5 -0
  32. data/lib/chef/resource/link.rb +1 -1
  33. data/lib/chef/resource/macosx_service.rb +59 -0
  34. data/lib/chef/resource/remote_file.rb +0 -4
  35. data/lib/chef/resource_resolver.rb +101 -0
  36. data/lib/chef/rest.rb +4 -5
  37. data/lib/chef/search/query.rb +1 -1
  38. data/lib/chef/server_api.rb +1 -0
  39. data/lib/chef/version.rb +1 -1
  40. data/spec/data/lwrp/providers/buck_passer.rb +2 -1
  41. data/spec/data/lwrp/resources/bar.rb +1 -1
  42. data/spec/data/{big_json.json → nested.json} +2 -2
  43. data/spec/functional/event_loggers/windows_eventlog_spec.rb +14 -0
  44. data/spec/functional/resource/execute_spec.rb +1 -1
  45. data/spec/integration/client/client_spec.rb +12 -1
  46. data/spec/integration/client/ipv6_spec.rb +1 -1
  47. data/spec/integration/knife/common_options_spec.rb +3 -3
  48. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +1 -1
  49. data/spec/integration/solo/solo_spec.rb +7 -5
  50. data/spec/unit/application/client_spec.rb +10 -0
  51. data/spec/unit/chef_class_spec.rb +91 -0
  52. data/spec/unit/client_spec.rb +13 -0
  53. data/spec/unit/http/basic_client_spec.rb +43 -6
  54. data/spec/unit/http/socketless_chef_zero_client_spec.rb +174 -0
  55. data/spec/unit/http_spec.rb +14 -0
  56. data/spec/unit/json_compat_spec.rb +7 -20
  57. data/spec/unit/knife/ssh_spec.rb +18 -0
  58. data/spec/unit/knife/status_spec.rb +69 -3
  59. data/spec/unit/knife_spec.rb +5 -0
  60. data/spec/unit/provider/package/rubygems_spec.rb +19 -0
  61. data/spec/unit/provider/service/macosx_spec.rb +230 -203
  62. data/spec/unit/provider_resolver_spec.rb +1 -0
  63. data/spec/unit/recipe_spec.rb +48 -0
  64. data/spec/unit/resource/link_spec.rb +15 -0
  65. data/spec/unit/resource_spec.rb +6 -6
  66. data/spec/unit/rest_spec.rb +9 -0
  67. data/spec/unit/search/query_spec.rb +24 -0
  68. data/spec/unit/shell_spec.rb +3 -1
  69. metadata +16 -9
  70. data/spec/data/big_json_plus_one.json +0 -2
@@ -76,7 +76,7 @@ END_CLIENT_RB
76
76
 
77
77
  let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..", "bin") }
78
78
 
79
- let(:chef_client_cmd) { %Q[ruby '#{chef_dir}/chef-client' -c "#{path_to('config/client.rb')}" -lwarn] }
79
+ let(:chef_client_cmd) { %Q[ruby '#{chef_dir}/chef-client' --minimal-ohai -c "#{path_to('config/client.rb')}" -lwarn] }
80
80
 
81
81
  after do
82
82
  FileUtils.rm_rf(cache_path)
@@ -39,7 +39,7 @@ describe 'knife common options', :workstation do
39
39
 
40
40
  it 'knife raw /nodes/x should retrieve the node' do
41
41
  knife('raw /nodes/x').should_succeed( /"name": "x"/ )
42
- expect(Chef::Config.chef_server_url).to eq('http://localhost:9999')
42
+ expect(Chef::Config.chef_server_url).to eq('chefzero://localhost:9999')
43
43
  end
44
44
  end
45
45
 
@@ -101,7 +101,7 @@ EOM
101
101
 
102
102
  it 'knife raw -z --chef-zero-port=9999 /nodes/x retrieves the node' do
103
103
  knife('raw -z --chef-zero-port=9999 /nodes/x').should_succeed( /"name": "x"/ )
104
- expect(Chef::Config.chef_server_url).to eq('http://localhost:9999')
104
+ expect(Chef::Config.chef_server_url).to eq('chefzero://localhost:9999')
105
105
  end
106
106
 
107
107
  context 'when the default port (8889) is already bound' do
@@ -149,7 +149,7 @@ EOM
149
149
 
150
150
  it 'knife raw -z --chef-zero-port=9999 /nodes/x retrieves the node' do
151
151
  knife('raw -z --chef-zero-port=9999 /nodes/x').should_succeed( /"name": "x"/ )
152
- expect(Chef::Config.chef_server_url).to eq('http://localhost:9999')
152
+ expect(Chef::Config.chef_server_url).to eq('chefzero://localhost:9999')
153
153
  end
154
154
  end
155
155
  end
@@ -16,7 +16,7 @@ describe "LWRPs with inline resources" do
16
16
  # machine that has omnibus chef installed. In that case we need to ensure
17
17
  # we're running `chef-client` from the source tree and not the external one.
18
18
  # cf. CHEF-4914
19
- let(:chef_client) { "ruby '#{chef_dir}/chef-client'" }
19
+ let(:chef_client) { "ruby '#{chef_dir}/chef-client' --minimal-ohai" }
20
20
 
21
21
  when_the_repository "has a cookbook with a nested LWRP" do
22
22
  before do
@@ -15,6 +15,8 @@ describe "chef-solo" do
15
15
 
16
16
  let(:cookbook_ancient_100_metadata_rb) { cb_metadata("ancient", "1.0.0") }
17
17
 
18
+ let(:chef_solo) { "ruby bin/chef-solo --minimal-ohai" }
19
+
18
20
  when_the_repository "has a cookbook with a basic recipe" do
19
21
  before do
20
22
  file 'cookbooks/x/metadata.rb', cookbook_x_100_metadata_rb
@@ -26,7 +28,7 @@ describe "chef-solo" do
26
28
  cookbook_path "#{path_to('cookbooks')}"
27
29
  file_cache_path "#{path_to('config/cache')}"
28
30
  EOM
29
- result = shell_out("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir)
31
+ result = shell_out("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir)
30
32
  result.error!
31
33
  expect(result.stdout).to include("ITWORKS")
32
34
  end
@@ -41,7 +43,7 @@ EOM
41
43
  {"run_list":["x::default"]}
42
44
  E
43
45
 
44
- result = shell_out("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -j '#{path_to('config/node.json')}' -l debug", :cwd => chef_dir)
46
+ result = shell_out("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -j '#{path_to('config/node.json')}' -l debug", :cwd => chef_dir)
45
47
  result.error!
46
48
  expect(result.stdout).to include("ITWORKS")
47
49
  end
@@ -62,7 +64,7 @@ E
62
64
  cookbook_path "#{path_to('cookbooks')}"
63
65
  file_cache_path "#{path_to('config/cache')}"
64
66
  EOM
65
- result = shell_out("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir)
67
+ result = shell_out("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir)
66
68
  expect(result.exitstatus).to eq(0) # For CHEF-5120 this becomes 1
67
69
  expect(result.stdout).to include("WARN: MissingCookbookDependency")
68
70
  end
@@ -95,14 +97,14 @@ EOM
95
97
  chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..")
96
98
 
97
99
  # Instantiate the first chef-solo run
98
- s1 = Process.spawn("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \
100
+ s1 = Process.spawn("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \
99
101
  -l debug -L #{path_to('logs/runs.log')}", :chdir => chef_dir)
100
102
 
101
103
  # Give it some time to progress
102
104
  sleep 1
103
105
 
104
106
  # Instantiate the second chef-solo run
105
- s2 = Process.spawn("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \
107
+ s2 = Process.spawn("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \
106
108
  -l debug -L #{path_to('logs/runs.log')}", :chdir => chef_dir)
107
109
 
108
110
  Process.waitpid(s1)
@@ -131,6 +131,16 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
131
131
 
132
132
  end
133
133
 
134
+ describe "when --no-listen is set" do
135
+
136
+ it "configures listen = false" do
137
+ app.config[:listen] = false
138
+ app.reconfigure
139
+ expect(Chef::Config[:listen]).to eq(false)
140
+ end
141
+
142
+ end
143
+
134
144
  describe "when the json_attribs configuration option is specified" do
135
145
 
136
146
  let(:json_attribs) { {"a" => "b"} }
@@ -0,0 +1,91 @@
1
+ #
2
+ # Author:: Lamont Granquist (<lamont@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+
21
+ describe "Chef class" do
22
+ let(:platform) { "debian" }
23
+
24
+ let(:node) do
25
+ node = Chef::Node.new
26
+ node.automatic['platform'] = platform
27
+ node
28
+ end
29
+
30
+ let(:run_context) do
31
+ Chef::RunContext.new(node, nil, nil)
32
+ end
33
+
34
+ let(:resource_priority_map) do
35
+ double("Chef::Platform::ResourcePriorityMap")
36
+ end
37
+
38
+ let(:provider_priority_map) do
39
+ double("Chef::Platform::ProviderPriorityMap")
40
+ end
41
+
42
+ before do
43
+ Chef.set_run_context(run_context)
44
+ Chef.set_node(node)
45
+ Chef.set_resource_priority_map(resource_priority_map)
46
+ Chef.set_provider_priority_map(provider_priority_map)
47
+ end
48
+
49
+ after do
50
+ Chef.reset!
51
+ end
52
+
53
+ context "priority maps" do
54
+ context "#get_provider_priority_array" do
55
+ it "should use the current node to get the right priority_map" do
56
+ expect(provider_priority_map).to receive(:get_priority_array).with(node, :http_request).and_return("stuff")
57
+ expect(Chef.get_provider_priority_array(:http_request)).to eql("stuff")
58
+ end
59
+ end
60
+ context "#get_resource_priority_array" do
61
+ it "should use the current node to get the right priority_map" do
62
+ expect(resource_priority_map).to receive(:get_priority_array).with(node, :http_request).and_return("stuff")
63
+ expect(Chef.get_resource_priority_array(:http_request)).to eql("stuff")
64
+ end
65
+ end
66
+ context "#set_provider_priority_array" do
67
+ it "should delegate to the provider_priority_map" do
68
+ expect(provider_priority_map).to receive(:set_priority_array).with(:http_request, ["a", "b"], platform: "debian").and_return("stuff")
69
+ expect(Chef.set_provider_priority_array(:http_request, ["a", "b"], platform: "debian")).to eql("stuff")
70
+ end
71
+ end
72
+ context "#set_priority_map_for_resource" do
73
+ it "should delegate to the resource_priority_map" do
74
+ expect(resource_priority_map).to receive(:set_priority_array).with(:http_request, ["a", "b"], platform: "debian").and_return("stuff")
75
+ expect(Chef.set_resource_priority_array(:http_request, ["a", "b"], platform: "debian")).to eql("stuff")
76
+ end
77
+ end
78
+ end
79
+
80
+ context "#run_context" do
81
+ it "should return the injected RunContext" do
82
+ expect(Chef.run_context).to eql(run_context)
83
+ end
84
+ end
85
+
86
+ context "#node" do
87
+ it "should return the injected Node" do
88
+ expect(Chef.node).to eql(node)
89
+ end
90
+ end
91
+ end
@@ -78,6 +78,19 @@ describe Chef::Client do
78
78
  allow(Ohai::System).to receive(:new).and_return(ohai_system)
79
79
  end
80
80
 
81
+ context "when minimal ohai is configured" do
82
+ before do
83
+ Chef::Config[:minimal_ohai] = true
84
+ end
85
+
86
+ it "runs ohai with only the minimum required plugins" do
87
+ expected_filter = %w[fqdn machinename hostname platform platform_version os os_version]
88
+ expect(ohai_system).to receive(:all_plugins).with(expected_filter)
89
+ client.run_ohai
90
+ end
91
+
92
+ end
93
+
81
94
  describe "authentication protocol selection" do
82
95
  after do
83
96
  Chef::Config[:authentication_protocol_version] = "1.0"
@@ -21,7 +21,7 @@ require 'chef/http/basic_client'
21
21
  describe "HTTP Connection" do
22
22
 
23
23
  let(:uri) { URI("https://example.com:4443") }
24
- subject { Chef::HTTP::BasicClient.new(uri) }
24
+ subject(:basic_client) { Chef::HTTP::BasicClient.new(uri) }
25
25
 
26
26
  describe ".new" do
27
27
  it "creates an instance" do
@@ -45,11 +45,6 @@ describe "HTTP Connection" do
45
45
  let(:proxy_port) { 8080 }
46
46
  let(:proxy) { "#{proxy_prefix}#{proxy_host}:#{proxy_port}" }
47
47
 
48
- before do
49
- Chef::Config["#{uri.scheme}_proxy"] = proxy
50
- Chef::Config[:no_proxy] = nil
51
- end
52
-
53
48
  it "should contain the host" do
54
49
  proxy_uri = subject.proxy_uri
55
50
  expect(proxy_uri.host).to eq(proxy_host)
@@ -63,14 +58,56 @@ describe "HTTP Connection" do
63
58
 
64
59
  context "when the config setting is normalized (does not contain the scheme)" do
65
60
  include_examples "a proxy uri" do
61
+
66
62
  let(:proxy_prefix) { "" }
63
+
64
+ before do
65
+ Chef::Config["#{uri.scheme}_proxy"] = proxy
66
+ Chef::Config[:no_proxy] = nil
67
+ end
68
+
67
69
  end
68
70
  end
69
71
 
70
72
  context "when the config setting is not normalized (contains the scheme)" do
71
73
  include_examples "a proxy uri" do
72
74
  let(:proxy_prefix) { "#{uri.scheme}://" }
75
+
76
+ before do
77
+ Chef::Config["#{uri.scheme}_proxy"] = proxy
78
+ Chef::Config[:no_proxy] = nil
79
+ end
80
+
81
+ end
82
+ end
83
+
84
+ context "when the proxy is set by the environment" do
85
+
86
+ include_examples "a proxy uri" do
87
+
88
+ let(:env) do
89
+ {
90
+ "https_proxy" => "https://proxy.mycorp.com:8080",
91
+ "https_proxy_user" => "jane_username",
92
+ "https_proxy_pass" => "opensesame"
93
+ }
94
+ end
95
+
96
+ let(:proxy_uri) { URI.parse(env["https_proxy"]) }
97
+
98
+ before do
99
+ allow(basic_client).to receive(:env).and_return(env)
100
+ end
101
+
102
+ it "sets the proxy user" do
103
+ expect(basic_client.http_proxy_user(proxy_uri)).to eq("jane_username")
104
+ end
105
+
106
+ it "sets the proxy pass" do
107
+ expect(basic_client.http_proxy_pass(proxy_uri)).to eq("opensesame")
108
+ end
73
109
  end
110
+
74
111
  end
75
112
  end
76
113
  end
@@ -0,0 +1,174 @@
1
+ #--
2
+ # Author:: Daniel DeLeo (<dan@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/http/socketless_chef_zero_client'
20
+
21
+ describe Chef::HTTP::SocketlessChefZeroClient do
22
+
23
+ let(:relative_url) { "" }
24
+ let(:uri_str) { "chefzero://localhost:1/#{relative_url}" }
25
+ let(:uri) { URI(uri_str) }
26
+
27
+ subject(:zero_client) { Chef::HTTP::SocketlessChefZeroClient.new(uri) }
28
+
29
+ it "has a host" do
30
+ expect(zero_client.host).to eq("localhost")
31
+ end
32
+
33
+ it "has a port" do
34
+ expect(zero_client.port).to eq(1)
35
+ end
36
+
37
+ describe "converting requests to rack format" do
38
+
39
+ let(:expected_rack_req) do
40
+ {
41
+ "SCRIPT_NAME" => "",
42
+ "SERVER_NAME" => "localhost",
43
+ "REQUEST_METHOD" => method.to_s.upcase,
44
+ "PATH_INFO" => uri.path,
45
+ "QUERY_STRING" => uri.query,
46
+ "SERVER_PORT" => uri.port,
47
+ "HTTP_HOST" => "localhost:#{uri.port}",
48
+ "rack.url_scheme" => "chefzero",
49
+ }
50
+ end
51
+
52
+ context "when the request has no body" do
53
+
54
+ let(:method) { :GET }
55
+ let(:relative_url) { "clients" }
56
+ let(:headers) { { "Accept" => "application/json" } }
57
+ let(:body) { false }
58
+ let(:expected_body_str) { "" }
59
+
60
+ let(:rack_req) { zero_client.req_to_rack(method, uri, body, headers) }
61
+
62
+ it "creates a rack request env" do
63
+ # StringIO doesn't implement == in a way that we can compare, so we
64
+ # check rack.input individually and then iterate over everything else
65
+ expect(rack_req["rack.input"].string).to eq(expected_body_str)
66
+ expected_rack_req.each do |key, value|
67
+ expect(rack_req[key]).to eq(value)
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ context "when the request has a body" do
74
+
75
+ let(:method) { :PUT }
76
+ let(:relative_url) { "clients/foo" }
77
+ let(:headers) { { "Accept" => "application/json" } }
78
+ let(:body) { "bunch o' JSON" }
79
+ let(:expected_body_str) { "bunch o' JSON" }
80
+
81
+ let(:rack_req) { zero_client.req_to_rack(method, uri, body, headers) }
82
+
83
+ it "creates a rack request env" do
84
+ # StringIO doesn't implement == in a way that we can compare, so we
85
+ # check rack.input individually and then iterate over everything else
86
+ expect(rack_req["rack.input"].string).to eq(expected_body_str)
87
+ expected_rack_req.each do |key, value|
88
+ expect(rack_req[key]).to eq(value)
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ describe "converting responses to Net::HTTP objects" do
97
+
98
+ let(:net_http_response) { zero_client.to_net_http(code, headers, body) }
99
+
100
+ context "when the request was successful (2XX)" do
101
+
102
+ let(:code) { 200 }
103
+ let(:headers) { { "Content-Type" => "Application/JSON" } }
104
+ let(:body) { [ "bunch o' JSON" ] }
105
+
106
+ it "creates a Net::HTTP success response object" do
107
+ expect(net_http_response).to be_a_kind_of(Net::HTTPOK)
108
+ expect(net_http_response.read_body).to eq("bunch o' JSON")
109
+ expect(net_http_response["content-type"]).to eq("Application/JSON")
110
+ end
111
+
112
+ it "does not fail when calling read_body with a block" do
113
+ expect(net_http_response.read_body {|chunk| chunk }).to eq("bunch o' JSON")
114
+ end
115
+
116
+ end
117
+
118
+ context "when the requested object doesn't exist (404)" do
119
+
120
+ let(:code) { 404 }
121
+ let(:headers) { { "Content-Type" => "Application/JSON" } }
122
+ let(:body) { [ "nope" ] }
123
+
124
+ it "creates a Net::HTTPNotFound response object" do
125
+ expect(net_http_response).to be_a_kind_of(Net::HTTPNotFound)
126
+ end
127
+ end
128
+
129
+ end
130
+
131
+ describe "request-response round trip" do
132
+
133
+ let(:method) { :GET }
134
+ let(:relative_url) { "clients" }
135
+ let(:headers) { { "Accept" => "application/json" } }
136
+ let(:body) { false }
137
+
138
+ let(:expected_rack_req) do
139
+ {
140
+ "SCRIPT_NAME" => "",
141
+ "SERVER_NAME" => "localhost",
142
+ "REQUEST_METHOD" => method.to_s.upcase,
143
+ "PATH_INFO" => uri.path,
144
+ "QUERY_STRING" => uri.query,
145
+ "SERVER_PORT" => uri.port,
146
+ "HTTP_HOST" => "localhost:#{uri.port}",
147
+ "rack.url_scheme" => "chefzero",
148
+ "rack.input" => an_instance_of(StringIO),
149
+ }
150
+ end
151
+
152
+
153
+ let(:response_code) { 200 }
154
+ let(:response_headers) { { "Content-Type" => "Application/JSON" } }
155
+ let(:response_body) { [ "bunch o' JSON" ] }
156
+
157
+ let(:rack_response) { [ response_code, response_headers, response_body ] }
158
+
159
+ let(:response) { zero_client.request(method, uri, body, headers) }
160
+
161
+ before do
162
+ expect(ChefZero::SocketlessServerMap).to receive(:request).with(1, expected_rack_req).and_return(rack_response)
163
+ end
164
+
165
+ it "makes a rack request to Chef Zero and returns the response as a Net::HTTP object" do
166
+ _client, net_http_response = response
167
+ expect(net_http_response).to be_a_kind_of(Net::HTTPOK)
168
+ expect(net_http_response.code).to eq("200")
169
+ expect(net_http_response.body).to eq("bunch o' JSON")
170
+ end
171
+
172
+ end
173
+
174
+ end