poise-application-python 4.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.kitchen.travis.yml +9 -0
- data/.kitchen.yml +10 -0
- data/.travis.yml +20 -0
- data/.yardopts +3 -0
- data/Berksfile +35 -0
- data/CHANGELOG.md +71 -0
- data/Gemfile +37 -0
- data/LICENSE +201 -0
- data/README.md +334 -0
- data/Rakefile +17 -0
- data/SUPPORTERS.md +81 -0
- data/chef/templates/celeryconfig.py.erb +5 -0
- data/chef/templates/settings.py.erb +13 -0
- data/lib/poise_application_python.rb +23 -0
- data/lib/poise_application_python/app_mixin.rb +67 -0
- data/lib/poise_application_python/cheftie.rb +17 -0
- data/lib/poise_application_python/error.rb +25 -0
- data/lib/poise_application_python/resources.rb +26 -0
- data/lib/poise_application_python/resources/celery_beat.rb +43 -0
- data/lib/poise_application_python/resources/celery_config.rb +109 -0
- data/lib/poise_application_python/resources/celery_worker.rb +77 -0
- data/lib/poise_application_python/resources/django.rb +355 -0
- data/lib/poise_application_python/resources/gunicorn.rb +127 -0
- data/lib/poise_application_python/resources/pip_requirements.rb +47 -0
- data/lib/poise_application_python/resources/python.rb +57 -0
- data/lib/poise_application_python/resources/python_execute.rb +89 -0
- data/lib/poise_application_python/resources/python_package.rb +62 -0
- data/lib/poise_application_python/resources/virtualenv.rb +75 -0
- data/lib/poise_application_python/service_mixin.rb +57 -0
- data/lib/poise_application_python/version.rb +19 -0
- data/poise-application-python.gemspec +45 -0
- data/test/cookbooks/application_python_test/attributes/default.rb +17 -0
- data/test/cookbooks/application_python_test/metadata.rb +20 -0
- data/test/cookbooks/application_python_test/recipes/default.rb +83 -0
- data/test/cookbooks/application_python_test/recipes/django.rb +32 -0
- data/test/cookbooks/application_python_test/recipes/flask.rb +25 -0
- data/test/gemfiles/chef-12.gemfile +19 -0
- data/test/gemfiles/master.gemfile +27 -0
- data/test/integration/default/serverspec/default_spec.rb +81 -0
- data/test/integration/default/serverspec/django_spec.rb +56 -0
- data/test/integration/default/serverspec/flask_spec.rb +39 -0
- data/test/spec/app_mixin_spec.rb +69 -0
- data/test/spec/resources/celery_config_spec.rb +58 -0
- data/test/spec/resources/django_spec.rb +303 -0
- data/test/spec/resources/gunicorn_spec.rb +96 -0
- data/test/spec/resources/python_execute_spec.rb +46 -0
- data/test/spec/resources/python_spec.rb +44 -0
- data/test/spec/resources/virtualenv_spec.rb +44 -0
- data/test/spec/spec_helper.rb +19 -0
- metadata +216 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'spec_helper'
|
18
|
+
|
19
|
+
describe PoiseApplicationPython::Resources::CeleryConfig do
|
20
|
+
step_into(:application_celery_config)
|
21
|
+
before do
|
22
|
+
allow(File).to receive(:directory?).and_call_original
|
23
|
+
allow(File).to receive(:directory?).with('/test').and_return(true)
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with defaults' do
|
27
|
+
recipe do
|
28
|
+
application_celery_config '/test'
|
29
|
+
end
|
30
|
+
it { is_expected.to deploy_application_celery_config('/test').with(path: '/test/celeryconfig.py') }
|
31
|
+
it { is_expected.to render_file('/test/celeryconfig.py').with_content(eq(<<-CELERYCONFIG)) }
|
32
|
+
# Generated by Chef for application_celery_config[/test]
|
33
|
+
|
34
|
+
CELERYCONFIG
|
35
|
+
end # /context with defaults
|
36
|
+
|
37
|
+
context 'with a specific path' do
|
38
|
+
recipe do
|
39
|
+
application_celery_config '/test/foo.py'
|
40
|
+
end
|
41
|
+
it { is_expected.to deploy_application_celery_config('/test/foo.py').with(path: '/test/foo.py') }
|
42
|
+
end # /context with a specific path
|
43
|
+
|
44
|
+
context 'with template options' do
|
45
|
+
recipe do
|
46
|
+
application_celery_config '/test' do
|
47
|
+
options do
|
48
|
+
broker_url 'amqp://'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
it { is_expected.to render_file('/test/celeryconfig.py').with_content(eq(<<-CELERYCONFIG)) }
|
53
|
+
# Generated by Chef for application_celery_config[/test]
|
54
|
+
|
55
|
+
BROKER_URL = "amqp://"
|
56
|
+
CELERYCONFIG
|
57
|
+
end # /context with template options
|
58
|
+
end
|
@@ -0,0 +1,303 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'spec_helper'
|
18
|
+
|
19
|
+
describe PoiseApplicationPython::Resources::Django do
|
20
|
+
describe PoiseApplicationPython::Resources::Django::Resource do
|
21
|
+
describe '#local_settings' do
|
22
|
+
subject { chef_run.application_django('/test').local_settings_content }
|
23
|
+
|
24
|
+
context 'with defaults' do
|
25
|
+
recipe(subject: false) do
|
26
|
+
application_django '/test'
|
27
|
+
end
|
28
|
+
it { is_expected.to eq <<-SETTINGS }
|
29
|
+
# Generated by Chef for application_django[/test]
|
30
|
+
|
31
|
+
DEBUG = False
|
32
|
+
|
33
|
+
DATABASES = {"default":{}}
|
34
|
+
SETTINGS
|
35
|
+
end # /context with defaults
|
36
|
+
|
37
|
+
context 'with a URL' do
|
38
|
+
recipe(subject: false) do
|
39
|
+
application_django '/test' do
|
40
|
+
database 'postgres://myuser@dbhost/myapp'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
it { is_expected.to eq <<-SETTINGS }
|
44
|
+
# Generated by Chef for application_django[/test]
|
45
|
+
|
46
|
+
DEBUG = False
|
47
|
+
|
48
|
+
DATABASES = {"default":{"URL":"postgres://myuser@dbhost/myapp","ENGINE":"django.db.backends.postgresql_psycopg2","NAME":"myapp","USER":"myuser","HOST":"dbhost"}}
|
49
|
+
SETTINGS
|
50
|
+
end # /context with a URL
|
51
|
+
|
52
|
+
context 'with an options block' do
|
53
|
+
recipe(subject: false) do
|
54
|
+
application_django '/test' do
|
55
|
+
database do
|
56
|
+
engine 'postgres'
|
57
|
+
name 'myapp'
|
58
|
+
user 'myuser'
|
59
|
+
host 'dbhost'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
it { is_expected.to eq <<-SETTINGS }
|
64
|
+
# Generated by Chef for application_django[/test]
|
65
|
+
|
66
|
+
DEBUG = False
|
67
|
+
|
68
|
+
DATABASES = {"default":{"ENGINE":"django.db.backends.postgresql_psycopg2","NAME":"myapp","USER":"myuser","HOST":"dbhost"}}
|
69
|
+
SETTINGS
|
70
|
+
end # /context with an options block
|
71
|
+
|
72
|
+
context 'with debug mode' do
|
73
|
+
recipe(subject: false) do
|
74
|
+
application_django '/test' do
|
75
|
+
debug true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
it { is_expected.to eq <<-SETTINGS }
|
79
|
+
# Generated by Chef for application_django[/test]
|
80
|
+
|
81
|
+
DEBUG = True
|
82
|
+
|
83
|
+
DATABASES = {"default":{}}
|
84
|
+
SETTINGS
|
85
|
+
end # /context with debug mode
|
86
|
+
|
87
|
+
context 'with a single allowed host' do
|
88
|
+
recipe(subject: false) do
|
89
|
+
application_django '/test' do
|
90
|
+
allowed_hosts 'example.com'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
it { is_expected.to eq <<-SETTINGS }
|
94
|
+
# Generated by Chef for application_django[/test]
|
95
|
+
|
96
|
+
ALLOWED_HOSTS = ["example.com"]
|
97
|
+
|
98
|
+
DEBUG = False
|
99
|
+
|
100
|
+
DATABASES = {"default":{}}
|
101
|
+
SETTINGS
|
102
|
+
end # /context with a single allowed host
|
103
|
+
|
104
|
+
context 'with multiple allowed hosts' do
|
105
|
+
recipe(subject: false) do
|
106
|
+
application_django '/test' do
|
107
|
+
allowed_hosts %w{example.com www.example.com}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
it { is_expected.to eq <<-SETTINGS }
|
111
|
+
# Generated by Chef for application_django[/test]
|
112
|
+
|
113
|
+
ALLOWED_HOSTS = ["example.com","www.example.com"]
|
114
|
+
|
115
|
+
DEBUG = False
|
116
|
+
|
117
|
+
DATABASES = {"default":{}}
|
118
|
+
SETTINGS
|
119
|
+
end # /context with multiple allowed hosts
|
120
|
+
|
121
|
+
context 'with a secret key' do
|
122
|
+
recipe(subject: false) do
|
123
|
+
application_django '/test' do
|
124
|
+
secret_key 'swordfish'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
it { is_expected.to eq <<-SETTINGS }
|
128
|
+
# Generated by Chef for application_django[/test]
|
129
|
+
|
130
|
+
DEBUG = False
|
131
|
+
|
132
|
+
DATABASES = {"default":{}}
|
133
|
+
|
134
|
+
SECRET_KEY = "swordfish"
|
135
|
+
SETTINGS
|
136
|
+
end # /context with a secret key
|
137
|
+
end # /describe #local_settings
|
138
|
+
|
139
|
+
describe '#default_local_settings_path' do
|
140
|
+
subject { chef_run.application_django('/test').send(:default_local_settings_path) }
|
141
|
+
|
142
|
+
context 'with no settings.py' do
|
143
|
+
recipe(subject: false) do
|
144
|
+
application_django '/test' do
|
145
|
+
def settings_module
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
it { is_expected.to be_nil }
|
151
|
+
end # /context with no settings.py
|
152
|
+
|
153
|
+
context 'with basic settings.py' do
|
154
|
+
recipe(subject: false) do
|
155
|
+
application_django '/test' do
|
156
|
+
settings_module 'myapp.settings'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
it { is_expected.to eq '/test/myapp/local_settings.py' }
|
160
|
+
end # /context with basic settings.py
|
161
|
+
end # /describe #default_local_settings_path
|
162
|
+
|
163
|
+
describe '#default_manage_path' do
|
164
|
+
subject { chef_run.application_django('/test').send(:default_manage_path) }
|
165
|
+
recipe(subject: false) do
|
166
|
+
application_django '/test'
|
167
|
+
end
|
168
|
+
before do
|
169
|
+
allow(chef_run.application_django('/test')).to receive(:find_file).with('manage.py').and_return('/test/manage.py')
|
170
|
+
end
|
171
|
+
|
172
|
+
it { is_expected.to eq '/test/manage.py' }
|
173
|
+
end # /describe #default_manage_path
|
174
|
+
|
175
|
+
describe '#default_settings_module' do
|
176
|
+
let(:settings_path) { nil }
|
177
|
+
subject { chef_run.application_django('/test').send(:default_settings_module) }
|
178
|
+
recipe(subject: false) do
|
179
|
+
application_django '/test'
|
180
|
+
end
|
181
|
+
before do
|
182
|
+
allow(chef_run.application_django('/test')).to receive(:find_file).with('settings.py').and_return(settings_path)
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'with no settings.py' do
|
186
|
+
it { is_expected.to be_nil }
|
187
|
+
end # /context with no settings.py
|
188
|
+
|
189
|
+
context 'with simple settings.py' do
|
190
|
+
let(:settings_path) { '/test/myapp/settings.py' }
|
191
|
+
it { is_expected.to eq 'myapp.settings' }
|
192
|
+
end # /context with simple settings.py
|
193
|
+
end # /describe #default_settings_module
|
194
|
+
|
195
|
+
describe '#default_wsgi_module' do
|
196
|
+
let(:wsgi_path) { nil }
|
197
|
+
subject { chef_run.application_django('/test').send(:default_wsgi_module) }
|
198
|
+
recipe(subject: false) do
|
199
|
+
application_django '/test'
|
200
|
+
end
|
201
|
+
before do
|
202
|
+
allow(chef_run.application_django('/test')).to receive(:find_file).with('wsgi.py').and_return(wsgi_path)
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'with no wsgi.py' do
|
206
|
+
it { is_expected.to be_nil }
|
207
|
+
end # /context with no wsgi.py
|
208
|
+
|
209
|
+
context 'with simple wsgi.py' do
|
210
|
+
let(:wsgi_path) { '/test/wsgi.py' }
|
211
|
+
it { is_expected.to eq 'wsgi' }
|
212
|
+
end # /context with simple wsgi.py
|
213
|
+
end # /describe #default_wsgi_module
|
214
|
+
|
215
|
+
describe '#find_file' do
|
216
|
+
let(:files) { [] }
|
217
|
+
recipe(subject: false) do
|
218
|
+
application_django '/test'
|
219
|
+
end
|
220
|
+
subject { chef_run.application_django('/test').send(:find_file, 'myfile.py') }
|
221
|
+
before do
|
222
|
+
allow(Dir).to receive(:[]).and_call_original
|
223
|
+
allow(Dir).to receive(:[]).with('/test/**/myfile.py').and_return(files)
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'with no matching files' do
|
227
|
+
it { is_expected.to be_nil }
|
228
|
+
end # /context with no matching files
|
229
|
+
|
230
|
+
context 'with one matching file' do
|
231
|
+
let(:files) { %w{/test/myfile.py} }
|
232
|
+
it { is_expected.to eq '/test/myfile.py' }
|
233
|
+
end # /context with one matching file
|
234
|
+
|
235
|
+
context 'with two matching files' do
|
236
|
+
let(:files) { %w{/test/myfile.py /test/sub/myfile.py} }
|
237
|
+
it { is_expected.to eq '/test/myfile.py' }
|
238
|
+
end # /context with two matching files
|
239
|
+
|
240
|
+
context 'with two matching files in a different order' do
|
241
|
+
let(:files) { %w{/test/sub/myfile.py /test/myfile.py} }
|
242
|
+
it { is_expected.to eq '/test/myfile.py' }
|
243
|
+
end # /context with two matching files in a different order
|
244
|
+
|
245
|
+
context 'with two matching files on the same level' do
|
246
|
+
let(:files) { %w{/test/b/myfile.py /test/a/myfile.py} }
|
247
|
+
it { is_expected.to eq '/test/a/myfile.py' }
|
248
|
+
end # /context with two matching files on the same level
|
249
|
+
end # /describe #find_file
|
250
|
+
end # /describe PoiseApplicationPython::Resources::Django::Resource
|
251
|
+
|
252
|
+
describe PoiseApplicationPython::Resources::Django::Provider do
|
253
|
+
step_into(:application_django)
|
254
|
+
context 'with default settings' do
|
255
|
+
recipe do
|
256
|
+
application_django '/test' do
|
257
|
+
# Hardwire all paths so it doesn't have to search.
|
258
|
+
manage_path 'manage.py'
|
259
|
+
settings_module 'myapp.settings'
|
260
|
+
wsgi_module 'wsgi'
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
it { is_expected.to run_python_execute('manage.py collectstatic --noinput') }
|
265
|
+
it { is_expected.to_not run_python_execute('manage.py syncdb --noinput') }
|
266
|
+
it { is_expected.to_not run_python_execute('manage.py migrate --noinput') }
|
267
|
+
it { is_expected.to render_file('/test/myapp/local_settings.py') }
|
268
|
+
end # /context with default settings
|
269
|
+
|
270
|
+
context 'with syncdb' do
|
271
|
+
recipe do
|
272
|
+
application_django '/test' do
|
273
|
+
# Hardwire all paths so it doesn't have to search.
|
274
|
+
manage_path 'manage.py'
|
275
|
+
settings_module 'myapp.settings'
|
276
|
+
syncdb true
|
277
|
+
wsgi_module 'wsgi'
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
it { is_expected.to run_python_execute('manage.py collectstatic --noinput') }
|
282
|
+
it { is_expected.to run_python_execute('manage.py syncdb --noinput') }
|
283
|
+
it { is_expected.to_not run_python_execute('manage.py migrate --noinput') }
|
284
|
+
end # /context with syncdb
|
285
|
+
|
286
|
+
context 'with migrate' do
|
287
|
+
recipe do
|
288
|
+
application_django '/test' do
|
289
|
+
# Hardwire all paths so it doesn't have to search.
|
290
|
+
manage_path 'manage.py'
|
291
|
+
migrate true
|
292
|
+
settings_module 'myapp.settings'
|
293
|
+
wsgi_module 'wsgi'
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
it { is_expected.to run_python_execute('manage.py collectstatic --noinput') }
|
298
|
+
it { is_expected.to_not run_python_execute('manage.py syncdb --noinput') }
|
299
|
+
it { is_expected.to run_python_execute('manage.py migrate --noinput') }
|
300
|
+
it { is_expected.to render_file('/test/myapp/local_settings.py') }
|
301
|
+
end # /context with migrate
|
302
|
+
end # /describe PoiseApplicationPython::Resources::Django::Provider
|
303
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'spec_helper'
|
18
|
+
|
19
|
+
describe PoiseApplicationPython::Resources::Gunicorn do
|
20
|
+
describe PoiseApplicationPython::Resources::Gunicorn::Resource do
|
21
|
+
describe '#default_app_module' do
|
22
|
+
let(:app_state) { {} }
|
23
|
+
let(:files) { [] }
|
24
|
+
let(:test_resource) { described_class.new(nil, nil) }
|
25
|
+
before do
|
26
|
+
allow(test_resource).to receive(:app_state).and_return(app_state)
|
27
|
+
allow(Dir).to receive(:exist?).and_return(!files.empty?)
|
28
|
+
allow(Dir).to receive(:entries).and_return(files)
|
29
|
+
end
|
30
|
+
subject { test_resource.send(:default_app_module) }
|
31
|
+
|
32
|
+
context 'with an app_state key' do
|
33
|
+
let(:app_state) { {python_wsgi_module: 'django'} }
|
34
|
+
it { is_expected.to eq 'django' }
|
35
|
+
end # /context with an app_state key
|
36
|
+
|
37
|
+
context 'with a wsgi.py' do
|
38
|
+
let(:files) { %w{wsgi.py} }
|
39
|
+
it { is_expected.to eq 'wsgi' }
|
40
|
+
end # /context with a wsgi.py
|
41
|
+
|
42
|
+
context 'with an app.py and main.py' do
|
43
|
+
let(:files) { %w{app.py main.py} }
|
44
|
+
it { is_expected.to eq 'main' }
|
45
|
+
end # /context with an app.py and main.py
|
46
|
+
|
47
|
+
context 'with a foo.txt and bar.py' do
|
48
|
+
let(:files) { %w{foo.txt bar.py} }
|
49
|
+
it { is_expected.to eq 'bar' }
|
50
|
+
end # /context with a foo.txt and bar.py
|
51
|
+
|
52
|
+
context 'with a foo.txt' do
|
53
|
+
let(:files) { %w{foo.txt } }
|
54
|
+
it { is_expected.to be_nil }
|
55
|
+
end # /context with a foo.txt
|
56
|
+
end # /describe #default_app_module
|
57
|
+
end # /describe PoiseApplicationPython::Resources::Gunicorn::Resource
|
58
|
+
|
59
|
+
describe PoiseApplicationPython::Resources::Gunicorn::Provider do
|
60
|
+
let(:new_resource) { double('new_resource') }
|
61
|
+
let(:test_provider) { described_class.new(new_resource, nil) }
|
62
|
+
|
63
|
+
describe '#gunicorn_command_options' do
|
64
|
+
let(:props) { {} }
|
65
|
+
let(:new_resource) { PoiseApplicationPython::Resources::Gunicorn::Resource.new('/test', nil) }
|
66
|
+
subject { test_provider.send(:gunicorn_command_options).join(' ') }
|
67
|
+
before do
|
68
|
+
props.each {|key, value| new_resource.send(key, value) }
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with defaults' do
|
72
|
+
it { is_expected.to eq '--bind 0.0.0.0:80' }
|
73
|
+
end # /context with defaults
|
74
|
+
|
75
|
+
context 'with a config file' do
|
76
|
+
let(:props) { {config: '/test/myconfig.py'} }
|
77
|
+
it { is_expected.to eq '--config /test/myconfig.py --bind 0.0.0.0:80' }
|
78
|
+
end # /context with a config file
|
79
|
+
|
80
|
+
context 'with a blank config file' do
|
81
|
+
let(:props) { {config: ''} }
|
82
|
+
it { is_expected.to eq '--bind 0.0.0.0:80' }
|
83
|
+
end # /context with a blank config file
|
84
|
+
|
85
|
+
context 'with two binds' do
|
86
|
+
let(:props) { {bind: %w{0.0.0.0:80 0.0.0.0:81}} }
|
87
|
+
it { is_expected.to eq '--bind 0.0.0.0:80 --bind 0.0.0.0:81' }
|
88
|
+
end # /context with two binds
|
89
|
+
|
90
|
+
context 'with a config file and preload' do
|
91
|
+
let(:props) { {config: '/test/myconfig.py', preload_app: true} }
|
92
|
+
it { is_expected.to eq '--config /test/myconfig.py --bind 0.0.0.0:80 --preload' }
|
93
|
+
end # /context with a config file and preload
|
94
|
+
end # /describe #gunicorn_command_options
|
95
|
+
end # /describe PoiseApplicationPython::Resources::Gunicorn::Provider
|
96
|
+
end
|