~didrocks/ubuntuone-client/dont-suffer-zg-crash

« back to all changes in this revision

Viewing changes to tests/syncdaemon/test_pathlockingtree.py

  • Committer: Bazaar Package Importer
  • Author(s): Rodney Dawes
  • Date: 2011-01-25 16:42:52 UTC
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: james.westby@ubuntu.com-20110125164252-rl1pybasx1nsqgoy
Tags: upstream-1.5.3
ImportĀ upstreamĀ versionĀ 1.5.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# ubuntuone.syncdaemon.tests.test_pathlockingtree - PathLockingTree tests
 
2
#
 
3
# Author: Facundo Batista <facundo@canonical.com>
 
4
#
 
5
# Copyright 2011 Canonical Ltd.
 
6
#
 
7
# This program is free software: you can redistribute it and/or modify it
 
8
# under the terms of the GNU General Public License version 3, as published
 
9
# by the Free Software Foundation.
 
10
#
 
11
# This program is distributed in the hope that it will be useful, but
 
12
# WITHOUT ANY WARRANTY; without even the implied warranties of
 
13
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
14
# PURPOSE.  See the GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License along
 
17
# with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
""" ActionQueue tests """
 
19
 
 
20
import logging
 
21
 
 
22
from twisted.internet import defer
 
23
from twisted.trial.unittest import TestCase as TwistedTestCase
 
24
 
 
25
from ubuntuone.devtools.handlers import MementoHandler
 
26
from ubuntuone.syncdaemon.action_queue import PathLockingTree
 
27
 
 
28
 
 
29
class InternalDeferredTests(TwistedTestCase):
 
30
    """Test the internal deferreds handling functionality."""
 
31
 
 
32
    def setUp(self):
 
33
        """Set up."""
 
34
        self.plt = PathLockingTree()
 
35
 
 
36
    def test_single_element_old(self):
 
37
        """Add to a single element that was there."""
 
38
        self.plt.acquire('path')
 
39
        self.plt.acquire('path')
 
40
 
 
41
        # root has only one child
 
42
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
43
        child = self.plt.root['children_nodes']['path']
 
44
 
 
45
        # child has right values
 
46
        self.assertEqual(len(child['children_nodes']), 0)
 
47
        self.assertEqual(len(child['children_deferreds']), 0)
 
48
        self.assertEqual(len(child['node_deferreds']), 2)
 
49
 
 
50
    def test_single_element_new(self):
 
51
        """Add a single element that is new."""
 
52
        self.plt.acquire('path')
 
53
 
 
54
        # root has only one child
 
55
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
56
        child = self.plt.root['children_nodes']['path']
 
57
 
 
58
        # child has right values
 
59
        self.assertEqual(len(child['children_nodes']), 0)
 
60
        self.assertEqual(len(child['children_deferreds']), 0)
 
61
        self.assertEqual(len(child['node_deferreds']), 1)
 
62
 
 
63
    def test_two_element_both_old(self):
 
64
        """Add to two already there elements."""
 
65
        self.plt.acquire('path1', 'path2')
 
66
        self.plt.acquire('path1', 'path2')
 
67
 
 
68
        # root has only one child
 
69
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
70
        child = self.plt.root['children_nodes']['path1']
 
71
 
 
72
        # root's child has right values
 
73
        self.assertEqual(len(child['children_nodes']), 1)
 
74
        self.assertEqual(len(child['children_deferreds']), 2)
 
75
        self.assertEqual(len(child['node_deferreds']), 0)
 
76
 
 
77
        # root's grandchild has right values
 
78
        child = child['children_nodes']['path2']
 
79
        self.assertEqual(len(child['children_nodes']), 0)
 
80
        self.assertEqual(len(child['children_deferreds']), 0)
 
81
        self.assertEqual(len(child['node_deferreds']), 2)
 
82
 
 
83
    def test_two_element_both_new(self):
 
84
        """Add to two new elements."""
 
85
        self.plt.acquire('path1', 'path2')
 
86
 
 
87
        # root has only one child
 
88
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
89
        child = self.plt.root['children_nodes']['path1']
 
90
 
 
91
        # root's child has right values
 
92
        self.assertEqual(len(child['children_nodes']), 1)
 
93
        self.assertEqual(len(child['children_deferreds']), 1)
 
94
        self.assertEqual(len(child['node_deferreds']), 0)
 
95
 
 
96
        # root's grandchild has right values
 
97
        child = child['children_nodes']['path2']
 
98
        self.assertEqual(len(child['children_nodes']), 0)
 
99
        self.assertEqual(len(child['children_deferreds']), 0)
 
100
        self.assertEqual(len(child['node_deferreds']), 1)
 
101
 
 
102
    def test_two_element_mixed(self):
 
103
        """Add to one new and one old elements."""
 
104
        # first one
 
105
        self.plt.acquire('path1')
 
106
 
 
107
        # root has only one child
 
108
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
109
        child = self.plt.root['children_nodes']['path1']
 
110
 
 
111
        # root's child has right values
 
112
        self.assertEqual(len(child['children_nodes']), 0)
 
113
        self.assertEqual(len(child['children_deferreds']), 0)
 
114
        self.assertEqual(len(child['node_deferreds']), 1)
 
115
 
 
116
        # second one
 
117
        self.plt.acquire('path1', 'path2')
 
118
 
 
119
        # root's child has right values
 
120
        self.assertEqual(len(child['children_nodes']), 1)
 
121
        self.assertEqual(len(child['children_deferreds']), 1)
 
122
        self.assertEqual(len(child['node_deferreds']), 1)
 
123
 
 
124
        # root's grandchild has right values
 
125
        child = child['children_nodes']['path2']
 
126
        self.assertEqual(len(child['children_nodes']), 0)
 
127
        self.assertEqual(len(child['children_deferreds']), 0)
 
128
        self.assertEqual(len(child['node_deferreds']), 1)
 
129
 
 
130
    def test_element_to_longer_branch(self):
 
131
        """Add element in the middle of longer branch."""
 
132
        # first a long one, then a shorter one
 
133
        self.plt.acquire(*"abc")
 
134
        self.plt.acquire("a")
 
135
 
 
136
        # root has only one child
 
137
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
138
        child = self.plt.root['children_nodes']['a']
 
139
 
 
140
        # root's child has right values
 
141
        self.assertEqual(len(child['children_nodes']), 1)
 
142
        self.assertEqual(len(child['children_deferreds']), 1)
 
143
        self.assertEqual(len(child['node_deferreds']), 1)
 
144
 
 
145
        # root's grandchild has right values
 
146
        child = child['children_nodes']['b']
 
147
        self.assertEqual(len(child['children_nodes']), 1)
 
148
        self.assertEqual(len(child['children_deferreds']), 1)
 
149
        self.assertEqual(len(child['node_deferreds']), 0)
 
150
 
 
151
        # root's grandgrandchild has right values
 
152
        child = child['children_nodes']['c']
 
153
        self.assertEqual(len(child['children_nodes']), 0)
 
154
        self.assertEqual(len(child['children_deferreds']), 0)
 
155
        self.assertEqual(len(child['node_deferreds']), 1)
 
156
 
 
157
    def test_second_to_root(self):
 
158
        """Add other root child."""
 
159
        self.plt.acquire("path1")
 
160
        self.plt.acquire("path2")
 
161
 
 
162
        # root has two children
 
163
        self.assertEqual(len(self.plt.root['children_nodes']), 2)
 
164
 
 
165
        # root's child 1 has right values
 
166
        child = self.plt.root['children_nodes']['path1']
 
167
        self.assertEqual(len(child['children_nodes']), 0)
 
168
        self.assertEqual(len(child['children_deferreds']), 0)
 
169
        self.assertEqual(len(child['node_deferreds']), 1)
 
170
 
 
171
        # root's child 2 has right values
 
172
        child = self.plt.root['children_nodes']['path2']
 
173
        self.assertEqual(len(child['children_nodes']), 0)
 
174
        self.assertEqual(len(child['children_deferreds']), 0)
 
175
        self.assertEqual(len(child['node_deferreds']), 1)
 
176
 
 
177
    def test_diverging_branch(self):
 
178
        """Add a branch that separates from other."""
 
179
        # first a long one, then a shorter one
 
180
        self.plt.acquire(*"abcd")
 
181
        self.plt.acquire(*"abj")
 
182
 
 
183
        # root has only one child
 
184
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
185
 
 
186
        # node a values
 
187
        node_a = self.plt.root['children_nodes']['a']
 
188
        self.assertEqual(len(node_a['children_nodes']), 1)
 
189
        self.assertEqual(len(node_a['children_deferreds']), 2)
 
190
        self.assertEqual(len(node_a['node_deferreds']), 0)
 
191
 
 
192
        # node a values
 
193
        node_b = node_a['children_nodes']['b']
 
194
        self.assertEqual(len(node_b['children_nodes']), 2)
 
195
        self.assertEqual(len(node_b['children_deferreds']), 2)
 
196
        self.assertEqual(len(node_b['node_deferreds']), 0)
 
197
 
 
198
        # node c values
 
199
        node_c = node_b['children_nodes']['c']
 
200
        self.assertEqual(len(node_c['children_nodes']), 1)
 
201
        self.assertEqual(len(node_c['children_deferreds']), 1)
 
202
        self.assertEqual(len(node_c['node_deferreds']), 0)
 
203
 
 
204
        # node a values
 
205
        node_d = node_c['children_nodes']['d']
 
206
        self.assertEqual(len(node_d['children_nodes']), 0)
 
207
        self.assertEqual(len(node_d['children_deferreds']), 0)
 
208
        self.assertEqual(len(node_d['node_deferreds']), 1)
 
209
 
 
210
        # node a values
 
211
        node_j = node_b['children_nodes']['j']
 
212
        self.assertEqual(len(node_j['children_nodes']), 0)
 
213
        self.assertEqual(len(node_j['children_deferreds']), 0)
 
214
        self.assertEqual(len(node_j['node_deferreds']), 1)
 
215
 
 
216
 
 
217
class LockingTests(TwistedTestCase):
 
218
    """Test the locking between elements."""
 
219
 
 
220
    def setUp(self):
 
221
        """Set up."""
 
222
        self.plt = PathLockingTree()
 
223
 
 
224
    @defer.inlineCallbacks
 
225
    def test_none_before(self):
 
226
        """Not lock because nothing there before."""
 
227
        yield self.plt.acquire("path")
 
228
 
 
229
    @defer.inlineCallbacks
 
230
    def test_same_path_one_previous(self):
 
231
        """Lock on same path, one previous command."""
 
232
        release = yield self.plt.acquire("path")
 
233
        d = self.plt.acquire("path")
 
234
 
 
235
        # add func first and change value later, to check when released
 
236
        d.addCallback(lambda _: self.assertTrue(was_later))
 
237
 
 
238
        was_later = True
 
239
        release()
 
240
        yield d
 
241
 
 
242
    @defer.inlineCallbacks
 
243
    def test_same_path_two_previous(self):
 
244
        """Lock on same path, two previous commands."""
 
245
        releases = []
 
246
        d1 = self.plt.acquire("path")
 
247
        d1.addCallback(releases.append)
 
248
        d2 = self.plt.acquire("path")
 
249
        d2.addCallback(releases.append)
 
250
 
 
251
        # add func first, test all releases were made before the check
 
252
        d3 = self.plt.acquire("path")
 
253
        d3.addCallback(lambda _: self.assertFalse(releases))
 
254
 
 
255
        releases.pop(0)()
 
256
        releases.pop(0)()
 
257
        yield d3
 
258
 
 
259
    @defer.inlineCallbacks
 
260
    def test_same_path_having_parent(self):
 
261
        """Lock with parent having just the parent."""
 
262
        yield self.plt.acquire("path1")
 
263
        yield self.plt.acquire("path1", "path2")
 
264
 
 
265
    @defer.inlineCallbacks
 
266
    def test_same_path_having_children(self):
 
267
        """Lock with parent having just the parent."""
 
268
        yield self.plt.acquire("path1", "path2", "path3")
 
269
        yield self.plt.acquire("path1", "path2")
 
270
 
 
271
    @defer.inlineCallbacks
 
272
    def test_with_parent_none(self):
 
273
        """Lock with parent but empty."""
 
274
        yield self.plt.acquire("path", on_parent=True)
 
275
 
 
276
    @defer.inlineCallbacks
 
277
    def test_with_parent_just_parent(self):
 
278
        """Lock with parent having just the parent."""
 
279
        release = yield self.plt.acquire("path1")
 
280
        d = self.plt.acquire("path1", "path2", on_parent=True)
 
281
 
 
282
        # add func first and change value later, to check when released
 
283
        d.addCallback(lambda _: self.assertTrue(was_later))
 
284
 
 
285
        was_later = True
 
286
        release()
 
287
        yield d
 
288
 
 
289
    @defer.inlineCallbacks
 
290
    def test_with_parent_having_same(self):
 
291
        """Lock with parent having also the same path."""
 
292
        releases = []
 
293
        d = self.plt.acquire(*"abc")
 
294
        d.addCallback(releases.append)
 
295
        d = self.plt.acquire(*"abcd")
 
296
        d.addCallback(releases.append)
 
297
 
 
298
        # add func first, test all releases were made before the check
 
299
        d = self.plt.acquire(*"abcd", on_parent=True)
 
300
        d.addCallback(lambda _: self.assertFalse(releases))
 
301
 
 
302
        releases.pop(0)()
 
303
        releases.pop(0)()
 
304
        yield d
 
305
 
 
306
    @defer.inlineCallbacks
 
307
    def test_with_parent_multiple(self):
 
308
        """Lock with some commands in parent and same."""
 
309
        releases = []
 
310
        d = self.plt.acquire(*"abcd")
 
311
        d.addCallback(releases.append)
 
312
        d = self.plt.acquire(*"abcd")
 
313
        d.addCallback(releases.append)
 
314
        d = self.plt.acquire(*"abc")
 
315
        d.addCallback(releases.append)
 
316
        d = self.plt.acquire(*"abc")
 
317
        d.addCallback(releases.append)
 
318
 
 
319
        # add func first, test all releases were made before the check
 
320
        d = self.plt.acquire(*"abcd", on_parent=True)
 
321
        d.addCallback(lambda _: self.assertFalse(releases))
 
322
 
 
323
        releases.pop(0)()
 
324
        releases.pop(0)()
 
325
        releases.pop(0)()
 
326
        releases.pop(0)()
 
327
        yield d
 
328
 
 
329
    @defer.inlineCallbacks
 
330
    def test_with_parent_having_just_children(self):
 
331
        """Lock with parent but only has children."""
 
332
        yield self.plt.acquire("path1", "path2", "path3")
 
333
        yield self.plt.acquire("path1", "path2", on_parent=True)
 
334
 
 
335
    @defer.inlineCallbacks
 
336
    def test_with_children_none(self):
 
337
        """Lock with children but empty."""
 
338
        yield self.plt.acquire("path", on_children=True)
 
339
 
 
340
    @defer.inlineCallbacks
 
341
    def test_with_children_just_children(self):
 
342
        """Lock with children having just a child."""
 
343
        release = yield self.plt.acquire("path1", "path2")
 
344
        d = self.plt.acquire("path1", on_children=True)
 
345
 
 
346
        # add func first and change value later, to check when released
 
347
        d.addCallback(lambda _: self.assertTrue(was_later))
 
348
 
 
349
        was_later = True
 
350
        release()
 
351
        yield d
 
352
 
 
353
    @defer.inlineCallbacks
 
354
    def test_with_children_having_same(self):
 
355
        """Lock with children having also the same path."""
 
356
        releases = []
 
357
        d = self.plt.acquire(*"ab")
 
358
        d.addCallback(releases.append)
 
359
        d = self.plt.acquire(*"abc")
 
360
        d.addCallback(releases.append)
 
361
 
 
362
        # add func first, test all releases were made before the check
 
363
        d = self.plt.acquire(*"ab", on_children=True)
 
364
        d.addCallback(lambda _: self.assertFalse(releases))
 
365
 
 
366
        releases.pop(0)()
 
367
        releases.pop(0)()
 
368
        yield d
 
369
 
 
370
    @defer.inlineCallbacks
 
371
    def test_with_children_multiple(self):
 
372
        """Lock with some commands in children and same."""
 
373
        releases = []
 
374
        d = self.plt.acquire(*"ab")
 
375
        d.addCallback(releases.append)
 
376
        d = self.plt.acquire(*"ab")
 
377
        d.addCallback(releases.append)
 
378
        d = self.plt.acquire(*"abc")
 
379
        d.addCallback(releases.append)
 
380
        d = self.plt.acquire(*"abc")
 
381
        d.addCallback(releases.append)
 
382
 
 
383
        # add func first, test all releases were made before the check
 
384
        d = self.plt.acquire(*"ab", on_children=True)
 
385
        d.addCallback(lambda _: self.assertFalse(releases))
 
386
 
 
387
        releases.pop(0)()
 
388
        releases.pop(0)()
 
389
        releases.pop(0)()
 
390
        releases.pop(0)()
 
391
        yield d
 
392
 
 
393
    @defer.inlineCallbacks
 
394
    def test_with_children_and_parent_all_mixed(self):
 
395
        """Lock with some commands everywhere, :p."""
 
396
        releases = []
 
397
        d = self.plt.acquire(*"ab")
 
398
        d.addCallback(releases.append)
 
399
        d = self.plt.acquire(*"abc")
 
400
        d.addCallback(releases.append)
 
401
        d = self.plt.acquire(*"abc")
 
402
        d.addCallback(releases.append)
 
403
        d = self.plt.acquire(*"a")
 
404
        d.addCallback(releases.append)
 
405
 
 
406
        # add func first, test all releases were made before the check
 
407
        d = self.plt.acquire(*"ab", on_children=True, on_parent=True)
 
408
        d.addCallback(lambda _: self.assertFalse(releases))
 
409
 
 
410
        releases.pop(0)()
 
411
        releases.pop(0)()
 
412
        releases.pop(0)()
 
413
        releases.pop(0)()
 
414
        yield d
 
415
 
 
416
 
 
417
class CleaningTests(TwistedTestCase):
 
418
    """Test that the releases clean the tree."""
 
419
 
 
420
    def setUp(self):
 
421
        """Set up."""
 
422
        self.plt = PathLockingTree()
 
423
 
 
424
    @defer.inlineCallbacks
 
425
    def test_simple(self):
 
426
        """Simple clean, add one, release it."""
 
427
        release = yield self.plt.acquire("path")
 
428
        release()
 
429
        self.assertEqual(len(self.plt.root['children_nodes']), 0)
 
430
 
 
431
    @defer.inlineCallbacks
 
432
    def test_add_two_release_one(self):
 
433
        """Add two different paths, release them by one."""
 
434
        release1 = yield self.plt.acquire("path1")
 
435
        release2 = yield self.plt.acquire("path2")
 
436
        self.assertEqual(len(self.plt.root['children_nodes']), 2)
 
437
 
 
438
        release1()
 
439
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
440
 
 
441
        release2()
 
442
        self.assertEqual(len(self.plt.root['children_nodes']), 0)
 
443
 
 
444
    @defer.inlineCallbacks
 
445
    def test_longer_branch(self):
 
446
        """Simple clean, but using a longer branch."""
 
447
        release = yield self.plt.acquire(*"abc")
 
448
        release()
 
449
        self.assertEqual(len(self.plt.root['children_nodes']), 0)
 
450
 
 
451
    @defer.inlineCallbacks
 
452
    def test_overlapped_release_shorter(self):
 
453
        """Overlap two paths, release shorter."""
 
454
        release1 = yield self.plt.acquire(*"abc")
 
455
        release2 = yield self.plt.acquire(*"ab")
 
456
 
 
457
        # release shorter, check structure
 
458
        release2()
 
459
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
460
        node_a = self.plt.root['children_nodes']['a']
 
461
        self.assertEqual(len(node_a['children_nodes']), 1)
 
462
        self.assertEqual(len(node_a['children_deferreds']), 1)
 
463
        self.assertEqual(len(node_a['node_deferreds']), 0)
 
464
        node_b = node_a['children_nodes']['b']
 
465
        self.assertEqual(len(node_b['children_nodes']), 1)
 
466
        self.assertEqual(len(node_b['children_deferreds']), 1)
 
467
        self.assertEqual(len(node_b['node_deferreds']), 0)
 
468
        node_c = node_b['children_nodes']['c']
 
469
        self.assertEqual(len(node_c['children_nodes']), 0)
 
470
        self.assertEqual(len(node_c['children_deferreds']), 0)
 
471
        self.assertEqual(len(node_c['node_deferreds']), 1)
 
472
 
 
473
        # release longer, empty now!
 
474
        release1()
 
475
        self.assertEqual(len(self.plt.root['children_nodes']), 0)
 
476
 
 
477
    @defer.inlineCallbacks
 
478
    def test_overlapped_release_longer(self):
 
479
        """Overlap two paths, release longer."""
 
480
        release1 = yield self.plt.acquire(*"abc")
 
481
        release2 = yield self.plt.acquire(*"ab")
 
482
 
 
483
        # release longer, check structure
 
484
        release1()
 
485
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
486
        node_a = self.plt.root['children_nodes']['a']
 
487
        self.assertEqual(len(node_a['children_nodes']), 1)
 
488
        self.assertEqual(len(node_a['children_deferreds']), 1)
 
489
        self.assertEqual(len(node_a['node_deferreds']), 0)
 
490
        node_b = node_a['children_nodes']['b']
 
491
        self.assertEqual(len(node_b['children_nodes']), 0)
 
492
        self.assertEqual(len(node_b['children_deferreds']), 0)
 
493
        self.assertEqual(len(node_b['node_deferreds']), 1)
 
494
 
 
495
        # release shorter, empty now!
 
496
        release2()
 
497
        self.assertEqual(len(self.plt.root['children_nodes']), 0)
 
498
 
 
499
    @defer.inlineCallbacks
 
500
    def test_same_long_path_double(self):
 
501
        """Two long branchs."""
 
502
        release1 = yield self.plt.acquire(*"ab")
 
503
 
 
504
        releases = []
 
505
        d = self.plt.acquire(*"ab")
 
506
        d.addCallback(releases.append)
 
507
 
 
508
        # release first, check structure
 
509
        release1()
 
510
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
511
        node_a = self.plt.root['children_nodes']['a']
 
512
        self.assertEqual(len(node_a['children_nodes']), 1)
 
513
        self.assertEqual(len(node_a['children_deferreds']), 1)
 
514
        self.assertEqual(len(node_a['node_deferreds']), 0)
 
515
        node_b = node_a['children_nodes']['b']
 
516
        self.assertEqual(len(node_b['children_nodes']), 0)
 
517
        self.assertEqual(len(node_b['children_deferreds']), 0)
 
518
        self.assertEqual(len(node_b['node_deferreds']), 1)
 
519
 
 
520
        # release second, empty now!
 
521
        releases.pop(0)()
 
522
        self.assertEqual(len(self.plt.root['children_nodes']), 0)
 
523
 
 
524
    @defer.inlineCallbacks
 
525
    def test_diverging_branch(self):
 
526
        """Diverging branches."""
 
527
        release1 = yield self.plt.acquire(*"abc")
 
528
        release2 = yield self.plt.acquire(*"aj")
 
529
 
 
530
        # release longer, check structure
 
531
        release1()
 
532
        self.assertEqual(len(self.plt.root['children_nodes']), 1)
 
533
        node_a = self.plt.root['children_nodes']['a']
 
534
        self.assertEqual(len(node_a['children_nodes']), 1)
 
535
        self.assertEqual(len(node_a['children_deferreds']), 1)
 
536
        self.assertEqual(len(node_a['node_deferreds']), 0)
 
537
        node_j = node_a['children_nodes']['j']
 
538
        self.assertEqual(len(node_j['children_nodes']), 0)
 
539
        self.assertEqual(len(node_j['children_deferreds']), 0)
 
540
        self.assertEqual(len(node_j['node_deferreds']), 1)
 
541
 
 
542
        # release second, empty now!
 
543
        release2()
 
544
        self.assertEqual(len(self.plt.root['children_nodes']), 0)
 
545
 
 
546
 
 
547
class LoggingTests(TwistedTestCase):
 
548
    """Test the logging."""
 
549
 
 
550
    def setUp(self):
 
551
        """Set up."""
 
552
        self.plt = PathLockingTree()
 
553
 
 
554
        self.handler = MementoHandler()
 
555
        self.plt.logger.addHandler(self.handler)
 
556
 
 
557
    @defer.inlineCallbacks
 
558
    def test_logger_can_be_given(self):
 
559
        """Accept an external logger."""
 
560
        logger = logging.getLogger("ubuntuone.SyncDaemon.Test")
 
561
        handler = MementoHandler()
 
562
        logger.addHandler(handler)
 
563
 
 
564
        # acquire and test
 
565
        release = yield self.plt.acquire('path', logger=logger)
 
566
        self.assertTrue(handler.check_debug("acquiring on"))
 
567
 
 
568
        # release and test
 
569
        release()
 
570
        self.assertTrue(handler.check_debug("releasing"))
 
571
 
 
572
 
 
573
    def test_acquire_single_default(self):
 
574
        """Single path, full check."""
 
575
        self.plt.acquire('path')
 
576
        self.assertTrue(self.handler.check_debug(
 
577
                        "acquiring on", "path",
 
578
                        "(on_parent=False, on_children=False)", "wait for: 0"))
 
579
 
 
580
    def test_acquire_single_on_parent(self):
 
581
        """Single path, on parent."""
 
582
        self.plt.acquire('path', on_parent=True)
 
583
        self.assertTrue(self.handler.check_debug("on_parent=True"))
 
584
 
 
585
    def test_acquire_single_on_children(self):
 
586
        """Single path, on children."""
 
587
        self.plt.acquire('path', on_children=True)
 
588
        self.assertTrue(self.handler.check_debug("on_children=True"))
 
589
 
 
590
    def test_acquire_single_on_both(self):
 
591
        """Single path, on both."""
 
592
        self.plt.acquire('path', on_parent=True, on_children=True)
 
593
        self.assertTrue(self.handler.check_debug(
 
594
                        "(on_parent=True, on_children=True)"))
 
595
 
 
596
    def test_acquire_multiple(self):
 
597
        """Single path, on both."""
 
598
        self.plt.acquire('1', '2', *"abc")
 
599
        self.assertTrue(self.handler.check_debug("'1', '2', 'a', 'b', 'c'"))
 
600
 
 
601
    def test_acquire_waiting(self):
 
602
        """Single path, on both."""
 
603
        self.plt.acquire('path')
 
604
        self.assertTrue(self.handler.check_debug("wait for: 0"))
 
605
 
 
606
        self.plt.acquire('path')
 
607
        self.assertTrue(self.handler.check_debug("wait for: 1"))
 
608
 
 
609
        self.plt.acquire('path')
 
610
        self.assertTrue(self.handler.check_debug("wait for: 2"))
 
611
 
 
612
    @defer.inlineCallbacks
 
613
    def test_release_simple(self):
 
614
        """Single release."""
 
615
        release = yield self.plt.acquire("path")
 
616
        release()
 
617
        self.assertTrue(self.handler.check_debug("releasing",
 
618
                                                 "path", "remaining: 0"))
 
619
 
 
620
    @defer.inlineCallbacks
 
621
    def test_release_double(self):
 
622
        """Double release."""
 
623
        release1 = yield self.plt.acquire("path1")
 
624
        release2 = yield self.plt.acquire("path2")
 
625
        release1()
 
626
        self.assertTrue(self.handler.check_debug("releasing",
 
627
                                                 "path1", "remaining: 1"))
 
628
        release2()
 
629
        self.assertTrue(self.handler.check_debug("releasing",
 
630
                                                 "path2", "remaining: 0"))
 
631
 
 
632
    @defer.inlineCallbacks
 
633
    def test_release_longer_branches(self):
 
634
        """Longer branches."""
 
635
        release = yield self.plt.acquire(*"abcde")
 
636
        self.plt.acquire(*"abc")
 
637
        self.plt.acquire(*"abcdefg")
 
638
        self.plt.acquire(*"abklop")
 
639
        self.plt.acquire(*"foobar")
 
640
        release()
 
641
        self.assertTrue(self.handler.check_debug("releasing",
 
642
                                                 "'a', 'b', 'c', 'd', 'e'",
 
643
                                                 "remaining: 4"))