Merge lp:~mandel/ubuntuone-client/fix-fsm into lp:ubuntuone-client
- fix-fsm
- Merge into trunk
Proposed by
Manuel de la Peña
Status: | Merged |
---|---|
Approved by: | Alejandro J. Cura |
Approved revision: | 1116 |
Merged at revision: | 1079 |
Proposed branch: | lp:~mandel/ubuntuone-client/fix-fsm |
Merge into: | lp:ubuntuone-client |
Prerequisite: | lp:~mandel/ubuntuone-client/fix-rm-path |
Diff against target: |
640 lines (+481/-51) 2 files modified
tests/platform/windows/test_filesystem_notifications.py (+436/-1) ubuntuone/platform/windows/filesystem_notifications.py (+45/-50) |
To merge this branch: | bzr merge lp:~mandel/ubuntuone-client/fix-fsm |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alejandro J. Cura (community) | Approve | ||
Natalia Bidart (community) | Approve | ||
Review via email: mp+69814@code.launchpad.net |
Commit message
Improve the test coverage for fsm on windows.
Description of the change
Improve the test coverage for fsm on windows.
To post a comment you must log in.
- 1114. By Manuel de la Peña
-
Merged with trunk.
- 1115. By Manuel de la Peña
-
Fixed according to the comments from the reviews.
Revision history for this message
Natalia Bidart (nataliabidart) wrote : | # |
Failing tests will be solved in a incoming branch.
review:
Approve
- 1116. By Manuel de la Peña
-
Merged with trunk and ensured that the criss-cross does not brake a thing.
Revision history for this message
Alejandro J. Cura (alecu) wrote : | # |
Launchpad above complains about conflicts, and bzr complains about criss-cross.
I've just verified with bzr merge and bzr merge --weave, and the results are the same, so the base branch may be off, but the resulting merge is fine.
So I'm approving. Great branch!
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'tests/platform/windows/test_filesystem_notifications.py' | |||
2 | --- tests/platform/windows/test_filesystem_notifications.py 2011-07-29 13:32:31 +0000 | |||
3 | +++ tests/platform/windows/test_filesystem_notifications.py 2011-07-29 17:34:51 +0000 | |||
4 | @@ -21,13 +21,19 @@ | |||
5 | 21 | import tempfile | 21 | import tempfile |
6 | 22 | import thread | 22 | import thread |
7 | 23 | import time | 23 | import time |
8 | 24 | import itertools | ||
9 | 24 | 25 | ||
10 | 25 | from twisted.internet import defer | 26 | from twisted.internet import defer |
11 | 26 | 27 | ||
12 | 27 | from contrib.testing.testcase import BaseTwistedTestCase | 28 | from contrib.testing.testcase import BaseTwistedTestCase |
13 | 28 | from ubuntuone.platform.windows import os_helper | 29 | from ubuntuone.platform.windows import os_helper |
15 | 29 | from ubuntuone.platform.windows.pyinotify import ProcessEvent | 30 | from ubuntuone.platform.windows.pyinotify import ( |
16 | 31 | ProcessEvent, | ||
17 | 32 | IN_OPEN, | ||
18 | 33 | IN_CLOSE_WRITE | ||
19 | 34 | ) | ||
20 | 30 | from ubuntuone.platform.windows.filesystem_notifications import ( | 35 | from ubuntuone.platform.windows.filesystem_notifications import ( |
21 | 36 | NotifyProcessor, | ||
22 | 31 | Watch, | 37 | Watch, |
23 | 32 | WatchManager, | 38 | WatchManager, |
24 | 33 | FILE_NOTIFY_CHANGE_FILE_NAME, | 39 | FILE_NOTIFY_CHANGE_FILE_NAME, |
25 | @@ -699,3 +705,432 @@ | |||
26 | 699 | # assert that other events are not ignored | 705 | # assert that other events are not ignored |
27 | 700 | self.watch._process_events([(1, 'test')]) | 706 | self.watch._process_events([(1, 'test')]) |
28 | 701 | self.assertEqual(1, len(events)) | 707 | self.assertEqual(1, len(events)) |
29 | 708 | |||
30 | 709 | |||
31 | 710 | class FakeEvent(object): | ||
32 | 711 | """Fake event.""" | ||
33 | 712 | |||
34 | 713 | def __init__(self, wd=0, dir=True, name=None, path=None, pathname=None, | ||
35 | 714 | cookie=None): | ||
36 | 715 | """Create fake event.""" | ||
37 | 716 | self.dir = dir | ||
38 | 717 | self.wd = wd | ||
39 | 718 | self.name = name | ||
40 | 719 | self.path = path | ||
41 | 720 | self.pathname = pathname | ||
42 | 721 | self.cookie = cookie | ||
43 | 722 | |||
44 | 723 | |||
45 | 724 | class FakeLog(object): | ||
46 | 725 | """A fake log that is used by the general processor.""" | ||
47 | 726 | |||
48 | 727 | def __init__(self): | ||
49 | 728 | """Create the fake.""" | ||
50 | 729 | self.called_methods = [] | ||
51 | 730 | |||
52 | 731 | def info(self, *args): | ||
53 | 732 | """Fake the info call.""" | ||
54 | 733 | self.called_methods.append(('info', args)) | ||
55 | 734 | |||
56 | 735 | |||
57 | 736 | class FakeGeneralProcessor(object): | ||
58 | 737 | """Fake implementation of the general processor.""" | ||
59 | 738 | |||
60 | 739 | def __init__(self): | ||
61 | 740 | """Create the fake.""" | ||
62 | 741 | self.called_methods = [] | ||
63 | 742 | self.paths_to_return = [] | ||
64 | 743 | self.log = FakeLog() | ||
65 | 744 | self.share_id = None | ||
66 | 745 | self.ignore = False | ||
67 | 746 | |||
68 | 747 | def rm_from_mute_filter(self, event, paths): | ||
69 | 748 | """Fake rm_from_mute_filter.""" | ||
70 | 749 | self.called_methods.append(('rm_from_mute_filter', event, paths)) | ||
71 | 750 | |||
72 | 751 | def add_to_mute_filter(self, event, paths): | ||
73 | 752 | """Fake add_to_move_filter.""" | ||
74 | 753 | self.called_methods.append(('add_to_mute_filter', event, paths)) | ||
75 | 754 | |||
76 | 755 | def is_ignored(self, path): | ||
77 | 756 | """Fake is_ignored.""" | ||
78 | 757 | self.called_methods.append(('is_ignored', path)) | ||
79 | 758 | return self.ignore | ||
80 | 759 | |||
81 | 760 | def push_event(self, event): | ||
82 | 761 | """Fake push event.""" | ||
83 | 762 | self.called_methods.append(('push_event', event)) | ||
84 | 763 | |||
85 | 764 | def eq_push(self, event, path=None, path_to=None, path_from=None): | ||
86 | 765 | """Fake event to push event.""" | ||
87 | 766 | self.called_methods.append(('eq_push', event, path, path_to, | ||
88 | 767 | path_from)) | ||
89 | 768 | |||
90 | 769 | def get_paths_starting_with(self, fullpath, include_base=False): | ||
91 | 770 | """Fake get_paths_starting_with.""" | ||
92 | 771 | self.called_methods.append(('get_paths_starting_with', fullpath, | ||
93 | 772 | include_base)) | ||
94 | 773 | return self.paths_to_return | ||
95 | 774 | |||
96 | 775 | def get_path_share_id(self, path): | ||
97 | 776 | """Fake get_path_share_id.""" | ||
98 | 777 | self.called_methods.append(('get_path_share_id', path)) | ||
99 | 778 | return self.share_id | ||
100 | 779 | |||
101 | 780 | def rm_watch(self, path): | ||
102 | 781 | """Fake the remove watch.""" | ||
103 | 782 | self.called_methods.append(('rm_watch', path)) | ||
104 | 783 | |||
105 | 784 | def freeze_begin(self, path): | ||
106 | 785 | """Fake freeze_begin""" | ||
107 | 786 | self.called_methods.append(('freeze_begin', path)) | ||
108 | 787 | |||
109 | 788 | def freeze_rollback(self): | ||
110 | 789 | """Fake rollback.""" | ||
111 | 790 | self.called_methods.append(('freeze_rollback',)) | ||
112 | 791 | |||
113 | 792 | def freeze_commit(self, path): | ||
114 | 793 | """Fake freeze commit.""" | ||
115 | 794 | self.called_methods.append(('freeze_commit', path)) | ||
116 | 795 | |||
117 | 796 | |||
118 | 797 | class TestNotifyProcessor(BaseTwistedTestCase): | ||
119 | 798 | """Test the notify processor.""" | ||
120 | 799 | |||
121 | 800 | def setUp(self): | ||
122 | 801 | """set up the diffeent tests.""" | ||
123 | 802 | super(TestNotifyProcessor, self).setUp() | ||
124 | 803 | self.processor = NotifyProcessor(None) | ||
125 | 804 | self.general = FakeGeneralProcessor() | ||
126 | 805 | self.processor.general_processor = self.general | ||
127 | 806 | |||
128 | 807 | def test_rm_from_mute_filter(self): | ||
129 | 808 | """Test that we remove the event from the mute filter.""" | ||
130 | 809 | event = 'event' | ||
131 | 810 | paths = 'paths' | ||
132 | 811 | self.processor.rm_from_mute_filter(event, paths) | ||
133 | 812 | self.assertEqual(1, len(self.general.called_methods)) | ||
134 | 813 | self.assertEqual('rm_from_mute_filter', | ||
135 | 814 | self.general.called_methods[0][0]) | ||
136 | 815 | self.assertEqual(event, self.general.called_methods[0][1]) | ||
137 | 816 | self.assertEqual(paths, self.general.called_methods[0][2]) | ||
138 | 817 | |||
139 | 818 | def test_add_to_mute_filter(self): | ||
140 | 819 | """Test that we add the path to the mute filter.""" | ||
141 | 820 | event = 'event' | ||
142 | 821 | paths = 'paths' | ||
143 | 822 | self.processor.add_to_mute_filter(event, paths) | ||
144 | 823 | self.assertEqual(1, len(self.general.called_methods)) | ||
145 | 824 | self.assertEqual('add_to_mute_filter', | ||
146 | 825 | self.general.called_methods[0][0]) | ||
147 | 826 | self.assertEqual(event, self.general.called_methods[0][1]) | ||
148 | 827 | self.assertEqual(paths, self.general.called_methods[0][2]) | ||
149 | 828 | |||
150 | 829 | def test_platform_is_ignored(self): | ||
151 | 830 | """Test that we do indeed ignore the correct paths.""" | ||
152 | 831 | not_ignored = 'test' | ||
153 | 832 | ignored = not_ignored + '.lnk' | ||
154 | 833 | self.assertFalse(self.processor.platform_is_ignored(not_ignored), | ||
155 | 834 | 'Only links should be ignored.') | ||
156 | 835 | self.assertTrue(self.processor.platform_is_ignored(ignored), | ||
157 | 836 | 'Links should be ignored.') | ||
158 | 837 | |||
159 | 838 | def test_is_ignored(self): | ||
160 | 839 | """Test that we do ensure that the path is ignored.""" | ||
161 | 840 | path = 'path' | ||
162 | 841 | self.processor.is_ignored(path) | ||
163 | 842 | self.assertEqual(1, len(self.general.called_methods)) | ||
164 | 843 | self.assertEqual('is_ignored', | ||
165 | 844 | self.general.called_methods[0][0]) | ||
166 | 845 | self.assertEqual(path, self.general.called_methods[0][1]) | ||
167 | 846 | |||
168 | 847 | def test_release_held_event(self): | ||
169 | 848 | """Test that we do release the held event.""" | ||
170 | 849 | event = 'event' | ||
171 | 850 | # set the held event to assert that is pushed | ||
172 | 851 | self.processor.held_event = event | ||
173 | 852 | self.processor.release_held_event() | ||
174 | 853 | self.assertEqual('push_event', | ||
175 | 854 | self.general.called_methods[0][0]) | ||
176 | 855 | self.assertEqual(event, self.general.called_methods[0][1]) | ||
177 | 856 | |||
178 | 857 | def test_process_IN_MODIFY_dir(self): | ||
179 | 858 | """Test that the modify works as exepcted with dirs.""" | ||
180 | 859 | event = FakeEvent(dir=True) | ||
181 | 860 | self.processor.process_IN_MODIFY(event) | ||
182 | 861 | # no method should be called | ||
183 | 862 | self.assertEqual(0, len(self.general.called_methods)) | ||
184 | 863 | |||
185 | 864 | def test_process_IN_MODIFY_file(self): | ||
186 | 865 | """Test that the modify works as expected with files.""" | ||
187 | 866 | event = FakeEvent(dir=False, wd=0, name='name', | ||
188 | 867 | path='path', pathname='pathname') | ||
189 | 868 | self.processor.process_IN_MODIFY(event) | ||
190 | 869 | # we should be getting two different method, and open and a close | ||
191 | 870 | self.assertEqual(2, len(self.general.called_methods)) | ||
192 | 871 | self.assertEqual('push_event', | ||
193 | 872 | self.general.called_methods[0][0]) | ||
194 | 873 | self.assertEqual('push_event', | ||
195 | 874 | self.general.called_methods[1][0]) | ||
196 | 875 | self.assertEqual(event.dir, self.general.called_methods[0][1].dir) | ||
197 | 876 | self.assertEqual(event.wd, self.general.called_methods[0][1].wd) | ||
198 | 877 | self.assertEqual(event.name, self.general.called_methods[0][1].name) | ||
199 | 878 | self.assertEqual(event.path, self.general.called_methods[0][1].path) | ||
200 | 879 | self.assertEqual(event.pathname, | ||
201 | 880 | self.general.called_methods[0][1].pathname) | ||
202 | 881 | self.assertEqual(IN_OPEN, | ||
203 | 882 | self.general.called_methods[0][1].mask) | ||
204 | 883 | self.assertEqual(event.dir, self.general.called_methods[1][1].dir) | ||
205 | 884 | self.assertEqual(event.wd, self.general.called_methods[1][1].wd) | ||
206 | 885 | self.assertEqual(event.name, self.general.called_methods[1][1].name) | ||
207 | 886 | self.assertEqual(event.path, self.general.called_methods[1][1].path) | ||
208 | 887 | self.assertEqual(event.pathname, | ||
209 | 888 | self.general.called_methods[1][1].pathname) | ||
210 | 889 | self.assertEqual(IN_CLOSE_WRITE, | ||
211 | 890 | self.general.called_methods[1][1].mask) | ||
212 | 891 | |||
213 | 892 | def test_process_IN_MOVED_FROM(self): | ||
214 | 893 | """Test that the in moved from works as expected.""" | ||
215 | 894 | event = FakeEvent(dir=False, wd=0, name='name', | ||
216 | 895 | path='path', pathname='pathname') | ||
217 | 896 | self.processor.process_IN_MOVED_FROM(event) | ||
218 | 897 | self.assertEqual(event, self.processor.held_event) | ||
219 | 898 | |||
220 | 899 | def test_process_IN_MOVED_TO_dir(self): | ||
221 | 900 | """Test that the in moved to works as expected.""" | ||
222 | 901 | event = FakeEvent(wd=0, dir=True, name='name', path='path', | ||
223 | 902 | pathname=os.path.join('test', 'pathname'), | ||
224 | 903 | cookie='cookie') | ||
225 | 904 | held_event = FakeEvent(wd=0, dir=True, name='hname', path='hpath', | ||
226 | 905 | pathname=os.path.join('test', 'hpathname'), | ||
227 | 906 | cookie='cookie') | ||
228 | 907 | self.general.share_id = 'my_share_id' | ||
229 | 908 | self.processor.held_event = held_event | ||
230 | 909 | self.processor.process_IN_MOVED_TO(event) | ||
231 | 910 | self.assertEqual(5, len(self.general.called_methods)) | ||
232 | 911 | # assert that the ignores are called | ||
233 | 912 | self.assertEqual('is_ignored', self.general.called_methods[0][0]) | ||
234 | 913 | self.assertEqual(held_event.pathname, self.general.called_methods[0][1]) | ||
235 | 914 | self.assertEqual('is_ignored', self.general.called_methods[1][0]) | ||
236 | 915 | self.assertEqual(event.pathname, self.general.called_methods[1][1]) | ||
237 | 916 | # assert that we do request the share_id | ||
238 | 917 | self.assertEqual('get_path_share_id', self.general.called_methods[2][0]) | ||
239 | 918 | self.assertEqual(os.path.split(event.pathname)[0], | ||
240 | 919 | self.general.called_methods[2][1], | ||
241 | 920 | 'Get the share_id for event') | ||
242 | 921 | self.assertEqual('get_path_share_id', self.general.called_methods[3][0]) | ||
243 | 922 | self.assertEqual(os.path.split(held_event.pathname)[0], | ||
244 | 923 | self.general.called_methods[3][1], | ||
245 | 924 | 'Get the share_id for held event.') | ||
246 | 925 | |||
247 | 926 | self.assertEqual('eq_push', self.general.called_methods[4][0]) | ||
248 | 927 | self.assertEqual('FS_DIR_MOVE', self.general.called_methods[4][1]) | ||
249 | 928 | self.assertEqual(event.pathname, self.general.called_methods[4][3]) | ||
250 | 929 | self.assertEqual(held_event.pathname, self.general.called_methods[4][4]) | ||
251 | 930 | |||
252 | 931 | def test_process_IN_MOVED_TO_file(self): | ||
253 | 932 | """Test that the in moved to works as expected.""" | ||
254 | 933 | event = FakeEvent(wd=0, dir=False, name='name', path='path', | ||
255 | 934 | pathname=os.path.join('test', 'pathname'), | ||
256 | 935 | cookie='cookie') | ||
257 | 936 | held_event = FakeEvent(wd=0, dir=False, name='hname', path='hpath', | ||
258 | 937 | pathname=os.path.join('test', 'hpathname'), | ||
259 | 938 | cookie='cookie') | ||
260 | 939 | self.general.share_id = 'my_share_id' | ||
261 | 940 | self.processor.held_event = held_event | ||
262 | 941 | self.processor.process_IN_MOVED_TO(event) | ||
263 | 942 | self.assertEqual(5, len(self.general.called_methods)) | ||
264 | 943 | # assert that the ignores are called | ||
265 | 944 | self.assertEqual('is_ignored', self.general.called_methods[0][0]) | ||
266 | 945 | self.assertEqual(held_event.pathname, self.general.called_methods[0][1]) | ||
267 | 946 | self.assertEqual('is_ignored', self.general.called_methods[1][0]) | ||
268 | 947 | self.assertEqual(event.pathname, self.general.called_methods[1][1]) | ||
269 | 948 | # assert that we do request the share_id | ||
270 | 949 | self.assertEqual('get_path_share_id', self.general.called_methods[2][0]) | ||
271 | 950 | self.assertEqual(os.path.split(event.pathname)[0], | ||
272 | 951 | self.general.called_methods[2][1], | ||
273 | 952 | 'Get the share_id for event') | ||
274 | 953 | self.assertEqual('get_path_share_id', self.general.called_methods[3][0]) | ||
275 | 954 | self.assertEqual(os.path.split(held_event.pathname)[0], | ||
276 | 955 | self.general.called_methods[3][1], | ||
277 | 956 | 'Get the share_id for held event.') | ||
278 | 957 | |||
279 | 958 | self.assertEqual('eq_push', self.general.called_methods[4][0]) | ||
280 | 959 | self.assertEqual('FS_FILE_MOVE', self.general.called_methods[4][1]) | ||
281 | 960 | self.assertEqual(event.pathname, self.general.called_methods[4][3]) | ||
282 | 961 | self.assertEqual(held_event.pathname, self.general.called_methods[4][4]) | ||
283 | 962 | |||
284 | 963 | def test_fake_create_event_dir(self): | ||
285 | 964 | """Test that the in moved to works as expected.""" | ||
286 | 965 | event = FakeEvent(wd=0, dir=True, name='name', path='path', | ||
287 | 966 | pathname='pathname') | ||
288 | 967 | self.processor._fake_create_event(event) | ||
289 | 968 | self.assertEqual(1, len(self.general.called_methods)) | ||
290 | 969 | self.assertEqual('eq_push', self.general.called_methods[0][0]) | ||
291 | 970 | self.assertEqual('FS_DIR_CREATE', self.general.called_methods[0][1]) | ||
292 | 971 | self.assertEqual(event.pathname, self.general.called_methods[0][2]) | ||
293 | 972 | |||
294 | 973 | def test_fake_create_event_file(self): | ||
295 | 974 | """Test that the in moved to works as expected.""" | ||
296 | 975 | event = FakeEvent(wd=0, dir=False, name='name', path='path', | ||
297 | 976 | pathname='pathname') | ||
298 | 977 | self.processor._fake_create_event(event) | ||
299 | 978 | self.assertEqual(2, len(self.general.called_methods)) | ||
300 | 979 | self.assertEqual('eq_push', self.general.called_methods[0][0]) | ||
301 | 980 | self.assertEqual('FS_FILE_CREATE', self.general.called_methods[0][1]) | ||
302 | 981 | self.assertEqual(event.pathname, self.general.called_methods[0][2]) | ||
303 | 982 | self.assertEqual('eq_push', self.general.called_methods[1][0]) | ||
304 | 983 | self.assertEqual('FS_FILE_CLOSE_WRITE', | ||
305 | 984 | self.general.called_methods[1][1]) | ||
306 | 985 | self.assertEqual(event.pathname, self.general.called_methods[1][2]) | ||
307 | 986 | |||
308 | 987 | def test_fake_delete_create_event_dir(self): | ||
309 | 988 | """Test that we do fake a delete and a later delete.""" | ||
310 | 989 | event = FakeEvent(wd=0, dir=True, name='name', path='path', | ||
311 | 990 | pathname='pathname') | ||
312 | 991 | held_event = FakeEvent(wd=0, dir=True, name='hname', path='hpath', | ||
313 | 992 | pathname='hpathname') | ||
314 | 993 | self.processor.held_event = held_event | ||
315 | 994 | self.processor._fake_delete_create_event(event) | ||
316 | 995 | self.assertEqual(2, len(self.general.called_methods)) | ||
317 | 996 | self.assertEqual('eq_push', self.general.called_methods[0][0]) | ||
318 | 997 | self.assertEqual('FS_DIR_DELETE', self.general.called_methods[0][1]) | ||
319 | 998 | self.assertEqual(held_event.pathname, self.general.called_methods[0][2]) | ||
320 | 999 | self.assertEqual('eq_push', self.general.called_methods[1][0]) | ||
321 | 1000 | self.assertEqual('FS_DIR_CREATE', self.general.called_methods[1][1]) | ||
322 | 1001 | self.assertEqual(event.pathname, self.general.called_methods[1][2]) | ||
323 | 1002 | |||
324 | 1003 | def test_fake_delete_create_event_file(self): | ||
325 | 1004 | """Test that we do fake a delete and a later delete.""" | ||
326 | 1005 | event = FakeEvent(wd=0, dir=False, name='name', path='path', | ||
327 | 1006 | pathname='pathname') | ||
328 | 1007 | held_event = FakeEvent(wd=0, dir=False, name='hname', path='hpath', | ||
329 | 1008 | pathname='hpathname') | ||
330 | 1009 | self.processor.held_event = held_event | ||
331 | 1010 | self.processor._fake_delete_create_event(event) | ||
332 | 1011 | self.assertEqual(3, len(self.general.called_methods)) | ||
333 | 1012 | self.assertEqual('eq_push', self.general.called_methods[0][0]) | ||
334 | 1013 | self.assertEqual('FS_FILE_DELETE', self.general.called_methods[0][1]) | ||
335 | 1014 | self.assertEqual(held_event.pathname, self.general.called_methods[0][2]) | ||
336 | 1015 | self.assertEqual('eq_push', self.general.called_methods[1][0]) | ||
337 | 1016 | self.assertEqual('FS_FILE_CREATE', self.general.called_methods[1][1]) | ||
338 | 1017 | self.assertEqual(event.pathname, self.general.called_methods[1][2]) | ||
339 | 1018 | self.assertEqual('eq_push', self.general.called_methods[2][0]) | ||
340 | 1019 | self.assertEqual('FS_FILE_CLOSE_WRITE', | ||
341 | 1020 | self.general.called_methods[2][1]) | ||
342 | 1021 | self.assertEqual(event.pathname, self.general.called_methods[2][2]) | ||
343 | 1022 | |||
344 | 1023 | def test_process_default_no_held(self): | ||
345 | 1024 | """Test that the process default works as expected.""" | ||
346 | 1025 | event = 'event' | ||
347 | 1026 | self.processor.process_default(event) | ||
348 | 1027 | self.assertEqual(1, len(self.general.called_methods)) | ||
349 | 1028 | self.assertEqual('push_event', | ||
350 | 1029 | self.general.called_methods[0][0]) | ||
351 | 1030 | self.assertEqual(event, | ||
352 | 1031 | self.general.called_methods[0][1]) | ||
353 | 1032 | |||
354 | 1033 | def test_process_default_with_held(self): | ||
355 | 1034 | """Test that the process default works as expected.""" | ||
356 | 1035 | event = 'event' | ||
357 | 1036 | held_event = 'held_event' | ||
358 | 1037 | self.processor.held_event = held_event | ||
359 | 1038 | self.processor.process_default(event) | ||
360 | 1039 | self.assertEqual(2, len(self.general.called_methods)) | ||
361 | 1040 | self.assertEqual('push_event', | ||
362 | 1041 | self.general.called_methods[0][0]) | ||
363 | 1042 | self.assertEqual(held_event, | ||
364 | 1043 | self.general.called_methods[0][1]) | ||
365 | 1044 | self.assertEqual('push_event', | ||
366 | 1045 | self.general.called_methods[1][0]) | ||
367 | 1046 | self.assertEqual(event, | ||
368 | 1047 | self.general.called_methods[1][1]) | ||
369 | 1048 | |||
370 | 1049 | def test_handle_dir_delete_files(self): | ||
371 | 1050 | """Test that the handle dir delete works as expected.""" | ||
372 | 1051 | path = 'path' | ||
373 | 1052 | present_files = 'abcde' | ||
374 | 1053 | # create files and dirs to be returned from the get paths | ||
375 | 1054 | for file_name in present_files: | ||
376 | 1055 | self.general.paths_to_return.append((file_name, False)) | ||
377 | 1056 | self.processor.handle_dir_delete(path) | ||
378 | 1057 | # there are calls for, rm the wathc, get paths and then one per file | ||
379 | 1058 | self.assertEqual(len(present_files) + 2, | ||
380 | 1059 | len(self.general.called_methods)) | ||
381 | 1060 | rm_call = self.general.called_methods.pop(0) | ||
382 | 1061 | self.assertEqual('rm_watch', rm_call[0]) | ||
383 | 1062 | self.assertEqual(path, rm_call[1]) | ||
384 | 1063 | paths_call = self.general.called_methods.pop(0) | ||
385 | 1064 | self.assertEqual('get_paths_starting_with', paths_call[0]) | ||
386 | 1065 | self.assertEqual(path, paths_call[1]) | ||
387 | 1066 | self.assertFalse(paths_call[2]) | ||
388 | 1067 | # we need to push the delete events in reverse order because we want | ||
389 | 1068 | # to delete children before we delete parents | ||
390 | 1069 | present_files = present_files[::-1] | ||
391 | 1070 | for i, called_method in enumerate(self.general.called_methods): | ||
392 | 1071 | self.assertEqual('eq_push', called_method[0]) | ||
393 | 1072 | self.assertEqual('FS_FILE_DELETE', called_method[1]) | ||
394 | 1073 | self.assertEqual(present_files[i], called_method[2]) | ||
395 | 1074 | |||
396 | 1075 | def test_handle_dir_delete_dirs(self): | ||
397 | 1076 | """Test that the handle dir delete works as expected.""" | ||
398 | 1077 | path = 'path' | ||
399 | 1078 | present_files = 'abcde' | ||
400 | 1079 | # create files and dirs to be returned from the get paths | ||
401 | 1080 | for file_name in present_files: | ||
402 | 1081 | self.general.paths_to_return.append((file_name, True)) | ||
403 | 1082 | self.processor.handle_dir_delete(path) | ||
404 | 1083 | # there are calls for, rm the wathc, get paths and then one per file | ||
405 | 1084 | self.assertEqual(2 * len(present_files) + 2, | ||
406 | 1085 | len(self.general.called_methods)) | ||
407 | 1086 | rm_call = self.general.called_methods.pop(0) | ||
408 | 1087 | self.assertEqual('rm_watch', rm_call[0]) | ||
409 | 1088 | self.assertEqual(path, rm_call[1]) | ||
410 | 1089 | paths_call = self.general.called_methods.pop(0) | ||
411 | 1090 | self.assertEqual('get_paths_starting_with', paths_call[0]) | ||
412 | 1091 | self.assertEqual(path, paths_call[1]) | ||
413 | 1092 | self.assertFalse(paths_call[2]) | ||
414 | 1093 | # we need to push the delete events in reverse order because we want | ||
415 | 1094 | # to delete children before we delete parents | ||
416 | 1095 | present_files = present_files[::-1] | ||
417 | 1096 | |||
418 | 1097 | # from http://docs.python.org/library/itertools.html#recipes | ||
419 | 1098 | def grouper(n, iterable, fillvalue=None): | ||
420 | 1099 | "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" | ||
421 | 1100 | args = [iter(iterable)] * n | ||
422 | 1101 | return itertools.izip_longest(fillvalue=fillvalue, *args) | ||
423 | 1102 | |||
424 | 1103 | for i, called_methods in enumerate(grouper(2, | ||
425 | 1104 | self.general.called_methods)): | ||
426 | 1105 | rm_call = called_methods[0] | ||
427 | 1106 | self.assertEqual('rm_watch', rm_call[0]) | ||
428 | 1107 | self.assertEqual(present_files[i], rm_call[1]) | ||
429 | 1108 | push_call = called_methods[1] | ||
430 | 1109 | self.assertEqual('eq_push', push_call[0]) | ||
431 | 1110 | self.assertEqual('FS_DIR_DELETE', push_call[1]) | ||
432 | 1111 | self.assertEqual(present_files[i], push_call[2]) | ||
433 | 1112 | |||
434 | 1113 | def test_freeze_begin(self): | ||
435 | 1114 | """Test that the freeze being works as expected.""" | ||
436 | 1115 | path = 'path' | ||
437 | 1116 | self.processor.freeze_begin(path) | ||
438 | 1117 | self.assertEqual(1, len(self.general.called_methods)) | ||
439 | 1118 | self.assertEqual('freeze_begin', | ||
440 | 1119 | self.general.called_methods[0][0]) | ||
441 | 1120 | self.assertEqual(path, self.general.called_methods[0][1]) | ||
442 | 1121 | |||
443 | 1122 | def test_freeze_rollback(self): | ||
444 | 1123 | """Test that the freeze rollback works as expected.""" | ||
445 | 1124 | self.processor.freeze_rollback() | ||
446 | 1125 | self.assertEqual(1, len(self.general.called_methods)) | ||
447 | 1126 | self.assertEqual('freeze_rollback', | ||
448 | 1127 | self.general.called_methods[0][0]) | ||
449 | 1128 | |||
450 | 1129 | def test_freeze_commit(self): | ||
451 | 1130 | """Test that the freeze commit works as expected.""" | ||
452 | 1131 | path = 'path' | ||
453 | 1132 | self.processor.freeze_commit(path) | ||
454 | 1133 | self.assertEqual(1, len(self.general.called_methods)) | ||
455 | 1134 | self.assertEqual('freeze_commit', | ||
456 | 1135 | self.general.called_methods[0][0]) | ||
457 | 1136 | self.assertEqual(path, self.general.called_methods[0][1]) | ||
458 | 702 | 1137 | ||
459 | === modified file 'ubuntuone/platform/windows/filesystem_notifications.py' | |||
460 | --- ubuntuone/platform/windows/filesystem_notifications.py 2011-07-29 13:32:31 +0000 | |||
461 | +++ ubuntuone/platform/windows/filesystem_notifications.py 2011-07-29 17:34:51 +0000 | |||
462 | @@ -152,11 +152,6 @@ | |||
463 | 152 | # a directory from a thread | 152 | # a directory from a thread |
464 | 153 | self._watch_started_deferred = defer.Deferred() | 153 | self._watch_started_deferred = defer.Deferred() |
465 | 154 | 154 | ||
466 | 155 | def _is_excluded(self, event): | ||
467 | 156 | """Return if an event is ignored.""" | ||
468 | 157 | return event.mask == IN_OPEN | IN_ISDIR | ||
469 | 158 | |||
470 | 159 | # XXX: confirm is using this decorator is correct!!! (nessita) | ||
471 | 160 | @is_valid_windows_path(path_indexes=[1]) | 155 | @is_valid_windows_path(path_indexes=[1]) |
472 | 161 | def _path_is_dir(self, path): | 156 | def _path_is_dir(self, path): |
473 | 162 | """Check if the path is a dir and update the local subdir list.""" | 157 | """Check if the path is a dir and update the local subdir list.""" |
474 | @@ -223,9 +218,7 @@ | |||
475 | 223 | # the exclude filter returns False, that is, the event will not | 218 | # the exclude filter returns False, that is, the event will not |
476 | 224 | # be excluded | 219 | # be excluded |
477 | 225 | self.log.debug('Event is %s.', event) | 220 | self.log.debug('Event is %s.', event) |
481 | 226 | if not self._is_excluded(event): | 221 | self._processor(event) |
479 | 227 | self.log.debug('Processing event %r', event) | ||
480 | 228 | self._processor(event) | ||
482 | 229 | 222 | ||
483 | 230 | def _watch(self): | 223 | def _watch(self): |
484 | 231 | """Watch a path that is a directory.""" | 224 | """Watch a path that is a directory.""" |
485 | @@ -500,6 +493,9 @@ | |||
486 | 500 | 493 | ||
487 | 501 | def process_IN_MODIFY(self, event): | 494 | def process_IN_MODIFY(self, event): |
488 | 502 | """Capture a modify event and fake an open ^ close write events.""" | 495 | """Capture a modify event and fake an open ^ close write events.""" |
489 | 496 | # lets ignore dir changes | ||
490 | 497 | if event.dir: | ||
491 | 498 | return | ||
492 | 503 | # on windows we just get IN_MODIFY, lets always fake | 499 | # on windows we just get IN_MODIFY, lets always fake |
493 | 504 | # an OPEN & CLOSE_WRITE couple | 500 | # an OPEN & CLOSE_WRITE couple |
494 | 505 | raw_open = raw_close = { | 501 | raw_open = raw_close = { |
495 | @@ -508,20 +504,13 @@ | |||
496 | 508 | 'name': event.name, | 504 | 'name': event.name, |
497 | 509 | 'path': event.path} | 505 | 'path': event.path} |
498 | 510 | # caculate the open mask | 506 | # caculate the open mask |
503 | 511 | if event.dir: | 507 | raw_open['mask'] = IN_OPEN |
500 | 512 | raw_open['mask'] = IN_OPEN | IN_ISDIR | ||
501 | 513 | else: | ||
502 | 514 | raw_open['mask'] = IN_OPEN | ||
504 | 515 | # create the event using the raw data, then fix the pathname param | 508 | # create the event using the raw data, then fix the pathname param |
505 | 516 | open_event = Event(raw_open) | 509 | open_event = Event(raw_open) |
506 | 517 | open_event.pathname = event.pathname | 510 | open_event.pathname = event.pathname |
507 | 518 | # push the open | 511 | # push the open |
508 | 519 | self.general_processor.push_event(open_event) | 512 | self.general_processor.push_event(open_event) |
514 | 520 | # calculate the close mask | 513 | raw_close['mask'] = IN_CLOSE_WRITE |
510 | 521 | if event.dir: | ||
511 | 522 | raw_close['mask'] = IN_CLOSE_WRITE | IN_ISDIR | ||
512 | 523 | else: | ||
513 | 524 | raw_close['mask'] = IN_CLOSE_WRITE | ||
515 | 525 | close_event = Event(raw_close) | 514 | close_event = Event(raw_close) |
516 | 526 | close_event.pathname = event.pathname | 515 | close_event.pathname = event.pathname |
517 | 527 | # push the close event | 516 | # push the close event |
518 | @@ -534,6 +523,36 @@ | |||
519 | 534 | self.held_event) | 523 | self.held_event) |
520 | 535 | self.held_event = event | 524 | self.held_event = event |
521 | 536 | 525 | ||
522 | 526 | def _fake_create_event(self, event): | ||
523 | 527 | """Fake the creation of an event.""" | ||
524 | 528 | # this is the case of a MOVE from an ignored path (links for example) | ||
525 | 529 | # to a valid path | ||
526 | 530 | if event.dir: | ||
527 | 531 | evtname = "FS_DIR_" | ||
528 | 532 | else: | ||
529 | 533 | evtname = "FS_FILE_" | ||
530 | 534 | self.general_processor.eq_push(evtname + "CREATE", path=event.pathname) | ||
531 | 535 | if not event.dir: | ||
532 | 536 | self.general_processor.eq_push('FS_FILE_CLOSE_WRITE', | ||
533 | 537 | path=event.pathname) | ||
534 | 538 | |||
535 | 539 | def _fake_delete_create_event(self, event): | ||
536 | 540 | """Fake the deletion and the creation.""" | ||
537 | 541 | # this is the case of a MOVE from a watch UDF to a diff UDF which | ||
538 | 542 | # means that we have to copy the way linux works. | ||
539 | 543 | if event.dir: | ||
540 | 544 | evtname = "FS_DIR_" | ||
541 | 545 | else: | ||
542 | 546 | evtname = "FS_FILE_" | ||
543 | 547 | m = "Delete because of different shares: %r" | ||
544 | 548 | self.log.info(m, self.held_event.pathname) | ||
545 | 549 | self.general_processor.eq_push(evtname + "DELETE", | ||
546 | 550 | path=self.held_event.pathname) | ||
547 | 551 | self.general_processor.eq_push(evtname + "CREATE", path=event.pathname) | ||
548 | 552 | if not event.dir: | ||
549 | 553 | self.general_processor.eq_push('FS_FILE_CLOSE_WRITE', | ||
550 | 554 | path=event.pathname) | ||
551 | 555 | |||
552 | 537 | def process_IN_MOVED_TO(self, event): | 556 | def process_IN_MOVED_TO(self, event): |
553 | 538 | """Capture the MOVED_TO to maybe syntethize FILE_MOVED.""" | 557 | """Capture the MOVED_TO to maybe syntethize FILE_MOVED.""" |
554 | 539 | if self.held_event is not None: | 558 | if self.held_event is not None: |
555 | @@ -548,37 +567,21 @@ | |||
556 | 548 | f_path_dir) | 567 | f_path_dir) |
557 | 549 | t_share_id = self.general_processor.get_path_share_id( | 568 | t_share_id = self.general_processor.get_path_share_id( |
558 | 550 | t_path_dir) | 569 | t_path_dir) |
559 | 551 | if event.dir: | ||
560 | 552 | evtname = "FS_DIR_" | ||
561 | 553 | else: | ||
562 | 554 | evtname = "FS_FILE_" | ||
563 | 555 | if f_share_id != t_share_id: | 570 | if f_share_id != t_share_id: |
564 | 556 | # if the share_id are != push a delete/create | 571 | # if the share_id are != push a delete/create |
574 | 557 | m = "Delete because of different shares: %r" | 572 | self._fake_delete_create_event(event) |
566 | 558 | self.log.info(m, self.held_event.pathname) | ||
567 | 559 | self.general_processor.eq_push( | ||
568 | 560 | evtname + "DELETE", path=self.held_event.pathname) | ||
569 | 561 | self.general_processor.eq_push( | ||
570 | 562 | evtname + "CREATE", path=event.pathname) | ||
571 | 563 | if not event.dir: | ||
572 | 564 | self.general_processor.eq_push( | ||
573 | 565 | 'FS_FILE_CLOSE_WRITE', path=event.pathname) | ||
575 | 566 | else: | 573 | else: |
576 | 574 | if event.dir: | ||
577 | 575 | evtname = "FS_DIR_" | ||
578 | 576 | else: | ||
579 | 577 | evtname = "FS_FILE_" | ||
580 | 567 | self.general_processor.eq_push(evtname + "MOVE", | 578 | self.general_processor.eq_push(evtname + "MOVE", |
581 | 568 | path_from=self.held_event.pathname, | 579 | path_from=self.held_event.pathname, |
582 | 569 | path_to=event.pathname) | 580 | path_to=event.pathname) |
583 | 570 | elif is_to_forreal: | 581 | elif is_to_forreal: |
584 | 571 | # this is the case of a MOVE from something ignored | 582 | # this is the case of a MOVE from something ignored |
585 | 572 | # to a valid filename | 583 | # to a valid filename |
595 | 573 | if event.dir: | 584 | self._fake_create_event(event) |
587 | 574 | evtname = "FS_DIR_" | ||
588 | 575 | else: | ||
589 | 576 | evtname = "FS_FILE_" | ||
590 | 577 | self.general_processor.eq_push(evtname + "CREATE", | ||
591 | 578 | path=event.pathname) | ||
592 | 579 | if not event.dir: | ||
593 | 580 | self.general_processor.eq_push('FS_FILE_CLOSE_WRITE', | ||
594 | 581 | path=event.pathname) | ||
596 | 582 | 585 | ||
597 | 583 | self.held_event = None | 586 | self.held_event = None |
598 | 584 | return | 587 | return |
599 | @@ -601,7 +604,8 @@ | |||
600 | 601 | @is_valid_syncdaemon_path(path_indexes=[1]) | 604 | @is_valid_syncdaemon_path(path_indexes=[1]) |
601 | 602 | def handle_dir_delete(self, fullpath): | 605 | def handle_dir_delete(self, fullpath): |
602 | 603 | """Some special work when a directory is deleted.""" | 606 | """Some special work when a directory is deleted.""" |
604 | 604 | # remove the watch on that dir from our structures | 607 | # remove the watch on that dir from our structures, this mainly tells |
605 | 608 | # the monitor to remove the watch which is fowaded to a watch manager. | ||
606 | 605 | self.general_processor.rm_watch(fullpath) | 609 | self.general_processor.rm_watch(fullpath) |
607 | 606 | 610 | ||
608 | 607 | # handle the case of move a dir to a non-watched directory | 611 | # handle the case of move a dir to a non-watched directory |
609 | @@ -613,6 +617,7 @@ | |||
610 | 613 | m = "Pushing deletion because of parent dir move: (is_dir=%s) %r" | 617 | m = "Pushing deletion because of parent dir move: (is_dir=%s) %r" |
611 | 614 | self.general_processor.log.info(m, is_dir, path) | 618 | self.general_processor.log.info(m, is_dir, path) |
612 | 615 | if is_dir: | 619 | if is_dir: |
613 | 620 | # same as the above remove | ||
614 | 616 | self.general_processor.rm_watch(path) | 621 | self.general_processor.rm_watch(path) |
615 | 617 | self.general_processor.eq_push('FS_DIR_DELETE', path=path) | 622 | self.general_processor.eq_push('FS_DIR_DELETE', path=path) |
616 | 618 | else: | 623 | else: |
617 | @@ -661,10 +666,6 @@ | |||
618 | 661 | self.log.setLevel(TRACE) | 666 | self.log.setLevel(TRACE) |
619 | 662 | self.fs = fs | 667 | self.fs = fs |
620 | 663 | self.eq = eq | 668 | self.eq = eq |
621 | 664 | # XXX: We need to find a decent time for the time out, is 0.2 seconds | ||
622 | 665 | # too little? | ||
623 | 666 | self.timeout = timeout | ||
624 | 667 | # general inotify | ||
625 | 668 | self._processor = NotifyProcessor(self, ignore_config) | 669 | self._processor = NotifyProcessor(self, ignore_config) |
626 | 669 | self._watch_manager = WatchManager(self._processor) | 670 | self._watch_manager = WatchManager(self._processor) |
627 | 670 | 671 | ||
628 | @@ -697,12 +698,6 @@ | |||
629 | 697 | self._watch_manager.add_watch(dirpath, FILESYSTEM_MONITOR_MASK, | 698 | self._watch_manager.add_watch(dirpath, FILESYSTEM_MONITOR_MASK, |
630 | 698 | auto_add=True) | 699 | auto_add=True) |
631 | 699 | 700 | ||
632 | 700 | @windowspath(path_indexes=[1]) | ||
633 | 701 | def has_watch(self, dirpath): | ||
634 | 702 | """Check if a dirpath is watched.""" | ||
635 | 703 | wd = self._watch_manager.get_wd(dirpath) | ||
636 | 704 | return wd is not None | ||
637 | 705 | |||
638 | 706 | def is_frozen(self): | 701 | def is_frozen(self): |
639 | 707 | """Checks if there's something frozen.""" | 702 | """Checks if there's something frozen.""" |
640 | 708 | return self._processor.frozen_path is not None | 703 | return self._processor.frozen_path is not None |
======= ======= ======= ======= ======= ======= ======= ======= ======= ======= ======= == internet. defer.TimeoutEr ror: <tests. platform. test_filesystem _notifications. MutedSignalsTes ts testMethod= test_dir_ create> (test_dir_create) still running at 2.0 secs
[ERROR]
Traceback (most recent call last):
Failure: twisted.
tests.platform. test_filesystem _notifications. MutedSignalsTes ts.test_ dir_create ======= ======= ======= ======= ======= ======= ======= ======= ======= ======= == lib\site- packages\ twisted\ internet\ base.py" , line 793, in runUntilCurrent func(*call. args, **call.kw) client\ review_ fix-fsm\ tests\platform\ test_filesystem _notifications. py", line 205, in check_filter assertFalse( self.monitor. _processor. mute_filter. _cnt) trial.unittest. FailTest: None
=======
[ERROR]
Traceback (most recent call last):
File "C:\Python27\
call.
File "E:\u1\
self.
twisted.
tests.platform. test_filesystem _notifications. MutedSignalsTes ts.test_ dir_create test_filesystem _notifications. MutedSignalsTes ts.test_ dir_delete test_filesystem _notifications. MutedSignalsTes ts.test_ dir_moved_ inside test_filesystem _notifications. MutedSignalsTes ts.test_ file_create_ close_write test_filesystem _notifications. MutedSignalsTes ts.test_ file_delete test_filesystem _notifications. MutedSignalsTes ts.test_ file_moved_ from_conflict test_filesystem _notifications. MutedSignalsTes ts.test_ file_moved_ from_partial test_filesystem _notifications. MutedSignalsTes ts.test_ file_moved_ inside ======= ======= ======= ======= ======= ======= ======= ======= ======= ======= == internet. defer.TimeoutEr ror: <tests. platform. test_filesystem _notifications. MutedSignalsTes ts testMethod= test_dir_ delete> (test_dir_delete) still running at 2.0 secs
tests.platform.
tests.platform.
tests.platform.
tests.platform.
tests.platform.
tests.platform.
tests.platform.
=======
[ERROR]
Traceback (most recent call last):
Failure: twisted.
tests.platform. test_filesystem _notifications. MutedSignalsTes ts.test_ dir_delete ======= ======= ======= ======= ======= ======= ======= ======= ======= ======= == internet. defer.TimeoutEr ror: <tests. platform. test_filesystem _notifications. MutedSignalsTes ts testMethod= test_dir_ moved_inside> (test_dir_ moved_inside) still running at 2.0 secs
=======
[ERROR]
Traceback (most recent call last):
Failure: twisted.
tests.platform. test_filesystem _notifications. MutedSignalsTes ts.test_ dir_moved_ inside ======= ======= ======= ======= ======= ======= ======= ======= ======= ======= == internet. defer.TimeoutEr ror: <tests. platform. test_filesystem _notifications. MutedSignalsTes ts testMethod= test_file_ create_ close_write> (test_file_ create_ close_write) still running at 2.0 secs
=======
[ERROR]
Traceback (most recent call last):
Failure: twisted.
tests.platform. test_filesystem _notifications. MutedSignalsTes ts.test_ file_create_ close_write ======= ======= ======= ======= ======= ======= ======= ======= ======= ======= == internet. defer.TimeoutEr ror: <tests. platform. test_filesystem _notifications. MutedSignalsTes ts testMethod= test_file_ delete> (test_file_delete) still running at 2.0 secs
=======
[ERROR]
Traceback (most recent call last):
Failure: twisted.
tests.platform. test_filesystem _notifications. MutedSignalsTes ts.test_ file_delete ======= ======= ======= ======= ======= ======= ======= =====.. .
=======