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 |