Skip to content

Commit 5095b85

Browse files
author
Matthew Fisher
committed
fix(controller): merge structure with new structure
If the old structure contained values like {'web': 0}, the container count would be zero, so the resulting vals structure would be an empty dictionary. By taking the "requested" structure and updating it with the actual container queryset, values like {'web': 0} will stay the same. From that result, the structure will not be considered in an "initial" state[1], which means that a new deploy will not cause the containers to be accidentally scaled back up to one. [1]: https://github.com/deis/deis/blob/ebc3df479a672acb4a81525ba1edd0fb4d70a6a9/controller/api/models.py#L605
1 parent ebc3df4 commit 5095b85

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

controller/api/models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,9 @@ def scale(self, user, structure): # noqa
275275
# save new structure to the database
276276
vals = self.container_set.exclude(type='run').values(
277277
'type').annotate(Count('pk')).order_by()
278-
self.structure = {v['type']: v['pk__count'] for v in vals}
278+
new_structure = structure.copy()
279+
new_structure.update({v['type']: v['pk__count'] for v in vals})
280+
self.structure = new_structure
279281
self.save()
280282
return changed
281283

controller/api/tests/test_build.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,48 @@ def test_unauthorized_user_cannot_modify_build(self):
253253
response = self.client.post(url, json.dumps(body), content_type='application/json',
254254
HTTP_AUTHORIZATION='token {}'.format(unauthorized_token))
255255
self.assertEqual(response.status_code, 403)
256+
257+
@mock.patch('requests.post', mock_import_repository_task)
258+
def test_new_build_does_not_scale_up_automatically(self):
259+
"""
260+
After the first initial deploy, if the containers are scaled down to zero,
261+
they should stay that way on a new release.
262+
"""
263+
url = '/v1/apps'
264+
response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
265+
self.assertEqual(response.status_code, 201)
266+
app_id = response.data['id']
267+
# post a new build
268+
url = "/v1/apps/{app_id}/builds".format(**locals())
269+
body = {'image': 'autotest/example',
270+
'sha': 'a'*40,
271+
'procfile': json.dumps({'web': 'node server.js',
272+
'worker': 'node worker.js'})}
273+
response = self.client.post(url, json.dumps(body), content_type='application/json',
274+
HTTP_AUTHORIZATION='token {}'.format(self.token))
275+
self.assertEqual(response.status_code, 201)
276+
url = "/v1/apps/{app_id}/containers/web".format(**locals())
277+
response = self.client.get(url,
278+
HTTP_AUTHORIZATION='token {}'.format(self.token))
279+
self.assertEqual(response.status_code, 200)
280+
self.assertEqual(len(response.data['results']), 1)
281+
# scale to zero
282+
url = "/v1/apps/{app_id}/scale".format(**locals())
283+
body = {'web': 0}
284+
response = self.client.post(url, json.dumps(body), content_type='application/json',
285+
HTTP_AUTHORIZATION='token {}'.format(self.token))
286+
self.assertEqual(response.status_code, 204)
287+
# post another build
288+
url = "/v1/apps/{app_id}/builds".format(**locals())
289+
body = {'image': 'autotest/example',
290+
'sha': 'a'*40,
291+
'procfile': json.dumps({'web': 'node server.js',
292+
'worker': 'node worker.js'})}
293+
response = self.client.post(url, json.dumps(body), content_type='application/json',
294+
HTTP_AUTHORIZATION='token {}'.format(self.token))
295+
self.assertEqual(response.status_code, 201)
296+
url = "/v1/apps/{app_id}/containers/web".format(**locals())
297+
response = self.client.get(url,
298+
HTTP_AUTHORIZATION='token {}'.format(self.token))
299+
self.assertEqual(response.status_code, 200)
300+
self.assertEqual(len(response.data['results']), 0)

0 commit comments

Comments
 (0)