| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2015 The LUCI Authors. All rights reserved. | 2 # Copyright 2015 The LUCI Authors. All rights reserved. |
| 3 # Use of this source code is governed under the Apache License, Version 2.0 | 3 # Use of this source code is governed under the Apache License, Version 2.0 |
| 4 # that can be found in the LICENSE file. | 4 # that can be found in the LICENSE file. |
| 5 | 5 |
| 6 import datetime | 6 import datetime |
| 7 import logging | 7 import logging |
| 8 import sys | 8 import sys |
| 9 import unittest | 9 import unittest |
| 10 | 10 |
| 11 import test_env | 11 import test_env |
| 12 test_env.setup_test_env() | 12 test_env.setup_test_env() |
| 13 | 13 |
| 14 from google.appengine.ext import ndb | 14 from google.appengine.ext import ndb |
| 15 | 15 |
| 16 from components import config as config_component | 16 from components import config as config_component |
| 17 from components import utils | 17 from components import utils |
| 18 from components.auth import model | 18 from components.auth import model |
| 19 from components.config import validation_context | |
| 20 from test_support import test_case | 19 from test_support import test_case |
| 21 | 20 |
| 22 from proto import config_pb2 | 21 from proto import config_pb2 |
| 23 import config | 22 import config |
| 24 | 23 |
| 25 | 24 |
| 26 class ConfigTest(test_case.TestCase): | 25 class ConfigTest(test_case.TestCase): |
| 27 def setUp(self): | 26 def setUp(self): |
| 28 super(ConfigTest, self).setUp() | 27 super(ConfigTest, self).setUp() |
| 29 | 28 |
| 30 def test_refetch_config(self): | 29 def test_refetch_config(self): |
| 31 # Mock of "current known revision" state. | 30 initial_revs = { |
| 32 revs = { | |
| 33 'a.cfg': config.Revision('old_a_rev', 'urla'), | 31 'a.cfg': config.Revision('old_a_rev', 'urla'), |
| 34 'b.cfg': config.Revision('old_b_rev', 'urlb'), | 32 'b.cfg': config.Revision('old_b_rev', 'urlb'), |
| 35 'c.cfg': config.Revision('old_c_rev', 'urlc'), | 33 'c.cfg': config.Revision('old_c_rev', 'urlc'), |
| 36 } | 34 } |
| 37 | 35 |
| 36 revs = initial_revs.copy() |
| 38 bumps = [] | 37 bumps = [] |
| 38 |
| 39 def bump_rev(pkg, rev, conf): | 39 def bump_rev(pkg, rev, conf): |
| 40 revs[pkg] = rev | 40 revs[pkg] = rev |
| 41 bumps.append((pkg, rev, conf, ndb.in_transaction())) | 41 bumps.append((pkg, rev, conf, ndb.in_transaction())) |
| 42 return True | 42 return True |
| 43 | 43 |
| 44 @ndb.tasklet |
| 45 def get_rev_async(pkg): |
| 46 raise ndb.Return(revs[pkg]) |
| 47 |
| 44 self.mock(config, 'is_remote_configured', lambda: True) | 48 self.mock(config, 'is_remote_configured', lambda: True) |
| 45 self.mock(config, '_CONFIG_SCHEMAS', { | 49 self.mock(config, '_CONFIG_SCHEMAS', { |
| 46 # Will be updated outside of auth db transaction. | 50 # Will be updated outside of auth db transaction. |
| 47 'a.cfg': { | 51 'a.cfg': { |
| 48 'proto_class': None, | 52 'proto_class': None, |
| 49 'revision_getter': lambda: revs['a.cfg'], | 53 'revision_getter': lambda: get_rev_async('a.cfg'), |
| 50 'validator': lambda body: self.assertEqual(body, 'new a body'), | 54 'validator': lambda body: self.assertEqual(body, 'new a body'), |
| 51 'updater': lambda rev, conf: bump_rev('a.cfg', rev, conf), | 55 'updater': lambda rev, conf: bump_rev('a.cfg', rev, conf), |
| 52 'use_authdb_transaction': False, | 56 'use_authdb_transaction': False, |
| 53 }, | 57 }, |
| 54 # Will not be changed. | 58 # Will not be changed. |
| 55 'b.cfg': { | 59 'b.cfg': { |
| 56 'proto_class': None, | 60 'proto_class': None, |
| 57 'revision_getter': lambda: revs['b.cfg'], | 61 'revision_getter': lambda: get_rev_async('b.cfg'), |
| 58 'validator': lambda _body: True, | 62 'validator': lambda _body: True, |
| 59 'updater': lambda rev, conf: bump_rev('b.cfg', rev, conf), | 63 'updater': lambda rev, conf: bump_rev('b.cfg', rev, conf), |
| 60 'use_authdb_transaction': False, | 64 'use_authdb_transaction': False, |
| 61 }, | 65 }, |
| 62 # Will be updated inside auth db transaction. | 66 # Will be updated inside auth db transaction. |
| 63 'c.cfg': { | 67 'c.cfg': { |
| 64 'proto_class': None, | 68 'proto_class': None, |
| 65 'revision_getter': lambda: revs['c.cfg'], | 69 'revision_getter': lambda: get_rev_async('c.cfg'), |
| 66 'validator': lambda body: self.assertEqual(body, 'new c body'), | 70 'validator': lambda body: self.assertEqual(body, 'new c body'), |
| 67 'updater': lambda rev, conf: bump_rev('c.cfg', rev, conf), | 71 'updater': lambda rev, conf: bump_rev('c.cfg', rev, conf), |
| 68 'use_authdb_transaction': True, | 72 'use_authdb_transaction': True, |
| 69 }, | 73 }, |
| 70 }) | 74 }) |
| 71 self.mock(config, '_fetch_configs', lambda _: { | 75 |
| 76 # _fetch_configs is called by config.refetch_config(). |
| 77 configs_to_fetch = { |
| 72 'a.cfg': (config.Revision('new_a_rev', 'urla'), 'new a body'), | 78 'a.cfg': (config.Revision('new_a_rev', 'urla'), 'new a body'), |
| 73 'b.cfg': (config.Revision('old_b_rev', 'urlb'), 'old b body'), | 79 'b.cfg': (config.Revision('old_b_rev', 'urlb'), 'old b body'), |
| 74 'c.cfg': (config.Revision('new_c_rev', 'urlc'), 'new c body'), | 80 'c.cfg': (config.Revision('new_c_rev', 'urlc'), 'new c body'), |
| 75 }) | 81 } |
| 82 self.mock(config, '_fetch_configs', lambda _: configs_to_fetch) |
| 83 |
| 84 # Old revisions initially. |
| 85 self.assertEqual(initial_revs, config.get_revisions()) |
| 76 | 86 |
| 77 # Initial update. | 87 # Initial update. |
| 78 config.refetch_config() | 88 config.refetch_config() |
| 79 self.assertEqual([ | 89 self.assertEqual([ |
| 80 ('a.cfg', config.Revision('new_a_rev', 'urla'), 'new a body', False), | 90 ('a.cfg', config.Revision('new_a_rev', 'urla'), 'new a body', False), |
| 81 ('c.cfg', config.Revision('new_c_rev', 'urlc'), 'new c body', True), | 91 ('c.cfg', config.Revision('new_c_rev', 'urlc'), 'new c body', True), |
| 82 ], bumps) | 92 ], bumps) |
| 83 del bumps[:] | 93 del bumps[:] |
| 84 | 94 |
| 95 # Updated revisions now. |
| 96 self.assertEqual( |
| 97 {k: v[0] for k, v in configs_to_fetch.iteritems()}, |
| 98 config.get_revisions()) |
| 99 |
| 85 # Refetch, nothing new. | 100 # Refetch, nothing new. |
| 86 config.refetch_config() | 101 config.refetch_config() |
| 87 self.assertFalse(bumps) | 102 self.assertFalse(bumps) |
| 88 | 103 |
| 89 def test_update_imports_config(self): | 104 def test_update_imports_config(self): |
| 90 new_rev = config.Revision('rev', 'url') | 105 new_rev = config.Revision('rev', 'url') |
| 91 body = 'tarball{url:"a" systems:"b"}' | 106 body = 'tarball{url:"a" systems:"b"}' |
| 92 self.assertTrue(config._update_imports_config(new_rev, body)) | 107 self.assertTrue(config._update_imports_config(new_rev, body)) |
| 93 self.assertEqual(new_rev, config._get_imports_config_revision()) | 108 self.assertEqual( |
| 109 new_rev, config._get_imports_config_revision_async().get_result()) |
| 94 | 110 |
| 95 def test_validate_ip_whitelist_config_ok(self): | 111 def test_validate_ip_whitelist_config_ok(self): |
| 96 conf = config_pb2.IPWhitelistConfig( | 112 conf = config_pb2.IPWhitelistConfig( |
| 97 ip_whitelists=[ | 113 ip_whitelists=[ |
| 98 config_pb2.IPWhitelistConfig.IPWhitelist( | 114 config_pb2.IPWhitelistConfig.IPWhitelist( |
| 99 name='abc', | 115 name='abc', |
| 100 subnets=['127.0.0.1/32', '0.0.0.0/0']), | 116 subnets=['127.0.0.1/32', '0.0.0.0/0']), |
| 101 config_pb2.IPWhitelistConfig.IPWhitelist( | 117 config_pb2.IPWhitelistConfig.IPWhitelist( |
| 102 name='bots', | 118 name='bots', |
| 103 subnets=[], | 119 subnets=[], |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 self.assertEqual( | 607 self.assertEqual( |
| 592 'https://host/repo/+/aaa/path/b/c.cfg', | 608 'https://host/repo/+/aaa/path/b/c.cfg', |
| 593 config._gitiles_url('https://host/repo/+/HEAD/path', 'aaa', 'b/c.cfg')) | 609 config._gitiles_url('https://host/repo/+/HEAD/path', 'aaa', 'b/c.cfg')) |
| 594 self.assertEqual( | 610 self.assertEqual( |
| 595 'https://not-gitiles', | 611 'https://not-gitiles', |
| 596 config._gitiles_url('https://not-gitiles', 'aaa', 'b/c.cfg')) | 612 config._gitiles_url('https://not-gitiles', 'aaa', 'b/c.cfg')) |
| 597 | 613 |
| 598 def test_update_service_config(self): | 614 def test_update_service_config(self): |
| 599 # Missing. | 615 # Missing. |
| 600 self.assertIsNone(config._get_service_config('abc.cfg')) | 616 self.assertIsNone(config._get_service_config('abc.cfg')) |
| 601 self.assertIsNone(config._get_service_config_rev('abc.cfg')) | 617 self.assertIsNone( |
| 618 config._get_service_config_rev_async('abc.cfg').get_result()) |
| 602 # Updated. | 619 # Updated. |
| 603 rev = config.Revision('rev', 'url') | 620 rev = config.Revision('rev', 'url') |
| 604 self.assertTrue(config._update_service_config('abc.cfg', rev, 'body')) | 621 self.assertTrue(config._update_service_config('abc.cfg', rev, 'body')) |
| 605 self.assertEqual('body', config._get_service_config('abc.cfg')) | 622 self.assertEqual('body', config._get_service_config('abc.cfg')) |
| 606 self.assertEqual(rev, config._get_service_config_rev('abc.cfg')) | 623 self.assertEqual( |
| 624 rev, config._get_service_config_rev_async('abc.cfg').get_result()) |
| 607 # Same body, returns False, though updates rev. | 625 # Same body, returns False, though updates rev. |
| 608 rev2 = config.Revision('rev2', 'url') | 626 rev2 = config.Revision('rev2', 'url') |
| 609 self.assertFalse(config._update_service_config('abc.cfg', rev2, 'body')) | 627 self.assertFalse(config._update_service_config('abc.cfg', rev2, 'body')) |
| 610 self.assertEqual(rev2, config._get_service_config_rev('abc.cfg')) | 628 self.assertEqual( |
| 629 rev2, config._get_service_config_rev_async('abc.cfg').get_result()) |
| 611 | 630 |
| 612 def test_settings_updates(self): | 631 def test_settings_updates(self): |
| 613 # Fetch only settings.cfg in this test case. | 632 # Fetch only settings.cfg in this test case. |
| 614 self.mock(config, 'is_remote_configured', lambda: True) | 633 self.mock(config, 'is_remote_configured', lambda: True) |
| 615 self.mock(config, '_CONFIG_SCHEMAS', { | 634 self.mock(config, '_CONFIG_SCHEMAS', { |
| 616 'settings.cfg': config._CONFIG_SCHEMAS['settings.cfg'], | 635 'settings.cfg': config._CONFIG_SCHEMAS['settings.cfg'], |
| 617 }) | 636 }) |
| 618 | 637 |
| 619 # Default settings. | 638 # Default settings. |
| 620 self.assertEqual(config_pb2.SettingsCfg(), config.get_settings()) | 639 self.assertEqual(config_pb2.SettingsCfg(), config.get_settings()) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 647 self.assertEqual(config_pb2.SettingsCfg(), config.get_settings()) | 666 self.assertEqual(config_pb2.SettingsCfg(), config.get_settings()) |
| 648 | 667 |
| 649 | 668 |
| 650 if __name__ == '__main__': | 669 if __name__ == '__main__': |
| 651 if '-v' in sys.argv: | 670 if '-v' in sys.argv: |
| 652 unittest.TestCase.maxDiff = None | 671 unittest.TestCase.maxDiff = None |
| 653 logging.basicConfig(level=logging.DEBUG) | 672 logging.basicConfig(level=logging.DEBUG) |
| 654 else: | 673 else: |
| 655 logging.basicConfig(level=logging.FATAL) | 674 logging.basicConfig(level=logging.FATAL) |
| 656 unittest.main() | 675 unittest.main() |
| OLD | NEW |