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()