|
| 1 | + |
1 | 2 | # coding: utf-8
|
2 | 3 | require 'spec_helper'
|
3 | 4 | require 'puppet/http'
|
|
258 | 259 | end
|
259 | 260 | end
|
260 | 261 |
|
| 262 | + context 'when posting for a v4 catalog' do |
| 263 | + let(:uri) {"https://compiler.example.com:8140/puppet/v4/catalog"} |
| 264 | + let(:persistence) {{ facts: true, catalog: true }} |
| 265 | + let(:facts) {{ 'foo' => 'bar' }} |
| 266 | + let(:trusted_facts) {{}} |
| 267 | + let(:uuid) { "ec3d2844-b236-4287-b0ad-632fbb4d1ff0" } |
| 268 | + let(:job_id) { "1" } |
| 269 | + let(:payload) {{ |
| 270 | + environment: environment, |
| 271 | + persistence: persistence, |
| 272 | + facts: facts, |
| 273 | + trusted_facts: trusted_facts, |
| 274 | + transaction_uuid: uuid, |
| 275 | + job_id: job_id, |
| 276 | + options: { |
| 277 | + prefer_requested_environment: false, |
| 278 | + capture_logs: false |
| 279 | + } |
| 280 | + }} |
| 281 | + let(:serialized_catalog) {{ 'catalog' => catalog.to_data_hash }.to_json} |
| 282 | + let(:catalog_response) {{ body: serialized_catalog, headers: {'Content-Type' => formatter.mime }}} |
| 283 | + |
| 284 | + it 'includes default HTTP headers' do |
| 285 | + stub_request(:post, uri).with do |request| |
| 286 | + expect(request.headers).to include({'X-Puppet-Version' => /./, 'User-Agent' => /./}) |
| 287 | + expect(request.headers).to_not include('X-Puppet-Profiling') |
| 288 | + end.to_return(**catalog_response) |
| 289 | + |
| 290 | + subject.post_catalog4(certname, payload) |
| 291 | + end |
| 292 | + |
| 293 | + it 'defaults the server and port based on settings' do |
| 294 | + Puppet[:server] = 'compiler2.example.com' |
| 295 | + Puppet[:serverport] = 8141 |
| 296 | + |
| 297 | + stub_request(:post, "https://compiler2.example.com:8141/puppet/v4/catalog") |
| 298 | + .to_return(**catalog_response) |
| 299 | + |
| 300 | + subject.post_catalog4(certname, payload) |
| 301 | + end |
| 302 | + |
| 303 | + it 'includes puppet headers set via the :http_extra_headers and :profile settings' do |
| 304 | + stub_request(:post, uri).with(headers: {'Example-Header' => 'real-thing', 'another' => 'thing', 'X-Puppet-Profiling' => 'true'}). |
| 305 | + to_return(**catalog_response) |
| 306 | + |
| 307 | + Puppet[:http_extra_headers] = 'Example-Header:real-thing,another:thing' |
| 308 | + Puppet[:profile] = true |
| 309 | + |
| 310 | + subject.post_catalog4(certname, payload) |
| 311 | + end |
| 312 | + |
| 313 | + it 'returns a deserialized catalog' do |
| 314 | + stub_request(:post, uri) |
| 315 | + .to_return(**catalog_response) |
| 316 | + |
| 317 | + _, cat, _ = subject.post_catalog4(certname, payload) |
| 318 | + expect(cat).to be_a(Puppet::Resource::Catalog) |
| 319 | + expect(cat.name).to eq(certname) |
| 320 | + end |
| 321 | + |
| 322 | + it 'returns the request response' do |
| 323 | + stub_request(:post, uri) |
| 324 | + .to_return(**catalog_response) |
| 325 | + |
| 326 | + resp, _, _ = subject.post_catalog4(certname, payload) |
| 327 | + expect(resp).to be_a(Puppet::HTTP::Response) |
| 328 | + end |
| 329 | + |
| 330 | + it 'raises a response error if unsuccessful' do |
| 331 | + stub_request(:post, uri) |
| 332 | + .to_return(status: [500, "Server Error"]) |
| 333 | + |
| 334 | + expect { |
| 335 | + subject.post_catalog4(certname, payload) |
| 336 | + }.to raise_error do |err| |
| 337 | + expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError) |
| 338 | + expect(err.message).to eq('Server Error') |
| 339 | + expect(err.response.code).to eq(500) |
| 340 | + end |
| 341 | + end |
| 342 | + |
| 343 | + it 'raises a response error when server response is not JSON' do |
| 344 | + stub_request(:post, uri) |
| 345 | + .to_return(body: "this isn't valid JSON", headers: {'Content-Type' => 'application/json'}) |
| 346 | + |
| 347 | + expect { |
| 348 | + subject.post_catalog4(certname, payload) |
| 349 | + }.to raise_error do |err| |
| 350 | + expect(err).to be_an_instance_of(Puppet::HTTP::SerializationError) |
| 351 | + expect(err.message).to match(/Failed to deserialize catalog from puppetserver response/) |
| 352 | + end |
| 353 | + end |
| 354 | + |
| 355 | + it 'raises a response error when server response a JSON serialized catalog' do |
| 356 | + stub_request(:post, uri) |
| 357 | + .to_return(body: {oops: 'bad response data'}.to_json, headers: {'Content-Type' => 'application/json'}) |
| 358 | + |
| 359 | + expect { |
| 360 | + subject.post_catalog4(certname, payload) |
| 361 | + }.to raise_error do |err| |
| 362 | + expect(err).to be_an_instance_of(Puppet::HTTP::SerializationError) |
| 363 | + expect(err.message).to match(/Failed to deserialize catalog from puppetserver response/) |
| 364 | + end |
| 365 | + end |
| 366 | + |
| 367 | + it 'raises ArgumentError when the `persistence` hash does not contain required keys' do |
| 368 | + payload[:persistence].delete(:facts) |
| 369 | + expect { subject.post_catalog4(certname, payload) }.to raise_error do |err| |
| 370 | + expect(err).to be_an_instance_of(ArgumentError) |
| 371 | + expect(err.message).to match(/The 'persistence' hash is missing the keys: facts/) |
| 372 | + end |
| 373 | + end |
| 374 | + |
| 375 | + it 'raises ArgumentError when `facts` are not a Hash' do |
| 376 | + payload[:facts] = Puppet::Node::Facts.new(certname) |
| 377 | + expect { subject.post_catalog4(certname, payload) }.to raise_error do |err| |
| 378 | + expect(err).to be_an_instance_of(ArgumentError) |
| 379 | + expect(err.message).to match(/Facts must be a Hash not a Puppet::Node::Facts/) |
| 380 | + end |
| 381 | + end |
| 382 | + end |
| 383 | + |
261 | 384 | context 'when getting a node' do
|
262 | 385 | let(:uri) { %r{/puppet/v3/node/ziggy} }
|
263 | 386 | let(:node_response) { { body: formatter.render(node), headers: {'Content-Type' => formatter.mime } } }
|
|
0 commit comments