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

Side by Side 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: Just rebase. 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 unified diff | Download patch
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 import unittest
6
7 from common.diff import ChangeType
8 from waterfall import build_failure_analysis
9 from waterfall.failure_signal import FailureSignal
10
11
12 class BuildFailureAnalysisTest(unittest.TestCase):
13
14 def testIsSameFile(self):
15 self.assertTrue(build_failure_analysis._IsSameFile('a/b/x.cc', 'x.cc'))
16 self.assertTrue(build_failure_analysis._IsSameFile('a/b/x.cc', 'b/x.cc'))
17 self.assertTrue(build_failure_analysis._IsSameFile('a/b/x.cc', 'a/b/x.cc'))
18
19 self.assertFalse(
20 build_failure_analysis._IsSameFile('a/prefix_x.cc.', 'x.cc'))
21 self.assertFalse(
22 build_failure_analysis._IsSameFile('prefix_a/x.cc.', 'a/x.cc'))
23 self.assertFalse(
24 build_failure_analysis._IsSameFile('c/x.cc.', 'a/b/c/x.cc'))
25 self.assertFalse(build_failure_analysis._IsSameFile('a/x.cc.', 'a/y.cc'))
26
27 def testNormalizeObjectFile(self):
28 cases = {
29 'obj/a/T.x.o': 'a/x.o',
30 'obj/a/T.x.y.o': 'a/x.y.o',
31 'x.o': 'x.o'
32 }
33 for obj_file, expected_file in cases.iteritems():
34 self.assertEqual(
35 expected_file,
36 build_failure_analysis._NormalizeObjectFile(obj_file))
37
38 def testStripCommonSuffix(self):
39 cases = {
40 'a_file':
41 'a_file_%s.cc' % '_'.join(build_failure_analysis._COMMON_SUFFIXES),
42 'src/b_file': 'src/b_file_impl_mac.h',
43 'c_file': 'c_file_browsertest.cc',
44 'xdtest': 'xdtest.cc',
45 }
46 for expected_file, file_path in cases.iteritems():
47 self.assertEqual(
48 expected_file,
49 build_failure_analysis._StripExtensionAndCommonSuffix(file_path))
50
51 def testIsRelated(self):
52 self.assertTrue(build_failure_analysis._IsRelated('a.py', 'a_test.py'))
53 self.assertTrue(
54 build_failure_analysis._IsRelated('a.h', 'a_impl_test.o'))
55 self.assertTrue(
56 build_failure_analysis._IsRelated('a/b/x.cc', 'a/b/y.cc'))
57
58 self.assertFalse(
59 build_failure_analysis._IsRelated('a/x.cc', 'a/b/y.cc'))
60 self.assertFalse(
61 build_failure_analysis._IsRelated('a/x.cc', 'xdtest.cc'))
62
63 def testCheckFilesAgainstSuspectedCL(self):
64 failure_signal_json = {
65 'files': {
66 'src/a/b/f1.cc': [],
67 'b/c/f2.h': [10, 20],
68 'd/e/f3_test.cc': [],
69 'x/y/f4.py': [],
70 'f5_impl.cc': []
71 }
72 }
73 change_log_json = {
74 'touched_files': [
75 {
76 'change_type': ChangeType.ADD,
77 'old_path': '/dev/null',
78 'new_path': 'a/b/f1.cc'
79 },
80 {
81 'change_type': ChangeType.MODIFY,
82 'old_path': 'a/b/c/f2.h',
83 'new_path': 'a/b/c/f2.h'
84 },
85 {
86 'change_type': ChangeType.MODIFY,
87 'old_path': 'd/e/f3.h',
88 'new_path': 'd/e/f3.h'
89 },
90 {
91 'change_type': ChangeType.DELETE,
92 'old_path': 'x/y/f4.py',
93 'new_path': '/dev/null'
94 },
95 {
96 'change_type': ChangeType.DELETE,
97 'old_path': 'h/f5.h',
98 'new_path': '/dev/null'
99 },
100 {
101 'change_type': ChangeType.RENAME,
102 'old_path': 't/y/x.cc',
103 'new_path': 's/z/x.cc'
104 },
105 ]
106 }
107
108 justification = build_failure_analysis._CheckFiles(
109 FailureSignal.FromJson(failure_signal_json), change_log_json)
110 self.assertIsNotNone(justification)
111 self.assertEqual(2, justification['suspect_points'])
112 self.assertEqual(13, justification['score'])
113
114 def testCheckFilesAgainstUnrelatedCL(self):
115 failure_signal_json = {
116 'files': {
117 'src/a/b/f.cc': [],
118 }
119 }
120 change_log_json = {
121 'touched_files': [
122 {
123 'change_type': ChangeType.ADD,
124 'old_path': '/dev/null',
125 'new_path': 'a/d/f1.cc'
126 },
127 ]
128 }
129
130 justification = build_failure_analysis._CheckFiles(
131 FailureSignal.FromJson(failure_signal_json), change_log_json)
132 self.assertIsNone(justification)
133
134 def testAnalyzeSuccessfulBuild(self):
135 failure_info = {
136 'failed': False,
137 }
138 result = build_failure_analysis.AnalyzeBuildFailure(
139 failure_info, None, None)
140 self.assertEqual(0, len(result))
141
142 def testAnalyzeBuildFailure(self):
143 failure_info = {
144 'failed': True,
145 'failed_steps': {
146 'a': {
147 'current_failure': 99,
148 'first_failure': 98,
149 },
150 'b': {
151 'current_failure': 99,
152 'first_failure': 98,
153 },
154 },
155 'builds': {
156 '99': {
157 'blame_list': ['r99_1', 'r99_2'],
158 },
159 '98': {
160 'blame_list': ['r98_1'],
161 },
162 }
163 }
164 change_logs = {
165 'r99_1': {
166 'touched_files': [
167 {
168 'change_type': ChangeType.ADD,
169 'old_path': '/dev/null',
170 'new_path': 'x/y/f99_1.cc'
171 },
172 ],
173 },
174 'r99_2': {
175 'touched_files': [
176 {
177 'change_type': ChangeType.MODIFY,
178 'old_path': 'a/b/f99_2.cc',
179 'new_path': 'a/b/f99_2.cc'
180 },
181 ],
182 },
183 'r98_1': {
184 'touched_files': [
185 {
186 'change_type': ChangeType.MODIFY,
187 'old_path': 'y/z/f98.cc',
188 'new_path': 'y/z/f98.cc'
189 },
190 ],
191 },
192 }
193 failure_signals_json = {
194 'a': {
195 'files': {
196 'src/a/b/f99_2.cc': [],
197 },
198 },
199 'b': {
200 'files': {
201 'f.cc': [],
202 },
203 },
204 }
205 expected_analysis_result = {
206 'a': {
207 'r99_2': {
208 'suspect_points': 0,
209 'score': 1,
210 'hints': [
211 'modify a/b/f99_2.cc',
212 ]
213 },
214 },
215 }
216
217 analysis_result = build_failure_analysis.AnalyzeBuildFailure(
218 failure_info, change_logs, failure_signals_json)
219 self.assertEqual(expected_analysis_result, analysis_result)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698