| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import argparse | 5 import argparse |
| 6 import json | 6 import json |
| 7 import os | 7 import os |
| 8 import requests | 8 import requests |
| 9 import tempfile | 9 import tempfile |
| 10 import unittest | 10 import unittest |
| 11 | 11 |
| 12 import mock | 12 import mock |
| 13 | 13 |
| 14 from testing_support import auto_stub | 14 from testing_support import auto_stub |
| 15 | 15 |
| 16 from infra_libs.ts_mon import config | 16 from infra_libs.ts_mon import config |
| 17 from infra_libs.ts_mon.common import interface | 17 from infra_libs.ts_mon.common import interface |
| 18 from infra_libs.ts_mon.common import standard_metrics | 18 from infra_libs.ts_mon.common import standard_metrics |
| 19 from infra_libs.ts_mon.common import monitors |
| 20 from infra_libs.ts_mon.common import targets |
| 19 from infra_libs.ts_mon.common.test import stubs | 21 from infra_libs.ts_mon.common.test import stubs |
| 20 import infra_libs | 22 import infra_libs |
| 21 | 23 |
| 22 | 24 |
| 23 class GlobalsTest(auto_stub.TestCase): | 25 class GlobalsTest(auto_stub.TestCase): |
| 24 | 26 |
| 25 def setUp(self): | 27 def setUp(self): |
| 26 super(GlobalsTest, self).setUp() | 28 super(GlobalsTest, self).setUp() |
| 27 self.mock(interface, 'state', stubs.MockState()) | |
| 28 self.mock(config, 'load_machine_config', lambda x: {}) | 29 self.mock(config, 'load_machine_config', lambda x: {}) |
| 29 | 30 |
| 30 def tearDown(self): | 31 def tearDown(self): |
| 31 # It's important to call close() before un-setting the mock state object, | 32 # It's important to call close() before un-setting the mock state object, |
| 32 # because any FlushThread started by the test is stored in that mock state | 33 # because any FlushThread started by the test is stored in that mock state |
| 33 # and needs to be stopped before running any other tests. | 34 # and needs to be stopped before running any other tests. |
| 34 interface.close() | 35 interface.close() |
| 36 # This should probably live in interface.close() |
| 37 interface.state = interface.State() |
| 35 super(GlobalsTest, self).tearDown() | 38 super(GlobalsTest, self).tearDown() |
| 36 | 39 |
| 37 @mock.patch('requests.get', autospec=True) | 40 @mock.patch('requests.get', autospec=True) |
| 38 @mock.patch('socket.getfqdn', autospec=True) | 41 @mock.patch('socket.getfqdn', autospec=True) |
| 39 @mock.patch('infra_libs.ts_mon.api_monitor.ApiMonitor', autospec=True) | 42 def test_pubsub_monitor_args(self, fake_fqdn, fake_get): |
| 40 @mock.patch('infra_libs.ts_mon.common.targets.DeviceTarget', autospec=True) | |
| 41 def test_default_monitor_args(self, fake_target, fake_monitor, fake_fqdn, | |
| 42 fake_get): | |
| 43 singleton = mock.Mock() | |
| 44 fake_monitor.return_value = singleton | |
| 45 fake_target.return_value = singleton | |
| 46 fake_fqdn.return_value = 'slave1-a1.reg.tld' | 43 fake_fqdn.return_value = 'slave1-a1.reg.tld' |
| 47 fake_get.return_value.side_effect = requests.exceptions.ConnectionError | 44 fake_get.return_value.side_effect = requests.exceptions.ConnectionError |
| 48 p = argparse.ArgumentParser() | 45 p = argparse.ArgumentParser() |
| 49 config.add_argparse_options(p) | 46 config.add_argparse_options(p) |
| 50 args = p.parse_args([ | 47 args = p.parse_args([ |
| 51 '--ts-mon-credentials', '/path/to/creds.p8.json', | 48 '--ts-mon-credentials', '/path/to/creds.p8.json', |
| 52 '--ts-mon-endpoint', | 49 '--ts-mon-endpoint', 'pubsub://invalid-project/invalid-topic']) |
| 53 'https://www.googleapis.com/acquisitions/v1_mon_shared/storage']) | 50 |
| 54 config.process_argparse_options(args) | 51 config.process_argparse_options(args) |
| 55 fake_monitor.assert_called_once_with( | 52 |
| 56 '/path/to/creds.p8.json', | 53 self.assertIsInstance(interface.state.global_monitor, |
| 57 'https://www.googleapis.com/acquisitions/v1_mon_shared/storage', | 54 monitors.PubSubMonitor) |
| 58 use_instrumented_http=True) | 55 |
| 59 self.assertIs(interface.state.global_monitor, singleton) | 56 self.assertIsInstance(interface.state.target, targets.DeviceTarget) |
| 60 fake_target.assert_called_once_with('reg', 'default', '1', 'slave1-a1') | 57 self.assertEquals(interface.state.target.hostname, 'slave1-a1') |
| 61 self.assertIs(interface.state.target, singleton) | 58 self.assertEquals(interface.state.target.region, 'reg') |
| 62 self.assertEquals(args.ts_mon_flush, 'auto') | 59 self.assertEquals(args.ts_mon_flush, 'auto') |
| 63 self.assertIsNotNone(interface.state.flush_thread) | 60 self.assertIsNotNone(interface.state.flush_thread) |
| 64 self.assertTrue(standard_metrics.up.get()) | 61 self.assertTrue(standard_metrics.up.get()) |
| 65 | 62 |
| 66 @mock.patch('requests.get', autospec=True) | 63 @mock.patch('requests.get', autospec=True) |
| 67 @mock.patch('socket.getfqdn', autospec=True) | 64 @mock.patch('socket.getfqdn', autospec=True) |
| 68 @mock.patch('infra_libs.ts_mon.api_monitor.ApiMonitor', autospec=True) | 65 def test_default_target_uppercase_fqdn(self, fake_fqdn, fake_get): |
| 69 @mock.patch('infra_libs.ts_mon.common.targets.DeviceTarget', autospec=True) | |
| 70 def test_default_monitor_args_uppercase_fqdn(self, fake_target, fake_monitor, | |
| 71 fake_fqdn, fake_get): | |
| 72 singleton = mock.Mock() | |
| 73 fake_monitor.return_value = singleton | |
| 74 fake_target.return_value = singleton | |
| 75 fake_fqdn.return_value = 'SLAVE1-A1.REG.TLD' | 66 fake_fqdn.return_value = 'SLAVE1-A1.REG.TLD' |
| 76 fake_get.return_value.side_effect = requests.exceptions.ConnectionError | 67 fake_get.return_value.side_effect = requests.exceptions.ConnectionError |
| 77 p = argparse.ArgumentParser() | 68 p = argparse.ArgumentParser() |
| 78 config.add_argparse_options(p) | 69 config.add_argparse_options(p) |
| 79 args = p.parse_args([ | 70 args = p.parse_args([ |
| 80 '--ts-mon-credentials', '/path/to/creds.p8.json', | 71 '--ts-mon-credentials', '/path/to/creds.p8.json', |
| 81 '--ts-mon-endpoint', | 72 '--ts-mon-endpoint', 'unsupported://www.googleapis.com/some/api']) |
| 82 'https://www.googleapis.com/acquisitions/v1_mon_shared/storage']) | |
| 83 config.process_argparse_options(args) | 73 config.process_argparse_options(args) |
| 84 fake_target.assert_called_once_with('reg', 'default', '1', 'slave1-a1') | 74 self.assertIsInstance(interface.state.target, targets.DeviceTarget) |
| 75 self.assertEquals(interface.state.target.hostname, 'slave1-a1') |
| 76 self.assertEquals(interface.state.target.region, 'reg') |
| 85 | 77 |
| 86 @mock.patch('requests.get', autospec=True) | 78 @mock.patch('requests.get', autospec=True) |
| 87 @mock.patch('socket.getfqdn', autospec=True) | 79 @mock.patch('socket.getfqdn', autospec=True) |
| 88 @mock.patch('infra_libs.ts_mon.api_monitor.ApiMonitor', autospec=True) | 80 def test_default_target_fqdn_without_domain(self, fake_fqdn, fake_get): |
| 89 @mock.patch('infra_libs.ts_mon.common.targets.DeviceTarget', autospec=True) | 81 fake_fqdn.return_value = 'SLAVE1-A1' |
| 90 def test_fallback_monitor_args(self, fake_target, fake_monitor, fake_fqdn, | 82 fake_get.return_value.side_effect = requests.exceptions.ConnectionError |
| 91 fake_get): | 83 p = argparse.ArgumentParser() |
| 92 singleton = mock.Mock() | 84 config.add_argparse_options(p) |
| 93 fake_monitor.return_value = singleton | 85 args = p.parse_args([ |
| 94 fake_target.return_value = singleton | 86 '--ts-mon-credentials', '/path/to/creds.p8.json', |
| 87 '--ts-mon-endpoint', 'unsupported://www.googleapis.com/some/api']) |
| 88 config.process_argparse_options(args) |
| 89 self.assertIsInstance(interface.state.target, targets.DeviceTarget) |
| 90 self.assertEquals(interface.state.target.hostname, 'slave1-a1') |
| 91 self.assertEquals(interface.state.target.region, '') |
| 92 |
| 93 @mock.patch('requests.get', autospec=True) |
| 94 @mock.patch('socket.getfqdn', autospec=True) |
| 95 def test_fallback_monitor_args(self, fake_fqdn, fake_get): |
| 95 fake_fqdn.return_value = 'foo' | 96 fake_fqdn.return_value = 'foo' |
| 96 fake_get.return_value.side_effect = requests.exceptions.ConnectionError | 97 fake_get.return_value.side_effect = requests.exceptions.ConnectionError |
| 97 p = argparse.ArgumentParser() | 98 p = argparse.ArgumentParser() |
| 98 config.add_argparse_options(p) | 99 config.add_argparse_options(p) |
| 99 args = p.parse_args([ | 100 args = p.parse_args([ |
| 100 '--ts-mon-credentials', '/path/to/creds.p8.json', | 101 '--ts-mon-credentials', '/path/to/creds.p8.json', |
| 101 '--ts-mon-endpoint', | 102 '--ts-mon-endpoint', 'unsupported://www.googleapis.com/some/api']) |
| 102 'https://www.googleapis.com/acquisitions/v1_mon_shared/storage']) | |
| 103 config.process_argparse_options(args) | 103 config.process_argparse_options(args) |
| 104 fake_monitor.assert_called_once_with( | |
| 105 '/path/to/creds.p8.json', | |
| 106 'https://www.googleapis.com/acquisitions/v1_mon_shared/storage', | |
| 107 use_instrumented_http=True) | |
| 108 self.assertIs(interface.state.global_monitor, singleton) | |
| 109 fake_target.assert_called_once_with('', 'default', '', 'foo') | |
| 110 self.assertIs(interface.state.target, singleton) | |
| 111 | 104 |
| 105 self.assertIsInstance(interface.state.global_monitor, |
| 106 monitors.NullMonitor) |
| 107 |
| 108 @mock.patch('requests.get', autospec=True) |
| 112 @mock.patch('socket.getfqdn', autospec=True) | 109 @mock.patch('socket.getfqdn', autospec=True) |
| 113 @mock.patch('infra_libs.ts_mon.api_monitor.ApiMonitor', autospec=True) | 110 def test_manual_flush(self, fake_fqdn, fake_get): |
| 114 @mock.patch('infra_libs.ts_mon.common.targets.DeviceTarget', autospec=True) | |
| 115 def test_manual_flush(self, fake_target, fake_monitor, fake_fqdn): | |
| 116 singleton = mock.Mock() | |
| 117 fake_monitor.return_value = singleton | |
| 118 fake_target.return_value = singleton | |
| 119 fake_fqdn.return_value = 'foo' | 111 fake_fqdn.return_value = 'foo' |
| 112 fake_get.return_value.side_effect = requests.exceptions.ConnectionError |
| 120 p = argparse.ArgumentParser() | 113 p = argparse.ArgumentParser() |
| 121 config.add_argparse_options(p) | 114 config.add_argparse_options(p) |
| 122 args = p.parse_args(['--ts-mon-flush', 'manual']) | 115 args = p.parse_args(['--ts-mon-flush', 'manual']) |
| 116 |
| 123 config.process_argparse_options(args) | 117 config.process_argparse_options(args) |
| 124 self.assertIsNone(interface.state.flush_thread) | 118 self.assertIsNone(interface.state.flush_thread) |
| 125 | 119 |
| 126 @mock.patch('infra_libs.ts_mon.api_monitor.ApiMonitor', autospec=True) | |
| 127 def test_monitor_args(self, fake_monitor): | |
| 128 singleton = mock.Mock() | |
| 129 fake_monitor.return_value = singleton | |
| 130 p = argparse.ArgumentParser() | |
| 131 config.add_argparse_options(p) | |
| 132 args = p.parse_args(['--ts-mon-credentials', '/path/to/creds.p8.json', | |
| 133 '--ts-mon-endpoint', 'https://foo.tld/api']) | |
| 134 config.process_argparse_options(args) | |
| 135 fake_monitor.assert_called_once_with( | |
| 136 '/path/to/creds.p8.json', 'https://foo.tld/api', | |
| 137 use_instrumented_http=True) | |
| 138 self.assertIs(interface.state.global_monitor, singleton) | |
| 139 | |
| 140 @mock.patch('infra_libs.ts_mon.common.monitors.PubSubMonitor', autospec=True) | 120 @mock.patch('infra_libs.ts_mon.common.monitors.PubSubMonitor', autospec=True) |
| 141 def test_pubsub_args(self, fake_monitor): | 121 def test_pubsub_args(self, fake_monitor): |
| 142 singleton = mock.Mock() | 122 singleton = mock.Mock() |
| 143 fake_monitor.return_value = singleton | 123 fake_monitor.return_value = singleton |
| 144 p = argparse.ArgumentParser() | 124 p = argparse.ArgumentParser() |
| 145 config.add_argparse_options(p) | 125 config.add_argparse_options(p) |
| 146 args = p.parse_args(['--ts-mon-credentials', '/path/to/creds.p8.json', | 126 args = p.parse_args(['--ts-mon-credentials', '/path/to/creds.p8.json', |
| 147 '--ts-mon-endpoint', 'pubsub://mytopic/myproject']) | 127 '--ts-mon-endpoint', 'pubsub://mytopic/myproject']) |
| 148 config.process_argparse_options(args) | 128 config.process_argparse_options(args) |
| 149 fake_monitor.assert_called_once_with( | 129 fake_monitor.assert_called_once_with( |
| 150 '/path/to/creds.p8.json', 'mytopic', 'myproject', | 130 '/path/to/creds.p8.json', 'mytopic', 'myproject', |
| 151 use_instrumented_http=True) | 131 use_instrumented_http=True) |
| 152 self.assertIs(interface.state.global_monitor, singleton) | 132 self.assertIs(interface.state.global_monitor, singleton) |
| 153 | 133 |
| 154 @mock.patch('infra_libs.ts_mon.common.monitors.DebugMonitor', auto_spec=True) | 134 @mock.patch('infra_libs.ts_mon.common.monitors.DebugMonitor', auto_spec=True) |
| 155 def test_dryrun_args(self, fake_monitor): | 135 def test_dryrun_args(self, fake_monitor): |
| 156 singleton = mock.Mock() | 136 singleton = mock.Mock() |
| 157 fake_monitor.return_value = singleton | 137 fake_monitor.return_value = singleton |
| 158 p = argparse.ArgumentParser() | 138 p = argparse.ArgumentParser() |
| 159 config.add_argparse_options(p) | 139 config.add_argparse_options(p) |
| 160 args = p.parse_args(['--ts-mon-endpoint', 'file://foo.txt']) | 140 args = p.parse_args(['--ts-mon-endpoint', 'file://foo.txt']) |
| 161 config.process_argparse_options(args) | 141 config.process_argparse_options(args) |
| 162 fake_monitor.assert_called_once_with('foo.txt') | 142 fake_monitor.assert_called_once_with('foo.txt') |
| 163 self.assertIs(interface.state.global_monitor, singleton) | 143 self.assertIs(interface.state.global_monitor, singleton) |
| 164 | 144 |
| 165 @mock.patch('infra_libs.ts_mon.api_monitor.ApiMonitor', autospec=True) | |
| 166 @mock.patch('infra_libs.ts_mon.common.targets.DeviceTarget', autospec=True) | 145 @mock.patch('infra_libs.ts_mon.common.targets.DeviceTarget', autospec=True) |
| 167 def test_device_args(self, fake_target, _fake_monitor): | 146 def test_device_args(self, fake_target): |
| 168 singleton = mock.Mock() | 147 singleton = mock.Mock() |
| 169 fake_target.return_value = singleton | 148 fake_target.return_value = singleton |
| 170 p = argparse.ArgumentParser() | 149 p = argparse.ArgumentParser() |
| 171 config.add_argparse_options(p) | 150 config.add_argparse_options(p) |
| 172 args = p.parse_args(['--ts-mon-credentials', '/path/to/creds.p8.json', | 151 args = p.parse_args(['--ts-mon-credentials', '/path/to/creds.p8.json', |
| 173 '--ts-mon-target-type', 'device', | 152 '--ts-mon-target-type', 'device', |
| 174 '--ts-mon-device-region', 'reg', | 153 '--ts-mon-device-region', 'reg', |
| 175 '--ts-mon-device-role', 'role', | 154 '--ts-mon-device-role', 'role', |
| 176 '--ts-mon-device-network', 'net', | 155 '--ts-mon-device-network', 'net', |
| 177 '--ts-mon-device-hostname', 'host']) | 156 '--ts-mon-device-hostname', 'host']) |
| 178 config.process_argparse_options(args) | 157 config.process_argparse_options(args) |
| 179 fake_target.assert_called_once_with('reg', 'role', 'net', 'host') | 158 fake_target.assert_called_once_with('reg', 'role', 'net', 'host') |
| 180 self.assertIs(interface.state.target, singleton) | 159 self.assertIs(interface.state.target, singleton) |
| 181 | 160 |
| 182 @mock.patch('infra_libs.ts_mon.api_monitor.ApiMonitor', autospec=True) | |
| 183 @mock.patch('infra_libs.ts_mon.common.targets.TaskTarget', autospec=True) | 161 @mock.patch('infra_libs.ts_mon.common.targets.TaskTarget', autospec=True) |
| 184 def test_task_args(self, fake_target, _fake_monitor): | 162 def test_task_args(self, fake_target): |
| 185 singleton = mock.Mock() | 163 singleton = mock.Mock() |
| 186 fake_target.return_value = singleton | 164 fake_target.return_value = singleton |
| 187 p = argparse.ArgumentParser() | 165 p = argparse.ArgumentParser() |
| 188 config.add_argparse_options(p) | 166 config.add_argparse_options(p) |
| 189 args = p.parse_args(['--ts-mon-credentials', '/path/to/creds.p8.json', | 167 args = p.parse_args(['--ts-mon-credentials', '/path/to/creds.p8.json', |
| 190 '--ts-mon-target-type', 'task', | 168 '--ts-mon-target-type', 'task', |
| 191 '--ts-mon-task-service-name', 'serv', | 169 '--ts-mon-task-service-name', 'serv', |
| 192 '--ts-mon-task-job-name', 'job', | 170 '--ts-mon-task-job-name', 'job', |
| 193 '--ts-mon-task-region', 'reg', | 171 '--ts-mon-task-region', 'reg', |
| 194 '--ts-mon-task-hostname', 'host', | 172 '--ts-mon-task-hostname', 'host', |
| 195 '--ts-mon-task-number', '1']) | 173 '--ts-mon-task-number', '1']) |
| 196 config.process_argparse_options(args) | 174 config.process_argparse_options(args) |
| 197 fake_target.assert_called_once_with('serv', 'job' ,'reg', 'host', 1) | 175 fake_target.assert_called_once_with('serv', 'job', 'reg', 'host', 1) |
| 198 self.assertIs(interface.state.target, singleton) | 176 self.assertIs(interface.state.target, singleton) |
| 199 | 177 |
| 200 @mock.patch('infra_libs.ts_mon.common.monitors.NullMonitor', autospec=True) | 178 @mock.patch('infra_libs.ts_mon.common.monitors.NullMonitor', autospec=True) |
| 201 def test_no_args(self, fake_monitor): | 179 def test_no_args(self, fake_monitor): |
| 202 singleton = mock.Mock() | 180 singleton = mock.Mock() |
| 203 fake_monitor.return_value = singleton | 181 fake_monitor.return_value = singleton |
| 204 p = argparse.ArgumentParser() | 182 p = argparse.ArgumentParser() |
| 205 config.add_argparse_options(p) | 183 config.add_argparse_options(p) |
| 206 args = p.parse_args([]) | 184 args = p.parse_args([]) |
| 207 config.process_argparse_options(args) | 185 config.process_argparse_options(args) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 with infra_libs.temporary_directory() as temp_dir: | 221 with infra_libs.temporary_directory() as temp_dir: |
| 244 filename = os.path.join(temp_dir, 'config') | 222 filename = os.path.join(temp_dir, 'config') |
| 245 with open(filename, 'w') as fh: | 223 with open(filename, 'w') as fh: |
| 246 fh.write('not a json file') | 224 fh.write('not a json file') |
| 247 | 225 |
| 248 with self.assertRaises(ValueError): | 226 with self.assertRaises(ValueError): |
| 249 config.load_machine_config(filename) | 227 config.load_machine_config(filename) |
| 250 | 228 |
| 251 def test_load_machine_config_not_exists(self): | 229 def test_load_machine_config_not_exists(self): |
| 252 self.assertEquals({}, config.load_machine_config('does not exist')) | 230 self.assertEquals({}, config.load_machine_config('does not exist')) |
| OLD | NEW |