Merge lp:~mandel/ubuntuone-client/fix-fsm into lp:ubuntuone-client

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
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.
lp:~mandel/ubuntuone-client/fix-fsm updated
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 :
Download full text (6.4 KiB)

===============================================================================
[ERROR]
Traceback (most recent call last):
Failure: twisted.internet.defer.TimeoutError: <tests.platform.test_filesystem_notifications.MutedSignalsTests testMethod=test_dir_create> (test_dir_create) still running at 2.0 secs

tests.platform.test_filesystem_notifications.MutedSignalsTests.test_dir_create
===============================================================================
[ERROR]
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\twisted\internet\base.py", line 793, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "E:\u1\client\review_fix-fsm\tests\platform\test_filesystem_notifications.py", line 205, in check_filter
    self.assertFalse(self.monitor._processor.mute_filter._cnt)
twisted.trial.unittest.FailTest: None

tests.platform.test_filesystem_notifications.MutedSignalsTests.test_dir_create
tests.platform.test_filesystem_notifications.MutedSignalsTests.test_dir_delete
tests.platform.test_filesystem_notifications.MutedSignalsTests.test_dir_moved_inside
tests.platform.test_filesystem_notifications.MutedSignalsTests.test_file_create_close_write
tests.platform.test_filesystem_notifications.MutedSignalsTests.test_file_delete
tests.platform.test_filesystem_notifications.MutedSignalsTests.test_file_moved_from_conflict
tests.platform.test_filesystem_notifications.MutedSignalsTests.test_file_moved_from_partial
tests.platform.test_filesystem_notifications.MutedSignalsTests.test_file_moved_inside
===============================================================================
[ERROR]
Traceback (most recent call last):
Failure: twisted.internet.defer.TimeoutError: <tests.platform.test_filesystem_notifications.MutedSignalsTests testMethod=test_dir_delete> (test_dir_delete) still running at 2.0 secs

tests.platform.test_filesystem_notifications.MutedSignalsTests.test_dir_delete
===============================================================================
[ERROR]
Traceback (most recent call last):
Failure: twisted.internet.defer.TimeoutError: <tests.platform.test_filesystem_notifications.MutedSignalsTests testMethod=test_dir_moved_inside> (test_dir_moved_inside) still running at 2.0 secs

tests.platform.test_filesystem_notifications.MutedSignalsTests.test_dir_moved_inside
===============================================================================
[ERROR]
Traceback (most recent call last):
Failure: twisted.internet.defer.TimeoutError: <tests.platform.test_filesystem_notifications.MutedSignalsTests testMethod=test_file_create_close_write> (test_file_create_close_write) still running at 2.0 secs

tests.platform.test_filesystem_notifications.MutedSignalsTests.test_file_create_close_write
===============================================================================
[ERROR]
Traceback (most recent call last):
Failure: twisted.internet.defer.TimeoutError: <tests.platform.test_filesystem_notifications.MutedSignalsTests testMethod=test_file_delete> (test_file_delete) still running at 2.0 secs

tests.platform.test_filesystem_notifications.MutedSignalsTests.test_file_delete
=============================================================...

Read more...

review: Needs Fixing
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Failing tests will be solved in a incoming branch.

review: Approve
lp:~mandel/ubuntuone-client/fix-fsm updated
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
=== modified file 'tests/platform/windows/test_filesystem_notifications.py'
--- tests/platform/windows/test_filesystem_notifications.py 2011-07-29 13:32:31 +0000
+++ tests/platform/windows/test_filesystem_notifications.py 2011-07-29 17:34:51 +0000
@@ -21,13 +21,19 @@
21import tempfile21import tempfile
22import thread22import thread
23import time23import time
24import itertools
2425
25from twisted.internet import defer26from twisted.internet import defer
2627
27from contrib.testing.testcase import BaseTwistedTestCase28from contrib.testing.testcase import BaseTwistedTestCase
28from ubuntuone.platform.windows import os_helper29from ubuntuone.platform.windows import os_helper
29from ubuntuone.platform.windows.pyinotify import ProcessEvent30from ubuntuone.platform.windows.pyinotify import (
31 ProcessEvent,
32 IN_OPEN,
33 IN_CLOSE_WRITE
34)
30from ubuntuone.platform.windows.filesystem_notifications import (35from ubuntuone.platform.windows.filesystem_notifications import (
36 NotifyProcessor,
31 Watch,37 Watch,
32 WatchManager,38 WatchManager,
33 FILE_NOTIFY_CHANGE_FILE_NAME,39 FILE_NOTIFY_CHANGE_FILE_NAME,
@@ -699,3 +705,432 @@
699 # assert that other events are not ignored705 # assert that other events are not ignored
700 self.watch._process_events([(1, 'test')])706 self.watch._process_events([(1, 'test')])
701 self.assertEqual(1, len(events))707 self.assertEqual(1, len(events))
708
709
710class FakeEvent(object):
711 """Fake event."""
712
713 def __init__(self, wd=0, dir=True, name=None, path=None, pathname=None,
714 cookie=None):
715 """Create fake event."""
716 self.dir = dir
717 self.wd = wd
718 self.name = name
719 self.path = path
720 self.pathname = pathname
721 self.cookie = cookie
722
723
724class FakeLog(object):
725 """A fake log that is used by the general processor."""
726
727 def __init__(self):
728 """Create the fake."""
729 self.called_methods = []
730
731 def info(self, *args):
732 """Fake the info call."""
733 self.called_methods.append(('info', args))
734
735
736class FakeGeneralProcessor(object):
737 """Fake implementation of the general processor."""
738
739 def __init__(self):
740 """Create the fake."""
741 self.called_methods = []
742 self.paths_to_return = []
743 self.log = FakeLog()
744 self.share_id = None
745 self.ignore = False
746
747 def rm_from_mute_filter(self, event, paths):
748 """Fake rm_from_mute_filter."""
749 self.called_methods.append(('rm_from_mute_filter', event, paths))
750
751 def add_to_mute_filter(self, event, paths):
752 """Fake add_to_move_filter."""
753 self.called_methods.append(('add_to_mute_filter', event, paths))
754
755 def is_ignored(self, path):
756 """Fake is_ignored."""
757 self.called_methods.append(('is_ignored', path))
758 return self.ignore
759
760 def push_event(self, event):
761 """Fake push event."""
762 self.called_methods.append(('push_event', event))
763
764 def eq_push(self, event, path=None, path_to=None, path_from=None):
765 """Fake event to push event."""
766 self.called_methods.append(('eq_push', event, path, path_to,
767 path_from))
768
769 def get_paths_starting_with(self, fullpath, include_base=False):
770 """Fake get_paths_starting_with."""
771 self.called_methods.append(('get_paths_starting_with', fullpath,
772 include_base))
773 return self.paths_to_return
774
775 def get_path_share_id(self, path):
776 """Fake get_path_share_id."""
777 self.called_methods.append(('get_path_share_id', path))
778 return self.share_id
779
780 def rm_watch(self, path):
781 """Fake the remove watch."""
782 self.called_methods.append(('rm_watch', path))
783
784 def freeze_begin(self, path):
785 """Fake freeze_begin"""
786 self.called_methods.append(('freeze_begin', path))
787
788 def freeze_rollback(self):
789 """Fake rollback."""
790 self.called_methods.append(('freeze_rollback',))
791
792 def freeze_commit(self, path):
793 """Fake freeze commit."""
794 self.called_methods.append(('freeze_commit', path))
795
796
797class TestNotifyProcessor(BaseTwistedTestCase):
798 """Test the notify processor."""
799
800 def setUp(self):
801 """set up the diffeent tests."""
802 super(TestNotifyProcessor, self).setUp()
803 self.processor = NotifyProcessor(None)
804 self.general = FakeGeneralProcessor()
805 self.processor.general_processor = self.general
806
807 def test_rm_from_mute_filter(self):
808 """Test that we remove the event from the mute filter."""
809 event = 'event'
810 paths = 'paths'
811 self.processor.rm_from_mute_filter(event, paths)
812 self.assertEqual(1, len(self.general.called_methods))
813 self.assertEqual('rm_from_mute_filter',
814 self.general.called_methods[0][0])
815 self.assertEqual(event, self.general.called_methods[0][1])
816 self.assertEqual(paths, self.general.called_methods[0][2])
817
818 def test_add_to_mute_filter(self):
819 """Test that we add the path to the mute filter."""
820 event = 'event'
821 paths = 'paths'
822 self.processor.add_to_mute_filter(event, paths)
823 self.assertEqual(1, len(self.general.called_methods))
824 self.assertEqual('add_to_mute_filter',
825 self.general.called_methods[0][0])
826 self.assertEqual(event, self.general.called_methods[0][1])
827 self.assertEqual(paths, self.general.called_methods[0][2])
828
829 def test_platform_is_ignored(self):
830 """Test that we do indeed ignore the correct paths."""
831 not_ignored = 'test'
832 ignored = not_ignored + '.lnk'
833 self.assertFalse(self.processor.platform_is_ignored(not_ignored),
834 'Only links should be ignored.')
835 self.assertTrue(self.processor.platform_is_ignored(ignored),
836 'Links should be ignored.')
837
838 def test_is_ignored(self):
839 """Test that we do ensure that the path is ignored."""
840 path = 'path'
841 self.processor.is_ignored(path)
842 self.assertEqual(1, len(self.general.called_methods))
843 self.assertEqual('is_ignored',
844 self.general.called_methods[0][0])
845 self.assertEqual(path, self.general.called_methods[0][1])
846
847 def test_release_held_event(self):
848 """Test that we do release the held event."""
849 event = 'event'
850 # set the held event to assert that is pushed
851 self.processor.held_event = event
852 self.processor.release_held_event()
853 self.assertEqual('push_event',
854 self.general.called_methods[0][0])
855 self.assertEqual(event, self.general.called_methods[0][1])
856
857 def test_process_IN_MODIFY_dir(self):
858 """Test that the modify works as exepcted with dirs."""
859 event = FakeEvent(dir=True)
860 self.processor.process_IN_MODIFY(event)
861 # no method should be called
862 self.assertEqual(0, len(self.general.called_methods))
863
864 def test_process_IN_MODIFY_file(self):
865 """Test that the modify works as expected with files."""
866 event = FakeEvent(dir=False, wd=0, name='name',
867 path='path', pathname='pathname')
868 self.processor.process_IN_MODIFY(event)
869 # we should be getting two different method, and open and a close
870 self.assertEqual(2, len(self.general.called_methods))
871 self.assertEqual('push_event',
872 self.general.called_methods[0][0])
873 self.assertEqual('push_event',
874 self.general.called_methods[1][0])
875 self.assertEqual(event.dir, self.general.called_methods[0][1].dir)
876 self.assertEqual(event.wd, self.general.called_methods[0][1].wd)
877 self.assertEqual(event.name, self.general.called_methods[0][1].name)
878 self.assertEqual(event.path, self.general.called_methods[0][1].path)
879 self.assertEqual(event.pathname,
880 self.general.called_methods[0][1].pathname)
881 self.assertEqual(IN_OPEN,
882 self.general.called_methods[0][1].mask)
883 self.assertEqual(event.dir, self.general.called_methods[1][1].dir)
884 self.assertEqual(event.wd, self.general.called_methods[1][1].wd)
885 self.assertEqual(event.name, self.general.called_methods[1][1].name)
886 self.assertEqual(event.path, self.general.called_methods[1][1].path)
887 self.assertEqual(event.pathname,
888 self.general.called_methods[1][1].pathname)
889 self.assertEqual(IN_CLOSE_WRITE,
890 self.general.called_methods[1][1].mask)
891
892 def test_process_IN_MOVED_FROM(self):
893 """Test that the in moved from works as expected."""
894 event = FakeEvent(dir=False, wd=0, name='name',
895 path='path', pathname='pathname')
896 self.processor.process_IN_MOVED_FROM(event)
897 self.assertEqual(event, self.processor.held_event)
898
899 def test_process_IN_MOVED_TO_dir(self):
900 """Test that the in moved to works as expected."""
901 event = FakeEvent(wd=0, dir=True, name='name', path='path',
902 pathname=os.path.join('test', 'pathname'),
903 cookie='cookie')
904 held_event = FakeEvent(wd=0, dir=True, name='hname', path='hpath',
905 pathname=os.path.join('test', 'hpathname'),
906 cookie='cookie')
907 self.general.share_id = 'my_share_id'
908 self.processor.held_event = held_event
909 self.processor.process_IN_MOVED_TO(event)
910 self.assertEqual(5, len(self.general.called_methods))
911 # assert that the ignores are called
912 self.assertEqual('is_ignored', self.general.called_methods[0][0])
913 self.assertEqual(held_event.pathname, self.general.called_methods[0][1])
914 self.assertEqual('is_ignored', self.general.called_methods[1][0])
915 self.assertEqual(event.pathname, self.general.called_methods[1][1])
916 # assert that we do request the share_id
917 self.assertEqual('get_path_share_id', self.general.called_methods[2][0])
918 self.assertEqual(os.path.split(event.pathname)[0],
919 self.general.called_methods[2][1],
920 'Get the share_id for event')
921 self.assertEqual('get_path_share_id', self.general.called_methods[3][0])
922 self.assertEqual(os.path.split(held_event.pathname)[0],
923 self.general.called_methods[3][1],
924 'Get the share_id for held event.')
925
926 self.assertEqual('eq_push', self.general.called_methods[4][0])
927 self.assertEqual('FS_DIR_MOVE', self.general.called_methods[4][1])
928 self.assertEqual(event.pathname, self.general.called_methods[4][3])
929 self.assertEqual(held_event.pathname, self.general.called_methods[4][4])
930
931 def test_process_IN_MOVED_TO_file(self):
932 """Test that the in moved to works as expected."""
933 event = FakeEvent(wd=0, dir=False, name='name', path='path',
934 pathname=os.path.join('test', 'pathname'),
935 cookie='cookie')
936 held_event = FakeEvent(wd=0, dir=False, name='hname', path='hpath',
937 pathname=os.path.join('test', 'hpathname'),
938 cookie='cookie')
939 self.general.share_id = 'my_share_id'
940 self.processor.held_event = held_event
941 self.processor.process_IN_MOVED_TO(event)
942 self.assertEqual(5, len(self.general.called_methods))
943 # assert that the ignores are called
944 self.assertEqual('is_ignored', self.general.called_methods[0][0])
945 self.assertEqual(held_event.pathname, self.general.called_methods[0][1])
946 self.assertEqual('is_ignored', self.general.called_methods[1][0])
947 self.assertEqual(event.pathname, self.general.called_methods[1][1])
948 # assert that we do request the share_id
949 self.assertEqual('get_path_share_id', self.general.called_methods[2][0])
950 self.assertEqual(os.path.split(event.pathname)[0],
951 self.general.called_methods[2][1],
952 'Get the share_id for event')
953 self.assertEqual('get_path_share_id', self.general.called_methods[3][0])
954 self.assertEqual(os.path.split(held_event.pathname)[0],
955 self.general.called_methods[3][1],
956 'Get the share_id for held event.')
957
958 self.assertEqual('eq_push', self.general.called_methods[4][0])
959 self.assertEqual('FS_FILE_MOVE', self.general.called_methods[4][1])
960 self.assertEqual(event.pathname, self.general.called_methods[4][3])
961 self.assertEqual(held_event.pathname, self.general.called_methods[4][4])
962
963 def test_fake_create_event_dir(self):
964 """Test that the in moved to works as expected."""
965 event = FakeEvent(wd=0, dir=True, name='name', path='path',
966 pathname='pathname')
967 self.processor._fake_create_event(event)
968 self.assertEqual(1, len(self.general.called_methods))
969 self.assertEqual('eq_push', self.general.called_methods[0][0])
970 self.assertEqual('FS_DIR_CREATE', self.general.called_methods[0][1])
971 self.assertEqual(event.pathname, self.general.called_methods[0][2])
972
973 def test_fake_create_event_file(self):
974 """Test that the in moved to works as expected."""
975 event = FakeEvent(wd=0, dir=False, name='name', path='path',
976 pathname='pathname')
977 self.processor._fake_create_event(event)
978 self.assertEqual(2, len(self.general.called_methods))
979 self.assertEqual('eq_push', self.general.called_methods[0][0])
980 self.assertEqual('FS_FILE_CREATE', self.general.called_methods[0][1])
981 self.assertEqual(event.pathname, self.general.called_methods[0][2])
982 self.assertEqual('eq_push', self.general.called_methods[1][0])
983 self.assertEqual('FS_FILE_CLOSE_WRITE',
984 self.general.called_methods[1][1])
985 self.assertEqual(event.pathname, self.general.called_methods[1][2])
986
987 def test_fake_delete_create_event_dir(self):
988 """Test that we do fake a delete and a later delete."""
989 event = FakeEvent(wd=0, dir=True, name='name', path='path',
990 pathname='pathname')
991 held_event = FakeEvent(wd=0, dir=True, name='hname', path='hpath',
992 pathname='hpathname')
993 self.processor.held_event = held_event
994 self.processor._fake_delete_create_event(event)
995 self.assertEqual(2, len(self.general.called_methods))
996 self.assertEqual('eq_push', self.general.called_methods[0][0])
997 self.assertEqual('FS_DIR_DELETE', self.general.called_methods[0][1])
998 self.assertEqual(held_event.pathname, self.general.called_methods[0][2])
999 self.assertEqual('eq_push', self.general.called_methods[1][0])
1000 self.assertEqual('FS_DIR_CREATE', self.general.called_methods[1][1])
1001 self.assertEqual(event.pathname, self.general.called_methods[1][2])
1002
1003 def test_fake_delete_create_event_file(self):
1004 """Test that we do fake a delete and a later delete."""
1005 event = FakeEvent(wd=0, dir=False, name='name', path='path',
1006 pathname='pathname')
1007 held_event = FakeEvent(wd=0, dir=False, name='hname', path='hpath',
1008 pathname='hpathname')
1009 self.processor.held_event = held_event
1010 self.processor._fake_delete_create_event(event)
1011 self.assertEqual(3, len(self.general.called_methods))
1012 self.assertEqual('eq_push', self.general.called_methods[0][0])
1013 self.assertEqual('FS_FILE_DELETE', self.general.called_methods[0][1])
1014 self.assertEqual(held_event.pathname, self.general.called_methods[0][2])
1015 self.assertEqual('eq_push', self.general.called_methods[1][0])
1016 self.assertEqual('FS_FILE_CREATE', self.general.called_methods[1][1])
1017 self.assertEqual(event.pathname, self.general.called_methods[1][2])
1018 self.assertEqual('eq_push', self.general.called_methods[2][0])
1019 self.assertEqual('FS_FILE_CLOSE_WRITE',
1020 self.general.called_methods[2][1])
1021 self.assertEqual(event.pathname, self.general.called_methods[2][2])
1022
1023 def test_process_default_no_held(self):
1024 """Test that the process default works as expected."""
1025 event = 'event'
1026 self.processor.process_default(event)
1027 self.assertEqual(1, len(self.general.called_methods))
1028 self.assertEqual('push_event',
1029 self.general.called_methods[0][0])
1030 self.assertEqual(event,
1031 self.general.called_methods[0][1])
1032
1033 def test_process_default_with_held(self):
1034 """Test that the process default works as expected."""
1035 event = 'event'
1036 held_event = 'held_event'
1037 self.processor.held_event = held_event
1038 self.processor.process_default(event)
1039 self.assertEqual(2, len(self.general.called_methods))
1040 self.assertEqual('push_event',
1041 self.general.called_methods[0][0])
1042 self.assertEqual(held_event,
1043 self.general.called_methods[0][1])
1044 self.assertEqual('push_event',
1045 self.general.called_methods[1][0])
1046 self.assertEqual(event,
1047 self.general.called_methods[1][1])
1048
1049 def test_handle_dir_delete_files(self):
1050 """Test that the handle dir delete works as expected."""
1051 path = 'path'
1052 present_files = 'abcde'
1053 # create files and dirs to be returned from the get paths
1054 for file_name in present_files:
1055 self.general.paths_to_return.append((file_name, False))
1056 self.processor.handle_dir_delete(path)
1057 # there are calls for, rm the wathc, get paths and then one per file
1058 self.assertEqual(len(present_files) + 2,
1059 len(self.general.called_methods))
1060 rm_call = self.general.called_methods.pop(0)
1061 self.assertEqual('rm_watch', rm_call[0])
1062 self.assertEqual(path, rm_call[1])
1063 paths_call = self.general.called_methods.pop(0)
1064 self.assertEqual('get_paths_starting_with', paths_call[0])
1065 self.assertEqual(path, paths_call[1])
1066 self.assertFalse(paths_call[2])
1067 # we need to push the delete events in reverse order because we want
1068 # to delete children before we delete parents
1069 present_files = present_files[::-1]
1070 for i, called_method in enumerate(self.general.called_methods):
1071 self.assertEqual('eq_push', called_method[0])
1072 self.assertEqual('FS_FILE_DELETE', called_method[1])
1073 self.assertEqual(present_files[i], called_method[2])
1074
1075 def test_handle_dir_delete_dirs(self):
1076 """Test that the handle dir delete works as expected."""
1077 path = 'path'
1078 present_files = 'abcde'
1079 # create files and dirs to be returned from the get paths
1080 for file_name in present_files:
1081 self.general.paths_to_return.append((file_name, True))
1082 self.processor.handle_dir_delete(path)
1083 # there are calls for, rm the wathc, get paths and then one per file
1084 self.assertEqual(2 * len(present_files) + 2,
1085 len(self.general.called_methods))
1086 rm_call = self.general.called_methods.pop(0)
1087 self.assertEqual('rm_watch', rm_call[0])
1088 self.assertEqual(path, rm_call[1])
1089 paths_call = self.general.called_methods.pop(0)
1090 self.assertEqual('get_paths_starting_with', paths_call[0])
1091 self.assertEqual(path, paths_call[1])
1092 self.assertFalse(paths_call[2])
1093 # we need to push the delete events in reverse order because we want
1094 # to delete children before we delete parents
1095 present_files = present_files[::-1]
1096
1097 # from http://docs.python.org/library/itertools.html#recipes
1098 def grouper(n, iterable, fillvalue=None):
1099 "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
1100 args = [iter(iterable)] * n
1101 return itertools.izip_longest(fillvalue=fillvalue, *args)
1102
1103 for i, called_methods in enumerate(grouper(2,
1104 self.general.called_methods)):
1105 rm_call = called_methods[0]
1106 self.assertEqual('rm_watch', rm_call[0])
1107 self.assertEqual(present_files[i], rm_call[1])
1108 push_call = called_methods[1]
1109 self.assertEqual('eq_push', push_call[0])
1110 self.assertEqual('FS_DIR_DELETE', push_call[1])
1111 self.assertEqual(present_files[i], push_call[2])
1112
1113 def test_freeze_begin(self):
1114 """Test that the freeze being works as expected."""
1115 path = 'path'
1116 self.processor.freeze_begin(path)
1117 self.assertEqual(1, len(self.general.called_methods))
1118 self.assertEqual('freeze_begin',
1119 self.general.called_methods[0][0])
1120 self.assertEqual(path, self.general.called_methods[0][1])
1121
1122 def test_freeze_rollback(self):
1123 """Test that the freeze rollback works as expected."""
1124 self.processor.freeze_rollback()
1125 self.assertEqual(1, len(self.general.called_methods))
1126 self.assertEqual('freeze_rollback',
1127 self.general.called_methods[0][0])
1128
1129 def test_freeze_commit(self):
1130 """Test that the freeze commit works as expected."""
1131 path = 'path'
1132 self.processor.freeze_commit(path)
1133 self.assertEqual(1, len(self.general.called_methods))
1134 self.assertEqual('freeze_commit',
1135 self.general.called_methods[0][0])
1136 self.assertEqual(path, self.general.called_methods[0][1])
7021137
=== modified file 'ubuntuone/platform/windows/filesystem_notifications.py'
--- ubuntuone/platform/windows/filesystem_notifications.py 2011-07-29 13:32:31 +0000
+++ ubuntuone/platform/windows/filesystem_notifications.py 2011-07-29 17:34:51 +0000
@@ -152,11 +152,6 @@
152 # a directory from a thread152 # a directory from a thread
153 self._watch_started_deferred = defer.Deferred()153 self._watch_started_deferred = defer.Deferred()
154154
155 def _is_excluded(self, event):
156 """Return if an event is ignored."""
157 return event.mask == IN_OPEN | IN_ISDIR
158
159 # XXX: confirm is using this decorator is correct!!! (nessita)
160 @is_valid_windows_path(path_indexes=[1])155 @is_valid_windows_path(path_indexes=[1])
161 def _path_is_dir(self, path):156 def _path_is_dir(self, path):
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."""
@@ -223,9 +218,7 @@
223 # the exclude filter returns False, that is, the event will not218 # the exclude filter returns False, that is, the event will not
224 # be excluded219 # be excluded
225 self.log.debug('Event is %s.', event)220 self.log.debug('Event is %s.', event)
226 if not self._is_excluded(event):221 self._processor(event)
227 self.log.debug('Processing event %r', event)
228 self._processor(event)
229222
230 def _watch(self):223 def _watch(self):
231 """Watch a path that is a directory."""224 """Watch a path that is a directory."""
@@ -500,6 +493,9 @@
500493
501 def process_IN_MODIFY(self, event):494 def process_IN_MODIFY(self, event):
502 """Capture a modify event and fake an open ^ close write events."""495 """Capture a modify event and fake an open ^ close write events."""
496 # lets ignore dir changes
497 if event.dir:
498 return
503 # on windows we just get IN_MODIFY, lets always fake499 # on windows we just get IN_MODIFY, lets always fake
504 # an OPEN & CLOSE_WRITE couple500 # an OPEN & CLOSE_WRITE couple
505 raw_open = raw_close = {501 raw_open = raw_close = {
@@ -508,20 +504,13 @@
508 'name': event.name,504 'name': event.name,
509 'path': event.path}505 'path': event.path}
510 # caculate the open mask506 # caculate the open mask
511 if event.dir:507 raw_open['mask'] = IN_OPEN
512 raw_open['mask'] = IN_OPEN | IN_ISDIR
513 else:
514 raw_open['mask'] = IN_OPEN
515 # create the event using the raw data, then fix the pathname param508 # create the event using the raw data, then fix the pathname param
516 open_event = Event(raw_open)509 open_event = Event(raw_open)
517 open_event.pathname = event.pathname510 open_event.pathname = event.pathname
518 # push the open511 # push the open
519 self.general_processor.push_event(open_event)512 self.general_processor.push_event(open_event)
520 # calculate the close mask513 raw_close['mask'] = IN_CLOSE_WRITE
521 if event.dir:
522 raw_close['mask'] = IN_CLOSE_WRITE | IN_ISDIR
523 else:
524 raw_close['mask'] = IN_CLOSE_WRITE
525 close_event = Event(raw_close)514 close_event = Event(raw_close)
526 close_event.pathname = event.pathname515 close_event.pathname = event.pathname
527 # push the close event516 # push the close event
@@ -534,6 +523,36 @@
534 self.held_event)523 self.held_event)
535 self.held_event = event524 self.held_event = event
536525
526 def _fake_create_event(self, event):
527 """Fake the creation of an event."""
528 # this is the case of a MOVE from an ignored path (links for example)
529 # to a valid path
530 if event.dir:
531 evtname = "FS_DIR_"
532 else:
533 evtname = "FS_FILE_"
534 self.general_processor.eq_push(evtname + "CREATE", path=event.pathname)
535 if not event.dir:
536 self.general_processor.eq_push('FS_FILE_CLOSE_WRITE',
537 path=event.pathname)
538
539 def _fake_delete_create_event(self, event):
540 """Fake the deletion and the creation."""
541 # this is the case of a MOVE from a watch UDF to a diff UDF which
542 # means that we have to copy the way linux works.
543 if event.dir:
544 evtname = "FS_DIR_"
545 else:
546 evtname = "FS_FILE_"
547 m = "Delete because of different shares: %r"
548 self.log.info(m, self.held_event.pathname)
549 self.general_processor.eq_push(evtname + "DELETE",
550 path=self.held_event.pathname)
551 self.general_processor.eq_push(evtname + "CREATE", path=event.pathname)
552 if not event.dir:
553 self.general_processor.eq_push('FS_FILE_CLOSE_WRITE',
554 path=event.pathname)
555
537 def process_IN_MOVED_TO(self, event):556 def process_IN_MOVED_TO(self, event):
538 """Capture the MOVED_TO to maybe syntethize FILE_MOVED."""557 """Capture the MOVED_TO to maybe syntethize FILE_MOVED."""
539 if self.held_event is not None:558 if self.held_event is not None:
@@ -548,37 +567,21 @@
548 f_path_dir)567 f_path_dir)
549 t_share_id = self.general_processor.get_path_share_id(568 t_share_id = self.general_processor.get_path_share_id(
550 t_path_dir)569 t_path_dir)
551 if event.dir:
552 evtname = "FS_DIR_"
553 else:
554 evtname = "FS_FILE_"
555 if f_share_id != t_share_id:570 if f_share_id != t_share_id:
556 # if the share_id are != push a delete/create571 # if the share_id are != push a delete/create
557 m = "Delete because of different shares: %r"572 self._fake_delete_create_event(event)
558 self.log.info(m, self.held_event.pathname)
559 self.general_processor.eq_push(
560 evtname + "DELETE", path=self.held_event.pathname)
561 self.general_processor.eq_push(
562 evtname + "CREATE", path=event.pathname)
563 if not event.dir:
564 self.general_processor.eq_push(
565 'FS_FILE_CLOSE_WRITE', path=event.pathname)
566 else:573 else:
574 if event.dir:
575 evtname = "FS_DIR_"
576 else:
577 evtname = "FS_FILE_"
567 self.general_processor.eq_push(evtname + "MOVE",578 self.general_processor.eq_push(evtname + "MOVE",
568 path_from=self.held_event.pathname,579 path_from=self.held_event.pathname,
569 path_to=event.pathname)580 path_to=event.pathname)
570 elif is_to_forreal:581 elif is_to_forreal:
571 # this is the case of a MOVE from something ignored582 # this is the case of a MOVE from something ignored
572 # to a valid filename583 # to a valid filename
573 if event.dir:584 self._fake_create_event(event)
574 evtname = "FS_DIR_"
575 else:
576 evtname = "FS_FILE_"
577 self.general_processor.eq_push(evtname + "CREATE",
578 path=event.pathname)
579 if not event.dir:
580 self.general_processor.eq_push('FS_FILE_CLOSE_WRITE',
581 path=event.pathname)
582585
583 self.held_event = None586 self.held_event = None
584 return587 return
@@ -601,7 +604,8 @@
601 @is_valid_syncdaemon_path(path_indexes=[1])604 @is_valid_syncdaemon_path(path_indexes=[1])
602 def handle_dir_delete(self, fullpath):605 def handle_dir_delete(self, fullpath):
603 """Some special work when a directory is deleted."""606 """Some special work when a directory is deleted."""
604 # remove the watch on that dir from our structures607 # remove the watch on that dir from our structures, this mainly tells
608 # the monitor to remove the watch which is fowaded to a watch manager.
605 self.general_processor.rm_watch(fullpath)609 self.general_processor.rm_watch(fullpath)
606610
607 # handle the case of move a dir to a non-watched directory611 # handle the case of move a dir to a non-watched directory
@@ -613,6 +617,7 @@
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"
614 self.general_processor.log.info(m, is_dir, path)618 self.general_processor.log.info(m, is_dir, path)
615 if is_dir:619 if is_dir:
620 # same as the above remove
616 self.general_processor.rm_watch(path)621 self.general_processor.rm_watch(path)
617 self.general_processor.eq_push('FS_DIR_DELETE', path=path)622 self.general_processor.eq_push('FS_DIR_DELETE', path=path)
618 else:623 else:
@@ -661,10 +666,6 @@
661 self.log.setLevel(TRACE)666 self.log.setLevel(TRACE)
662 self.fs = fs667 self.fs = fs
663 self.eq = eq668 self.eq = eq
664 # XXX: We need to find a decent time for the time out, is 0.2 seconds
665 # too little?
666 self.timeout = timeout
667 # general inotify
668 self._processor = NotifyProcessor(self, ignore_config)669 self._processor = NotifyProcessor(self, ignore_config)
669 self._watch_manager = WatchManager(self._processor)670 self._watch_manager = WatchManager(self._processor)
670671
@@ -697,12 +698,6 @@
697 self._watch_manager.add_watch(dirpath, FILESYSTEM_MONITOR_MASK,698 self._watch_manager.add_watch(dirpath, FILESYSTEM_MONITOR_MASK,
698 auto_add=True)699 auto_add=True)
699700
700 @windowspath(path_indexes=[1])
701 def has_watch(self, dirpath):
702 """Check if a dirpath is watched."""
703 wd = self._watch_manager.get_wd(dirpath)
704 return wd is not None
705
706 def is_frozen(self):701 def is_frozen(self):
707 """Checks if there's something frozen."""702 """Checks if there's something frozen."""
708 return self._processor.frozen_path is not None703 return self._processor.frozen_path is not None

Subscribers

People subscribed via source and target branches