~gz/ci-director/no_jenkins_open_no

« back to all changes in this revision

Viewing changes to cidirector/tests/test_cidirector.py

  • Committer: Aaron Bentley
  • Date: 2015-01-12 14:24:12 UTC
  • mfrom: (145.1.8 cloud-health)
  • Revision ID: aaron.bentley@canonical.com-20150112142412-x7at3lxhwdk3k3xj
Update cloud health when CI Director jobs are running.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
from mock import patch
17
17
 
18
18
from cidirector.cidirector import (
 
19
    ABORTED,
19
20
    BuildRevisionJob,
20
21
    CIDirector,
 
22
    CloudHealthJob,
21
23
    ConfigReader,
 
24
    FAILURE,
22
25
    get_build_parameters,
23
26
    get_buildvars_file,
24
27
    Job,
25
28
    JobInfo,
26
29
    main,
27
30
    Mailer,
 
31
    NOT_BUILT,
 
32
    list_cloud_health,
28
33
    parse_buildvars_file,
29
34
    RecordResultJob,
30
35
    ResourcefulJob,
31
36
    ResultJudge,
32
37
    ServerInfo,
 
38
    should_update_health,
 
39
    SUCCESS,
 
40
    UNSTABLE,
33
41
)
34
42
from cidirector.jobs import (
35
43
    BUILD_REVISION,
134
142
            self.job_info[key] = {
135
143
                'lastBuild': last_build,
136
144
                'description': value.get('description'),
 
145
                'lastCompletedBuild': value.get('last_completed')
137
146
            }
138
147
            building = value.get('building', False)
139
148
            color_suffix = '_anime' if building else ''
234
243
class TestCIDirector(TestCase):
235
244
 
236
245
    def setUp(self):
237
 
        def func(self, artifacts, current_version, build_url,
238
 
            build_number):
239
 
                return None
 
246
        def func(self, artifacts, current_version, build_url, build_number):
 
247
            return None
240
248
        patcher = patch(
241
249
            "cidirector.storage.StateFileJob.archive_results", func)
242
250
        patcher.start()
537
545
        director = CIDirector(jenkins, sf)
538
546
        director.update_builds()
539
547
        job_ids = [j.test_id for j in sf.iter_grouped_jobs()]
540
 
        self.assertEqual([PUBLISH_REVISION, 'foo-deploy'], job_ids)
 
548
        self.assertItemsEqual([PUBLISH_REVISION, 'foo-deploy'], job_ids)
541
549
 
542
550
    def get_state_file(self, published=True, built=True):
543
551
        sf = StateFile()
648
656
            [c[0][0] for c in jenkins.calls['get_build_info']],
649
657
            ['build-revision', 'build-revision', 'aws-deploy'])
650
658
 
 
659
    def update_cloud_health_check(self, result, status):
 
660
        foo = CloudHealthJob(name='foo', substrate='bar', last_completed=4)
 
661
        jenkins = make_cloud_health_jenkins([foo])
 
662
        jenkins.build_info['foo'] = {4: {
 
663
            'result': result, 'timestamp': 123456789, 'duration': 987654321}}
 
664
        director = CIDirector(jenkins, StateFile())
 
665
        director.state_file.start_revision('baz', '1', 'qux', '1.27', 23)
 
666
        director.update_cloud_health([foo])
 
667
        if status is None:
 
668
            self.assertEqual(
 
669
                director.state_file.get_cloud_health(23),
 
670
                {'substrates': {}})
 
671
        else:
 
672
            self.assertEqual(
 
673
                director.state_file.get_cloud_health(23),
 
674
                {'substrates': {'bar': {'foo': {4: {
 
675
                    'status': status,
 
676
                    'timestamp': '1973-11-29T21:33:09Z',
 
677
                    'duration': 987654321,
 
678
                    }}}}})
 
679
 
 
680
    def test_update_cloud_health_success(self):
 
681
        self.update_cloud_health_check(SUCCESS, SUCCEEDED),
 
682
 
 
683
    def test_update_cloud_health_failure(self):
 
684
        self.update_cloud_health_check(FAILURE, FAILED),
 
685
 
 
686
    def test_update_cloud_health_unstable(self):
 
687
        self.update_cloud_health_check(UNSTABLE, FAILED),
 
688
 
 
689
    def test_update_cloud_health_aborted(self):
 
690
        self.update_cloud_health_check(ABORTED, None),
 
691
 
 
692
    def test_update_cloud_health_not_built(self):
 
693
        self.update_cloud_health_check(NOT_BUILT, None),
 
694
 
 
695
    def test_update_cloud_health_already_set(self):
 
696
        foo = CloudHealthJob(name='foo', substrate='bar', last_completed=4)
 
697
        jenkins = make_cloud_health_jenkins([foo])
 
698
        jenkins.build_info['foo'] = {4: {'result': SUCCESS}}
 
699
        director = CIDirector(jenkins, StateFile())
 
700
        director.state_file.start_revision('baz', '1', 'qux', '1.27', 23)
 
701
        director.state_file.update_cloud_health(23, foo, FAILED, 4321, 1234)
 
702
        director.update_cloud_health([foo])
 
703
        self.assertEqual(
 
704
            director.state_file.get_cloud_health(23),
 
705
            {'substrates': {'bar': {'foo': {4: {
 
706
                'status': FAILED,
 
707
                'timestamp': '1970-01-01T01:12:01Z',
 
708
                'duration': 1234,
 
709
                }}}}})
 
710
 
 
711
    def test_update_cloud_health_other_build_set(self):
 
712
        foo = CloudHealthJob(name='foo', substrate='bar', last_completed=4)
 
713
        jenkins = make_cloud_health_jenkins([foo])
 
714
        jenkins.build_info['foo'] = {
 
715
            4: {'result': SUCCESS, 'timestamp': 5678, 'duration': 8765}}
 
716
        director = CIDirector(jenkins, StateFile())
 
717
        director.state_file.start_revision('baz', '1', 'qux', '1.27', 23)
 
718
        director.state_file.update_cloud_health(
 
719
            23, foo._replace(last_completed=5), FAILED, 1234, 4321)
 
720
        director.update_cloud_health([foo])
 
721
        self.assertEqual(
 
722
            director.state_file.get_cloud_health(23),
 
723
            {'substrates': {'bar': {'foo': {
 
724
                4: {
 
725
                    'status': SUCCEEDED,
 
726
                    'timestamp': '1970-01-01T01:34:38Z',
 
727
                    'duration': 8765,
 
728
                    },
 
729
                5: {
 
730
                    'status': FAILED,
 
731
                    'timestamp': '1970-01-01T00:20:34Z',
 
732
                    'duration': 4321,
 
733
                    },
 
734
                }}}})
 
735
 
651
736
 
652
737
def finally_fail(test_case, sf, test_id):
653
738
    sf.get_grouped_job(test_id).start_build(5)
1647
1732
                'failures': 0, 'last_build': 57, 'status': 'pending',
1648
1733
                'failure-threshold': 1, 'vote': True, 'building': True,
1649
1734
                'prerequisite_jobs': []},
 
1735
            'cloud-health': {'substrates': {}},
1650
1736
            'release_number': '1.17.2',
1651
1737
            'revision_id': 'rev-24',
1652
1738
            'revno': 24,
1653
 
            'tests': {}
 
1739
            'tests': {},
1654
1740
        })
1655
1741
 
1656
1742
    def test_adopt_build_empty_buildvars(self):
1680
1766
                'failures': 0, 'last_build': 58, 'status': 'pending',
1681
1767
                'failure-threshold': 1, 'vote': True, 'building': True,
1682
1768
                'prerequisite_jobs': []},
 
1769
            'cloud-health': {'substrates': {}},
1683
1770
            'release_number': '1.17.1',
1684
1771
            'revision_id': 'rev-23',
1685
1772
            'revno': 23,
1686
 
            'tests': {}
 
1773
            'tests': {},
1687
1774
        })
1688
1775
 
1689
1776
    def test_adopt_build_new_build(self):
1705
1792
                'failures': 0, 'last_build': 57, 'status': 'pending',
1706
1793
                'failure-threshold': 1, 'vote': True, 'building': True,
1707
1794
                'prerequisite_jobs': []},
 
1795
            'cloud-health': {'substrates': {}},
1708
1796
            'release_number': '1.17.2',
1709
1797
            'revision_id': 'rev-24',
1710
1798
            'revno': 24,
1711
 
            'tests': {}
 
1799
            'tests': {},
1712
1800
        })
1713
1801
 
1714
1802
    def test_adopt_build_no_revno(self):
1729
1817
                'failures': 0, 'last_build': 57, 'status': 'pending',
1730
1818
                'failure-threshold': 1, 'vote': True, 'building': True,
1731
1819
                'prerequisite_jobs': []},
 
1820
            'cloud-health': {'substrates': {}},
1732
1821
            'release_number': '1.17.2',
1733
1822
            'revision_id': 'rev-24',
1734
1823
            'revno': None,
1735
 
            'tests': {}
 
1824
            'tests': {},
1736
1825
        })
1737
1826
 
1738
1827
 
2046
2135
        with patch('cidirector.cidirector.build_revision') as br_mock:
2047
2136
            with patch('cidirector.cidirector.load_plugins') as lp_mock:
2048
2137
                with patch('cidirector.cidirector.RotatingFileHandler'
2049
 
                    ) as rfh_mock:
 
2138
                           ) as rfh_mock:
2050
2139
                    main(['b1', 'b2'])
2051
2140
                br_mock.assert_called_with(['b1', 'b2'])
2052
2141
                self.assertEqual(1, br_mock.call_count)
2068
2157
        self.assertEqual(logging.INFO, root_logger.level)
2069
2158
        self.assertEqual(5, root_logger.handlers[0].backupCount)
2070
2159
        self.assertEqual(log_path, root_logger.handlers[0].baseFilename)
 
2160
 
 
2161
 
 
2162
def make_description(tags=None, section='ci-director'):
 
2163
    lines = ['[{}]\n'.format(section)]
 
2164
    if tags is not None:
 
2165
        tags = ' '.join('{}={}'.format(k, v) for k, v in tags.items())
 
2166
        lines.append('tags: {}\n'.format(tags))
 
2167
    return ''.join(lines)
 
2168
 
 
2169
 
 
2170
def make_cloud_health_jenkins(jobs, section=None):
 
2171
    if section is None:
 
2172
        section = {}
 
2173
    job_dict = {}
 
2174
    for job in jobs:
 
2175
        job_dict[job.name] = {
 
2176
            'last_completed': {'number': job.last_completed},
 
2177
            'build_number': 5,
 
2178
            'description': make_description(
 
2179
                tags={'substrate': job.substrate},
 
2180
                section=section.get(job.name, 'cloud-health'))}
 
2181
    return FakeJenkins(job_dict)
 
2182
 
 
2183
 
 
2184
class TestListCloudHealth(TestCase):
 
2185
 
 
2186
    def test_list_cloud_health(self):
 
2187
        foo = CloudHealthJob(name='foo', substrate='bar', last_completed=4)
 
2188
        baz = CloudHealthJob(name='baz', substrate='qux', last_completed=6)
 
2189
        jenkins = make_cloud_health_jenkins([foo, baz])
 
2190
        si = ServerInfo(jenkins.get_info())
 
2191
        cloud_health = list(list_cloud_health(si, jenkins, None))
 
2192
        self.assertEqual(cloud_health, [foo, baz])
 
2193
 
 
2194
    def test_list_cloud_health_requires_section(self):
 
2195
        foo = CloudHealthJob(name='foo', substrate='bar', last_completed=4)
 
2196
        baz = CloudHealthJob(name='baz', substrate='qux', last_completed=6)
 
2197
        foo2 = CloudHealthJob(name='foo2', substrate='qux', last_completed=6)
 
2198
        jenkins = make_cloud_health_jenkins(
 
2199
            [foo, baz, foo2], section={'baz': 'cloud-wealth'})
 
2200
        si = ServerInfo(jenkins.get_info())
 
2201
        cloud_health = list(list_cloud_health(si, jenkins, None))
 
2202
        self.assertEqual(cloud_health, [
 
2203
            CloudHealthJob(name='foo', substrate='bar', last_completed=4),
 
2204
            CloudHealthJob(name='foo2', substrate='qux', last_completed=6),
 
2205
            ])
 
2206
 
 
2207
 
 
2208
class TestShouldUpdateHealth(TestCase):
 
2209
 
 
2210
    def test_should_update_health_build_revision(self):
 
2211
        jobs = [BUILD_REVISION, PUBLISH_REVISION]
 
2212
        self.assertEqual(False, should_update_health(None, jobs))
 
2213
 
 
2214
    def test_should_update_health_publish_revision(self):
 
2215
        self.assertEqual(True, should_update_health(None, [PUBLISH_REVISION]))
 
2216
 
 
2217
    def test_should_update_health_revision_results(self):
 
2218
        self.assertEqual(True, should_update_health(None, [REVISION_RESULTS]))
 
2219
 
 
2220
    def test_should_update_health_non_cid_job(self):
 
2221
        jenkins = FakeJenkins({'foo': {'build_number': 2}})
 
2222
        self.assertEqual(False, should_update_health(jenkins, ['foo']))
 
2223
 
 
2224
    def test_should_update_cid_job(self):
 
2225
        jenkins = FakeJenkins({'foo': {
 
2226
            'build_number': 2, 'description': make_description(tags={})}})
 
2227
        self.assertEqual(True, should_update_health(jenkins, ['foo']))