~verterok/ubuntuone-client/tritcask-3

« back to all changes in this revision

Viewing changes to tests/syncdaemon/test_vm.py

  • Committer: guillermo.gonzalez at canonical
  • Date: 2010-12-13 20:55:10 UTC
  • mfrom: (757.1.16 ubuntuone-client)
  • Revision ID: guillermo.gonzalez@canonical.com-20101213205510-md2aq59wyv9zv0m2
merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
from __future__ import with_statement
22
22
 
23
23
import collections
 
24
import inspect
24
25
import logging
25
26
import os
26
27
import uuid
37
38
    environ,
38
39
    MementoHandler,
39
40
)
40
 
from ubuntuone.syncdaemon import config
 
41
from ubuntuone.syncdaemon import config, event_queue
41
42
from ubuntuone.syncdaemon.volume_manager import (
42
43
    Share,
43
44
    Shared,
51
52
    VMFileShelf,
52
53
    VolumeDoesNotExist,
53
54
)
54
 
from ubuntuone.platform import get_udf_path_name
 
55
from ubuntuone.platform import get_udf_path_name, get_udf_path, get_share_path
55
56
from twisted.internet import defer, reactor
56
57
 
57
58
# grab the metadata version before tests fiddle with it
101
102
                self.hits = 0
102
103
                self.events = []
103
104
 
104
 
            def _handle_event(self, *args, **kwargs):
 
105
            def _handle_event(self, **kwargs):
105
106
                self.hits += 1
106
107
                if collect:
107
 
                    self.events.append((args, kwargs))
 
108
                    self.events.append(kwargs)
108
109
                if self.hits == count:
109
110
                    event_q.unsubscribe(self)
110
111
                    if collect:
111
112
                        callback(self.events)
112
 
                    elif kwargs:
113
 
                        callback((args, kwargs))
114
113
                    else:
115
 
                        callback(args)
 
114
                        callback(kwargs)
116
115
 
117
116
        listener = Listener()
118
117
        setattr(listener, 'handle_'+event, listener._handle_event)
123
122
                    generation=None, free_bytes=100):
124
123
        """Create an UDF and returns it and the volume"""
125
124
        with environ('HOME', self.home_dir):
126
 
            path = self.vm._build_udf_path(suggested_path)
 
125
            path = get_udf_path(suggested_path)
127
126
        # make sure suggested_path is unicode
128
127
        if isinstance(suggested_path, str):
129
128
            suggested_path = suggested_path.decode('utf-8')
147
146
 
148
147
        res = yield d
149
148
        mdobj = self.main.fs.get_by_path(self.root_dir)
150
 
        self.assertEqual(res, ('root_uuid', mdobj.mdid))
 
149
        self.assertEqual(res, dict(root_id='root_uuid', mdid=mdobj.mdid))
151
150
 
152
151
    @defer.inlineCallbacks
153
152
    def test__got_root_ok_twice(self):
162
161
 
163
162
        res = yield d
164
163
        mdobj = self.main.fs.get_by_path(self.root_dir)
165
 
        self.assertEqual(res, ('root_uuid', mdobj.mdid))
 
164
        self.assertEqual(res, dict(root_id='root_uuid', mdid=mdobj.mdid))
166
165
 
167
166
    @defer.inlineCallbacks
168
167
    def test__got_root_mismatch(self):
439
438
        def fake_delete_share(share_id):
440
439
            """Fake delete_share."""
441
440
            self.assertEqual(share_id, share.volume_id)
442
 
            self.main.event_q.push('AQ_DELETE_SHARE_OK', share_id)
 
441
            self.main.event_q.push('AQ_DELETE_SHARE_OK', share_id=share_id)
443
442
 
444
443
        self.patch(self.main.action_q, 'delete_share', fake_delete_share)
445
444
        d = defer.Deferred()
447
446
        self.vm.delete_share(share.volume_id)
448
447
        events = yield d
449
448
        event = events[0]
450
 
        self.assertEqual(event[0], (share,))
 
449
        self.assertEqual(event['share'], share)
451
450
 
452
451
    @defer.inlineCallbacks
453
452
    def test_delete_shared_error(self):
461
460
        def fake_delete_share(share_id):
462
461
            """Fake delete_share that always fails."""
463
462
            self.main.event_q.push('AQ_DELETE_SHARE_ERROR',
464
 
                                   share_id, 'a fake error')
 
463
                                   share_id=share_id, error='a fake error')
465
464
 
466
465
        self.patch(self.main.action_q, 'delete_share', fake_delete_share)
467
466
        d = defer.Deferred()
468
467
        self._listen_for('VM_SHARE_DELETE_ERROR', d.callback, 1, collect=True)
469
468
        self.vm.delete_share(share.volume_id)
470
469
        events = yield d
471
 
        event = events[0]
472
 
        self.assertEqual(event[0], (share.volume_id, 'a fake error'))
 
470
        self.assertEqual(events[0],
 
471
                         dict(share_id=share.volume_id, error='a fake error'))
473
472
 
474
473
    @defer.inlineCallbacks
475
474
    def test_delete_shared_error_missing_share(self):
481
480
        self._listen_for('VM_SHARE_DELETE_ERROR', d.callback, 1, collect=True)
482
481
        self.vm.delete_share('fake_share_id')
483
482
        events = yield d
484
 
        event = events[0]
485
 
        self.assertEqual(event[0], ('fake_share_id', 'DOES_NOT_EXIST'))
 
483
        self.assertEqual(events[0],
 
484
                         dict(share_id='fake_share_id', error='DOES_NOT_EXIST'))
486
485
 
487
486
    def test_accept_share(self):
488
487
        """ Test the accept_share method. """
668
667
        d = defer.Deferred()
669
668
        self._listen_for('SYS_ROOT_MISMATCH', d.callback)
670
669
        self.vm._got_root('root_id')
671
 
        current_id, new_id = yield d
672
 
        self.assertEquals('root_node_id', current_id)
673
 
        self.assertEquals('root_id', new_id)
 
670
        info = yield d
 
671
        self.assertEqual('root_node_id', info['root_id'])
 
672
        self.assertEqual('root_id', info['new_root_id'])
674
673
 
675
674
    def test_handle_SYS_QUOTA_EXCEEDED_is_called(self):
676
675
        """Test that we handle the event."""
694
693
        """Test that it updates the free space when error is on an UDF."""
695
694
        # create the udf
696
695
        with environ('HOME', self.home_dir):
697
 
            path = self.vm._build_udf_path(u"~/UDF")
 
696
            path = get_udf_path(u"~/UDF")
698
697
        volume_id = str(uuid.uuid4())
699
698
        volume = volumes.UDFVolume(volume_id, 'udf_node_id', None, 0, u"~/UDF")
700
699
        udf = UDF.from_udf_volume(volume, path)
713
712
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
714
713
                                           10, 'to_me', 'fake_share', 'usern',
715
714
                                           'visible_username', True, 'Modify')
716
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
717
 
                                             share_volume.other_visible_name)
 
715
        dir_name = get_share_path(share_volume.share_name,
 
716
                                  share_volume.other_visible_name)
718
717
        share_path = os.path.join(self.main.shares_dir, dir_name)
719
718
        share = Share.from_share_volume(share_volume, share_path)
720
719
        self.vm.add_share(share)
730
729
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
731
730
                                           10, 'to_me', 'fake_share', 'usern',
732
731
                                           'visible_username', False, 'View')
733
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
734
 
                                          share_volume.other_visible_name)
 
732
        dir_name = get_share_path(share_volume.share_name,
 
733
                                  share_volume.other_visible_name)
735
734
        share_path = os.path.join(self.main.shares_dir, dir_name)
736
735
        share = Share.from_share_volume(share_volume, share_path)
737
736
 
762
761
        self.vm.add_shared(share)
763
762
        d = defer.Deferred()
764
763
        self._listen_for('VM_SHARE_DELETED', d.callback, 1, collect=True)
765
 
        self.main.event_q.push('AQ_DELETE_SHARE_OK', 'share_id')
 
764
        self.main.event_q.push('AQ_DELETE_SHARE_OK', share_id='share_id')
766
765
        events = yield d
767
 
        event = events[0]
768
 
        self.assertEqual(event[0], (share,))
 
766
        self.assertEqual(events[0], dict(share=share))
769
767
 
770
768
    @defer.inlineCallbacks
771
769
    def test_handle_AQ_DELETE_SHARE_ERROR(self):
778
776
        d = defer.Deferred()
779
777
        self._listen_for('VM_SHARE_DELETE_ERROR', d.callback, 1, collect=True)
780
778
        self.main.event_q.push('AQ_DELETE_SHARE_ERROR',
781
 
                               'share_id', 'a fake error')
 
779
                               share_id='share_id', error='a fake error')
782
780
        events = yield d
783
 
        event = events[0]
784
 
        self.assertEqual(event[0], (share.volume_id, 'a fake error'))
 
781
        self.assertEqual(events[0],
 
782
                         dict(share_id=share.volume_id, error='a fake error'))
 
783
 
 
784
    def test_event_listener(self):
 
785
        """All event listeners should define methods with correct signature."""
 
786
        for evtname, evtargs in event_queue.EVENTS.iteritems():
 
787
            meth = getattr(VolumeManager, 'handle_' + evtname, None)
 
788
            if meth is not None:
 
789
                defined_args = inspect.getargspec(meth)[0]
 
790
                self.assertEqual(defined_args[0], 'self')
 
791
                self.assertEqual(set(defined_args[1:]), set(evtargs))
785
792
 
786
793
 
787
794
class VolumeManagerUnicodeTests(BaseVolumeManagerTests):
862
869
        os.environ['HOME'] = self.home_dir
863
870
        self.addCleanup(lambda: os.environ.__setitem__('HOME', old_home))
864
871
 
865
 
    def test_build_udf_path(self):
866
 
        """Test for VolumeManager._build_udf_path."""
867
 
        suggested_path = u"suggested_path"
868
 
        with environ('HOME', self.home_dir):
869
 
            udf_path = self.vm._build_udf_path(u"~/" + suggested_path)
870
 
        self.assertEquals(os.path.join(self.home_dir,
871
 
                                       suggested_path.encode('utf-8')),
872
 
                          udf_path)
873
 
 
874
872
    def test_udf_ancestors(self):
875
873
        """UDF's ancestors are correctly returned."""
876
874
        suggested_path = u'~/Documents/Reading/Books/PDFs'
1002
1000
                                           10, 'to_me', 'fake_share',
1003
1001
                                           'username', 'visible_username',
1004
1002
                                           True, 'View')
1005
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
1006
 
                                          share_volume.other_visible_name)
 
1003
        dir_name = get_share_path(share_volume.share_name,
 
1004
                                  share_volume.other_visible_name)
1007
1005
        share_path = os.path.join(self.main.shares_dir, dir_name)
1008
1006
        share = Share.from_share_volume(share_volume, share_path)
1009
1007
        # create a UDF
1205
1203
        events = yield d2
1206
1204
        yield share_created_d
1207
1205
 
1208
 
        events = [evt[1] for evt in events]
1209
1206
        expected_events = [{'generation': 10, 'volume_id': str(share_id)},
1210
1207
                           {'generation': 17, 'volume_id': ''}]
1211
1208
        self.assertEqual(events, expected_events)
1220
1217
            self.assertEqual(os.path.join(self.home_dir, 'UDF'), udf.path)
1221
1218
        else:  # udf was not added to VM
1222
1219
            self.assertEqual(2, len(list(self.vm.get_volumes())))
1223
 
            self.assertEqual(0, len(self.vm.udfs)) # the new udf
 
1220
            self.assertEqual(1, len(self.vm.udfs)) # the new udf
 
1221
            self.assertFalse(self.vm.udfs.values()[0].active)
1224
1222
 
1225
1223
        self.assertEqual(2, len(self.vm.shares)) # the share and the root
1226
1224
        # check that the share is in the shares dict
1244
1242
            # root, share and udf
1245
1243
            self.assertEqual(1, len(self.vm.udfs)) # one udf
1246
1244
            self.assertEqual(3, len(list(self.vm.get_volumes())))
1247
 
        else:  # udf was not added to VM
 
1245
        else:  # udf was added to VM, but isn't active
1248
1246
            self.assertEqual(2, len(list(self.vm.get_volumes())))
1249
 
            self.assertEqual(0, len(self.vm.udfs)) # the new udf
 
1247
            self.assertEqual(1, len(self.vm.udfs)) # the new udf
 
1248
            self.assertFalse(self.vm.udfs.values()[0].active)
1250
1249
 
1251
1250
    @defer.inlineCallbacks
1252
1251
    def test_handle_AQ_LIST_VOLUMES_accepted_share_with_autosubscribe(self):
1310
1309
        # patch AQ.create_udf
1311
1310
        def create_udf(path, name, marker):
1312
1311
            """Fake create_udf"""
1313
 
            self.main.event_q.push("AQ_CREATE_UDF_OK", **dict(volume_id=udf_id,
1314
 
                                                       node_id=node_id,
1315
 
                                                       marker=marker))
 
1312
            self.main.event_q.push("AQ_CREATE_UDF_OK", volume_id=udf_id,
 
1313
                                   node_id=node_id, marker=marker)
1316
1314
        self.main.action_q.create_udf = create_udf
1317
 
        def check(udf):
 
1315
        def check(info):
1318
1316
            """Check the udf attributes."""
1319
 
            udf = udf[0]
 
1317
            udf = info['udf']
1320
1318
            self.assertEquals(udf.path, path)
1321
1319
            self.assertEquals(udf.volume_id, str(udf_id))
1322
1320
            self.assertEquals(udf.node_id, str(node_id))
1372
1370
                                           10, 'to_me', u'ñoño',
1373
1371
                                           'username', u'visible_username',
1374
1372
                                           True, 'View')
1375
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
1376
 
                                          share_volume.other_visible_name)
 
1373
        dir_name = get_share_path(share_volume.share_name,
 
1374
                                  share_volume.other_visible_name)
1377
1375
        share_path = os.path.join(self.main.shares_dir, dir_name)
1378
1376
        share = Share.from_share_volume(share_volume, share_path)
1379
1377
        self.vm.add_share(share)
1385
1383
        self.main.action_q.delete_volume = delete_volume
1386
1384
        def check_udf(info):
1387
1385
            """Check the udf attributes."""
1388
 
            deleted_udf = info[0]
 
1386
            deleted_udf = info['volume']
1389
1387
            self.assertEquals(deleted_udf.path, udf.path)
1390
1388
            self.assertEquals(deleted_udf.volume_id, udf.volume_id)
1391
1389
            self.assertEquals(deleted_udf.node_id, udf.node_id)
1399
1397
 
1400
1398
        def check_share(info):
1401
1399
            """Check the share attributes."""
1402
 
            deleted_share = info[0]
 
1400
            deleted_share = info['volume']
1403
1401
            self.assertEquals(deleted_share.path, share.path)
1404
1402
            self.assertEquals(deleted_share.volume_id, share.volume_id)
1405
1403
            self.assertEquals(deleted_share.node_id, share.node_id)
1704
1702
        # patch AQ.create_udf
1705
1703
        def create_udf(path, name, marker):
1706
1704
            """Fake create_udf"""
1707
 
            self.main.event_q.push("AQ_CREATE_UDF_OK", **dict(volume_id=udf_id,
1708
 
                                                       node_id=node_id,
1709
 
                                                       marker=marker))
 
1705
            self.main.event_q.push("AQ_CREATE_UDF_OK", volume_id=udf_id,
 
1706
                                   node_id=node_id, marker=marker)
1710
1707
        self.main.action_q.create_udf = create_udf
1711
1708
        self._listen_for('VM_UDF_CREATED', d.callback)
1712
1709
        # fake VM state, call create_udf
1714
1711
            self.vm.create_udf(path)
1715
1712
        def check(info):
1716
1713
            """The callback"""
1717
 
            udf = info[0]
 
1714
            udf = info['udf']
1718
1715
            self.assertEquals(udf.path, path)
1719
1716
            self.assertEquals(udf.volume_id, str(udf_id))
1720
1717
            self.assertEquals(udf.node_id, str(node_id))
1732
1729
        # patch AQ.create_udf
1733
1730
        def create_udf(path, name, marker):
1734
1731
            """Fake create_udf"""
1735
 
            self.main.event_q.push("AQ_CREATE_UDF_ERROR", **dict(marker=marker,
1736
 
                                                            error="ERROR!"))
 
1732
            self.main.event_q.push("AQ_CREATE_UDF_ERROR",
 
1733
                                   marker=marker, error="ERROR!")
1737
1734
        self.main.action_q.create_udf = create_udf
1738
1735
        self._listen_for('VM_UDF_CREATE_ERROR', d.callback)
1739
1736
        # fake VM state, call create_udf
1741
1738
            self.vm.create_udf(path)
1742
1739
        def check(info):
1743
1740
            """The callback"""
1744
 
            udf_path, error = info
1745
 
            self.assertEquals(udf_path, path)
1746
 
            self.assertEquals(error, "ERROR!")
 
1741
            self.assertEquals(info['path'], path)
 
1742
            self.assertEquals(info['error'], "ERROR!")
1747
1743
            self.assertEquals(0, len(self.vm.marker_udf_map))
1748
1744
        d.addCallback(check)
1749
1745
        return d
1763
1759
        self.main.action_q.delete_volume = delete_volume
1764
1760
        def check(info):
1765
1761
            """Check the udf attributes."""
1766
 
            deleted_udf = info[0]
 
1762
            deleted_udf = info['volume']
1767
1763
            self.assertEquals(deleted_udf.path, udf.path)
1768
1764
            self.assertEquals(deleted_udf.volume_id, udf.volume_id)
1769
1765
            self.assertEquals(deleted_udf.node_id, udf.node_id)
1791
1787
        self.main.action_q.delete_volume = delete_volume
1792
1788
        def check(info):
1793
1789
            """Check the udf attributes."""
1794
 
            deleted_udf, error = info
 
1790
            deleted_udf, error = info['volume_id'], info['error']
1795
1791
            self.assertEquals(deleted_udf, udf.volume_id)
1796
1792
            self.assertIn(deleted_udf, self.vm.udfs)
1797
1793
            self.assertEquals(error, 'ERROR!')
1833
1829
        with environ('HOME', self.home_dir):
1834
1830
            self.vm.handle_SV_VOLUME_CREATED(udf_volume)
1835
1831
        info = yield d
1836
 
        udf = info[0]
 
1832
        udf = info['udf']
1837
1833
        self.assertEquals(udf.volume_id, str(udf_id))
1838
1834
        self.assertIn(str(udf_id), self.vm.udfs)
1839
1835
        if auto_subscribe:
1854
1850
        with environ('HOME', self.home_dir):
1855
1851
            self.vm.handle_SV_VOLUME_CREATED(share_volume)
1856
1852
        info = yield d
1857
 
        share_id = info[0]
 
1853
        share_id = info['share_id']
1858
1854
        share = self.vm.get_volume(share_id)
1859
1855
        self.assertEquals(share.volume_id, str(share_id))
1860
1856
        self.assertIn(str(share_id), self.vm.shares)
1878
1874
                                           10, 'to_me', u'ñoño',
1879
1875
                                           'username', u'visible_username',
1880
1876
                                           True, 'View')
1881
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
1882
 
                                          share_volume.other_visible_name)
 
1877
        dir_name = get_share_path(share_volume.share_name,
 
1878
                                  share_volume.other_visible_name)
1883
1879
        share_path = os.path.join(self.main.shares_dir, dir_name)
1884
1880
        share = Share.from_share_volume(share_volume, share_path)
1885
1881
        # create a UDF
1895
1891
            self.vm.handle_SV_VOLUME_DELETED(udf_volume.volume_id)
1896
1892
        info = yield d
1897
1893
 
1898
 
        udf = info[0]
 
1894
        udf = info['volume']
1899
1895
        self.assertEquals(udf.volume_id, str(udf_id))
1900
1896
        self.assertNotIn(str(udf_id), self.vm.udfs)
1901
1897
        # subscribe a new listener, for deleting a share.
1905
1901
        with environ('HOME', self.home_dir):
1906
1902
            self.vm.handle_SV_VOLUME_DELETED(share_volume.volume_id)
1907
1903
        share_info = yield share_deferred
1908
 
        share = share_info[0]
 
1904
        share = share_info['volume']
1909
1905
        self.assertEquals(share.volume_id, str(share_id))
1910
1906
        self.assertNotIn(str(share.volume_id), self.vm.shares)
1911
1907
 
1964
1960
        """Test for UDF.from_udf_volume."""
1965
1961
        suggested_path = u'~/foo/bar'
1966
1962
        with environ('HOME', self.home_dir):
1967
 
            path = self.vm._build_udf_path(suggested_path)
 
1963
            path = get_udf_path(suggested_path)
1968
1964
        volume = volumes.UDFVolume(uuid.uuid4(), uuid.uuid4(), None,
1969
1965
                                   10, suggested_path)
1970
1966
        udf = UDF.from_udf_volume(volume, path)
1976
1972
        volume = volumes.ShareVolume(uuid.uuid4(), uuid.uuid4(), None, 10,
1977
1973
                                     "to_me", u"share_name", u"other_username",
1978
1974
                                     u"other_visible_name", True, 'Modify')
1979
 
        dir_name = self.vm._build_share_path(volume.share_name,
1980
 
                                          volume.other_visible_name)
 
1975
        dir_name = get_share_path(volume.share_name,
 
1976
                                  volume.other_visible_name)
1981
1977
        path = os.path.join(self.main.shares_dir, dir_name)
1982
1978
        share = Share.from_share_volume(volume, path)
1983
1979
        self.assertTrue(isinstance(share.id, basestring))
2014
2010
        self._listen_for('VM_UDF_CREATED', lambda r: d.errback(Exception(r)))
2015
2011
        self.vm.create_udf(udf_path)
2016
2012
        result = yield d
2017
 
        self.assertEquals(0, len(list(self.vm.udfs.keys())))
2018
 
        self.assertEquals(result[0], udf_path)
2019
 
        self.assertEquals(result[1], "UDFs can not be nested")
 
2013
        self.assertEqual(0, len(list(self.vm.udfs.keys())))
 
2014
        self.assertEqual(result,
 
2015
                         dict(path=udf_path, error="UDFs can not be nested"))
2020
2016
 
2021
2017
    @defer.inlineCallbacks
2022
2018
    def test_no_UDFs_inside_udf(self):
2028
2024
        # patch FakeAQ
2029
2025
        def create_udf(path, name, marker):
2030
2026
            """Fake create_udf"""
2031
 
            self.main.event_q.push("AQ_CREATE_UDF_OK", **dict(volume_id=uuid.uuid4(),
2032
 
                                                       node_id=uuid.uuid4(),
2033
 
                                                       marker=marker))
 
2027
            self.main.event_q.push("AQ_CREATE_UDF_OK", volume_id=uuid.uuid4(),
 
2028
                                   node_id=uuid.uuid4(), marker=marker)
2034
2029
        self.main.action_q.create_udf = create_udf
2035
2030
        d = defer.Deferred()
2036
2031
        self._listen_for('VM_UDF_CREATE_ERROR', d.callback)
2038
2033
        self.vm.create_udf(udf_child)
2039
2034
        result = yield d
2040
2035
        self.assertEquals(1, len(list(self.vm.udfs.keys())))
2041
 
        self.assertEquals(result[0], udf_child)
2042
 
        self.assertEquals(result[1], "UDFs can not be nested")
 
2036
        self.assertEqual(result,
 
2037
                         dict(path=udf_child, error="UDFs can not be nested"))
2043
2038
 
2044
2039
    @defer.inlineCallbacks
2045
2040
    def test_no_UDFs_as_UDF_parent(self):
2051
2046
        # patch FakeAQ
2052
2047
        def create_udf(path, name, marker):
2053
2048
            """Fake create_udf."""
2054
 
            self.main.event_q.push("AQ_CREATE_UDF_OK", **dict(volume_id=uuid.uuid4(),
2055
 
                                                       node_id=uuid.uuid4(),
2056
 
                                                       marker=marker))
 
2049
            self.main.event_q.push("AQ_CREATE_UDF_OK", volume_id=uuid.uuid4(),
 
2050
                                   node_id=uuid.uuid4(), marker=marker)
2057
2051
        self.main.action_q.create_udf = create_udf
2058
2052
        d = defer.Deferred()
2059
2053
        self._listen_for('VM_UDF_CREATE_ERROR', d.callback)
2061
2055
        self.vm.create_udf(udf_parent_path)
2062
2056
        result = yield d
2063
2057
        self.assertEquals(1, len(list(self.vm.udfs.keys())))
2064
 
        self.assertEquals(result[0], udf_parent_path)
2065
 
        self.assertEquals(result[1], "UDFs can not be nested")
 
2058
        d = dict(path=udf_parent_path, error="UDFs can not be nested")
 
2059
        self.assertEqual(result, d)
2066
2060
 
2067
2061
 
2068
2062
    @defer.inlineCallbacks
2109
2103
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
2110
2104
                                           None, 'to_me', 'fake_share', 'username',
2111
2105
                                           'visible_username', True, 'View')
2112
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
2113
 
                                          share_volume.other_visible_name)
 
2106
        dir_name = get_share_path(share_volume.share_name,
 
2107
                                  share_volume.other_visible_name)
2114
2108
        share_path = os.path.join(self.main.shares_dir, dir_name)
2115
2109
        share = Share.from_share_volume(share_volume, share_path)
2116
2110
        # get the root
2152
2146
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
2153
2147
                                           None, 'to_me', 'fake_share', 'username',
2154
2148
                                           'visible_username', True, 'View')
2155
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
2156
 
                                          share_volume.other_visible_name)
 
2149
        dir_name = get_share_path(share_volume.share_name,
 
2150
                                  share_volume.other_visible_name)
2157
2151
        share_path = os.path.join(self.main.shares_dir, dir_name)
2158
2152
        share = Share.from_share_volume(share_volume, share_path)
2159
2153
        # get the root
2204
2198
        # patch FakeAQ
2205
2199
        def create_udf(path, name, marker):
2206
2200
            """Fake create_udf"""
2207
 
            self.main.event_q.push("AQ_CREATE_UDF_OK", **dict(volume_id=uuid.uuid4(),
2208
 
                                                       node_id=uuid.uuid4(),
2209
 
                                                       marker=marker))
 
2201
            self.main.event_q.push("AQ_CREATE_UDF_OK", volume_id=uuid.uuid4(),
 
2202
                                   node_id=uuid.uuid4(), marker=marker)
2210
2203
        self.main.action_q.create_udf = create_udf
2211
2204
        # create the symlink
2212
2205
        os.makedirs(real_udf_path)
2217
2210
        self.vm.create_udf(udf_path)
2218
2211
        result = yield d
2219
2212
        self.assertEquals(0, len(list(self.vm.udfs.keys())))
2220
 
        self.assertEquals(result[0], udf_path)
2221
 
        self.assertEquals(result[1], "UDFs can not be a symlink")
 
2213
        self.assertEqual(result, dict(path=udf_path,
 
2214
                                      error="UDFs can not be a symlink"))
2222
2215
 
2223
2216
    @defer.inlineCallbacks
2224
2217
    def test_UDF_cant_be_inside_symlink(self):
2230
2223
        # patch FakeAQ
2231
2224
        def create_udf(path, name, marker):
2232
2225
            """Fake create_udf"""
2233
 
            self.main.event_q.push("AQ_CREATE_UDF_OK", **dict(volume_id=uuid.uuid4(),
2234
 
                                                       node_id=uuid.uuid4(),
2235
 
                                                       marker=marker))
 
2226
            self.main.event_q.push("AQ_CREATE_UDF_OK", volume_id=uuid.uuid4(),
 
2227
                                   node_id=uuid.uuid4(), marker=marker)
2236
2228
        self.main.action_q.create_udf = create_udf
2237
2229
        # create the symlink
2238
2230
        os.makedirs(real_udf_path)
2243
2235
        self.vm.create_udf(udf_path)
2244
2236
        result = yield d
2245
2237
        self.assertEquals(0, len(list(self.vm.udfs.keys())))
2246
 
        self.assertEquals(result[0], udf_path)
2247
 
        self.assertEquals(result[1], "UDFs can not be a symlink")
 
2238
        self.assertEqual(result, dict(path=udf_path,
 
2239
                                      error="UDFs can not be a symlink"))
2248
2240
 
2249
2241
    @defer.inlineCallbacks
2250
2242
    def test_server_rescan(self):
2270
2262
            yield self.vm.server_rescan()
2271
2263
        yield server_rescan_d
2272
2264
        events = yield vol_rescan_d
2273
 
        events_dict = dict((event[1]['volume_id'], event[1]['generation']) \
 
2265
        events_dict = dict((event['volume_id'], event['generation'])
2274
2266
                           for event in events)
2275
2267
        self.assertIn(str(share_id), events_dict)
2276
2268
        # new udfs server rescan is triggered after local rescan.
2424
2416
        self.assertEqual(udfs, [str(udf_id)])
2425
2417
        # wait for the UDF local and server rescan
2426
2418
        yield udf_d
2427
 
        events_dict = dict((event[1]['volume_id'], event[1]['generation']) \
 
2419
        events_dict = dict((event['volume_id'], event['generation'])
2428
2420
                           for event in events)
2429
2421
        self.assertIn(str(share_id), events_dict)
2430
2422
        # new udfs server rescan is triggered after local rescan.
2452
2444
        with environ('HOME', self.home_dir):
2453
2445
            self.vm._volumes_rescan_cb(response)
2454
2446
        events = yield d
2455
 
        events_dict = dict((event[1]['volume_id'], event[1]['generation']) \
 
2447
        events_dict = dict((event['volume_id'], event['generation'])
2456
2448
                           for event in events)
2457
2449
        self.assertIn(str(share_id), events_dict)
2458
2450
        self.assertIn(str(udf_id), events_dict)
2469
2461
        with environ('HOME', self.home_dir):
2470
2462
            self.vm._volumes_rescan_cb(response)
2471
2463
        events = yield d
2472
 
        events_dict = dict((event[1]['volume_id'], event[1]['generation']) \
 
2464
        events_dict = dict((event['volume_id'], event['generation'])
2473
2465
                           for event in events)
2474
2466
        self.assertNotIn(str(share_id), events_dict)
2475
2467
        self.assertNotIn(str(udf_id), events_dict)
2488
2480
        with environ('HOME', self.home_dir):
2489
2481
            self.vm._volumes_rescan_cb(response)
2490
2482
        events = yield d
2491
 
        events_dict = dict((event[1]['volume_id'], event[1]['generation']) \
 
2483
        events_dict = dict((event['volume_id'], event['generation'])
2492
2484
                           for event in events)
2493
2485
        self.assertIn(request.ROOT, events_dict)
2494
2486
        self.assertEquals(str(root_id), self.vm.root.node_id)
2511
2503
        with environ('HOME', self.home_dir):
2512
2504
            self.vm._volumes_rescan_cb(response)
2513
2505
        events = yield d
2514
 
        events_dict = dict((event[1]['volume_id'], event[1]['generation']) \
 
2506
        events_dict = dict((event['volume_id'], event['generation'])
2515
2507
                           for event in events)
2516
2508
        self.assertIn(request.ROOT, events_dict)
2517
2509
        self.assertEquals(str(root_id), self.vm.root.node_id)
2536
2528
            self.vm._volumes_rescan_cb(response)
2537
2529
        event = yield d
2538
2530
        self.assertEqual(len(event), 2)
2539
 
        events_dict = {event[1]['volume_id']:event[1]['generation']}
 
2531
        events_dict = {event['volume_id']: event['generation']}
2540
2532
        self.assertNotIn(udf.volume_id, events_dict)
2541
2533
        self.assertIn(request.ROOT, events_dict)
2542
2534
 
2562
2554
            self.vm._volumes_rescan_cb(response)
2563
2555
        events = yield d
2564
2556
        self.assertEqual(len(events), 2)
2565
 
        events_dict = dict((evt[1]['volume_id'], evt[1]['generation']) \
 
2557
        events_dict = dict((evt['volume_id'], evt['generation'])
2566
2558
                           for evt in events)
2567
2559
        self.assertIn(udf.volume_id, events_dict)
2568
2560
        self.assertIn(request.ROOT, events_dict)
2573
2565
        self.assertEquals(udf.path, mdobj.path)
2574
2566
 
2575
2567
    @defer.inlineCallbacks
 
2568
    def test_volumes_rescan_cb_active_udf(self):
 
2569
        """Test _volumes_rescan_cb with an active UDF and no-autosubscribe."""
 
2570
        udf_id = uuid.uuid4()
 
2571
        udf, udf_volume = self._create_udf(udf_id, uuid.uuid4(), '~/UDF')
 
2572
        udf_volume.generation = 10
 
2573
        root_id = uuid.uuid4()
 
2574
        root_volume = volumes.RootVolume(root_id, 1, 500)
 
2575
        response = [udf_volume, root_volume]
 
2576
        yield self.vm.add_udf(udf)
 
2577
        # subscribe the udf
 
2578
        yield self.vm.subscribe_udf(udf.volume_id)
 
2579
        d = defer.Deferred()
 
2580
        self._listen_for('SV_VOLUME_NEW_GENERATION', d.callback, 1)
 
2581
        with environ('HOME', self.home_dir):
 
2582
            shares, udfs = self.vm._volumes_rescan_cb(response)
 
2583
            self.assertIn(udf.volume_id, udfs)
 
2584
        yield d
 
2585
 
 
2586
    @defer.inlineCallbacks
2576
2587
    def test_update_generation(self):
2577
2588
        """Test for the update_generation method."""
2578
2589
        share_id = uuid.uuid4()
2579
2590
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
2580
2591
                                           10, 'to_me', 'fake_share', 'username',
2581
2592
                                           'visible_username', True, 'View')
2582
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
2583
 
                                          share_volume.other_visible_name)
 
2593
        dir_name = get_share_path(share_volume.share_name,
 
2594
                                  share_volume.other_visible_name)
2584
2595
        share_path = os.path.join(self.main.shares_dir, dir_name)
2585
2596
        share = Share.from_share_volume(share_volume, share_path)
2586
2597
        # get the root
2617
2628
        self.vm.update_generation(udf.volume_id, 10)
2618
2629
        d = defer.Deferred()
2619
2630
        self.patch(self.main.action_q, 'get_delta', lambda v, g: d.callback((v, g)))
2620
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', udf.volume_id, 100)
 
2631
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2632
                               volume_id=udf.volume_id, generation=100)
2621
2633
        vol_id, gen = yield d
2622
2634
        vol = self.vm.get_volume(vol_id)
2623
2635
        self.assertEqual(vol_id, vol.volume_id)
2633
2645
        self.vm.update_generation(udf.volume_id, None)
2634
2646
        d = defer.Deferred()
2635
2647
        self.patch(self.main.action_q, 'rescan_from_scratch', d.callback)
2636
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', udf.volume_id, 100)
 
2648
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2649
                               volume_id=udf.volume_id, generation=100)
2637
2650
        vol_id = yield d
2638
2651
        self.assertEquals(vol_id, udf.volume_id)
2639
2652
 
2645
2658
        udf, udf_volume = self._create_udf(udf_id, 'udf_node_id', '~/UDF')
2646
2659
        yield self.vm.add_udf(udf)
2647
2660
        self.vm.update_generation(udf.volume_id, 100)
2648
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', udf.volume_id, 100)
 
2661
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2662
                               volume_id=udf.volume_id, generation=100)
2649
2663
        self.assertEqual(1, len(self.handler.records))
2650
2664
        msg = 'Got SV_VOLUME_NEW_GENERATION(%r, %r) but volume' + \
2651
2665
                ' is at generation: %r'
2661
2675
        self.vm.update_generation(root.volume_id, 10)
2662
2676
        d = defer.Deferred()
2663
2677
        self.patch(self.main.action_q, 'get_delta', lambda v, g: d.callback((v, g)))
2664
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', root.volume_id, 100)
 
2678
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2679
                               volume_id=root.volume_id, generation=100)
2665
2680
        vol_id, gen = yield d
2666
2681
        vol = self.vm.get_volume(vol_id)
2667
2682
        self.assertEqual(vol_id, vol.volume_id)
2676
2691
        self.vm.update_generation(root.volume_id, None)
2677
2692
        d = defer.Deferred()
2678
2693
        self.patch(self.main.action_q, 'rescan_from_scratch', d.callback)
2679
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', root.volume_id, 100)
 
2694
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2695
                               volume_id=root.volume_id, generation=100)
2680
2696
        vol_id = yield d
2681
2697
        self.assertEquals(vol_id, root.volume_id)
2682
2698
 
2686
2702
        root = self.vm.get_volume(request.ROOT)
2687
2703
        self.vm._got_root('root_node_id')
2688
2704
        self.vm.update_generation(root.volume_id, 100)
2689
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', root.volume_id, 100)
 
2705
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2706
                               volume_id=root.volume_id, generation=100)
2690
2707
        self.assertEqual(1, len(self.handler.records))
2691
2708
        msg = 'Got SV_VOLUME_NEW_GENERATION(%r, %r) but volume' + \
2692
2709
                ' is at generation: %r'
2700
2717
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
2701
2718
                                           10, 'to_me', 'fake_share', 'username',
2702
2719
                                           'visible_username', True, 'View')
2703
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
2704
 
                                          share_volume.other_visible_name)
 
2720
        dir_name = get_share_path(share_volume.share_name,
 
2721
                                  share_volume.other_visible_name)
2705
2722
        share_path = os.path.join(self.main.shares_dir, dir_name)
2706
2723
        share = Share.from_share_volume(share_volume, share_path)
2707
2724
        self.vm.add_share(share)
2708
2725
        self.vm.update_generation(share.volume_id, 10)
2709
2726
        d = defer.Deferred()
2710
2727
        self.patch(self.main.action_q, 'get_delta', lambda v, g: d.callback((v, g)))
2711
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', share.volume_id, 100)
 
2728
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2729
                               volume_id=share.volume_id, generation=100)
2712
2730
        vol_id, gen = yield d
2713
2731
        vol = self.vm.get_volume(vol_id)
2714
2732
        self.assertEqual(vol_id, vol.volume_id)
2721
2739
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
2722
2740
                                           10, 'to_me', 'fake_share', 'username',
2723
2741
                                           'visible_username', True, 'View')
2724
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
2725
 
                                          share_volume.other_visible_name)
 
2742
        dir_name = get_share_path(share_volume.share_name,
 
2743
                                  share_volume.other_visible_name)
2726
2744
        share_path = os.path.join(self.main.shares_dir, dir_name)
2727
2745
        share = Share.from_share_volume(share_volume, share_path)
2728
2746
        self.vm.add_share(share)
2729
2747
        self.vm.update_generation(share.volume_id, None)
2730
2748
        d = defer.Deferred()
2731
2749
        self.patch(self.main.action_q, 'rescan_from_scratch', d.callback)
2732
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', share.volume_id, 100)
 
2750
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2751
                               volume_id=share.volume_id, generation=100)
2733
2752
        vol_id = yield d
2734
2753
        self.assertEquals(vol_id, share.volume_id)
2735
2754
 
2739
2758
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
2740
2759
                                           10, 'to_me', 'fake_share', 'username',
2741
2760
                                           'visible_username', True, 'View')
2742
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
2743
 
                                          share_volume.other_visible_name)
 
2761
        dir_name = get_share_path(share_volume.share_name,
 
2762
                                  share_volume.other_visible_name)
2744
2763
        share_path = os.path.join(self.main.shares_dir, dir_name)
2745
2764
        share = Share.from_share_volume(share_volume, share_path)
2746
2765
        self.vm.add_share(share)
2747
2766
        self.vm.update_generation(share.volume_id, 100)
2748
 
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION', share.volume_id, 100)
 
2767
        self.main.event_q.push('SV_VOLUME_NEW_GENERATION',
 
2768
                               volume_id=share.volume_id, generation=100)
2749
2769
        self.assertTrue(self.handler.check_info(
2750
2770
                        'Got SV_VOLUME_NEW_GENERATION(%r, %r) but volume '
2751
2771
                        'is at generation: %r' % (share.volume_id, 100, 100)))
2765
2785
        share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', None,
2766
2786
                                           10, 'to_me', 'fake_share', 'username',
2767
2787
                                           'visible_username', True, 'View')
2768
 
        dir_name = self.vm._build_share_path(share_volume.share_name,
2769
 
                                          share_volume.other_visible_name)
 
2788
        dir_name = get_share_path(share_volume.share_name,
 
2789
                                  share_volume.other_visible_name)
2770
2790
        share_path = os.path.join(self.main.shares_dir, dir_name)
2771
2791
        share = Share.from_share_volume(share_volume, share_path)
2772
2792
        # get the root