chef-zero 4.2.3 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +155 -150
  4. data/Rakefile +31 -31
  5. data/bin/chef-zero +100 -100
  6. data/lib/chef_zero.rb +10 -7
  7. data/lib/chef_zero/chef_data/acl_path.rb +139 -139
  8. data/lib/chef_zero/chef_data/cookbook_data.rb +240 -240
  9. data/lib/chef_zero/chef_data/data_normalizer.rb +207 -207
  10. data/lib/chef_zero/chef_data/default_creator.rb +446 -446
  11. data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -29
  12. data/lib/chef_zero/data_store/data_error.rb +31 -31
  13. data/lib/chef_zero/data_store/data_not_found_error.rb +28 -28
  14. data/lib/chef_zero/data_store/default_facade.rb +149 -149
  15. data/lib/chef_zero/data_store/interface_v1.rb +67 -67
  16. data/lib/chef_zero/data_store/interface_v2.rb +18 -18
  17. data/lib/chef_zero/data_store/memory_store.rb +33 -33
  18. data/lib/chef_zero/data_store/memory_store_v2.rb +155 -155
  19. data/lib/chef_zero/data_store/raw_file_store.rb +147 -147
  20. data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +142 -142
  21. data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +107 -107
  22. data/lib/chef_zero/endpoints/acl_endpoint.rb +38 -38
  23. data/lib/chef_zero/endpoints/acls_endpoint.rb +29 -29
  24. data/lib/chef_zero/endpoints/actor_endpoint.rb +94 -88
  25. data/lib/chef_zero/endpoints/actors_endpoint.rb +64 -64
  26. data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +31 -31
  27. data/lib/chef_zero/endpoints/container_endpoint.rb +22 -22
  28. data/lib/chef_zero/endpoints/containers_endpoint.rb +13 -13
  29. data/lib/chef_zero/endpoints/cookbook_endpoint.rb +39 -39
  30. data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +119 -119
  31. data/lib/chef_zero/endpoints/cookbooks_base.rb +65 -65
  32. data/lib/chef_zero/endpoints/cookbooks_endpoint.rb +19 -19
  33. data/lib/chef_zero/endpoints/data_bag_endpoint.rb +45 -45
  34. data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +25 -25
  35. data/lib/chef_zero/endpoints/data_bags_endpoint.rb +23 -23
  36. data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +24 -24
  37. data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +123 -123
  38. data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +22 -22
  39. data/lib/chef_zero/endpoints/environment_endpoint.rb +33 -33
  40. data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +23 -23
  41. data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +22 -22
  42. data/lib/chef_zero/endpoints/environment_role_endpoint.rb +36 -36
  43. data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +22 -22
  44. data/lib/chef_zero/endpoints/group_endpoint.rb +20 -20
  45. data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -13
  46. data/lib/chef_zero/endpoints/license_endpoint.rb +25 -25
  47. data/lib/chef_zero/endpoints/node_endpoint.rb +17 -17
  48. data/lib/chef_zero/endpoints/node_identifiers_endpoint.rb +22 -0
  49. data/lib/chef_zero/endpoints/not_found_endpoint.rb +11 -11
  50. data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -22
  51. data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +30 -29
  52. data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -26
  53. data/lib/chef_zero/endpoints/organization_endpoint.rb +46 -41
  54. data/lib/chef_zero/endpoints/organization_user_base.rb +15 -0
  55. data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -48
  56. data/lib/chef_zero/endpoints/organization_users_endpoint.rb +43 -14
  57. data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -20
  58. data/lib/chef_zero/endpoints/organizations_endpoint.rb +62 -55
  59. data/lib/chef_zero/endpoints/policies_endpoint.rb +151 -154
  60. data/lib/chef_zero/endpoints/principal_endpoint.rb +42 -42
  61. data/lib/chef_zero/endpoints/rest_list_endpoint.rb +42 -42
  62. data/lib/chef_zero/endpoints/rest_object_endpoint.rb +63 -63
  63. data/lib/chef_zero/endpoints/role_endpoint.rb +16 -16
  64. data/lib/chef_zero/endpoints/role_environments_endpoint.rb +14 -14
  65. data/lib/chef_zero/endpoints/sandbox_endpoint.rb +27 -27
  66. data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +50 -50
  67. data/lib/chef_zero/endpoints/search_endpoint.rb +194 -192
  68. data/lib/chef_zero/endpoints/searches_endpoint.rb +18 -18
  69. data/lib/chef_zero/endpoints/server_api_version_endpoint.rb +14 -0
  70. data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -30
  71. data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +40 -40
  72. data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -19
  73. data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -19
  74. data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -22
  75. data/lib/chef_zero/endpoints/version_endpoint.rb +12 -12
  76. data/lib/chef_zero/log.rb +7 -7
  77. data/lib/chef_zero/rest_base.rb +242 -214
  78. data/lib/chef_zero/rest_error_response.rb +11 -11
  79. data/lib/chef_zero/rest_request.rb +69 -65
  80. data/lib/chef_zero/rest_router.rb +45 -45
  81. data/lib/chef_zero/rspec.rb +308 -308
  82. data/lib/chef_zero/server.rb +642 -637
  83. data/lib/chef_zero/socketless_server_map.rb +92 -92
  84. data/lib/chef_zero/solr/query/binary_operator.rb +52 -52
  85. data/lib/chef_zero/solr/query/phrase.rb +23 -23
  86. data/lib/chef_zero/solr/query/range_query.rb +46 -46
  87. data/lib/chef_zero/solr/query/regexpable_query.rb +29 -29
  88. data/lib/chef_zero/solr/query/subquery.rb +37 -37
  89. data/lib/chef_zero/solr/query/term.rb +45 -45
  90. data/lib/chef_zero/solr/query/unary_operator.rb +43 -43
  91. data/lib/chef_zero/solr/solr_doc.rb +53 -53
  92. data/lib/chef_zero/solr/solr_parser.rb +203 -203
  93. data/lib/chef_zero/version.rb +3 -3
  94. data/spec/run_oc_pedant.rb +63 -56
  95. data/spec/search_spec.rb +32 -32
  96. data/spec/server_spec.rb +92 -91
  97. data/spec/socketless_server_map_spec.rb +76 -76
  98. data/spec/support/oc_pedant.rb +132 -134
  99. data/spec/support/stickywicket.pem +27 -27
  100. metadata +10 -15
  101. data/spec/run_pedant.rb +0 -103
  102. data/spec/support/pedant.rb +0 -129
@@ -1,3 +1,3 @@
1
- module ChefZero
2
- VERSION = '4.2.3'
3
- end
1
+ module ChefZero
2
+ VERSION = '4.3.0'
3
+ end
@@ -1,56 +1,63 @@
1
- #!/usr/bin/env ruby
2
- require 'bundler'
3
- require 'bundler/setup'
4
-
5
- require 'chef_zero/server'
6
- require 'rspec/core'
7
-
8
- tmpdir = nil
9
-
10
- begin
11
- if ENV['FILE_STORE']
12
- require 'tmpdir'
13
- require 'chef_zero/data_store/raw_file_store'
14
- tmpdir = Dir.mktmpdir
15
- data_store = ChefZero::DataStore::RawFileStore.new(tmpdir, true)
16
- data_store = ChefZero::DataStore::DefaultFacade.new(data_store, false, false)
17
- server = ChefZero::Server.new(:port => 8889, :single_org => false, :data_store => data_store)
18
- server.start_background
19
-
20
- else
21
- server = ChefZero::Server.new(:port => 8889, :single_org => false)#, :log_level => :debug)
22
- server.start_background
23
- end
24
-
25
- require 'rspec/core'
26
- require 'pedant'
27
- require 'pedant/opensource/platform'
28
- require 'pedant/multitenant'
29
- require 'pedant/organization'
30
-
31
- #Pedant::Config.rerun = true
32
-
33
- Pedant.config.suite = 'api'
34
- Pedant.config[:config_file] = 'spec/support/oc_pedant.rb'
35
- Pedant.setup([
36
- '--skip-knife',
37
- '--skip-keys',
38
- '--skip-controls',
39
- '--skip-acl',
40
- '--skip-validation',
41
- '--skip-authentication',
42
- '--skip-authorization',
43
- '--skip-omnibus',
44
- '--skip-usags',
45
- '--skip-internal_orgs',
46
- '--skip-rename_org'
47
- ])
48
-
49
- result = RSpec::Core::Runner.run(Pedant.config.rspec_args)
50
-
51
- server.stop if server.running?
52
- ensure
53
- FileUtils.remove_entry_secure(tmpdir) if tmpdir
54
- end
55
-
56
- exit(result)
1
+ #!/usr/bin/env ruby
2
+ require 'bundler'
3
+ require 'bundler/setup'
4
+
5
+ require 'chef_zero/server'
6
+ require 'rspec/core'
7
+
8
+ tmpdir = nil
9
+
10
+ begin
11
+ if ENV['FILE_STORE']
12
+ require 'tmpdir'
13
+ require 'chef_zero/data_store/raw_file_store'
14
+ tmpdir = Dir.mktmpdir
15
+ data_store = ChefZero::DataStore::RawFileStore.new(tmpdir, true)
16
+ data_store = ChefZero::DataStore::DefaultFacade.new(data_store, false, false)
17
+ server = ChefZero::Server.new(:port => 8889, :single_org => false, :data_store => data_store)
18
+ server.start_background
19
+
20
+ else
21
+ server = ChefZero::Server.new(:port => 8889, :single_org => false)#, :log_level => :debug)
22
+ server.start_background
23
+ end
24
+
25
+ require 'rspec/core'
26
+ require 'pedant'
27
+ require 'pedant/organization'
28
+
29
+ #Pedant::Config.rerun = true
30
+
31
+ Pedant.config.suite = 'api'
32
+ Pedant.config.internal_server = 'http://localhost:8889'
33
+ Pedant.config[:config_file] = 'spec/support/oc_pedant.rb'
34
+ Pedant.config[:server_api_version] = 0
35
+ Pedant.setup([
36
+ '--skip-knife',
37
+ '--skip-keys',
38
+ '--skip-controls',
39
+ '--skip-acl',
40
+ '--skip-validation',
41
+ '--skip-authentication',
42
+ '--skip-authorization',
43
+ '--skip-omnibus',
44
+ '--skip-usags',
45
+ '--exclude-internal-orgs',
46
+ '--skip-headers',
47
+
48
+ # Chef 12 features not yet 100% supported by Chef Zero
49
+ '--skip-policies',
50
+ '--skip-cookbook-artifacts',
51
+ '--skip-containers',
52
+ '--skip-api-v1'
53
+
54
+ ])
55
+
56
+ result = RSpec::Core::Runner.run(Pedant.config.rspec_args)
57
+
58
+ server.stop if server.running?
59
+ ensure
60
+ FileUtils.remove_entry_secure(tmpdir) if tmpdir
61
+ end
62
+
63
+ exit(result)
data/spec/search_spec.rb CHANGED
@@ -1,32 +1,32 @@
1
- require 'chef_zero/solr/solr_parser'
2
- require 'chef_zero/solr/solr_doc'
3
-
4
- describe ChefZero::Solr::SolrParser do
5
- let (:all_docs) do
6
- docs = []
7
- [{'foo' => 'a'},
8
- {'foo' => 'd'}].each_with_index do |h, i|
9
- docs.push ChefZero::Solr::SolrDoc.new(h, i)
10
- end
11
- docs
12
- end
13
-
14
- def search_for(query)
15
- q = ChefZero::Solr::SolrParser.new(query).parse
16
- all_docs.select {|doc| q.matches_doc?(doc) }
17
- end
18
-
19
- it "handles terms" do
20
- search_for('foo:d').size.should eq(1)
21
- end
22
-
23
- it "handles ranges" do
24
- search_for('foo:[a TO c]').size.should eq(1)
25
- end
26
-
27
- it "handles wildcard ranges" do
28
- search_for('foo:[* TO c]').size.should eq(1)
29
- search_for('foo:[c TO *]').size.should eq(1)
30
- search_for('foo:[* TO *]').size.should eq(2)
31
- end
32
- end
1
+ require 'chef_zero/solr/solr_parser'
2
+ require 'chef_zero/solr/solr_doc'
3
+
4
+ describe ChefZero::Solr::SolrParser do
5
+ let (:all_docs) do
6
+ docs = []
7
+ [{'foo' => 'a'},
8
+ {'foo' => 'd'}].each_with_index do |h, i|
9
+ docs.push ChefZero::Solr::SolrDoc.new(h, i)
10
+ end
11
+ docs
12
+ end
13
+
14
+ def search_for(query)
15
+ q = ChefZero::Solr::SolrParser.new(query).parse
16
+ all_docs.select {|doc| q.matches_doc?(doc) }
17
+ end
18
+
19
+ it "handles terms" do
20
+ search_for('foo:d').size.should eq(1)
21
+ end
22
+
23
+ it "handles ranges" do
24
+ search_for('foo:[a TO c]').size.should eq(1)
25
+ end
26
+
27
+ it "handles wildcard ranges" do
28
+ search_for('foo:[* TO c]').size.should eq(1)
29
+ search_for('foo:[c TO *]').size.should eq(1)
30
+ search_for('foo:[* TO *]').size.should eq(2)
31
+ end
32
+ end
data/spec/server_spec.rb CHANGED
@@ -1,91 +1,92 @@
1
- require 'chef_zero/server'
2
- require 'uri'
3
-
4
- describe ChefZero::Server do
5
- context 'with a server bound to port 8889' do
6
- before :each do
7
- @server = ChefZero::Server.new(:port => 8889)
8
- @server.start_background
9
- end
10
- after :each do
11
- @server.stop
12
- end
13
-
14
- it 'a second server bound to port 8889 throws EADDRINUSE' do
15
- expect { ChefZero::Server.new(:port => 8889).start }.to raise_error Errno::EADDRINUSE
16
- end
17
-
18
- it 'a server bound to range 8889-9999 binds to a port > 8889' do
19
- server = ChefZero::Server.new(:port => 8889.upto(9999))
20
- server.start_background
21
- expect(server.port).to be > 8889
22
- expect(URI(server.url).port).to be > 8889
23
- end
24
-
25
- it 'a server bound to range 8889-8889 throws an exception' do
26
- expect { ChefZero::Server.new(:port => 8889.upto(8889)).start_background }.to raise_error Errno::EADDRINUSE
27
- end
28
-
29
- context 'accept headers' do
30
- def get_nodes(accepts)
31
- uri = URI(@server.url)
32
- httpcall = Net::HTTP.new(uri.host, uri.port)
33
- httpcall.get('/nodes', 'Accept' => accepts)
34
- end
35
-
36
- def get_version
37
- uri = URI(@server.url)
38
- httpcall = Net::HTTP.new(uri.host, uri.port)
39
- httpcall.get('/version', 'Accept' => 'text/plain, application/json')
40
- end
41
-
42
- it 'accepts requests with no accept header' do
43
- request = Net::HTTP::Get.new('/nodes')
44
- request.delete('Accept')
45
- uri = URI(@server.url)
46
- response = Net::HTTP.new(uri.host, uri.port).request(request)
47
- expect(response.code).to eq '200'
48
- end
49
-
50
- it 'accepts requests with accept: application/json' do
51
- expect(get_nodes('application/json').code).to eq '200'
52
- end
53
-
54
- it 'accepts requests with accept: application/*' do
55
- expect(get_nodes('application/*').code).to eq '200'
56
- end
57
-
58
- it 'accepts requests with accept: application/*' do
59
- expect(get_nodes('*/*').code).to eq '200'
60
- end
61
-
62
- it 'denies requests with accept: application/blah' do
63
- expect(get_nodes('application/blah').code).to eq '406'
64
- end
65
-
66
- it 'denies requests with accept: blah/json' do
67
- expect(get_nodes('blah/json').code).to eq '406'
68
- end
69
-
70
- it 'denies requests with accept: blah/*' do
71
- expect(get_nodes('blah/*').code).to eq '406'
72
- end
73
-
74
- it 'denies requests with accept: blah/*' do
75
- expect(get_nodes('blah/*').code).to eq '406'
76
- end
77
-
78
- it 'denies requests with accept: <empty string>' do
79
- expect(get_nodes('').code).to eq '406'
80
- end
81
-
82
- it 'accepts requests with accept: a/b;a=b;c=d, application/json;a=b, application/xml;a=b' do
83
- expect(get_nodes('a/b;a=b;c=d, application/json;a=b, application/xml;a=b').code).to eq '200'
84
- end
85
-
86
- it 'accepts /version' do
87
- expect(get_version.body.start_with?('chef-zero')).to be true
88
- end
89
- end
90
- end
91
- end
1
+ require 'chef_zero/server'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ describe ChefZero::Server do
6
+ context 'with a server bound to port 8889' do
7
+ before :each do
8
+ @server = ChefZero::Server.new(:port => 8889)
9
+ @server.start_background
10
+ end
11
+ after :each do
12
+ @server.stop
13
+ end
14
+
15
+ it 'a second server bound to port 8889 throws EADDRINUSE' do
16
+ expect { ChefZero::Server.new(:port => 8889).start }.to raise_error Errno::EADDRINUSE
17
+ end
18
+
19
+ it 'a server bound to range 8889-9999 binds to a port > 8889' do
20
+ server = ChefZero::Server.new(:port => 8889.upto(9999))
21
+ server.start_background
22
+ expect(server.port).to be > 8889
23
+ expect(URI(server.url).port).to be > 8889
24
+ end
25
+
26
+ it 'a server bound to range 8889-8889 throws an exception' do
27
+ expect { ChefZero::Server.new(:port => 8889.upto(8889)).start_background }.to raise_error Errno::EADDRINUSE
28
+ end
29
+
30
+ context 'accept headers' do
31
+ def get_nodes(accepts)
32
+ uri = URI(@server.url)
33
+ httpcall = Net::HTTP.new(uri.host, uri.port)
34
+ httpcall.get('/nodes', 'Accept' => accepts)
35
+ end
36
+
37
+ def get_version
38
+ uri = URI(@server.url)
39
+ httpcall = Net::HTTP.new(uri.host, uri.port)
40
+ httpcall.get('/version', 'Accept' => 'text/plain, application/json')
41
+ end
42
+
43
+ it 'accepts requests with no accept header' do
44
+ request = Net::HTTP::Get.new('/nodes')
45
+ request.delete('Accept')
46
+ uri = URI(@server.url)
47
+ response = Net::HTTP.new(uri.host, uri.port).request(request)
48
+ expect(response.code).to eq '200'
49
+ end
50
+
51
+ it 'accepts requests with accept: application/json' do
52
+ expect(get_nodes('application/json').code).to eq '200'
53
+ end
54
+
55
+ it 'accepts requests with accept: application/*' do
56
+ expect(get_nodes('application/*').code).to eq '200'
57
+ end
58
+
59
+ it 'accepts requests with accept: application/*' do
60
+ expect(get_nodes('*/*').code).to eq '200'
61
+ end
62
+
63
+ it 'denies requests with accept: application/blah' do
64
+ expect(get_nodes('application/blah').code).to eq '406'
65
+ end
66
+
67
+ it 'denies requests with accept: blah/json' do
68
+ expect(get_nodes('blah/json').code).to eq '406'
69
+ end
70
+
71
+ it 'denies requests with accept: blah/*' do
72
+ expect(get_nodes('blah/*').code).to eq '406'
73
+ end
74
+
75
+ it 'denies requests with accept: blah/*' do
76
+ expect(get_nodes('blah/*').code).to eq '406'
77
+ end
78
+
79
+ it 'denies requests with accept: <empty string>' do
80
+ expect(get_nodes('').code).to eq '406'
81
+ end
82
+
83
+ it 'accepts requests with accept: a/b;a=b;c=d, application/json;a=b, application/xml;a=b' do
84
+ expect(get_nodes('a/b;a=b;c=d, application/json;a=b, application/xml;a=b').code).to eq '200'
85
+ end
86
+
87
+ it 'accepts /version' do
88
+ expect(get_version.body.start_with?('chef-zero')).to be true
89
+ end
90
+ end
91
+ end
92
+ end
@@ -1,76 +1,76 @@
1
- require 'chef_zero/socketless_server_map'
2
-
3
-
4
- describe "Socketless Mode" do
5
-
6
- let(:server_map) { ChefZero::SocketlessServerMap.instance.tap { |i| i.reset! } }
7
-
8
- let(:server) { instance_double("ChefZero::Server") }
9
-
10
- let(:second_server) { instance_double("ChefZero::Server") }
11
-
12
- it "registers a socketful server" do
13
- server_map.register_port(8889, server)
14
- expect(server_map).to have_server_on_port(8889)
15
- end
16
-
17
- it "retrieves a server by port" do
18
- server_map.register_port(8889, server)
19
- expect(ChefZero::SocketlessServerMap.server_on_port(8889)).to eq(server)
20
- end
21
-
22
- context "when a no-listen server is registered" do
23
-
24
- let!(:port) { server_map.register_no_listen_server(server) }
25
-
26
- it "assigns the server a low port number" do
27
- expect(port).to eq(1)
28
- end
29
-
30
- context "and another server is registered" do
31
-
32
- let!(:next_port) { server_map.register_no_listen_server(second_server) }
33
-
34
- it "assigns another port when another server is registered" do
35
- expect(next_port).to eq(2)
36
- end
37
-
38
- it "raises NoSocketlessPortAvailable when too many servers are registered" do
39
- expect { 1000.times { server_map.register_no_listen_server(server) } }.to raise_error(ChefZero::NoSocketlessPortAvailable)
40
- end
41
-
42
- it "deregisters a server" do
43
- expect(server_map).to have_server_on_port(1)
44
- server_map.deregister(1)
45
- expect(server_map).to_not have_server_on_port(1)
46
- end
47
-
48
- describe "routing requests to a server" do
49
-
50
- let(:rack_req) do
51
- r = {}
52
- r["REQUEST_METHOD"] = "GET"
53
- r["SCRIPT_NAME"] = ""
54
- r["PATH_INFO"] = "/clients"
55
- r["QUERY_STRING"] = ""
56
- r["rack.input"] = StringIO.new("")
57
- r
58
- end
59
-
60
- let(:rack_response) { [200, {}, ["this is the response body"] ] }
61
-
62
- it "routes a request to the registered port" do
63
- expect(server).to receive(:handle_socketless_request).with(rack_req).and_return(rack_response)
64
- response = server_map.request(1, rack_req)
65
- expect(response).to eq(rack_response)
66
- end
67
-
68
- it "raises ServerNotFound when a request is sent to an unregistered port" do
69
- expect { server_map.request(99, rack_req) }.to raise_error(ChefZero::ServerNotFound)
70
- end
71
- end
72
- end
73
- end
74
-
75
-
76
- end
1
+ require 'chef_zero/socketless_server_map'
2
+
3
+
4
+ describe "Socketless Mode" do
5
+
6
+ let(:server_map) { ChefZero::SocketlessServerMap.instance.tap { |i| i.reset! } }
7
+
8
+ let(:server) { instance_double("ChefZero::Server") }
9
+
10
+ let(:second_server) { instance_double("ChefZero::Server") }
11
+
12
+ it "registers a socketful server" do
13
+ server_map.register_port(8889, server)
14
+ expect(server_map).to have_server_on_port(8889)
15
+ end
16
+
17
+ it "retrieves a server by port" do
18
+ server_map.register_port(8889, server)
19
+ expect(ChefZero::SocketlessServerMap.server_on_port(8889)).to eq(server)
20
+ end
21
+
22
+ context "when a no-listen server is registered" do
23
+
24
+ let!(:port) { server_map.register_no_listen_server(server) }
25
+
26
+ it "assigns the server a low port number" do
27
+ expect(port).to eq(1)
28
+ end
29
+
30
+ context "and another server is registered" do
31
+
32
+ let!(:next_port) { server_map.register_no_listen_server(second_server) }
33
+
34
+ it "assigns another port when another server is registered" do
35
+ expect(next_port).to eq(2)
36
+ end
37
+
38
+ it "raises NoSocketlessPortAvailable when too many servers are registered" do
39
+ expect { 1000.times { server_map.register_no_listen_server(server) } }.to raise_error(ChefZero::NoSocketlessPortAvailable)
40
+ end
41
+
42
+ it "deregisters a server" do
43
+ expect(server_map).to have_server_on_port(1)
44
+ server_map.deregister(1)
45
+ expect(server_map).to_not have_server_on_port(1)
46
+ end
47
+
48
+ describe "routing requests to a server" do
49
+
50
+ let(:rack_req) do
51
+ r = {}
52
+ r["REQUEST_METHOD"] = "GET"
53
+ r["SCRIPT_NAME"] = ""
54
+ r["PATH_INFO"] = "/clients"
55
+ r["QUERY_STRING"] = ""
56
+ r["rack.input"] = StringIO.new("")
57
+ r
58
+ end
59
+
60
+ let(:rack_response) { [200, {}, ["this is the response body"] ] }
61
+
62
+ it "routes a request to the registered port" do
63
+ expect(server).to receive(:handle_socketless_request).with(rack_req).and_return(rack_response)
64
+ response = server_map.request(1, rack_req)
65
+ expect(response).to eq(rack_response)
66
+ end
67
+
68
+ it "raises ServerNotFound when a request is sent to an unregistered port" do
69
+ expect { server_map.request(99, rack_req) }.to raise_error(ChefZero::ServerNotFound)
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+
76
+ end