Merge lp:~chipaca/ubuntuone-client/improv-v2-upgrade into lp:ubuntuone-client

Proposed by John Lenton
Status: Merged
Approved by: Guillermo Gonzalez
Approved revision: 188
Merged at revision: not available
Proposed branch: lp:~chipaca/ubuntuone-client/improv-v2-upgrade
Merge into: lp:ubuntuone-client
Diff against target: None lines
To merge this branch: bzr merge lp:~chipaca/ubuntuone-client/improv-v2-upgrade
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Eric Casteleijn (community) Approve
Review via email: mp+10805@code.launchpad.net

Commit message

fixes #405688

To post a comment you must log in.
Revision history for this message
John Lenton (chipaca) wrote :

This fixes #405688, by being a lot more cautious in moving around conflicts and partials. If anybody can think of more cases for the tests, please let me know :)

Revision history for this message
Eric Casteleijn (thisfred) wrote :

Indeed it does! +1

review: Approve
Revision history for this message
Guillermo Gonzalez (verterok) wrote :

yessir

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'tests/syncdaemon/test_vm.py'
--- tests/syncdaemon/test_vm.py 2009-08-25 18:26:17 +0000
+++ tests/syncdaemon/test_vm.py 2009-08-27 16:41:47 +0000
@@ -562,6 +562,162 @@
562 self.assertTrue(os.path.exists(self.shares_dir + '/.u1partial.bar'))562 self.assertTrue(os.path.exists(self.shares_dir + '/.u1partial.bar'))
563 self.assertTrue(os.path.exists(self.shares_dir + '/baz/baz.u1conflict'))563 self.assertTrue(os.path.exists(self.shares_dir + '/baz/baz.u1conflict'))
564564
565 def test_2_to_3_more(self):
566 """ Test the upgrade from v.2 of the metadata to v.3 some more"""
567 vm_data_dir = os.path.join(self.data_dir, 'vm')
568 os.makedirs(vm_data_dir)
569 with open(os.path.join(vm_data_dir, '.version'), 'w') as fd:
570 fd.write('2')
571
572 expected = []
573
574 for dirname in self.root_dir, self.shares_dir:
575 # a plain .conflict...
576 # ...on a file
577 open(dirname + '/1a.conflict', 'w').close()
578 expected.append(dirname + '/1a.u1conflict')
579 # ...on an empty directory
580 os.mkdir(dirname + '/1b.conflict')
581 expected.append(dirname + '/1b.u1conflict')
582 # ...on a directory with content
583 os.mkdir(dirname + '/1c.conflict')
584 os.mkdir(dirname + '/1c.conflict/1c')
585 expected.append(dirname + '/1c.u1conflict/1c')
586 # ...in a readonly directory
587 os.mkdir(dirname + '/1d')
588 os.mkdir(dirname + '/1d/1d.conflict')
589 os.chmod(dirname + '/1d', 0500)
590 expected.append(dirname + '/1d/1d.u1conflict')
591 # ...in a directory that is also a .conflict
592 os.mkdir(dirname + '/1e.conflict')
593 os.mkdir(dirname + '/1e.conflict/1e.conflict')
594 expected.append(dirname + '/1e.u1conflict/1e.u1conflict')
595
596 # a numbered .conflict...
597 # ...on a file
598 open(dirname + '/2a.conflict.2', 'w').close()
599 expected.append(dirname + '/2a.u1conflict.2')
600 # ...on an empty directory
601 os.mkdir(dirname + '/2b.conflict.3')
602 expected.append(dirname + '/2b.u1conflict.3')
603 # ...on a directory with content
604 os.mkdir(dirname + '/2c.conflict.4')
605 os.mkdir(dirname + '/2c.conflict.4/2c')
606 expected.append(dirname + '/2c.u1conflict.4/2c')
607 # ...in a readonly directory
608 os.mkdir(dirname + '/2d')
609 os.mkdir(dirname + '/2d/2d.conflict.5')
610 os.chmod(dirname + '/2d', 0500)
611 expected.append(dirname + '/2d/2d.u1conflict.5')
612 # ...in a directory that is also a .conflict
613 os.mkdir(dirname + '/2e.conflict')
614 os.mkdir(dirname + '/2e.conflict/2e.conflict.6')
615 expected.append(dirname + '/2e.u1conflict/2e.u1conflict.6')
616
617 # a plain .conflict of which there already exists a .u1conflict...
618 # ...on a file
619 open(dirname + '/3a.conflict', 'w').close()
620 open(dirname + '/3a.u1conflict', 'w').close()
621 expected.append(dirname + '/3a.u1conflict')
622 expected.append(dirname + '/3a.u1conflict.1')
623 # ...on an empty directory
624 os.mkdir(dirname + '/3b.conflict')
625 os.mkdir(dirname + '/3b.u1conflict')
626 expected.append(dirname + '/3b.u1conflict')
627 expected.append(dirname + '/3b.u1conflict.1')
628 # ...on a directory with content
629 os.mkdir(dirname + '/3c.conflict')
630 os.mkdir(dirname + '/3c.conflict/3c')
631 os.mkdir(dirname + '/3c.u1conflict')
632 os.mkdir(dirname + '/3c.u1conflict/3c2')
633 expected.append(dirname + '/3c.u1conflict.1/3c')
634 expected.append(dirname + '/3c.u1conflict/3c2')
635 # ...in a readonly directory
636 os.mkdir(dirname + '/3d')
637 os.mkdir(dirname + '/3d/3d.conflict')
638 os.mkdir(dirname + '/3d/3d.u1conflict')
639 os.mkdir(dirname + '/3d/3d.u1conflict/3d')
640 os.chmod(dirname + '/3d', 0500)
641 expected.append(dirname + '/3d/3d.u1conflict/3d')
642 expected.append(dirname + '/3d/3d.u1conflict.1')
643 # ...in a directory that is also a .conflict
644 os.mkdir(dirname + '/3e.conflict')
645 os.mkdir(dirname + '/3e.conflict/3e.conflict')
646 os.mkdir(dirname + '/3e.conflict/3e.u1conflict')
647 os.mkdir(dirname + '/3e.conflict/3e.u1conflict/3e')
648 expected.append(dirname + '/3e.u1conflict/3e.u1conflict/3e')
649 expected.append(dirname + '/3e.u1conflict/3e.u1conflict.1')
650
651 # a numbered .conflict of which there already exists a .u1conflict...
652 # ...on a file
653 open(dirname + '/4a.conflict.1', 'w').close()
654 open(dirname + '/4a.u1conflict.1', 'w').close()
655 expected.append(dirname + '/4a.u1conflict.1')
656 expected.append(dirname + '/4a.u1conflict.2')
657 # ...on an empty directory
658 os.mkdir(dirname + '/4b.conflict.2')
659 os.mkdir(dirname + '/4b.u1conflict.2')
660 expected.append(dirname + '/4b.u1conflict.2')
661 expected.append(dirname + '/4b.u1conflict.3')
662 # ...on a directory with content
663 os.mkdir(dirname + '/4c.conflict.3')
664 os.mkdir(dirname + '/4c.conflict.3/4c')
665 os.mkdir(dirname + '/4c.u1conflict.3')
666 expected.append(dirname + '/4c.u1conflict.4/4c')
667 expected.append(dirname + '/4c.u1conflict.3')
668 # ...in a readonly directory
669 os.mkdir(dirname + '/4d')
670 os.mkdir(dirname + '/4d/4d.conflict.4')
671 os.mkdir(dirname + '/4d/4d.u1conflict.4')
672 os.chmod(dirname + '/4d', 0500)
673 expected.append(dirname + '/4d/4d.u1conflict.4')
674 expected.append(dirname + '/4d/4d.u1conflict.5')
675 # ...in a directory that is also a .conflict
676 os.mkdir(dirname + '/4e.conflict')
677 os.mkdir(dirname + '/4e.conflict/4e.conflict.5')
678 os.mkdir(dirname + '/4e.conflict/4e.u1conflict.5')
679 expected.append(dirname + '/4e.u1conflict/4e.u1conflict.5')
680 expected.append(dirname + '/4e.u1conflict/4e.u1conflict.6')
681
682 # a plain .partial...
683 # ...of a file
684 open(dirname + '/5a.partial', 'w').close()
685 expected.append(dirname + '/.u1partial.5a')
686 # ...of a directory
687 os.mkdir(dirname + '/5b')
688 open(dirname + '/5b/.partial', 'w').close()
689 expected.append(dirname + '/5b/.u1partial')
690 # ...of a readonly directory
691 os.mkdir(dirname + '/5c')
692 open(dirname + '/5c/.partial', 'w').close()
693 os.chmod(dirname + '/5c', 0500)
694 expected.append(dirname + '/5c/.u1partial')
695
696 # a plain .partial of which there already exists a .u1partial...
697 # ...of a file
698 open(dirname + '/6a.partial', 'w').close()
699 open(dirname + '/.u1partial.6a', 'w').close()
700 expected.append(dirname + '/.u1partial.6a')
701 expected.append(dirname + '/.u1partial.6a.1')
702 # ...of a directory
703 os.mkdir(dirname + '/6b')
704 open(dirname + '/6b/.partial', 'w').close()
705 open(dirname + '/6b/.u1partial', 'w').close()
706 expected.append(dirname + '/6b/.u1partial')
707 expected.append(dirname + '/6b/.u1partial.1')
708 # ...of a readonly directory
709 os.mkdir(dirname + '/6c')
710 open(dirname + '/6c/.partial', 'w').close()
711 open(dirname + '/6c/.u1partial', 'w').close()
712 os.chmod(dirname + '/6c', 0500)
713 expected.append(dirname + '/6c/.u1partial')
714 expected.append(dirname + '/6c/.u1partial.1')
715
716 self.main = FakeMain(self.root_dir, self.shares_dir, self.data_dir)
717
718 for path in expected:
719 self.assertTrue(os.path.exists(path), 'missing ' + path)
720
565 def test_missing_version_file_with_version_non_0(self):721 def test_missing_version_file_with_version_non_0(self):
566 """ Test the upgrade from the first shelf layout version to v3722 """ Test the upgrade from the first shelf layout version to v3
567 while the metadata sould be in v3 format723 while the metadata sould be in v3 format
568724
=== modified file 'ubuntuone/syncdaemon/volume_manager.py'
--- ubuntuone/syncdaemon/volume_manager.py 2009-08-26 13:33:23 +0000
+++ ubuntuone/syncdaemon/volume_manager.py 2009-08-27 16:41:47 +0000
@@ -508,24 +508,48 @@
508 for dirpath, dirnames, filenames in os.walk(top):508 for dirpath, dirnames, filenames in os.walk(top):
509 with allow_writes(dirpath):509 with allow_writes(dirpath):
510 for names in filenames, dirnames:510 for names in filenames, dirnames:
511 for pos, name in enumerate(names):511 self._upgrade_names(dirpath, names)
512 if name == '.partial':
513 new_name = '.u1partial'
514 else:
515 new_name = re.sub(r'^(.+)\.partial$',
516 r'.u1partial.\1', name)
517 conflict_re = r'^(.+)\.conflict((?:\.\d+)?)$'
518 new_name = re.sub(conflict_re,
519 r'\1.u1conflict\2', new_name)
520 if new_name != name:
521 self.log.debug('renaming %r to %r',
522 name, new_name)
523 os.rename(os.path.join(dirpath, name),
524 os.path.join(dirpath, new_name))
525 names[pos] = new_name
526 self._upgrade_metadata_3(md_version)512 self._upgrade_metadata_3(md_version)
527 self._update_metadata_version()513 self._update_metadata_version()
528514
515 def _upgrade_names(self, dirpath, names):
516 """
517 Do the actual renaming for _upgrade_metadata_2
518 """
519 for pos, name in enumerate(names):
520 new_name = name
521 if re.match(r'.*\.partial$|\.u1partial(?:\..+)?', name):
522 if name == '.partial':
523 new_name = '.u1partial'
524 else:
525 new_name = re.sub(r'^(.+)\.partial$',
526 r'.u1partial.\1', name)
527 if new_name != name:
528 while os.path.lexists(os.path.join(dirpath, new_name)):
529 # very, very strange
530 self.log.warning('Found a .partial and .u1partial'
531 ' for the same file: %s!' % new_name)
532 new_name += '.1'
533 elif re.search(r'\.(?:u1)?conflict(?:\.\d+)?$', name):
534 new_name = re.sub(r'^(.+)\.conflict((?:\.\d+)?)$',
535 r'\1.u1conflict\2', name)
536 if new_name != name:
537 while os.path.lexists(os.path.join(dirpath, new_name)):
538 m = re.match(r'(.*\.u1conflict)((?:\.\d+)?)$', new_name)
539 base, num = m.groups()
540 if not num:
541 num = '.1'
542 else:
543 num = '.' + str(int(num[1:])+1)
544 new_name = base + num
545 if new_name != name:
546 old_path = os.path.join(dirpath, name)
547 new_path = os.path.join(dirpath, new_name)
548 self.log.debug('renaming %r to %r' % (old_path, new_path))
549 os.rename(old_path, new_path)
550 names[pos] = new_name
551
552
529 def _upgrade_metadata_3(self, md_version):553 def _upgrade_metadata_3(self, md_version):
530 """554 """
531 Upgrade to version 4 (new layout!)555 Upgrade to version 4 (new layout!)

Subscribers

People subscribed via source and target branches