Skip to content

Commit 8a840a7

Browse files
committed
Sort deploys so routable application types come first
1 parent 326053e commit 8a840a7

2 files changed

Lines changed: 29 additions & 23 deletions

File tree

rootfs/api/models/app.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections import OrderedDict
12
from datetime import datetime
23
import logging
34
import random
@@ -341,31 +342,33 @@ def deploy(self, user, release):
341342
self.save()
342343

343344
# deploy application to k8s. Also handles initial scaling
345+
deploys = {}
344346
build_type = app_build_type(release)
345347
for scale_type in self.structure.keys():
346-
image = release.image
347-
version = "v{}".format(release.version)
348-
kwargs = {
348+
deploys[scale_type] = {
349349
'memory': release.config.memory,
350350
'cpu': release.config.cpu,
351351
'tags': release.config.tags,
352352
'envs': release.config.values,
353353
'replicas': 0, # Scaling up happens in a separate operation
354-
'version': version,
354+
'version': "v{}".format(release.version),
355355
'app_type': scale_type,
356356
'build_type': build_type,
357357
'healthcheck': release.config.healthcheck(),
358358
# http://docs.deis.io/en/latest/using_deis/process-types/#web-vs-cmd-process-types
359359
'routable': True if scale_type in ['web', 'cmd'] else False
360360
}
361361

362-
command = self._get_command(scale_type)
362+
# Sort deploys so routable comes first
363+
deploys = OrderedDict(sorted(deploys.items(), key=lambda d: d[1].get('routable')))
364+
365+
for scale_type, kwargs in deploys.items():
363366
try:
364367
self._scheduler.deploy(
365368
namespace=self.id,
366369
name=self._get_job_id(scale_type),
367-
image=image,
368-
command=command,
370+
image=release.image,
371+
command=self._get_command(scale_type),
369372
**kwargs
370373
)
371374

rootfs/api/tests/test_app.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
from api.models import App
1616

17+
from . import adapter
18+
import requests_mock
19+
1720

1821
def mock_none(*args, **kwargs):
1922
return None
@@ -38,7 +41,7 @@ def tearDown(self):
3841
# make sure every test has a clean slate for k8s mocking
3942
cache.clear()
4043

41-
def test_app(self):
44+
def test_app(self, mock_requests):
4245
"""
4346
Test that a user can create, read, update and delete an application
4447
"""
@@ -59,7 +62,7 @@ def test_app(self):
5962
response = self.client.delete(url)
6063
self.assertEqual(response.status_code, 204)
6164

62-
def test_response_data(self):
65+
def test_response_data(self, mock_requests):
6366
"""Test that the serialized response contains only relevant data."""
6467
body = {'id': 'test'}
6568
response = self.client.post('/v2/apps', body)
@@ -72,7 +75,7 @@ def test_response_data(self):
7275
}
7376
self.assertDictContainsSubset(expected, response.data)
7477

75-
def test_app_override_id(self):
78+
def test_app_override_id(self, mock_requests):
7679
body = {'id': 'myid'}
7780
response = self.client.post('/v2/apps', body)
7881
self.assertEqual(response.status_code, 201)
@@ -82,7 +85,7 @@ def test_app_override_id(self):
8285
return response
8386

8487
@mock.patch('requests.get')
85-
def test_app_actions(self, mock_get):
88+
def test_app_actions(self, mock_requests, mock_get):
8689
url = '/v2/apps'
8790
body = {'id': 'autotest'}
8891
response = self.client.post(url, body)
@@ -126,7 +129,7 @@ def test_app_actions(self, mock_get):
126129
# TODO: test run needs an initial build
127130

128131
@mock.patch('api.models.logger')
129-
def test_app_release_notes_in_logs(self, mock_logger):
132+
def test_app_release_notes_in_logs(self, mock_requests, mock_logger):
130133
"""Verifies that an app's release summary is dumped into the logs."""
131134
url = '/v2/apps'
132135
body = {'id': 'autotest'}
@@ -137,7 +140,7 @@ def test_app_release_notes_in_logs(self, mock_logger):
137140
exp_log_call = mock.call(logging.INFO, exp_msg)
138141
mock_logger.log.has_calls(exp_log_call)
139142

140-
def test_app_errors(self):
143+
def test_app_errors(self, mock_requests):
141144
app_id = 'autotest-errors'
142145
url = '/v2/apps'
143146
body = {'id': 'camelCase'}
@@ -160,7 +163,7 @@ def test_app_errors(self):
160163
response = self.client.get(url)
161164
self.assertEqual(response.status_code, 404)
162165

163-
def test_app_reserved_names(self):
166+
def test_app_reserved_names(self, mock_requests):
164167
"""Nobody should be able to create applications with names which are reserved."""
165168
url = '/v2/apps'
166169
reserved_names = ['foo', 'bar']
@@ -173,7 +176,7 @@ def test_app_reserved_names(self):
173176
'{} is a reserved name.'.format(name),
174177
status_code=400)
175178

176-
def test_app_structure_is_valid_json(self):
179+
def test_app_structure_is_valid_json(self, mock_requests):
177180
"""Application structures should be valid JSON objects."""
178181
url = '/v2/apps'
179182
response = self.client.post(url)
@@ -190,7 +193,7 @@ def test_app_structure_is_valid_json(self):
190193
self.assertEqual(response.data['structure'], {"web": 1})
191194

192195
@mock.patch('api.models.logger')
193-
def test_admin_can_manage_other_apps(self, mock_logger):
196+
def test_admin_can_manage_other_apps(self, mock_requests, mock_logger):
194197
"""Administrators of Deis should be able to manage all applications.
195198
"""
196199
# log in as non-admin user and create an app
@@ -218,7 +221,7 @@ def test_admin_can_manage_other_apps(self, mock_logger):
218221
response = self.client.delete(url)
219222
self.assertEqual(response.status_code, 204)
220223

221-
def test_admin_can_see_other_apps(self):
224+
def test_admin_can_see_other_apps(self, mock_requests):
222225
"""If a user creates an application, the administrator should be able
223226
to see it.
224227
"""
@@ -236,7 +239,7 @@ def test_admin_can_see_other_apps(self):
236239
response = self.client.get(url)
237240
self.assertEqual(response.data['count'], 1)
238241

239-
def test_run_without_release_should_error(self):
242+
def test_run_without_release_should_error(self, mock_requests):
240243
"""
241244
A user should not be able to run a one-off command unless a release
242245
is present.
@@ -255,7 +258,7 @@ def test_run_without_release_should_error(self):
255258
@mock.patch('api.models.App.run', _mock_run)
256259
@mock.patch('api.models.App.deploy', mock_none)
257260
@mock.patch('api.models.Release.publish', mock_none)
258-
def test_run(self):
261+
def test_run(self, mock_requests):
259262
"""
260263
A user should be able to run a one off command
261264
"""
@@ -278,7 +281,7 @@ def test_run(self):
278281
self.assertEqual(response.data['rc'], 0)
279282
self.assertEqual(response.data['output'], 'mock')
280283

281-
def test_unauthorized_user_cannot_see_app(self):
284+
def test_unauthorized_user_cannot_see_app(self, mock_requests):
282285
"""
283286
An unauthorized user should not be able to access an app's resources.
284287
@@ -309,7 +312,7 @@ def test_unauthorized_user_cannot_see_app(self):
309312
response = self.client.delete(url)
310313
self.assertEqual(response.status_code, 403)
311314

312-
def test_app_info_not_showing_wrong_app(self):
315+
def test_app_info_not_showing_wrong_app(self, mock_requests):
313316
app_id = 'autotest'
314317
base_url = '/v2/apps'
315318
body = {'id': app_id}
@@ -318,7 +321,7 @@ def test_app_info_not_showing_wrong_app(self):
318321
response = self.client.get(url)
319322
self.assertEqual(response.status_code, 404)
320323

321-
def test_app_transfer(self):
324+
def test_app_transfer(self, mock_requests):
322325
owner = User.objects.get(username='autotest2')
323326
owner_token = Token.objects.get(user=owner).key
324327
self.client.credentials(HTTP_AUTHORIZATION='Token ' + owner_token)
@@ -366,7 +369,7 @@ def test_app_transfer(self):
366369
self.assertEqual(response.status_code, 200)
367370
self.assertEqual(response.data['owner'], self.user.username)
368371

369-
def test_app_exists_in_kubernetes(self):
372+
def test_app_exists_in_kubernetes(self, mock_requests):
370373
"""
371374
Create an app that has the same namespace as an existing kubernetes namespace
372375
"""

0 commit comments

Comments
 (0)