Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 datetime | 5 import datetime |
| 6 import json | 6 import json |
| 7 import os | 7 import os |
| 8 import urllib | 8 import urllib |
| 9 import zlib | 9 import zlib |
| 10 | 10 |
| 11 from common.http_client_appengine import HttpClientAppengine as HttpClient | 11 from common.http_client_appengine import HttpClientAppengine as HttpClient |
| 12 from common.pipeline_wrapper import pipeline_handlers | 12 from common.pipeline_wrapper import pipeline_handlers |
| 13 from common.waterfall import failure_type | 13 from common.waterfall import failure_type |
| 14 from model import analysis_status | 14 from model import analysis_status |
| 15 from model.wf_analysis import WfAnalysis | 15 from model.wf_analysis import WfAnalysis |
| 16 from model.wf_build import WfBuild | 16 from model.wf_build import WfBuild |
| 17 from model.wf_step import WfStep | 17 from model.wf_step import WfStep |
| 18 from waterfall import buildbot | 18 from waterfall import buildbot |
| 19 from waterfall import detect_first_failure_pipeline | |
| 19 from waterfall import lock_util | 20 from waterfall import lock_util |
| 20 from waterfall import swarming_util | 21 from waterfall import swarming_util |
| 21 from waterfall.build_info import BuildInfo | 22 from waterfall.build_info import BuildInfo |
| 22 from waterfall.detect_first_failure_pipeline import DetectFirstFailurePipeline | 23 from waterfall.detect_first_failure_pipeline import DetectFirstFailurePipeline |
| 23 from waterfall.test import wf_testcase | 24 from waterfall.test import wf_testcase |
| 24 | 25 |
| 25 | 26 |
| 26 class DetectFirstFailureTest(wf_testcase.WaterfallTestCase): | 27 class DetectFirstFailureTest(wf_testcase.WaterfallTestCase): |
| 27 app_module = pipeline_handlers._APP | 28 app_module = pipeline_handlers._APP |
| 28 | 29 |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 pipeline = DetectFirstFailurePipeline() | 304 pipeline = DetectFirstFailurePipeline() |
| 304 pipeline._InitiateTestLevelFirstFailureAndSaveLog( | 305 pipeline._InitiateTestLevelFirstFailureAndSaveLog( |
| 305 json_data, step, failed_step) | 306 json_data, step, failed_step) |
| 306 | 307 |
| 307 expected_failed_step = { | 308 expected_failed_step = { |
| 308 'current_failure': 223, | 309 'current_failure': 223, |
| 309 'first_failure': 221, | 310 'first_failure': 221, |
| 310 'tests': { | 311 'tests': { |
| 311 'Unittest2.Subtest1': { | 312 'Unittest2.Subtest1': { |
| 312 'current_failure': 223, | 313 'current_failure': 223, |
| 313 'first_failure': 223 | 314 'first_failure': 223, |
| 315 'base_test_name': 'Unittest2.Subtest1' | |
| 314 }, | 316 }, |
| 315 'Unittest3.Subtest2': { | 317 'Unittest3.Subtest2': { |
| 316 'current_failure': 223, | 318 'current_failure': 223, |
| 317 'first_failure': 223, | 319 'first_failure': 223, |
| 320 'base_test_name': 'Unittest3.Subtest2' | |
| 318 } | 321 } |
| 319 } | 322 } |
| 320 } | 323 } |
| 321 | 324 |
| 322 self.assertEqual(expected_failed_step, failed_step) | 325 self.assertEqual(expected_failed_step, failed_step) |
| 323 | 326 |
| 324 def testCheckFirstKnownFailureForSwarmingTestsFoundFlaky(self): | 327 def testCheckFirstKnownFailureForSwarmingTestsFoundFlaky(self): |
| 325 master_name = 'm' | 328 master_name = 'm' |
| 326 builder_name = 'b' | 329 builder_name = 'b' |
| 327 build_number = 221 | 330 build_number = 221 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 builder_name = 'b' | 386 builder_name = 'b' |
| 384 build_number = 223 | 387 build_number = 223 |
| 385 step_name = 'abc_test' | 388 step_name = 'abc_test' |
| 386 failed_step = { | 389 failed_step = { |
| 387 'current_failure': 223, | 390 'current_failure': 223, |
| 388 'first_failure': 221, | 391 'first_failure': 221, |
| 389 'tests': { | 392 'tests': { |
| 390 'Unittest2.Subtest1': { | 393 'Unittest2.Subtest1': { |
| 391 'current_failure': 223, | 394 'current_failure': 223, |
| 392 'first_failure': 223, | 395 'first_failure': 223, |
| 393 'last_pass': 223 | 396 'last_pass': 223, |
| 397 'base_test_name': 'Unittest2.Subtest1' | |
| 394 }, | 398 }, |
| 395 'Unittest3.Subtest2': { | 399 'Unittest3.Subtest2': { |
| 396 'current_failure': 223, | 400 'current_failure': 223, |
| 397 'first_failure': 223 | 401 'first_failure': 223, |
| 402 'base_test_name': 'Unittest3.Subtest2' | |
| 398 } | 403 } |
| 399 } | 404 } |
| 400 } | 405 } |
| 401 | 406 |
| 402 for n in xrange(222, 220, -1): | 407 for n in xrange(222, 220, -1): |
| 403 # Mock retrieving data from swarming server for a single step. | 408 # Mock retrieving data from swarming server for a single step. |
| 404 self._MockUrlFetchWithSwarmingData( | 409 self._MockUrlFetchWithSwarmingData( |
| 405 master_name, builder_name, n, 'abc_test') | 410 master_name, builder_name, n, 'abc_test') |
| 406 | 411 |
| 407 # Mock retrieving hash to output.json from isolated server. | 412 # Mock retrieving hash to output.json from isolated server. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 437 master_name, builder_name, build_number, step_name, failed_step, | 442 master_name, builder_name, build_number, step_name, failed_step, |
| 438 HttpClient()) | 443 HttpClient()) |
| 439 | 444 |
| 440 expected_failed_step = { | 445 expected_failed_step = { |
| 441 'current_failure': 223, | 446 'current_failure': 223, |
| 442 'first_failure': 221, | 447 'first_failure': 221, |
| 443 'tests': { | 448 'tests': { |
| 444 'Unittest2.Subtest1': { | 449 'Unittest2.Subtest1': { |
| 445 'current_failure': 223, | 450 'current_failure': 223, |
| 446 'first_failure': 222, | 451 'first_failure': 222, |
| 447 'last_pass': 221 | 452 'last_pass': 221, |
| 453 'base_test_name': 'Unittest2.Subtest1' | |
| 448 }, | 454 }, |
| 449 'Unittest3.Subtest2': { | 455 'Unittest3.Subtest2': { |
| 450 'current_failure': 223, | 456 'current_failure': 223, |
| 451 'first_failure': 221 | 457 'first_failure': 221, |
| 458 'base_test_name': 'Unittest3.Subtest2' | |
| 452 } | 459 } |
| 453 } | 460 } |
| 454 } | 461 } |
| 455 self.assertEqual(expected_failed_step, failed_step) | 462 self.assertEqual(expected_failed_step, failed_step) |
| 456 | 463 |
| 457 def testUpdateFirstFailureOnTestLevelFlaky(self): | 464 def testUpdateFirstFailureOnTestLevelFlaky(self): |
| 458 master_name = 'm' | 465 master_name = 'm' |
| 459 builder_name = 'b' | 466 builder_name = 'b' |
| 460 build_number = 223 | 467 build_number = 223 |
| 461 step_name = 'abc_test' | 468 step_name = 'abc_test' |
| 462 failed_step = { | 469 failed_step = { |
| 463 'current_failure': 223, | 470 'current_failure': 223, |
| 464 'first_failure': 221, | 471 'first_failure': 221, |
| 465 'tests': { | 472 'tests': { |
| 466 'Unittest2.Subtest1': { | 473 'Unittest2.Subtest1': { |
| 467 'current_failure': 223, | 474 'current_failure': 223, |
| 468 'first_failure': 223, | 475 'first_failure': 223, |
| 469 'last_pass': 223 | 476 'last_pass': 223, |
| 477 'base_test_name': 'Unittest2.Subtest1' | |
| 470 } | 478 } |
| 471 } | 479 } |
| 472 } | 480 } |
| 473 step = WfStep.Create(master_name, builder_name, 222, step_name) | 481 step = WfStep.Create(master_name, builder_name, 222, step_name) |
| 474 step.isolated = True | 482 step.isolated = True |
| 475 step.log_data = 'flaky' | 483 step.log_data = 'flaky' |
| 476 step.put() | 484 step.put() |
| 477 | 485 |
| 478 pipeline = DetectFirstFailurePipeline() | 486 pipeline = DetectFirstFailurePipeline() |
| 479 pipeline._UpdateFirstFailureOnTestLevel( | 487 pipeline._UpdateFirstFailureOnTestLevel( |
| 480 master_name, builder_name, build_number, step_name, failed_step, | 488 master_name, builder_name, build_number, step_name, failed_step, |
| 481 HttpClient()) | 489 HttpClient()) |
| 482 | 490 |
| 483 expected_failed_step = { | 491 expected_failed_step = { |
| 484 'current_failure': 223, | 492 'current_failure': 223, |
| 485 'first_failure': 223, | 493 'first_failure': 223, |
| 486 'last_pass': 222, | 494 'last_pass': 222, |
| 487 'tests': { | 495 'tests': { |
| 488 'Unittest2.Subtest1': { | 496 'Unittest2.Subtest1': { |
| 489 'current_failure': 223, | 497 'current_failure': 223, |
| 490 'first_failure': 223, | 498 'first_failure': 223, |
| 491 'last_pass': 222 | 499 'last_pass': 222, |
| 500 'base_test_name': 'Unittest2.Subtest1' | |
| 492 } | 501 } |
| 493 } | 502 } |
| 494 } | 503 } |
| 495 self.assertEqual(expected_failed_step, failed_step) | 504 self.assertEqual(expected_failed_step, failed_step) |
| 496 | 505 |
| 497 def testUpdateFailureInfoBuildsUpdateBuilds(self): | 506 def testUpdateFailureInfoBuildsUpdateBuilds(self): |
| 498 failed_steps = { | 507 failed_steps = { |
| 499 'compile': { | 508 'compile': { |
| 500 'current_failure': 223, | 509 'current_failure': 223, |
| 501 'first_failure': 222, | 510 'first_failure': 222, |
| 502 'last_pass': 221 | 511 'last_pass': 221 |
| 503 }, | 512 }, |
| 504 'abc_test': { | 513 'abc_test': { |
| 505 'current_failure': 223, | 514 'current_failure': 223, |
| 506 'first_failure': 222, | 515 'first_failure': 222, |
| 507 'last_pass': 221, | 516 'last_pass': 221, |
| 508 'list_isolated_data': [ | 517 'list_isolated_data': [ |
| 509 { | 518 { |
| 510 'isolatedserver': 'https://isolateserver.appspot.com', | 519 'isolatedserver': 'https://isolateserver.appspot.com', |
| 511 'namespace': 'default-gzip', | 520 'namespace': 'default-gzip', |
| 512 'digest': 'isolatedhashabctest-223' | 521 'digest': 'isolatedhashabctest-223' |
| 513 } | 522 } |
| 514 ], | 523 ], |
| 515 'tests': { | 524 'tests': { |
| 516 'Unittest2.Subtest1': { | 525 'Unittest2.Subtest1': { |
| 517 'current_failure': 223, | 526 'current_failure': 223, |
| 518 'first_failure': 222, | 527 'first_failure': 222, |
| 519 'last_pass': 221 | 528 'last_pass': 221, |
| 529 'base_test_name': 'Unittest2.Subtest1' | |
| 520 }, | 530 }, |
| 521 'Unittest3.Subtest2': { | 531 'Unittest3.Subtest2': { |
| 522 'current_failure': 223, | 532 'current_failure': 223, |
| 523 'first_failure': 222, | 533 'first_failure': 222, |
| 524 'last_pass': 221 | 534 'last_pass': 221, |
| 535 'base_test_name': 'Unittest3.Subtest2' | |
| 525 } | 536 } |
| 526 } | 537 } |
| 527 } | 538 } |
| 528 } | 539 } |
| 529 | 540 |
| 530 builds = { | 541 builds = { |
| 531 '220': { | 542 '220': { |
| 532 'blame_list': ['commit0'], | 543 'blame_list': ['commit0'], |
| 533 'chromium_revision': 'commit0' | 544 'chromium_revision': 'commit0' |
| 534 }, | 545 }, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 629 { | 640 { |
| 630 'isolatedserver': 'https://isolateserver.appspot.com', | 641 'isolatedserver': 'https://isolateserver.appspot.com', |
| 631 'namespace': 'default-gzip', | 642 'namespace': 'default-gzip', |
| 632 'digest': 'isolatedhashabctest-223' | 643 'digest': 'isolatedhashabctest-223' |
| 633 } | 644 } |
| 634 ], | 645 ], |
| 635 'tests': { | 646 'tests': { |
| 636 'Unittest2.Subtest1': { | 647 'Unittest2.Subtest1': { |
| 637 'current_failure': 223, | 648 'current_failure': 223, |
| 638 'first_failure': 222, | 649 'first_failure': 222, |
| 639 'last_pass': 221 | 650 'last_pass': 221, |
| 651 'base_test_name': 'Unittest2.Subtest1' | |
| 640 }, | 652 }, |
| 641 'Unittest3.Subtest2': { | 653 'Unittest3.Subtest2': { |
| 642 'current_failure': 223, | 654 'current_failure': 223, |
| 643 'first_failure': 222, | 655 'first_failure': 222, |
| 644 'last_pass': 221 | 656 'last_pass': 221, |
| 657 'base_test_name': 'Unittest3.Subtest2' | |
| 645 } | 658 } |
| 646 } | 659 } |
| 647 } | 660 } |
| 648 } | 661 } |
| 649 | 662 |
| 650 expected_step_log_data = { | 663 expected_step_log_data = { |
| 651 223: ('{"Unittest2.Subtest1": "RVJST1I6eF90ZXN0LmNjOjEyMzRcbmEvYi91Mn' | 664 223: ('{"Unittest2.Subtest1": "RVJST1I6eF90ZXN0LmNjOjEyMzRcbmEvYi91Mn' |
| 652 'MxLmNjOjU2NzogRmFpbHVyZVxuRVJST1I6WzJdOiAyNTk0NzM1MDAwIGJvZ28tb' | 665 'MxLmNjOjU2NzogRmFpbHVyZVxuRVJST1I6WzJdOiAyNTk0NzM1MDAwIGJvZ28tb' |
| 653 'Wljcm9zZWNvbmRzXG5FUlJPUjp4X3Rlc3QuY2M6MTIzNAphL2IvdTJzMS5jYzo1' | 666 'Wljcm9zZWNvbmRzXG5FUlJPUjp4X3Rlc3QuY2M6MTIzNAphL2IvdTJzMS5jYzo1' |
| 654 'Njc6IEZhaWx1cmUK", ' | 667 'Njc6IEZhaWx1cmUK", ' |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 715 cases = { | 728 cases = { |
| 716 failure_type.UNKNOWN: [], | 729 failure_type.UNKNOWN: [], |
| 717 failure_type.COMPILE: ['compile', 'slave_steps'], | 730 failure_type.COMPILE: ['compile', 'slave_steps'], |
| 718 failure_type.TEST: ['browser_tests'], | 731 failure_type.TEST: ['browser_tests'], |
| 719 } | 732 } |
| 720 for expected_type, failed_steps in cases.iteritems(): | 733 for expected_type, failed_steps in cases.iteritems(): |
| 721 build_info = BuildInfo('m', 'b', 123) | 734 build_info = BuildInfo('m', 'b', 123) |
| 722 build_info.failed_steps = failed_steps | 735 build_info.failed_steps = failed_steps |
| 723 self.assertEqual( | 736 self.assertEqual( |
| 724 expected_type, DetectFirstFailurePipeline._GetFailureType(build_info)) | 737 expected_type, DetectFirstFailurePipeline._GetFailureType(build_info)) |
| 738 | |
| 739 def testRemoveAnyPrefixes(self): | |
| 740 test_samples = ['test1', 'PRE_t', 'TestSuite1.Test1', | |
| 741 'TestSuite1.PRE_Test1', 'TestSuite1.PRE_PRE_Test1', | |
| 742 'PRE_TestSuite1.Test1'] | |
| 743 expected_base_tests = ['test1', 'PRE_t', 'TestSuite1.Test1', | |
|
stgao
2016/07/12 17:47:50
How about a map from original test to base test?
chanli
2016/07/12 20:04:52
Done.
| |
| 744 'TestSuite1.Test1', 'TestSuite1.Test1', | |
| 745 'PRE_TestSuite1.Test1'] | |
| 746 | |
| 747 base_tests = [detect_first_failure_pipeline._RemoveAnyPrefixes(test) | |
| 748 for test in test_samples] | |
| 749 print base_tests | |
| 750 self.assertEqual(base_tests, expected_base_tests) | |
| OLD | NEW |