Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1020)

Unified Diff: appengine/findit/waterfall/test/build_failure_analysis_test.py

Issue 838003004: [Findit] Add three sub-pipelines to analyze build failure. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: . Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: appengine/findit/waterfall/test/build_failure_analysis_test.py
diff --git a/appengine/findit/waterfall/test/build_failure_analysis_test.py b/appengine/findit/waterfall/test/build_failure_analysis_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..392b1a910b23c52f6c609134e4acb9f26bb0a151
--- /dev/null
+++ b/appengine/findit/waterfall/test/build_failure_analysis_test.py
@@ -0,0 +1,209 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import unittest
+
+from common.diff import ChangeType
+from waterfall import build_failure_analysis
+from waterfall.failure_signal import FailureSignal
+
+
+class BuildFailureAnalysisTest(unittest.TestCase):
+
+ def testIsSameFile(self):
+ self.assertTrue(build_failure_analysis.IsSameFile('a/b/x.cc', 'x.cc'))
+ self.assertFalse(build_failure_analysis.IsSameFile('a/b/pre_x.cc.', 'x.cc'))
+ self.assertFalse(build_failure_analysis.IsSameFile('a/b/x.cc.', 'a/b/y.cc'))
+
+ def testJoinAsFilePath(self):
+ self.assertEqual('a/x.cc',
+ build_failure_analysis.JoinAsFilePath('a', 'x.cc'))
+ self.assertEqual('x.cc',
+ build_failure_analysis.JoinAsFilePath(None, 'x.cc'))
+
+ def testNormalizeObjectFile(self):
+ cases = {
+ 'obj/a/T.x.o': 'a/x.o',
+ 'obj/a/T.x.y.o': 'a/x.y.o',
+ 'x.o': 'x.o'
+ }
+ for obj_file, expected_file in cases.iteritems():
+ self.assertEqual(
+ expected_file,
+ build_failure_analysis.NormalizeObjectFile(obj_file))
+
+ def testStripCommonPostfix(self):
+ cases = {
+ 'a_file':
+ 'a_file_%s.cc' % '_'.join(build_failure_analysis.COMMON_POSTFIXES),
+ 'src/b_file': 'src/b_file_impl_mac.h',
+ 'c_file': 'c_file_browsertest.cc'
+ }
+ for expected_file, file_path in cases.iteritems():
+ self.assertEqual(
+ expected_file,
+ build_failure_analysis.StripExtensionAndCommonPostfix(file_path))
+
+ def testIsCorrelated(self):
+ self.assertTrue(build_failure_analysis.IsCorrelated('a.h', 'a_test.py'))
+ self.assertTrue(build_failure_analysis.IsCorrelated('a.h', 'a_impl_test.o'))
+ self.assertTrue(build_failure_analysis.IsCorrelated('a/b/x.cc', 'a/b/y.cc'))
qyearsley 2015/01/15 21:15:03 Maybe add a negative case -- when is IsCorrelated
stgao 2015/01/16 20:21:39 Negative case added. If a CL changed file a.h, an
+
+ def testCheckFilesAgainstSuspectedCL(self):
+ failure_signal_json = {
+ 'files': {
+ 'src/a/b/f1.cc': [],
+ 'b/c/f2.h': [10, 20],
+ 'd/e/f3_test.cc': [],
+ 'x/y/f4.py': [],
+ 'f5_impl.cc': []
+ }
+ }
+ change_log_json = {
+ 'touched_files': [
+ {
+ 'change_type': ChangeType.ADD,
+ 'old_path': '/dev/null',
+ 'new_path': 'a/b/f1.cc'
+ },
+ {
+ 'change_type': ChangeType.MODIFY,
+ 'old_path': 'a/b/c/f2.h',
+ 'new_path': 'a/b/c/f2.h'
+ },
+ {
+ 'change_type': ChangeType.MODIFY,
+ 'old_path': 'd/e/f3.h',
+ 'new_path': 'd/e/f3.h'
+ },
+ {
+ 'change_type': ChangeType.DELETE,
+ 'old_path': 'x/y/f4.py',
+ 'new_path': '/dev/null'
+ },
+ {
+ 'change_type': ChangeType.DELETE,
+ 'old_path': 'h/f5.h',
+ 'new_path': '/dev/null'
+ },
+ {
+ 'change_type': ChangeType.RENAME,
+ 'old_path': 't/y/x.cc',
+ 'new_path': 's/z/x.cc'
+ },
+ ]
+ }
+
+ justification = build_failure_analysis.CheckFiles(
+ FailureSignal.FromJson(failure_signal_json), change_log_json)
+ self.assertIsNotNone(justification)
+ self.assertEqual(2, justification['suspects'])
+ self.assertEqual(13, justification['scores'])
+
+ def testCheckFilesAgainstUnrelatedCL(self):
+ failure_signal_json = {
+ 'files': {
+ 'src/a/b/f.cc': [],
+ }
+ }
+ change_log_json = {
+ 'touched_files': [
+ {
+ 'change_type': ChangeType.ADD,
+ 'old_path': '/dev/null',
+ 'new_path': 'a/d/f1.cc'
+ },
+ ]
+ }
+
+ justification = build_failure_analysis.CheckFiles(
+ FailureSignal.FromJson(failure_signal_json), change_log_json)
+ self.assertIsNone(justification)
+
+ def testAnalyzeSuccesfulBuild(self):
+ failure_info = {
+ 'failed': False,
+ }
+ result = build_failure_analysis.AnalyzeBuildFailure(
+ failure_info, None, None)
+ self.assertEqual(0, len(result))
+
+ def testAnalyzeBuildFailure(self):
+ failure_info = {
+ 'failed': True,
+ 'failed_steps': {
+ 'a': {
+ 'current_failure': 99,
+ 'first_failure': 98,
+ },
+ 'b': {
+ 'current_failure': 99,
+ 'first_failure': 98,
+ },
+ },
+ 'builds': {
+ '99': {
+ 'blame_list': ['r99_1', 'r99_2'],
+ },
+ '98': {
+ 'blame_list': ['r98_1'],
+ },
+ }
+ }
+ change_logs = {
+ 'r99_1': {
+ 'touched_files': [
+ {
+ 'change_type': ChangeType.ADD,
+ 'old_path': '/dev/null',
+ 'new_path': 'x/y/f99_1.cc'
+ },
+ ],
+ },
+ 'r99_2': {
+ 'touched_files': [
+ {
+ 'change_type': ChangeType.MODIFY,
+ 'old_path': 'a/b/f99_2.cc',
+ 'new_path': 'a/b/f99_2.cc'
+ },
+ ],
+ },
+ 'r98_1': {
+ 'touched_files': [
+ {
+ 'change_type': ChangeType.MODIFY,
+ 'old_path': 'y/z/f98.cc',
+ 'new_path': 'y/z/f98.cc'
+ },
+ ],
+ },
+ }
+ failure_signals_json = {
+ 'a': {
+ 'files': {
+ 'src/a/b/f99_2.cc': [],
+ },
+ },
+ 'b': {
+ 'files': {
+ 'f.cc': [],
+ },
+ },
+ }
+ expected_analysis_result = {
+ 'a': {
+ 'r99_2': {
+ 'suspects': 0,
+ 'scores': 1,
+ 'hints': [
+ 'modify a/b/f99_2.cc',
+ ]
+ },
+ },
+ }
+
+ analysis_result = build_failure_analysis.AnalyzeBuildFailure(
+ failure_info, change_logs, failure_signals_json)
+ self.assertEqual(expected_analysis_result, analysis_result)

Powered by Google App Engine
This is Rietveld 408576698