github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/kettle/make_db_test.py (about)

     1  #!/usr/bin/env python
     2  
     3  # Copyright 2017 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  """Tests for make_db."""
    18  
    19  import time
    20  import unittest
    21  
    22  import make_db
    23  import model
    24  
    25  
    26  
    27  TEST_BUCKETS_DATA = {
    28      'gs://kubernetes-jenkins/logs/': {'prefix': ''},
    29      'gs://bucket1/': {'prefix': 'bucket1_prefix'},
    30      'gs://bucket2/': {'prefix': 'bucket2_prefix'}
    31  }
    32  
    33  
    34  class MockedClient(make_db.GCSClient):
    35      """A GCSClient with stubs for external interactions."""
    36      NOW = int(time.time())
    37      LOG_DIR = 'gs://kubernetes-jenkins/logs/'
    38      JOB_DIR = LOG_DIR + 'fake/123/'
    39      ART_DIR = JOB_DIR + 'artifacts/'
    40      lists = {
    41          LOG_DIR: [LOG_DIR + 'fake/'],
    42          LOG_DIR + 'fake/': [JOB_DIR, LOG_DIR + 'fake/122/'],
    43          LOG_DIR + 'bad-latest/': [LOG_DIR + 'bad-latest/6/'],
    44          LOG_DIR + 'latest/': [LOG_DIR + 'latest/4/', LOG_DIR + 'latest/3/'],
    45          'gs://kubernetes-jenkins/pr-logs/directory/': [],
    46          ART_DIR: [ART_DIR + 'junit_01.xml'],
    47          ART_DIR.replace('123', '122'): [],
    48      }
    49      gets = {
    50          JOB_DIR + 'finished.json': {'timestamp': NOW, 'result': 'SUCCESS'},
    51          JOB_DIR + 'started.json': {'timestamp': NOW - 5},
    52          LOG_DIR + 'latest/latest-build.txt': '4',
    53          LOG_DIR + 'bad-latest/latest-build.txt': 'asdf',
    54          LOG_DIR + 'fake/122/finished.json': {'timestamp': 123},
    55          ART_DIR + 'junit_01.xml': '''
    56      <testsuite>
    57          <testcase name="Foo" time="3" />
    58          <testcase name="Bad" time="4">
    59              <failure>stacktrace</failure>
    60          </testcase>
    61          <testcase name="Lazy" time="0">
    62              <skipped />
    63          </testcase>
    64      </testsuite>
    65      '''}
    66  
    67      def get(self, path, as_json=True):
    68          return self.gets.get(path)
    69  
    70      def ls(self, path, **_kwargs):  # pylint: disable=arguments-differ
    71          return self.lists[path]
    72  
    73  
    74  class GCSClientTest(unittest.TestCase):
    75      """Unit tests for GCSClient"""
    76  
    77      # pylint: disable=protected-access
    78  
    79      JOBS_DIR = 'gs://kubernetes-jenkins/logs/'
    80  
    81      def setUp(self):
    82          self.client = MockedClient(self.JOBS_DIR)
    83  
    84      def test_get_junits(self):
    85          junits = self.client.get_junits_from_build(self.JOBS_DIR + 'fake/123')
    86          self.assertEqual(
    87              sorted(junits),
    88              ['gs://kubernetes-jenkins/logs/fake/123/artifacts/junit_01.xml'])
    89  
    90      def test_get_builds_normal_list(self):
    91          # normal case: lists a directory
    92          self.assertEqual((True, ['123', '122']), self.client._get_builds('fake'))
    93  
    94      def test_get_builds_latest(self):
    95          # optimization: does a range based on build-latest.txt
    96          precise, gen = self.client._get_builds('latest')
    97          self.assertFalse(precise)
    98          self.assertEqual(['4', '3', '2', '1'], list(gen))
    99  
   100  
   101      def test_get_builds_latest_fallback(self):
   102          # fallback: still lists a directory when build-latest.txt isn't an int
   103          self.assertEqual((True, ['6']), self.client._get_builds('bad-latest'))
   104  
   105      def test_get_builds_non_sequential(self):
   106          # fallback: setting sequential=false causes directory listing
   107          self.client.metadata = {'sequential': False}
   108          self.assertEqual((True, ['4', '3']),
   109                           self.client._get_builds('latest'))
   110  
   111  
   112  class MainTest(unittest.TestCase):
   113      """End-to-end test of the main function's output."""
   114      JOBS_DIR = GCSClientTest.JOBS_DIR
   115  
   116      def test_remove_system_out(self):
   117          self.assertEqual(make_db.remove_system_out('not<xml<lol'), 'not<xml<lol')
   118          self.assertEqual(
   119              make_db.remove_system_out('<a><b>c<system-out>bar</system-out></b></a>'),
   120              '<a><b>c</b></a>')
   121  
   122      @staticmethod
   123      def get_expected_builds():
   124          return {
   125              MockedClient.JOB_DIR.replace('123', '122')[:-1]:
   126                  (None, {'timestamp': 123}, []),
   127              MockedClient.JOB_DIR[:-1]:
   128                  ({'timestamp': MockedClient.NOW - 5},
   129                   {'timestamp': MockedClient.NOW, 'result': 'SUCCESS'},
   130                   [MockedClient.gets[MockedClient.ART_DIR + 'junit_01.xml']])
   131          }
   132  
   133      def assert_main_output(self, threads, expected=None, db=None,
   134                             client=MockedClient):
   135          if expected is None:
   136              expected = self.get_expected_builds()
   137          if db is None:
   138              db = model.Database(':memory:')
   139          make_db.main(db, {self.JOBS_DIR: {}}, threads, True, client)
   140  
   141          result = {path: (started, finished, db.test_results_for_build(path))
   142                    for _rowid, path, started, finished in db.get_builds()}
   143  
   144          self.assertEqual(result, expected)
   145          return db
   146  
   147      def test_clean(self):
   148          for threads in [1, 32]:
   149              self.assert_main_output(threads)
   150  
   151      def test_incremental_new(self):
   152          db = self.assert_main_output(1)
   153  
   154          new_junit = '''
   155              <testsuite>
   156                  <testcase name="New" time="8"/>
   157                  <testcase name="Foo" time="2.3"/>
   158              </testsuite>
   159          '''
   160  
   161          class MockedClientNewer(MockedClient):
   162              NOW = int(time.time())
   163              LOG_DIR = 'gs://kubernetes-jenkins/logs/'
   164              JOB_DIR = LOG_DIR + 'fake/124/'
   165              ART_DIR = JOB_DIR + 'artifacts/'
   166              lists = {
   167                  LOG_DIR: [LOG_DIR + 'fake/'],
   168                  LOG_DIR + 'fake/': [JOB_DIR, LOG_DIR + 'fake/123/'],
   169                  ART_DIR: [ART_DIR + 'junit_01.xml'],
   170                  'gs://kubernetes-jenkins/pr-logs/directory/': [],
   171              }
   172              gets = {
   173                  JOB_DIR + 'finished.json': {'timestamp': NOW},
   174                  ART_DIR + 'junit_01.xml': new_junit,
   175              }
   176  
   177          expected = self.get_expected_builds()
   178          expected[MockedClientNewer.JOB_DIR[:-1]] = (
   179              None, {'timestamp': MockedClientNewer.NOW}, [new_junit])
   180  
   181          self.assert_main_output(1, expected, db, MockedClientNewer)
   182  
   183  
   184  if __name__ == '__main__':
   185      unittest.main()