207 lines
11 KiB
Python
207 lines
11 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# Copyright (C) 2020-2021 Apple Inc. All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
|
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
import json
|
|
import os
|
|
import unittest
|
|
|
|
import loadConfig
|
|
|
|
|
|
class ConfigDotJSONTest(unittest.TestCase):
|
|
def get_config(self):
|
|
cwd = os.path.dirname(os.path.abspath(__file__))
|
|
return json.load(open(os.path.join(cwd, 'config.json')))
|
|
|
|
def test_configuration(self):
|
|
cwd = os.path.dirname(os.path.abspath(__file__))
|
|
loadConfig.loadBuilderConfig({}, is_test_mode_enabled=True, master_prefix_path=cwd)
|
|
|
|
def test_tab_character(self):
|
|
cwd = os.path.dirname(os.path.abspath(__file__))
|
|
with open(os.path.join(cwd, 'config.json'), 'r') as config:
|
|
self.assertTrue('\t' not in config.read(), 'Tab character found in config.json, please use spaces instead of tabs.')
|
|
|
|
def test_builder_keys(self):
|
|
config = self.get_config()
|
|
valid_builder_keys = ['additionalArguments', 'architectures', 'builddir', 'configuration', 'description',
|
|
'defaultProperties', 'device_model', 'env', 'factory', 'icon', 'locks', 'name', 'platform', 'properties',
|
|
'remotes', 'runTests', 'shortname', 'tags', 'triggers', 'workernames', 'workerbuilddir']
|
|
for builder in config.get('builders', []):
|
|
for key in builder:
|
|
self.assertTrue(key in valid_builder_keys, 'Unexpected key "{}" for builder {}'.format(key, builder.get('name')))
|
|
|
|
def test_multiple_scheduers_for_builder(self):
|
|
config = self.get_config()
|
|
builder_to_schduler_map = {}
|
|
|
|
for scheduler in config.get('schedulers'):
|
|
for buildername in scheduler.get('builderNames'):
|
|
self.assertTrue(buildername not in builder_to_schduler_map, 'builder {} appears multiple times in schedulers.'.format(buildername))
|
|
builder_to_schduler_map[buildername] = scheduler.get('name')
|
|
|
|
def test_schduler_contains_valid_builder_name(self):
|
|
config = self.get_config()
|
|
builder_name_list = [builder['name'] for builder in config['builders']]
|
|
for scheduler in config.get('schedulers'):
|
|
for buildername in scheduler.get('builderNames'):
|
|
self.assertTrue(buildername in builder_name_list, 'builder "{}" in scheduler "{}" is invalid.'.format(buildername, scheduler.get('name')))
|
|
|
|
def test_single_builder_for_triggerable_scheduler(self):
|
|
config = self.get_config()
|
|
for scheduler in config['schedulers']:
|
|
if scheduler.get('type') == 'Triggerable':
|
|
self.assertTrue(len(scheduler.get('builderNames')) == 1, 'scheduler "{}" triggers multiple builders.'.format(scheduler['name']))
|
|
|
|
|
|
class TagsForBuilderTest(unittest.TestCase):
|
|
def verifyTags(self, builderName, expectedTags):
|
|
tags = loadConfig.getTagsForBuilder({'name': builderName})
|
|
self.assertEqual(sorted(tags), sorted(expectedTags))
|
|
|
|
def test_getTagsForBuilder(self):
|
|
self.verifyTags('EWS', [])
|
|
self.verifyTags('TryBot-10-EWS', [])
|
|
self.verifyTags('11-EWS', [])
|
|
self.verifyTags('32-EWS', ['32'])
|
|
self.verifyTags('iOS-11-EWS', ['iOS'])
|
|
self.verifyTags('iOS(11),(test)-EWS', ['iOS', 'test'])
|
|
self.verifyTags('Windows-EWS', ['Windows'])
|
|
self.verifyTags('Windows_Windows', ['Windows'])
|
|
self.verifyTags('GTK-Build-EWS', ['GTK', 'Build'])
|
|
self.verifyTags('GTK-WK2-Tests-EWS', ['GTK', 'WK2', 'Tests'])
|
|
self.verifyTags('macOS-Sierra-Release-WK1-EWS', ['Sierra', 'Release', 'macOS', 'WK1'])
|
|
self.verifyTags('macOS-High-Sierra-Release-32bit-WK2-EWS', ['macOS', 'High', 'Sierra', 'Release', 'WK2', '32bit'])
|
|
|
|
def test_tags_type(self):
|
|
tags = loadConfig.getTagsForBuilder({'name': 'iOS-11-EWS'})
|
|
self.assertEqual(tags, ['iOS'])
|
|
self.assertEqual(type(tags[0]), str)
|
|
|
|
def test_getInvalidTags(self):
|
|
invalidTags = loadConfig.getInvalidTags()
|
|
expectedTags = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10',
|
|
'11', '12', '13', '14', '15', '16', '17', '18', '19', 'EWS', 'TryBot']
|
|
self.assertEqual(invalidTags, expectedTags)
|
|
|
|
|
|
class TestcheckValidWorker(unittest.TestCase):
|
|
def test_invalid_worker(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidWorker({})
|
|
self.assertEqual(context.exception.args, ('Worker is None or Empty.',))
|
|
|
|
def test_worker_with_missing_name(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidWorker({'platform': 'mac-sierra'})
|
|
self.assertEqual(context.exception.args, ('Worker "{\'platform\': \'mac-sierra\'}" does not have name defined.',))
|
|
|
|
def test_worker_with_missing_platName(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidWorker({'name': 'ews101'})
|
|
self.assertEqual(context.exception.args, ('Worker ews101 does not have platform defined.',))
|
|
|
|
def test_valid_worker(self):
|
|
loadConfig.checkValidWorker({'name': 'ews101', 'platform': 'mac-sierra'})
|
|
|
|
|
|
class TestcheckValidBuilder(unittest.TestCase):
|
|
def test_invalid_builder(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidBuilder({}, {})
|
|
self.assertEqual(context.exception.args, ('Builder is None or Empty.',))
|
|
|
|
def test_builder_with_missing_name(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidBuilder({}, {'platform': 'mac-sierra'})
|
|
self.assertEqual(context.exception.args, ('Builder "{\'platform\': \'mac-sierra\'}" does not have name defined.',))
|
|
|
|
def test_builder_with_invalid_identifier(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidBuilder({}, {'name': 'mac-wk2(test)', 'shortname': 'mac-wk2'})
|
|
self.assertEqual(context.exception.args, ('Builder name mac-wk2(test) is not a valid buildbot identifier.',))
|
|
|
|
def test_builder_with_extra_long_name(self):
|
|
longName = 'a' * 71
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidBuilder({}, {'name': longName, 'shortname': 'a'})
|
|
self.assertEqual(context.exception.args, ('Builder name {} is longer than maximum allowed by Buildbot (70 characters).'.format(longName),))
|
|
|
|
def test_builder_with_invalid_configuration(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidBuilder({}, {'name': 'mac-wk2', 'shortname': 'mac-wk2', 'configuration': 'asan'})
|
|
self.assertEqual(context.exception.args, ('Invalid configuration: asan for builder: mac-wk2',))
|
|
|
|
def test_builder_with_missing_factory(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidBuilder({}, {'name': 'mac-wk2', 'shortname': 'mac-wk2', 'configuration': 'release'})
|
|
self.assertEqual(context.exception.args, ('Builder mac-wk2 does not have factory defined.',))
|
|
|
|
def test_builder_with_missing_scheduler(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidBuilder({}, {'name': 'mac-wk2', 'shortname': 'mac-wk2', 'configuration': 'release', 'factory': 'WK2Factory', 'platform': 'mac-sierra', 'triggers': ['api-tests-mac-ews']})
|
|
self.assertEqual(context.exception.args, ('Trigger: api-tests-mac-ews in builder mac-wk2 does not exist in list of Trigerrable schedulers.',))
|
|
|
|
def test_builder_with_missing_platform(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkValidBuilder({}, {'name': 'mac-wk2', 'shortname': 'mac-wk2', 'configuration': 'release', 'factory': 'WK2Factory'})
|
|
self.assertEqual(context.exception.args, ('Builder mac-wk2 does not have platform defined.',))
|
|
|
|
def test_valid_builder(self):
|
|
loadConfig.checkValidBuilder({}, {'name': 'macOS-High-Sierra-WK2-EWS', 'shortname': 'mac-wk2', 'configuration': 'release', 'factory': 'WK2Factory', 'platform': 'mac-sierra'})
|
|
|
|
|
|
class TestcheckWorkersAndBuildersForConsistency(unittest.TestCase):
|
|
def __init__(self, *args, **kwargs):
|
|
self.WK2Builder = {'name': 'macOS-High-Sierra-WK2-EWS', 'shortname': 'mac-wk2', 'factory': 'WK2Factory', 'platform': 'mac-sierra', 'workernames': ['ews101', 'ews102']}
|
|
self.ews101 = {'name': 'ews101', 'platform': 'mac-sierra'}
|
|
self.ews102 = {'name': 'ews102', 'platform': 'ios-11'}
|
|
super(TestcheckWorkersAndBuildersForConsistency, self).__init__(*args, **kwargs)
|
|
|
|
def test_checkWorkersAndBuildersForConsistency(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkWorkersAndBuildersForConsistency({}, [], [self.WK2Builder])
|
|
self.assertEqual(context.exception.args, ('Builder macOS-High-Sierra-WK2-EWS has worker ews101, which is not defined in workers list!',))
|
|
|
|
def test_checkWorkersAndBuildersForConsistency1(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkWorkersAndBuildersForConsistency({}, [self.ews101, self.ews102], [self.WK2Builder])
|
|
self.assertEqual(context.exception.args, ('Builder "macOS-High-Sierra-WK2-EWS" is for platform "mac-sierra", but has worker "ews102" for platform "ios-11"!',))
|
|
|
|
def test_duplicate_worker(self):
|
|
with self.assertRaises(Exception) as context:
|
|
loadConfig.checkWorkersAndBuildersForConsistency({}, [self.ews101, self.ews101], [self.WK2Builder])
|
|
self.assertEqual(context.exception.args, ('Duplicate worker entry found for ews101.',))
|
|
|
|
def test_success(self):
|
|
loadConfig.checkWorkersAndBuildersForConsistency({}, [self.ews101, {'name': 'ews102', 'platform': 'mac-sierra'}], [self.WK2Builder])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
from steps_unittest_old import BuildBotConfigLoader
|
|
BuildBotConfigLoader()._add_dependent_modules_to_sys_modules()
|
|
import loadConfig
|
|
unittest.main()
|