OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/python | |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 """A Module for the history of the test expectation file.""" | |
7 | |
8 import re | |
9 import time | |
10 import pysvn | |
11 | |
12 from datetime import datetime | |
13 from datetime import timedelta | |
14 | |
15 # Default Webkit SVN location for chromium test expectation file. | |
16 # TODO(imasaki): support multiple test expectation files. | |
17 DEFAULT_TEST_EXPECTATION_LOCATION = ( | |
18 'http://svn.webkit.org/repository/webkit/trunk/' | |
19 'LayoutTests/platform/chromium/test_expectations.txt') | |
20 | |
21 | |
22 class TestExpectationsHistory: | |
23 """A class to represent history of the test expectation file. | |
24 | |
25 The history is obtained by calling PySVN.log()/diff() APIs. | |
26 | |
27 TODO(imasaki): Add more functionalities here like getting some statistics | |
28 about the test expectation file. | |
29 """ | |
30 | |
31 @staticmethod | |
32 def GetDiffBetweenTimes(start, end, testname_list, | |
33 te_location=DEFAULT_TEST_EXPECTATION_LOCATION): | |
34 """Get difference between time period for the specified test names. | |
35 | |
36 Given the time period, this method first gets the revision number. Then, | |
37 it gets the diff for each revision. Finally, it keeps the diff relating to | |
38 the test names and returns them along with other information about | |
39 revision. | |
40 | |
41 Args: | |
42 start: A timestamp specifying start of the time period to be | |
43 looked at. | |
44 end: A timestamp object specifying end of the time period to be | |
45 looked at. | |
46 testname_list: A list of strings representing test names of interest. | |
47 te_location: A location of the test expectation file. | |
48 | |
49 Returns: | |
50 A list of tuples (old_rev, new_rev, author, date, message, lines). The | |
51 |lines| contains the diff of the tests of interest. | |
52 """ | |
53 # Get directory name which is necesary to call PySVN.checkout(). | |
54 te_location_dir = te_location[0:te_location.rindex('/')] | |
55 client = pysvn.Client() | |
56 client.checkout(te_location_dir, 'tmp', recurse=False) | |
57 logs = client.log('tmp/test_expectations.txt', | |
58 revision_start=pysvn.Revision( | |
59 pysvn.opt_revision_kind.date, start), | |
60 revision_end=pysvn.Revision( | |
61 pysvn.opt_revision_kind.date, end)) | |
62 result_list = [] | |
63 # Find the last revision outside of time period and | |
64 # append it to preserve the last change before entering the time period. | |
65 # This is 1 day back as |start2| (called start2) from original |start|. | |
66 # The reason for using 1 day back is that there should be at least one | |
67 # revision during the 1 day period and so that at least 1 revision is | |
68 # obtained. | |
dennis_jeffrey
2011/08/26 19:01:26
Will anything bad happen if at least 1 revision do
imasaki1
2011/08/26 22:28:44
Modified the code to handle this case.
| |
69 start2 = time.mktime( | |
70 (datetime.fromtimestamp(start) - timedelta(days=1)).timetuple()) | |
71 logs2 = client.log('tmp/test_expectations.txt', | |
72 revision_start=pysvn.Revision( | |
73 pysvn.opt_revision_kind.date, start2), | |
74 revision_end=pysvn.Revision( | |
75 pysvn.opt_revision_kind.date, start)) | |
76 if logs2: | |
77 logs.append(logs2[len(logs2) - 2]) | |
78 for i in xrange(len(logs) - 1): | |
79 # PySVN.log() returns logs in reverse chronological order. | |
80 new_rev = logs[i].revision.number | |
81 old_rev = logs[i + 1].revision.number | |
82 # Parsing the actual diff. | |
83 text = client.diff('/tmp', 'tmp/test_expectations.txt', | |
84 revision1=pysvn.Revision( | |
85 pysvn.opt_revision_kind.number, old_rev), | |
86 revision2=pysvn.Revision( | |
87 pysvn.opt_revision_kind.number, new_rev)) | |
88 lines = text.split('\n') | |
89 target_lines = [] | |
90 for line in lines: | |
91 for testname in testname_list: | |
92 matches = re.findall(testname, line) | |
93 if matches: | |
94 if line[0] == '+' or line[0] == '-': | |
95 target_lines.append(line) | |
96 if target_lines: | |
97 # Needs to convert to normal date string for presentation. | |
98 result_list.append(( | |
99 old_rev, new_rev, logs[i].author, | |
100 datetime.fromtimestamp(logs[i].date).strftime('%Y-%m-%d %H:%M:%S'), | |
101 logs[i].message, target_lines)) | |
102 return result_list | |
OLD | NEW |