Chromium Code Reviews| 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 os | 6 import os |
| 7 import unittest | 7 import unittest |
| 8 | 8 |
| 9 import google.protobuf | |
| 10 | |
| 9 import infra_libs | 11 import infra_libs |
| 10 from infra_libs import event_mon | 12 from infra_libs import event_mon |
| 13 | |
| 11 from infra.tools.send_monitoring_event import send_event | 14 from infra.tools.send_monitoring_event import send_event |
| 12 | 15 |
| 16 from infra_libs.event_mon import (BuildEvent, ServiceEvent, | |
| 17 ChromeInfraEvent, LogRequestLite) | |
| 13 | 18 |
| 14 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data') | 19 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data') |
| 15 | 20 |
| 16 | 21 |
| 17 class SendingEventBaseTest(unittest.TestCase): | 22 class SendingEventBaseTest(unittest.TestCase): |
| 18 """Base class for all tests that send events.""" | 23 """Base class for all tests that send events.""" |
| 19 def setUp(self): | 24 def setUp(self): |
| 20 # Use the dry run mode instead of a mock. | 25 # Use the dry run mode instead of a mock. |
| 21 event_mon.setup_monitoring(run_type='dry') | 26 event_mon.setup_monitoring(run_type='dry') |
| 22 | 27 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 send_event.send_service_event(args) | 86 send_event.send_service_event(args) |
| 82 | 87 |
| 83 | 88 |
| 84 class TestBuildEvent(SendingEventBaseTest): | 89 class TestBuildEvent(SendingEventBaseTest): |
| 85 def test_send_build_event_smoke(self): | 90 def test_send_build_event_smoke(self): |
| 86 args = send_event.get_arguments( | 91 args = send_event.get_arguments( |
| 87 ['--event-mon-service-name', 'thing', | 92 ['--event-mon-service-name', 'thing', |
| 88 '--build-event-type', 'SCHEDULER', | 93 '--build-event-type', 'SCHEDULER', |
| 89 '--build-event-hostname', 'foo.bar.dns', | 94 '--build-event-hostname', 'foo.bar.dns', |
| 90 '--build-event-build-name', 'whatever']) | 95 '--build-event-build-name', 'whatever']) |
| 91 self.assertEquals(args.event_mon_run_type, 'dry') | 96 self.assertTrue(send_event.send_build_event(args)) |
| 92 send_event.send_build_event(args) | 97 |
| 93 | 98 def test_send_build_event_smoke_missing_goma_file(self): |
| 94 | 99 args = send_event.get_arguments( |
| 95 class TestEventsFromFile(SendingEventBaseTest): | 100 ['--event-mon-service-name', 'thing', |
| 101 '--build-event-type', 'BUILD', | |
| 102 '--build-event-hostname', 'foo.bar.dns', | |
| 103 '--build-event-build-name', 'whatever', | |
| 104 '--build-event-goma-stats-path', | |
| 105 os.path.join(DATA_DIR, 'this-file-does-not-exist')]) | |
| 106 with self.assertRaises(IOError): | |
| 107 send_event.send_build_event(args) | |
| 108 | |
| 109 | |
| 110 class TestInputModesFile(unittest.TestCase): | |
| 111 # Test the various ways to pass information to send_monitoring_event | |
| 112 # TODO(pgervais): test precedence order. | |
| 113 def tearDown(self): | |
| 114 event_mon.close() | |
| 115 | |
| 116 def test_send_build_event_with_goma_stats(self): | |
| 117 # Write a file to avoid mocks | |
| 118 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 119 outfile = os.path.join(tmpdir, 'out.bin') | |
| 120 args = send_event.get_arguments( | |
| 121 ['--event-mon-run-type', 'file', | |
| 122 '--event-mon-output-file', outfile, | |
| 123 '--event-mon-service-name', 'thing', | |
| 124 '--build-event-type', 'BUILD', | |
| 125 '--build-event-hostname', 'foo.bar.dns', | |
| 126 '--build-event-build-name', 'whatever', | |
| 127 '--build-event-goma-stats-path', | |
| 128 os.path.join(DATA_DIR, 'goma_stats.bin')]) | |
| 129 self.assertEquals(args.event_mon_run_type, 'file') | |
| 130 event_mon.process_argparse_options(args) | |
| 131 self.assertTrue(send_event.send_build_event(args)) | |
| 132 | |
| 133 # Now open the resulting file and check what was written | |
| 134 with open(outfile, 'rb') as f: | |
| 135 request = LogRequestLite.FromString(f.read()) | |
| 136 | |
| 137 self.assertEqual(len(request.log_event), 1) | |
| 138 event = ChromeInfraEvent.FromString(request.log_event[0].source_extension) | |
| 139 self.assertEqual(event.build_event.goma_stats.request_stats.total, 10) | |
| 140 self.assertEqual(event.build_event.goma_stats.request_stats.success, 9) | |
| 141 self.assertEqual(event.build_event.goma_stats.request_stats.failure, 1) | |
| 142 self.assertEqual(event.build_event.host_name, 'foo.bar.dns') | |
| 143 | |
| 144 def test_send_build_event_with_invalid_goma_stats(self): | |
| 145 # Write a file to avoid mocks | |
| 146 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 147 outfile = os.path.join(tmpdir, 'out.bin') | |
| 148 args = send_event.get_arguments( | |
| 149 ['--event-mon-run-type', 'file', | |
| 150 '--event-mon-output-file', outfile, | |
| 151 '--event-mon-service-name', 'thing', | |
| 152 '--build-event-type', 'BUILD', | |
| 153 '--build-event-hostname', 'foo.bar.dns', | |
| 154 '--build-event-build-name', 'whatever', | |
| 155 '--build-event-goma-stats-path', | |
| 156 os.path.join(DATA_DIR, 'garbage')]) | |
| 157 self.assertEquals(args.event_mon_run_type, 'file') | |
| 158 event_mon.process_argparse_options(args) | |
| 159 with self.assertRaises(google.protobuf.message.DecodeError): | |
| 160 send_event.send_build_event(args) | |
| 161 | |
| 162 # The default event used below (build-foo-builder.bin) has been generated by: | |
| 163 # ./run.py infra.tools.send_monitoring_event \ | |
| 164 # --event-mon-run-type=file \ | |
| 165 # --event-mon-output-file=./build-foo-builder.bin \ | |
| 166 # --build-event-hostname=myhostname \ | |
| 167 # --event-mon-timestamp-kind=BEGIN \ | |
| 168 # --event-mon-event-timestamp=123 \ | |
| 169 # --build-event-type=BUILD \ | |
| 170 # --build-event-build-name=foo" | |
| 171 def test_logrequest_path_valid_build_event(self): | |
| 172 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 173 outfile = os.path.join(tmpdir, 'out.bin') | |
| 174 args = send_event.get_arguments( | |
| 175 ['--event-mon-run-type', 'file', | |
| 176 '--event-mon-output-file', outfile, | |
| 177 '--event-mon-service-name', 'thing', | |
| 178 '--event-logrequest-path', | |
| 179 os.path.join(DATA_DIR, 'build-foo-builder.bin'), | |
| 180 '--build-event-build-number', '3' | |
| 181 ]) | |
| 182 self.assertEquals(args.event_mon_run_type, 'file') | |
| 183 event_mon.process_argparse_options(args) | |
| 184 send_event._process_logrequest_path(args) | |
| 185 self.assertTrue(send_event.send_build_event(args)) | |
| 186 | |
| 187 # Now open the resulting file and check what was written | |
| 188 with open(outfile, 'rb') as f: | |
| 189 request = LogRequestLite.FromString(f.read()) | |
| 190 | |
| 191 self.assertEqual(len(request.log_event), 1) | |
| 192 event = ChromeInfraEvent.FromString(request.log_event[0].source_extension) | |
| 193 self.assertEqual(event.build_event.host_name, 'myhostname') | |
| 194 self.assertEqual(event.build_event.build_number, 3) | |
| 195 self.assertEqual(event.timestamp_kind, ChromeInfraEvent.BEGIN) | |
| 196 | |
| 197 def test_logrequest_path_build_type_override(self): | |
| 198 # logrequest contains build event, overrid the type with an arg. | |
| 199 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 200 outfile = os.path.join(tmpdir, 'out.bin') | |
| 201 args = send_event.get_arguments( | |
| 202 ['--event-mon-run-type', 'file', | |
| 203 '--event-mon-output-file', outfile, | |
| 204 '--event-mon-service-name', 'thing', | |
| 205 '--event-logrequest-path', | |
| 206 os.path.join(DATA_DIR, 'build-foo-builder.bin'), | |
| 207 '--build-event-build-number', '3', | |
| 208 '--build-event-type', 'STEP', | |
| 209 ]) | |
| 210 self.assertEquals(args.event_mon_run_type, 'file') | |
| 211 event_mon.process_argparse_options(args) | |
| 212 send_event._process_logrequest_path(args) | |
| 213 self.assertTrue(send_event.send_build_event(args)) | |
| 214 | |
| 215 # Now open the resulting file and check what was written | |
| 216 with open(outfile, 'rb') as f: | |
| 217 request = LogRequestLite.FromString(f.read()) | |
| 218 | |
| 219 self.assertEqual(len(request.log_event), 1) | |
| 220 event = ChromeInfraEvent.FromString(request.log_event[0].source_extension) | |
| 221 self.assertEqual(event.build_event.host_name, 'myhostname') | |
| 222 self.assertEqual(event.build_event.type, BuildEvent.STEP) | |
| 223 self.assertEqual(event.build_event.build_number, 3) | |
| 224 self.assertEqual(event.timestamp_kind, ChromeInfraEvent.BEGIN) | |
| 225 | |
| 226 def test_logrequest_path_build_service_conflicts(self): | |
| 227 # logrequest contains build event, provides service event as arg | |
| 228 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 229 outfile = os.path.join(tmpdir, 'out.bin') | |
| 230 args = send_event.get_arguments( | |
| 231 ['--event-mon-run-type', 'file', | |
| 232 '--event-mon-output-file', outfile, | |
| 233 '--event-mon-service-name', 'thing', | |
| 234 '--event-logrequest-path', | |
| 235 os.path.join(DATA_DIR, 'build-foo-builder.bin'), | |
| 236 '--build-event-build-number', '3', | |
| 237 '--service-event-type', 'START', | |
| 238 ]) | |
| 239 self.assertEquals(args.event_mon_run_type, 'file') | |
| 240 event_mon.process_argparse_options(args) | |
| 241 with self.assertRaises(ValueError): | |
| 242 send_event._process_logrequest_path(args) | |
| 243 | |
| 244 # The default event used below has been generated using: | |
| 245 # ./run.py infra.tools.send_monitoring_event | |
| 246 # --event-mon-run-type=file | |
| 247 # --event-mon-output-file=./service-bar-service.bin | |
| 248 # --service-event-type=START | |
| 249 # --event-mon-service-name=bar | |
| 250 # --event-mon-hostname=myhostname | |
| 251 # --event-mon-timestamp-kind=BEGIN | |
| 252 # --event-mon-event-timestamp=123 | |
| 253 def test_logrequest_path_valid_service_event(self): | |
| 254 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 255 outfile = os.path.join(tmpdir, 'out.bin') | |
| 256 args = send_event.get_arguments( | |
| 257 ['--event-mon-run-type', 'file', | |
| 258 '--event-mon-output-file', outfile, | |
| 259 '--event-mon-service-name', 'thing', | |
| 260 '--event-logrequest-path', | |
| 261 os.path.join(DATA_DIR, 'service-bar-service.bin'), | |
| 262 ]) | |
|
Sergey Berezin
2015/11/03 00:58:42
nit: the indent looks odd to me - I'd expect 2 spa
pgervais
2015/11/03 01:03:49
Done.
| |
| 263 self.assertEquals(args.event_mon_run_type, 'file') | |
| 264 event_mon.process_argparse_options(args) | |
| 265 send_event._process_logrequest_path(args) | |
| 266 self.assertTrue(send_event.send_service_event(args)) | |
| 267 | |
| 268 # Now open the resulting file and check what was written | |
| 269 with open(outfile, 'rb') as f: | |
| 270 request = LogRequestLite.FromString(f.read()) | |
| 271 | |
| 272 self.assertEqual(len(request.log_event), 1) | |
| 273 event = ChromeInfraEvent.FromString(request.log_event[0].source_extension) | |
| 274 self.assertEqual(event.event_source.host_name, 'myhostname') | |
| 275 self.assertEqual(event.service_event.type, ServiceEvent.START) | |
| 276 self.assertEqual(event.timestamp_kind, ChromeInfraEvent.BEGIN) | |
|
Sergey Berezin
2015/11/03 00:58:42
Another option is to use expectations:
return st
pgervais
2015/11/03 01:03:49
This test is already confusing because we don't kn
Sergey Berezin
2015/11/03 01:19:09
Hmm... Would it make more sense then to generate t
| |
| 277 | |
| 278 def test_logrequest_path_service_type_override(self): | |
| 279 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 280 outfile = os.path.join(tmpdir, 'out.bin') | |
| 281 args = send_event.get_arguments( | |
| 282 ['--event-mon-run-type', 'file', | |
| 283 '--event-mon-output-file', outfile, | |
| 284 '--event-mon-service-name', 'thing', | |
| 285 '--event-logrequest-path', | |
| 286 os.path.join(DATA_DIR, 'service-bar-service.bin'), | |
| 287 '--service-event-type', 'STOP', | |
| 288 ]) | |
| 289 self.assertEquals(args.event_mon_run_type, 'file') | |
| 290 event_mon.process_argparse_options(args) | |
| 291 send_event._process_logrequest_path(args) | |
| 292 self.assertTrue(send_event.send_service_event(args)) | |
| 293 | |
| 294 # Now open the resulting file and check what was written | |
| 295 with open(outfile, 'rb') as f: | |
| 296 request = LogRequestLite.FromString(f.read()) | |
| 297 | |
| 298 self.assertEqual(len(request.log_event), 1) | |
| 299 event = ChromeInfraEvent.FromString(request.log_event[0].source_extension) | |
| 300 self.assertEqual(event.event_source.host_name, 'myhostname') | |
| 301 self.assertEqual(event.service_event.type, ServiceEvent.STOP) | |
| 302 self.assertEqual(event.timestamp_kind, ChromeInfraEvent.END) | |
| 303 | |
| 304 def test_logrequest_path_service_build_conflict(self): | |
| 305 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 306 outfile = os.path.join(tmpdir, 'out.bin') | |
| 307 args = send_event.get_arguments( | |
| 308 ['--event-mon-run-type', 'file', | |
| 309 '--event-mon-output-file', outfile, | |
| 310 '--event-mon-service-name', 'thing', | |
| 311 '--event-logrequest-path', | |
| 312 os.path.join(DATA_DIR, 'service-bar-service.bin'), | |
| 313 '--build-event-type', 'BUILD', | |
| 314 ]) | |
| 315 self.assertEquals(args.event_mon_run_type, 'file') | |
| 316 event_mon.process_argparse_options(args) | |
| 317 with self.assertRaises(ValueError): | |
| 318 send_event._process_logrequest_path(args) | |
| 319 | |
| 320 def test_logrequest_path_service_build_and_service(self): | |
| 321 # the logrequest provided contains both a service and a build type, | |
|
Sergey Berezin
2015/11/03 00:58:42
nit: capitalize the first letter in a sentence.
pgervais
2015/11/03 01:03:49
Done.
| |
| 322 # which is invalid. | |
| 323 with infra_libs.temporary_directory(prefix='send_event_test-') as tmpdir: | |
| 324 outfile = os.path.join(tmpdir, 'out.bin') | |
| 325 args = send_event.get_arguments( | |
| 326 ['--event-mon-run-type', 'file', | |
| 327 '--event-mon-output-file', outfile, | |
| 328 '--event-mon-service-name', 'thing', | |
| 329 '--event-logrequest-path', | |
| 330 os.path.join(DATA_DIR, 'build-and-service-event.bin'), | |
| 331 ]) | |
| 332 self.assertEquals(args.event_mon_run_type, 'file') | |
| 333 event_mon.process_argparse_options(args) | |
| 334 with self.assertRaises(ValueError): | |
| 335 send_event._process_logrequest_path(args) | |
| 336 | |
| 337 | |
| 338 class TestEventsFromTextFile(SendingEventBaseTest): | |
| 96 def test_send_events_from_file_smoke(self): | 339 def test_send_events_from_file_smoke(self): |
| 97 # Create a temporary file because we don't want to risk deleting a | 340 # Create a temporary file because we don't want to risk deleting a |
| 98 # checked-in file. | 341 # checked-in file. |
| 99 with infra_libs.temporary_directory(prefix='send-events-test') as tempdir: | 342 with infra_libs.temporary_directory(prefix='send-events-test') as tempdir: |
| 100 event_file = os.path.join(tempdir, 'events.log') | 343 event_file = os.path.join(tempdir, 'events.log') |
| 101 with open(event_file, 'w') as f: | 344 with open(event_file, 'w') as f: |
| 102 f.write('{"build-event-type": "STEP", ' | 345 f.write('{"build-event-type": "STEP", ' |
| 103 '"build-event-build-name": "infra-continuous-precise-64", ' | 346 '"build-event-build-name": "infra-continuous-precise-64", ' |
| 104 '"event-mon-service-name": "buildbot/master/chromium.infra", ' | 347 '"event-mon-service-name": "buildbot/master/chromium.infra", ' |
| 105 '"build-event-step-number": 9, ' | 348 '"build-event-step-number": 9, ' |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 self.assertTrue(any(fname.endswith(filename) for filename in filenames)) | 451 self.assertTrue(any(fname.endswith(filename) for filename in filenames)) |
| 209 | 452 |
| 210 def test_one_wildcard_one_file(self): | 453 def test_one_wildcard_one_file(self): |
| 211 filenames = ('events.log', 'events-1.log', 'events-2.log') | 454 filenames = ('events.log', 'events-1.log', 'events-2.log') |
| 212 file_list = send_event.get_event_file_list( | 455 file_list = send_event.get_event_file_list( |
| 213 [os.path.join(self.FILES_DIR, 'events-?.log'), | 456 [os.path.join(self.FILES_DIR, 'events-?.log'), |
| 214 os.path.join(self.FILES_DIR, 'events.log')]) | 457 os.path.join(self.FILES_DIR, 'events.log')]) |
| 215 self.assertTrue(len(file_list) == 3) | 458 self.assertTrue(len(file_list) == 3) |
| 216 for fname in file_list: | 459 for fname in file_list: |
| 217 self.assertTrue(any(fname.endswith(filename) for filename in filenames)) | 460 self.assertTrue(any(fname.endswith(filename) for filename in filenames)) |
| 461 | |
| 462 | |
| 463 class TestProcessRequestPath(SendingEventBaseTest): | |
| 464 def test_logrequest_missing_args(self): | |
| 465 orig_event = event_mon.get_default_event() | |
| 466 self.assertIsNot(orig_event, None) | |
| 467 | |
| 468 args = argparse.Namespace() | |
| 469 args.event_logrequest_path = None | |
| 470 send_event._process_logrequest_path(args) | |
| 471 | |
| 472 self.assertEqual(orig_event, event_mon.get_default_event()) | |
| 473 | |
| 474 def test_logrequest_with_valid_file(self): | |
| 475 orig_event = event_mon.get_default_event() | |
| 476 self.assertIsNot(orig_event, None) | |
| 477 | |
| 478 args = argparse.Namespace() | |
| 479 args.event_logrequest_path = os.path.join(DATA_DIR, 'logrequest-build.bin') | |
| 480 args.service_event_type = None | |
| 481 args.build_event_type = None | |
| 482 send_event._process_logrequest_path(args) | |
| 483 | |
| 484 new_event = event_mon.get_default_event() | |
| 485 self.assertNotEqual(orig_event, new_event) | |
| 486 self.assertEqual(new_event.build_event.type, BuildEvent.BUILD) | |
| 487 | |
| 488 def test_logrequest_with_no_log_event(self): | |
| 489 orig_event = event_mon.get_default_event() | |
| 490 self.assertIsNot(orig_event, None) | |
| 491 | |
| 492 args = argparse.Namespace() | |
| 493 args.event_logrequest_path = os.path.join(DATA_DIR, 'logrequest-empty.bin') | |
| 494 with self.assertRaises(ValueError): | |
| 495 send_event._process_logrequest_path(args) | |
| 496 | |
| 497 def test_logrequest_with_bad_content(self): | |
| 498 orig_event = event_mon.get_default_event() | |
| 499 self.assertIsNot(orig_event, None) | |
| 500 | |
| 501 args = argparse.Namespace() | |
| 502 args.event_logrequest_path = os.path.join(DATA_DIR, 'garbage') | |
| 503 with self.assertRaises(google.protobuf.message.DecodeError): | |
| 504 send_event._process_logrequest_path(args) | |
| 505 | |
| 506 def test_logrequest_with_missing_file(self): | |
| 507 args = argparse.Namespace() | |
| 508 args.event_logrequest_path = os.path.join(DATA_DIR, 'non-existent-file.bin') | |
| 509 with self.assertRaises(IOError): | |
| 510 send_event._process_logrequest_path(args) | |
| OLD | NEW |