github.com/tmlbl/deis@v1.0.2/controller/api/tests/test_release.py (about)

     1  """
     2  Unit tests for the Deis api app.
     3  
     4  Run the tests with "./manage.py test api"
     5  """
     6  
     7  from __future__ import unicode_literals
     8  
     9  import json
    10  import mock
    11  import requests
    12  
    13  from django.contrib.auth.models import User
    14  from django.test import TransactionTestCase
    15  from rest_framework.authtoken.models import Token
    16  
    17  from api.models import Release
    18  
    19  
    20  def mock_import_repository_task(*args, **kwargs):
    21      resp = requests.Response()
    22      resp.status_code = 200
    23      resp._content_consumed = True
    24      return resp
    25  
    26  
    27  class ReleaseTest(TransactionTestCase):
    28  
    29      """Tests push notification from build system"""
    30  
    31      fixtures = ['tests.json']
    32  
    33      def setUp(self):
    34          self.user = User.objects.get(username='autotest')
    35          self.token = Token.objects.get(user=self.user).key
    36  
    37      @mock.patch('requests.post', mock_import_repository_task)
    38      def test_release(self):
    39          """
    40          Test that a release is created when an app is created, and
    41          that updating config or build or triggers a new release
    42          """
    43          url = '/v1/apps'
    44          response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
    45          self.assertEqual(response.status_code, 201)
    46          app_id = response.data['id']
    47          # check that updating config rolls a new release
    48          url = '/v1/apps/{app_id}/config'.format(**locals())
    49          body = {'values': json.dumps({'NEW_URL1': 'http://localhost:8080/'})}
    50          response = self.client.post(
    51              url, json.dumps(body), content_type='application/json',
    52              HTTP_AUTHORIZATION='token {}'.format(self.token))
    53          self.assertEqual(response.status_code, 201)
    54          self.assertIn('NEW_URL1', response.data['values'])
    55          # check to see that an initial release was created
    56          url = '/v1/apps/{app_id}/releases'.format(**locals())
    57          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
    58          self.assertEqual(response.status_code, 200)
    59          # account for the config release as well
    60          self.assertEqual(response.data['count'], 2)
    61          url = '/v1/apps/{app_id}/releases/v1'.format(**locals())
    62          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
    63          self.assertEqual(response.status_code, 200)
    64          release1 = response.data
    65          self.assertIn('config', response.data)
    66          self.assertIn('build', response.data)
    67          self.assertEquals(release1['version'], 1)
    68          # check to see that a new release was created
    69          url = '/v1/apps/{app_id}/releases/v2'.format(**locals())
    70          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
    71          self.assertEqual(response.status_code, 200)
    72          release2 = response.data
    73          self.assertNotEqual(release1['uuid'], release2['uuid'])
    74          self.assertNotEqual(release1['config'], release2['config'])
    75          self.assertEqual(release1['build'], release2['build'])
    76          self.assertEquals(release2['version'], 2)
    77          # check that updating the build rolls a new release
    78          url = '/v1/apps/{app_id}/builds'.format(**locals())
    79          build_config = json.dumps({'PATH': 'bin:/usr/local/bin:/usr/bin:/bin'})
    80          body = {'image': 'autotest/example'}
    81          response = self.client.post(
    82              url, json.dumps(body), content_type='application/json',
    83              HTTP_AUTHORIZATION='token {}'.format(self.token))
    84          self.assertEqual(response.status_code, 201)
    85          self.assertEqual(response.data['image'], body['image'])
    86          # check to see that a new release was created
    87          url = '/v1/apps/{app_id}/releases/v3'.format(**locals())
    88          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
    89          self.assertEqual(response.status_code, 200)
    90          release3 = response.data
    91          self.assertNotEqual(release2['uuid'], release3['uuid'])
    92          self.assertNotEqual(release2['build'], release3['build'])
    93          self.assertEquals(release3['version'], 3)
    94          # check that we can fetch a previous release
    95          url = '/v1/apps/{app_id}/releases/v2'.format(**locals())
    96          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
    97          self.assertEqual(response.status_code, 200)
    98          release2 = response.data
    99          self.assertNotEqual(release2['uuid'], release3['uuid'])
   100          self.assertNotEqual(release2['build'], release3['build'])
   101          self.assertEquals(release2['version'], 2)
   102          # disallow post/put/patch/delete
   103          url = '/v1/apps/{app_id}/releases'.format(**locals())
   104          response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   105          self.assertEqual(response.status_code, 405)
   106          response = self.client.put(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   107          self.assertEqual(response.status_code, 405)
   108          response = self.client.patch(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   109          self.assertEqual(response.status_code, 405)
   110          response = self.client.delete(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   111          self.assertEqual(response.status_code, 405)
   112          return release3
   113  
   114      @mock.patch('requests.post', mock_import_repository_task)
   115      def test_release_rollback(self):
   116          url = '/v1/apps'
   117          response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   118          self.assertEqual(response.status_code, 201)
   119          app_id = response.data['id']
   120          # try to rollback with only 1 release extant, expecting 400
   121          url = "/v1/apps/{app_id}/releases/rollback/".format(**locals())
   122          response = self.client.post(url, content_type='application/json',
   123                                      HTTP_AUTHORIZATION='token {}'.format(self.token))
   124          self.assertEqual(response.status_code, 400)
   125          # update config to roll a new release
   126          url = '/v1/apps/{app_id}/config'.format(**locals())
   127          body = {'values': json.dumps({'NEW_URL1': 'http://localhost:8080/'})}
   128          response = self.client.post(
   129              url, json.dumps(body), content_type='application/json',
   130              HTTP_AUTHORIZATION='token {}'.format(self.token))
   131          self.assertEqual(response.status_code, 201)
   132          # update the build to roll a new release
   133          url = '/v1/apps/{app_id}/builds'.format(**locals())
   134          body = {'image': 'autotest/example'}
   135          response = self.client.post(
   136              url, json.dumps(body), content_type='application/json',
   137              HTTP_AUTHORIZATION='token {}'.format(self.token))
   138          self.assertEqual(response.status_code, 201)
   139          # rollback and check to see that a 4th release was created
   140          # with the build and config of release #2
   141          url = "/v1/apps/{app_id}/releases/rollback/".format(**locals())
   142          response = self.client.post(url, content_type='application/json',
   143                                      HTTP_AUTHORIZATION='token {}'.format(self.token))
   144          self.assertEqual(response.status_code, 201)
   145          url = '/v1/apps/{app_id}/releases'.format(**locals())
   146          response = self.client.get(url, content_type='application/json',
   147                                     HTTP_AUTHORIZATION='token {}'.format(self.token))
   148          self.assertEqual(response.status_code, 200)
   149          self.assertEqual(response.data['count'], 4)
   150          url = '/v1/apps/{app_id}/releases/v2'.format(**locals())
   151          response = self.client.get(url, content_type='application/json',
   152                                     HTTP_AUTHORIZATION='token {}'.format(self.token))
   153          self.assertEqual(response.status_code, 200)
   154          release2 = response.data
   155          self.assertEquals(release2['version'], 2)
   156          url = '/v1/apps/{app_id}/releases/v4'.format(**locals())
   157          response = self.client.get(url, content_type='application/json',
   158                                     HTTP_AUTHORIZATION='token {}'.format(self.token))
   159          self.assertEqual(response.status_code, 200)
   160          release4 = response.data
   161          self.assertEquals(release4['version'], 4)
   162          self.assertNotEqual(release2['uuid'], release4['uuid'])
   163          self.assertEqual(release2['build'], release4['build'])
   164          self.assertEqual(release2['config'], release4['config'])
   165          # rollback explicitly to release #1 and check that a 5th release
   166          # was created with the build and config of release #1
   167          url = "/v1/apps/{app_id}/releases/rollback/".format(**locals())
   168          body = {'version': 1}
   169          response = self.client.post(
   170              url, json.dumps(body), content_type='application/json',
   171              HTTP_AUTHORIZATION='token {}'.format(self.token))
   172          self.assertEqual(response.status_code, 201)
   173          url = '/v1/apps/{app_id}/releases'.format(**locals())
   174          response = self.client.get(url, content_type='application/json',
   175                                     HTTP_AUTHORIZATION='token {}'.format(self.token))
   176          self.assertEqual(response.status_code, 200)
   177          self.assertEqual(response.data['count'], 5)
   178          url = '/v1/apps/{app_id}/releases/v1'.format(**locals())
   179          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   180          self.assertEqual(response.status_code, 200)
   181          release1 = response.data
   182          url = '/v1/apps/{app_id}/releases/v5'.format(**locals())
   183          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   184          self.assertEqual(response.status_code, 200)
   185          release5 = response.data
   186          self.assertEqual(release5['version'], 5)
   187          self.assertNotEqual(release1['uuid'], release5['uuid'])
   188          self.assertEqual(release1['build'], release5['build'])
   189          self.assertEqual(release1['config'], release5['config'])
   190          # check to see that the current config is actually the initial one
   191          url = "/v1/apps/{app_id}/config".format(**locals())
   192          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   193          self.assertEqual(response.status_code, 200)
   194          self.assertEqual(response.data['values'], {})
   195          # rollback to #3 and see that it has the correct config
   196          url = "/v1/apps/{app_id}/releases/rollback/".format(**locals())
   197          body = {'version': 3}
   198          response = self.client.post(
   199              url, json.dumps(body), content_type='application/json',
   200              HTTP_AUTHORIZATION='token {}'.format(self.token))
   201          self.assertEqual(response.status_code, 201)
   202          url = "/v1/apps/{app_id}/config".format(**locals())
   203          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   204          self.assertEqual(response.status_code, 200)
   205          values = response.data['values']
   206          self.assertIn('NEW_URL1', values)
   207          self.assertEqual('http://localhost:8080/', values['NEW_URL1'])
   208  
   209      @mock.patch('requests.post', mock_import_repository_task)
   210      def test_release_str(self):
   211          """Test the text representation of a release."""
   212          release3 = self.test_release()
   213          release = Release.objects.get(uuid=release3['uuid'])
   214          self.assertEqual(str(release), "{}-v3".format(release3['app']))
   215  
   216      @mock.patch('requests.post', mock_import_repository_task)
   217      def test_release_summary(self):
   218          """Test the text summary of a release."""
   219          release3 = self.test_release()
   220          release = Release.objects.get(uuid=release3['uuid'])
   221          # check that the release has push and env change messages
   222          self.assertIn('autotest deployed ', release.summary)
   223  
   224      @mock.patch('requests.post', mock_import_repository_task)
   225      def test_admin_can_create_release(self):
   226          """If a non-user creates an app, an admin should be able to create releases."""
   227          user = User.objects.get(username='autotest2')
   228          token = Token.objects.get(user=user).key
   229          url = '/v1/apps'
   230          response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(token))
   231          self.assertEqual(response.status_code, 201)
   232          app_id = response.data['id']
   233          # check that updating config rolls a new release
   234          url = '/v1/apps/{app_id}/config'.format(**locals())
   235          body = {'values': json.dumps({'NEW_URL1': 'http://localhost:8080/'})}
   236          response = self.client.post(
   237              url, json.dumps(body), content_type='application/json',
   238              HTTP_AUTHORIZATION='token {}'.format(self.token))
   239          self.assertEqual(response.status_code, 201)
   240          self.assertIn('NEW_URL1', response.data['values'])
   241          # check to see that an initial release was created
   242          url = '/v1/apps/{app_id}/releases'.format(**locals())
   243          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token))
   244          self.assertEqual(response.status_code, 200)
   245          # account for the config release as well
   246          self.assertEqual(response.data['count'], 2)