|
1 # This Source Code Form is subject to the terms of the Mozilla Public |
|
2 # License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
|
4 |
|
5 from __future__ import print_function, unicode_literals |
|
6 |
|
7 import collections |
|
8 import json |
|
9 import os |
|
10 import sys |
|
11 |
|
12 import writeBuildFiles |
|
13 |
|
14 def extractLines(fp): |
|
15 lines = [] |
|
16 watch = False |
|
17 for line in fp: |
|
18 line = line.decode('utf-8') |
|
19 if line == '@@@ @@@ Failures\n': |
|
20 watch = True |
|
21 elif watch: |
|
22 watch = False |
|
23 idx = line.index('@@@') |
|
24 lines.append((line[:idx], line[idx + 3:])) |
|
25 return lines |
|
26 |
|
27 def ensuredir(path): |
|
28 dir = path[:path.rfind('/')] |
|
29 if not os.path.exists(dir): |
|
30 os.makedirs(dir) |
|
31 |
|
32 def dumpFailures(lines): |
|
33 files = [] |
|
34 for url, objstr in lines: |
|
35 if objstr == '{}\n': |
|
36 continue |
|
37 |
|
38 # Avoid overly large diffs. |
|
39 if 'editing/' in url: |
|
40 sep = ':' |
|
41 else: |
|
42 sep = ': ' |
|
43 |
|
44 jsonpath = 'failures/' + url + '.json' |
|
45 files.append(jsonpath) |
|
46 ensuredir(jsonpath) |
|
47 obj = json.loads(objstr, object_pairs_hook=collections.OrderedDict) |
|
48 formattedobjstr = json.dumps(obj, indent=2, separators=(',', sep)) + '\n' |
|
49 formattedobj = formattedobjstr.encode('utf-8') |
|
50 fp = open(jsonpath, 'wb') |
|
51 fp.write(formattedobj) |
|
52 fp.close() |
|
53 return files |
|
54 |
|
55 def writeFiles(files): |
|
56 pathmap = {} |
|
57 for path in files: |
|
58 dirp, leaf = path.rsplit('/', 1) |
|
59 pathmap.setdefault(dirp, []).append(leaf) |
|
60 |
|
61 for k, v in pathmap.items(): |
|
62 with open(k + '/mochitest.ini', 'w') as fh: |
|
63 result = writeBuildFiles.substManifest('parseFailures.py', v, []) |
|
64 fh.write(result) |
|
65 |
|
66 |
|
67 def main(logPath): |
|
68 fp = open(logPath, 'rb') |
|
69 lines = extractLines(fp) |
|
70 fp.close() |
|
71 |
|
72 files = dumpFailures(lines) |
|
73 writeFiles(files) |
|
74 |
|
75 if __name__ == '__main__': |
|
76 if len(sys.argv) < 2: |
|
77 print("Please pass the path to the logfile from which failures should be extracted.") |
|
78 main(sys.argv[1]) |
|
79 |