blob: 64fffdefa51610477f887c34578180b6af1b3a50 [file] [log] [blame]
#!/usr/bin/python
# Copyright 2016 The LUCI Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
"""Unit tests for config.py."""
import logging
import unittest
import test_env
test_env.setup_test_env()
from components import datastore_utils
from components import machine_provider
from components.config import validation
from test_support import test_case
import config
from proto import config_pb2
class UpdateConfigTest(test_case.TestCase):
"""Tests for config.update_template_configs."""
def tearDown(self, *args, **kwargs):
"""Performs post-test case tear-down."""
super(UpdateConfigTest, self).tearDown(*args, **kwargs)
# Even though the datastore resets between test cases and
# the underlying entity doesn't persist, the cache does.
config.Configuration.clear_cache()
def validator_test(self, validator, cfg, messages):
ctx = validation.Context()
validator(cfg, ctx)
self.assertEquals(ctx.result().messages, [
validation.Message(severity=logging.ERROR, text=m)
for m in messages
])
def install_mock(
self,
revision=None,
template_config=None,
manager_config=None,
settings_config=None,
):
"""Installs a mock for config.config.get_self_config.
Args:
template_config: What to return when templates.cfg is requested. Defaults
to an empty config_pb2.InstanceTemplateConfig instance.
manager_config: What to return when managers.cfg is requested. Defaults
to an empty config_pb2.InstanceGroupManagerConfig instance.
settings_config: What to return when settings.cfg is requested. Defaults
to an empty config_pb2.SettingsCfg instance.
"""
def get_self_config(path, _, **kwargs):
self.assertIn(path, ('templates.cfg', 'managers.cfg', 'settings.cfg'))
if path == 'templates.cfg':
proto = template_config or config_pb2.InstanceTemplateConfig()
elif path == 'managers.cfg':
proto = manager_config or config_pb2.InstanceGroupManagerConfig()
elif path == 'settings.cfg':
proto = settings_config or config_pb2.SettingsCfg()
return revision or 'mock-revision', proto
self.mock(config.config, 'get_self_config', get_self_config)
def test_empty_configs(self):
"""Ensures empty configs are successfully stored."""
self.install_mock()
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failIf(config.Configuration.cached().manager_config)
self.assertEqual(config.Configuration.cached().revision, 'mock-revision')
def test_repeated_base_names(self):
"""Ensures duplicate base names reject the entire config."""
template_config = config_pb2.InstanceTemplateConfig(
templates=[
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-1',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-2',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-3',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-4',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-2',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-3',
),
],
)
self.install_mock(template_config=template_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failIf(config.Configuration.cached().manager_config)
self.failIf(config.Configuration.cached().revision)
def test_too_many_instance_templates(self):
template_config = config_pb2.InstanceTemplateConfig(
templates=[
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-1',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-2',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-3',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-4',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-5',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-6',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-7',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-8',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-9',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-10',
),
config_pb2.InstanceTemplateConfig.InstanceTemplate(
base_name='base-name-11',
),
],
)
self.install_mock(template_config=template_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failIf(config.Configuration.cached().manager_config)
self.failIf(config.Configuration.cached().revision)
def test_repeated_zone_different_base_name(self):
"""Ensures repeated zones in different base names are valid."""
manager_config = config_pb2.InstanceGroupManagerConfig(
managers=[
config_pb2.InstanceGroupManagerConfig.InstanceGroupManager(
template_base_name='base-name-1',
zone='us-central1-a',
),
config_pb2.InstanceGroupManagerConfig.InstanceGroupManager(
template_base_name='base-name-2',
zone='us-central1-a',
),
config_pb2.InstanceGroupManagerConfig.InstanceGroupManager(
template_base_name='base-name-3',
zone='us-central1-a',
),
],
)
self.install_mock(manager_config=manager_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failUnless(config.Configuration.cached().manager_config)
self.assertEqual(config.Configuration.cached().revision, 'mock-revision')
def test_repeated_zone_same_base_name(self):
"""Ensures repeated zones in a base name reject the entire config."""
manager_config = config_pb2.InstanceGroupManagerConfig(
managers=[
config_pb2.InstanceGroupManagerConfig.InstanceGroupManager(
template_base_name='base-name-1',
zone='us-central1-a',
),
config_pb2.InstanceGroupManagerConfig.InstanceGroupManager(
template_base_name='base-name-2',
zone='us-central1-b',
),
config_pb2.InstanceGroupManagerConfig.InstanceGroupManager(
template_base_name='base-name-1',
zone='us-central1-a',
),
],
)
self.install_mock(manager_config=manager_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failIf(config.Configuration.cached().manager_config)
self.failIf(config.Configuration.cached().revision)
def test_minimum_size_exceeds_maximum_size(self):
"""Ensures repeated zones in a base name reject the entire config."""
manager_config = config_pb2.InstanceGroupManagerConfig(
managers=[
config_pb2.InstanceGroupManagerConfig.InstanceGroupManager(
maximum_size=1,
minimum_size=2,
template_base_name='base-name-1',
zone='us-central1-a',
),
],
)
self.install_mock(manager_config=manager_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failIf(config.Configuration.cached().manager_config)
self.failIf(config.Configuration.cached().revision)
def test_maximum_size_exceeds_maximum_allowed(self):
"""Ensures repeated zones in a base name reject the entire config."""
manager_config = config_pb2.InstanceGroupManagerConfig(
managers=[
config_pb2.InstanceGroupManagerConfig.InstanceGroupManager(
maximum_size=9999,
template_base_name='base-name-1',
zone='us-central1-a',
),
],
)
self.install_mock(manager_config=manager_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failIf(config.Configuration.cached().manager_config)
self.failIf(config.Configuration.cached().revision)
def test_update_template_configs(self):
"""Ensures config is updated when revision changes."""
manager_config = config_pb2.InstanceGroupManagerConfig(
managers=[config_pb2.InstanceGroupManagerConfig.InstanceGroupManager()],
)
self.install_mock(revision='revision-1', manager_config=manager_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failUnless(config.Configuration.cached().manager_config)
self.assertEqual(config.Configuration.cached().revision, 'revision-1')
template_config = config_pb2.InstanceTemplateConfig(
templates=[config_pb2.InstanceTemplateConfig.InstanceTemplate()],
)
self.install_mock(revision='revision-2', template_config=template_config)
config.update_template_configs()
self.failUnless(config.Configuration.cached().template_config)
self.failIf(config.Configuration.cached().manager_config)
self.assertEqual(config.Configuration.cached().revision, 'revision-2')
def test_update_template_configs_same_revision(self):
"""Ensures config is not updated when revision doesn't change."""
manager_config = config_pb2.InstanceGroupManagerConfig(
managers=[config_pb2.InstanceGroupManagerConfig.InstanceGroupManager()],
)
self.install_mock(manager_config=manager_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failUnless(config.Configuration.cached().manager_config)
self.assertEqual(config.Configuration.cached().revision, 'mock-revision')
template_config = config_pb2.InstanceTemplateConfig(
templates=[config_pb2.InstanceTemplateConfig.InstanceTemplate()],
)
self.install_mock(template_config=template_config)
config.update_template_configs()
self.failIf(config.Configuration.cached().template_config)
self.failUnless(config.Configuration.cached().manager_config)
self.assertEqual(config.Configuration.cached().revision, 'mock-revision')
def test_settings_valid_mp_config(self):
"""Ensures base MP settings are correctly received if configured."""
settings_config = config_pb2.SettingsCfg(mp_server='server')
self.install_mock(settings_config=settings_config)
self.assertEqual(config._get_settings()[1].mp_server, 'server')
self.assertEqual(machine_provider.MachineProviderConfiguration.instance_url,
'server')
def test_settings_empty_mp_config(self):
"""Ensures base MP settings are correctly received if not configured."""
settings_config = config_pb2.SettingsCfg()
self.install_mock(settings_config=settings_config)
mpdefault = machine_provider.MachineProviderConfiguration.get_instance_url()
self.failIf(config._get_settings()[1].mp_server)
self.assertEqual(machine_provider.MachineProviderConfiguration.instance_url,
mpdefault)
def test_validate_settings(self):
self.validator_test(config.validate_settings_config,
config_pb2.SettingsCfg(), [])
self.validator_test(
config.validate_settings_config,
config_pb2.SettingsCfg(mp_server='http://url'),
['mp_server must start with "https://" or "http://localhost"'])
self.validator_test(
config.validate_settings_config,
config_pb2.SettingsCfg(mp_server='url'),
['mp_server must start with "https://" or "http://localhost"'])
if __name__ == '__main__':
unittest.main()