github.com/abayer/test-infra@v0.0.5/gubernator/view_pr_test.py (about)

     1  #!/usr/bin/env python
     2  
     3  # Copyright 2016 The Kubernetes Authors.
     4  #
     5  # Licensed under the Apache License, Version 2.0 (the "License");
     6  # you may not use this file except in compliance with the License.
     7  # You may obtain a copy of the License at
     8  #
     9  #     http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  
    17  import datetime
    18  import unittest
    19  
    20  # TODO(fejta): use non-relative imports
    21  # https://google.github.io/styleguide/pyguide.html?showone=Packages#Packages
    22  import gcs_async_test
    23  from github import models
    24  import main_test
    25  import view_pr
    26  
    27  from webapp2_extras import securecookie
    28  
    29  
    30  app = main_test.app
    31  write = gcs_async_test.write
    32  
    33  class PathTest(unittest.TestCase):
    34      def test_org_repo(self):
    35          def check(path, org, repo):
    36              actual_org, actual_repo = view_pr.org_repo(path, 'kubernetes', 'kubernetes')
    37              self.assertEquals(actual_org, org)
    38              self.assertEquals(actual_repo, repo)
    39  
    40          check('', 'kubernetes', 'kubernetes')
    41          check('/test-infra', 'kubernetes', 'test-infra')
    42          check('/kubernetes', 'kubernetes', 'kubernetes')
    43          check('/kubernetes/test-infra', 'kubernetes', 'test-infra')
    44          check('/kubernetes/kubernetes', 'kubernetes', 'kubernetes')
    45          check('/google/cadvisor', 'google', 'cadvisor')
    46  
    47      def test_pr_path(self):
    48          def check(org, repo, pr, path):
    49              actual_path = view_pr.pr_path(org, repo, pr, 'kubernetes', 'kubernetes', 'pull_prefix')
    50              self.assertEquals(actual_path, '%s/%s' % ('pull_prefix', path))
    51  
    52          check('kubernetes', 'kubernetes', 1234, 1234)
    53          check('kubernetes', 'kubernetes', 'batch', 'batch')
    54          check('kubernetes', 'test-infra', 555, 'test-infra/555')
    55          check('kubernetes', 'test-infra', 'batch', 'test-infra/batch')
    56          check('google', 'cadvisor', '555', 'google_cadvisor/555')
    57          check('google', 'cadvisor', 'batch', 'google_cadvisor/batch')
    58  
    59  
    60  class PRTest(main_test.TestBase):
    61      BUILDS = {
    62          'build': [('12', {'version': 'bb', 'timestamp': 1467147654}, None),
    63                    ('11', {'version': 'bb', 'timestamp': 1467146654},
    64                     {'result': 'PASSED', 'passed': True}),
    65                    ('10', {'version': 'aa', 'timestamp': 1467136654},
    66                     {'result': 'FAILED', 'passed': False})],
    67          'e2e': [('47', {'version': 'bb', 'timestamp': '1467147654'},
    68                   {'result': '[UNSET]', 'passed': False}),
    69                  ('46', {'version': 'aa', 'timestamp': '1467136700'},
    70                   {'result': '[UNSET]', 'passed': False})]
    71      }
    72  
    73      def setUp(self):
    74          self.init_stubs()
    75  
    76      def init_pr_directory(self):
    77          gcs_async_test.install_handler(self.testbed.get_stub('urlfetch'),
    78              {'123/': ['build', 'e2e'],
    79               '123/build/': ['11', '10', '12'],  # out of order
    80               '123/e2e/': ['47', '46']})
    81  
    82          for job, builds in self.BUILDS.iteritems():
    83              for build, started, finished in builds:
    84                  path = '/kubernetes-jenkins/pr-logs/pull/123/%s/%s/' % (job, build)
    85                  if started:
    86                      write(path + 'started.json', started)
    87                  if finished:
    88                      write(path + 'finished.json', finished)
    89  
    90      def test_pr_builds(self):
    91          self.init_pr_directory()
    92          org, repo = view_pr.org_repo('',
    93              app.app.config['default_org'],
    94              app.app.config['default_repo'],
    95          )
    96          builds = view_pr.pr_builds(view_pr.pr_path(org, repo, '123',
    97              app.app.config['default_repo'],
    98              app.app.config['default_repo'],
    99              app.app.config['default_external_services']['gcs_pull_prefix'],
   100          ))
   101          self.assertEqual(builds, self.BUILDS)
   102  
   103      def test_pr_handler(self):
   104          self.init_pr_directory()
   105          response = app.get('/pr/123')
   106          self.assertIn('e2e/47', response)
   107          self.assertIn('PASSED', response)
   108          self.assertIn('colspan="3"', response)  # header
   109          self.assertIn('github.com/kubernetes/kubernetes/pull/123', response)
   110          self.assertIn('28 20:44', response)
   111  
   112      def test_pr_handler_missing(self):
   113          gcs_async_test.install_handler(self.testbed.get_stub('urlfetch'),
   114              {'124/': []})
   115          response = app.get('/pr/124')
   116          self.assertIn('No Results', response)
   117  
   118      def test_pr_build_log_redirect(self):
   119          path = '123/some-job/55/build-log.txt'
   120          response = app.get('/pr/' + path)
   121          self.assertEqual(response.status_code, 302)
   122          self.assertIn('https://storage.googleapis.com', response.location)
   123          self.assertIn(path, response.location)
   124  
   125  
   126  def make_pr(number, involved, payload, repo='kubernetes/kubernetes'):
   127      payload.setdefault('attn', {})
   128      payload.setdefault('assignees', [])
   129      payload.setdefault('author', involved[0])
   130      payload.setdefault('labels', {})
   131      digest = models.GHIssueDigest.make(repo, number, is_pr=True, is_open=True,
   132          involved=involved, payload=payload, updated_at=datetime.datetime.now())
   133      digest.put()
   134  
   135  
   136  class TestDashboard(main_test.TestBase):
   137      def setUp(self):
   138          app.reset()
   139          self.init_stubs()
   140  
   141      def test_empty(self):
   142          resp = app.get('/pr/all')
   143          self.assertIn('No Results', resp)
   144          resp = app.get('/pr/nobody')
   145          self.assertIn('No Results', resp)
   146  
   147      def test_all(self):
   148          make_pr(12, ['foo'], {'title': 'first'}, 'google/cadvisor')
   149          make_pr(13, ['bar'], {'title': 'second'}, 'kubernetes/kubernetes')
   150          resp = app.get('/pr/all')
   151          self.assertIn('Open Kubernetes PRs', resp)
   152          self.assertIn('first', resp)
   153          self.assertIn('second', resp)
   154  
   155      def test_json(self):
   156          make_pr(12, ['a'], {'title': 'b'}, 'c/d')
   157          resp = app.get('/pr/all?format=json')
   158          self.assertEqual(resp.headers['Content-Type'], 'application/json')
   159          self.assertEqual(len(resp.json), 1)
   160          pr = resp.json[0]
   161          self.assertEqual(pr['involved'], ['a'])
   162          self.assertEqual(pr['number'], 12)
   163          self.assertEqual(pr['repo'], 'c/d')
   164  
   165      def test_one_entry(self):
   166          make_pr(123, ['user'], {'attn': {'user': 'fix tests'}})
   167          resp = app.get('/pr/user')
   168          self.assertIn('123', resp)
   169  
   170      def test_case_insensitive(self):
   171          "Individual PR pages are case insensitive."
   172          make_pr(123, ['user'], {'attn': {'User': 'fix tests'}})
   173          resp = app.get('/pr/UseR')
   174          self.assertIn('123', resp)
   175          self.assertIn('Needs Attention (1)', resp)
   176  
   177      def test_milestone(self):
   178          "Milestone links filter by milestone."
   179          make_pr(123, ['user'], {'attn': {'User': 'fix tests'}})
   180          make_pr(124, ['user'], {'attn': {'user': 'fix tests'}, 'milestone': 'v1.24'})
   181          resp = app.get('/pr/user')
   182          self.assertIn('v1.24', resp)
   183          self.assertIn('123', resp)
   184          self.assertIn('124', resp)
   185          resp = app.get('/pr/user?milestone=v1.24')
   186          # Don't match timestamps that happen to include "123".
   187          self.assertNotRegexpMatches(str(resp), r'\b123\b')
   188          self.assertIn('124', resp)
   189  
   190      @staticmethod
   191      def make_session(**kwargs):
   192          # set the session cookie directly (easier than the full login flow)
   193          serializer = securecookie.SecureCookieSerializer(
   194              app.app.config['webapp2_extras.sessions']['secret_key'])
   195          return serializer.serialize('session', kwargs)
   196  
   197      def test_me(self):
   198          make_pr(124, ['human'], {'title': 'huge pr!'})
   199  
   200          # no cookie: we get redirected
   201          resp = app.get('/pr')
   202          self.assertEqual(resp.status_code, 302)
   203          self.assertEqual(resp.location, 'http://localhost/github_auth/pr')
   204  
   205          # we have a cookie now: we should get results for 'human'
   206          cookie = self.make_session(user='human')
   207          resp = app.get('/pr', headers={'Cookie': 'session=%s' % cookie})
   208          self.assertEqual(resp.status_code, 200)
   209          self.assertIn('huge pr!', resp)
   210  
   211      def test_pr_links_user(self):
   212          "Individual PR pages grab digest information"
   213          gcs_async_test.install_handler(self.testbed.get_stub('urlfetch'),
   214              {'12345/': []})
   215          make_pr(12345, ['human'], {'title': 'huge pr!'})
   216          resp = app.get('/pr/12345')
   217          self.assertIn('href="/pr/human"', resp)
   218          self.assertIn('huge pr!', resp)
   219  
   220      def test_build_links_user(self):
   221          "Build pages show PR information"
   222          make_pr(12345, ['human'], {'title': 'huge pr!'})
   223          build_dir = '/kubernetes-jenkins/pr-logs/pull/12345/e2e/5/'
   224          write(build_dir + 'started.json', '{}')
   225          resp = app.get('/build' + build_dir)
   226          self.assertIn('href="/pr/human"', resp)
   227          self.assertIn('huge pr!', resp)
   228  
   229      def test_acks(self):
   230          app.get('/')  # initialize session secrets
   231  
   232          make_pr(124, ['human'], {'title': 'huge pr', 'attn': {'human': 'help#123#456'}}, repo='k/k')
   233          cookie = self.make_session(user='human')
   234          headers = {'Cookie': 'session=%s' % cookie}
   235  
   236          def expect_count(count):
   237              resp = app.get('/pr', headers=headers)
   238              self.assertEqual(resp.body.count('huge pr'), count)
   239  
   240          # PR should appear twice
   241          expect_count(2)
   242  
   243          # Ack the PR...
   244          ack_params = {'command': 'ack', 'repo': 'k/k', 'number': 124, 'latest': 456}
   245          app.post_json('/pr', ack_params, headers=headers)
   246          expect_count(1)
   247          self.assertEqual(view_pr.get_acks('human', []), {'k/k 124': 456})
   248  
   249          # Clear the ack
   250          app.post_json('/pr', {'command': 'ack-clear'}, headers=headers)
   251          expect_count(2)
   252          self.assertEqual(view_pr.get_acks('human', []), {})
   253  
   254          # Ack with an older latest
   255          ack_params['latest'] = 123
   256          app.post_json('/pr', ack_params, headers=headers)
   257          expect_count(2)
   258  
   259  
   260  if __name__ == '__main__':
   261      unittest.main()