Ejemplo n.º 1
0
 def test_cli_quiet(self):
     """Test copying of a password without echoing the entry's text."""
     # Generate a password and some additional text for a dummy password store entry.
     a_password = random_string()
     additional_text = random_string()
     raw_entry = a_password + "\n\n" + additional_text
     # Prepare a mock method to test that the password is copied,
     # but without actually invoking the `pass' program.
     copy_password_method = MagicMock()
     # Some voodoo to mock methods in classes that
     # have yet to be instantiated follows :-).
     mocked_class = type("TestPasswordEntry", (PasswordEntry, ),
                         dict(text=raw_entry))
     setattr(mocked_class, "copy_password", copy_password_method)
     with PatchedAttribute(qpass, "PasswordEntry", mocked_class):
         with PatchedAttribute(cli, "is_clipboard_supported", lambda: True):
             with TemporaryDirectory() as directory:
                 touch(os.path.join(directory, "foo.gpg"))
                 returncode, output = run_cli(
                     main, "--password-store=%s" % directory, "--quiet",
                     "foo")
                 # Make sure the command succeeded.
                 assert returncode == 0
                 # Make sure the password was copied to the clipboard.
                 assert copy_password_method.called
                 # Make sure no output was generated.
                 assert not output.strip()
Ejemplo n.º 2
0
 def test_natural_order(self):
     """Verify the natural order sorting of the snippets in the configuration file."""
     first = "This should be the first line.\n"
     middle = "This should appear in the middle.\n"
     last = "This should be the last line.\n"
     with TemporaryDirectory() as temporary_directory:
         filename = os.path.join(temporary_directory, 'config')
         directory = '%s.d' % filename
         # Create the configuration file and directory.
         write_file(filename)
         os.makedirs(directory)
         # Create the files with configuration snippets.
         for number, contents in (1, first), (5, middle), (10, last):
             write_file(os.path.join(directory, '%i.conf' % number),
                        contents)
         # Use the command line interface to update the configuration file.
         returncode, output = run_cli(main, filename)
         assert returncode == 0
         # Make sure the configuration file was updated.
         assert os.path.isfile(filename)
         assert os.path.getsize(filename) > 0
         with open(filename) as handle:
             lines = handle.readlines()
             # Make sure all of the expected lines are present.
             assert first in lines
             assert middle in lines
             assert last in lines
             # Check the order of the lines (natural order instead of lexicographical).
             assert lines.index(first) < lines.index(middle)
             assert lines.index(middle) < lines.index(last)
Ejemplo n.º 3
0
 def test_filename_patterns(self):
     """Test support for filename patterns in configuration files."""
     with TemporaryDirectory(prefix='rotate-backups-',
                             suffix='-test-suite') as root:
         for subdirectory in 'laptop', 'vps':
             os.makedirs(os.path.join(root, subdirectory))
         config_file = os.path.join(root, 'rotate-backups.ini')
         parser = configparser.RawConfigParser()
         pattern = os.path.join(root, '*')
         parser.add_section(pattern)
         parser.set(pattern, 'daily', '7')
         parser.set(pattern, 'weekly', '4')
         parser.set(pattern, 'monthly', 'always')
         with open(config_file, 'w') as handle:
             parser.write(handle)
         # Check that the configured rotation scheme is applied.
         default_scheme = dict(monthly='always')
         program = RotateBackups(config_file=config_file,
                                 rotation_scheme=default_scheme)
         program.load_config_file(os.path.join(root, 'laptop'))
         assert program.rotation_scheme != default_scheme
         # Check that the available locations are matched.
         available_locations = [
             location for location, rotation_scheme, options in
             load_config_file(config_file)
         ]
         assert len(available_locations) == 2
         assert any(location.directory == os.path.join(root, 'laptop')
                    for location in available_locations)
         assert any(location.directory == os.path.join(root, 'vps')
                    for location in available_locations)
Ejemplo n.º 4
0
 def test_exclude_list(self):
     """Test that ``rsync-system-backup --exclude`` works as intended."""
     with TemporaryDirectory() as temporary_directory:
         source = os.path.join(temporary_directory, 'source')
         destination = os.path.join(temporary_directory, 'destination')
         latest_directory = os.path.join(destination, 'latest')
         # Create a source directory with two files.
         os.makedirs(source)
         with open(os.path.join(source, 'included.txt'), 'w') as handle:
             handle.write("This file should be included.\n")
         with open(os.path.join(source, 'excluded.txt'), 'w') as handle:
             handle.write("This file should be excluded.\n")
         # Run the program through the command line interface.
         exit_code, output = run_cli(
             main,
             '--backup',
             '--exclude=excluded.txt',
             '--no-sudo',
             '--disable-notifications',
             source,
             latest_directory,
         )
         assert exit_code == 0
         # Make sure one of the files was copied and the other wasn't.
         assert os.path.isfile(
             os.path.join(latest_directory, 'included.txt'))
         assert not os.path.exists(
             os.path.join(latest_directory, 'excluded.txt'))
Ejemplo n.º 5
0
 def test_missing_password_store_error(self):
     """Test the MissingPasswordStoreError exception."""
     with TemporaryDirectory() as directory:
         missing = os.path.join(directory, 'missing')
         program = PasswordStore(directory=missing)
         self.assertRaises(MissingPasswordStoreError,
                           program.ensure_directory_exists)
Ejemplo n.º 6
0
 def test_no_matching_password_error(self):
     """Test the NoMatchingPasswordError exception."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, 'Whatever.gpg'))
         program = PasswordStore(directory=directory)
         self.assertRaises(NoMatchingPasswordError, program.smart_search,
                           'x')
Ejemplo n.º 7
0
    def test_show_entry(self):
        """Test showing of an entry on the terminal."""
        password = random_string()
        # Some voodoo to mock methods in classes that
        # have yet to be instantiated follows :-).
        mocked_class = type(
            'TestPasswordEntry',
            (PasswordEntry, ),
            dict(text=password),
        )
        with PatchedAttribute(qpass, 'PasswordEntry', mocked_class):
            with TemporaryDirectory() as directory:
                name = 'some/random/password'
                touch(os.path.join(directory, '%s.gpg' % name))
                returncode, output = run_cli(
                    main,
                    '--password-store=%s' % directory,
                    '--no-clipboard',
                    name,
                )
                assert returncode == 0
                assert dedent(output) == dedent(
                    """
                    {title}

                    Password: {password}
                    """,
                    title=name.replace('/', ' / '),
                    password=password,
                )
Ejemplo n.º 8
0
 def test_argument_validation(self):
     """Test argument validation."""
     # Test that an invalid ionice scheduling class causes an error to be reported.
     returncode, output = run_cli(main, '--ionice=unsupported-class')
     assert returncode != 0
     # Test that an invalid rotation scheme causes an error to be reported.
     returncode, output = run_cli(main, '--hourly=not-a-number')
     assert returncode != 0
     # Argument validation tests that require an empty directory.
     with TemporaryDirectory(prefix='rotate-backups-',
                             suffix='-test-suite') as root:
         # Test that non-existing directories cause an error to be reported.
         returncode, output = run_cli(main,
                                      os.path.join(root, 'does-not-exist'))
         assert returncode != 0
         # Test that loading of a custom configuration file raises an
         # exception when the configuration file cannot be loaded.
         self.assertRaises(
             ValueError, lambda: list(
                 load_config_file(os.path.join(root, 'rotate-backups.ini')))
         )
         # Test that an empty rotation scheme raises an exception.
         self.create_sample_backup_set(root)
         self.assertRaises(
             ValueError,
             lambda: RotateBackups(rotation_scheme={}).rotate_backups(root))
     # Argument validation tests that assume the current user isn't root.
     if os.getuid() != 0:
         # I'm being lazy and will assume that this test suite will only be
         # run on systems where users other than root do not have access to
         # /root.
         returncode, output = run_cli(main, '-n', '/root')
         assert returncode != 0
Ejemplo n.º 9
0
 def test_encrypted_backup(self):
     """
     Test a backup to an encrypted filesystem.
     To make this test work you need to make the following additions
     to system files (and create ``/mnt/rsync-system-backup``):
     .. code-block:: sh
        $ grep rsync-system-backup /etc/fstab
        /dev/mapper/rsync-system-backup /mnt/rsync-system-backup ext4 noauto 0 0
        $ grep rsync-system-backup /etc/crypttab
        rsync-system-backup /tmp/rsync-system-backup.img /tmp/rsync-system-backup.key luks,noauto
        $ sudo cat /etc/sudoers.d/rsync-system-backup
         peter ALL=NOPASSWD:/usr/sbin/cryptdisks_start rsync-system-backup
         peter ALL=NOPASSWD:/usr/sbin/cryptdisks_stop rsync-system-backup
         peter ALL=NOPASSWD:/bin/mount /mnt/rsync-system-backup
         peter ALL=NOPASSWD:/bin/umount /mnt/rsync-system-backup
         peter ALL=NOPASSWD:/sbin/mkfs.ext4 /dev/mapper/rsync-system-backup
         peter ALL=NOPASSWD:/usr/bin/test -e /dev/mapper/rsync-system-backup
         peter ALL=NOPASSWD:/bin/mountpoint /mnt/rsync-system-backup
         peter ALL=NOPASSWD:/usr/bin/test -d /mnt/rsync-system-backup/latest
         peter ALL=NOPASSWD:/bin/mkdir -p /mnt/rsync-system-backup/latest
         peter ALL=NOPASSWD:/usr/bin/rsync * /tmp/* /mnt/rsync-system-backup/latest/
         peter ALL=NOPASSWD:/bin/cp --archive --link /mnt/rsync-system-backup/latest /mnt/rsync-system-backup/*
         peter ALL=NOPASSWD:/usr/bin/test -d /mnt/rsync-system-backup
         peter ALL=NOPASSWD:/usr/bin/test -r /mnt/rsync-system-backup
         peter ALL=NOPASSWD:/usr/bin/find /mnt/rsync-system-backup *
         peter ALL=NOPASSWD:/usr/bin/test -w /mnt/rsync-system-backup
         peter ALL=NOPASSWD:/bin/rm --recursive /mnt/rsync-system-backup/latest
     Of course you should change ``/etc/sudoers.d/rsync-system-backup`` to
     replace ``peter`` with your actual username :-).
     """
     if not os.path.isdir(MOUNT_POINT):
         return self.skipTest("Skipping test because %s doesn't exist!",
                              MOUNT_POINT)
     with TemporaryDirectory() as source:
         destination = os.path.join(MOUNT_POINT, 'latest')
         with prepared_image_file():
             # Create a source for testing.
             self.create_source(source)
             # Run the program through the command line interface.
             self.create_encrypted_backup(source, destination)
             # Unlock the encrypted image file.
             with unlocked_device(CRYPTO_NAME):
                 # Mount the encrypted filesystem.
                 with active_mountpoint(MOUNT_POINT):
                     # Verify that the backup was successful.
                     self.verify_destination(destination)
                     # Invoke rsync-system-backup using the same command line
                     # arguments, but this time while the encrypted device is
                     # already unlocked and the filesystem is already mounted.
                     self.create_encrypted_backup(source, destination)
                     # Verify that the backup was successful.
                     self.verify_destination(destination)
                 # Invoke rsync-system-backup using the same command line
                 # arguments, but this time while the encrypted device is
                 # already unlocked although the filesystem isn't mounted.
                 self.create_encrypted_backup(source, destination)
                 # Verify that the backup was successful.
                 with active_mountpoint(MOUNT_POINT):
                     self.verify_destination(destination)
Ejemplo n.º 10
0
 def test_temporary_directory(self):
     """Test :class:`humanfriendly.testing.TemporaryDirectory`."""
     with TemporaryDirectory() as directory:
         assert os.path.isdir(directory)
         temporary_file = os.path.join(directory, 'some-file')
         with open(temporary_file, 'w') as handle:
             handle.write("Hello world!")
     assert not os.path.exists(temporary_file)
     assert not os.path.exists(directory)
Ejemplo n.º 11
0
 def test_removal_command(self):
     """Test that the removal command can be customized."""
     with TemporaryDirectory(prefix='rotate-backups-',
                             suffix='-test-suite') as root:
         today = datetime.datetime.now()
         for date in today, (today - datetime.timedelta(hours=24)):
             os.mkdir(os.path.join(root, date.strftime('%Y-%m-%d')))
         program = RotateBackups(removal_command=['rmdir'],
                                 rotation_scheme=dict(monthly='always'))
         commands = program.rotate_backups(root, prepare=True)
         assert any(cmd.command_line[0] == 'rmdir' for cmd in commands)
Ejemplo n.º 12
0
 def test_rsync_module_path_as_destination(self):
     """Test that destination defaults to ``$RSYNC_MODULE_PATH``."""
     with TemporaryDirectory() as temporary_directory:
         try:
             os.environ['RSYNC_MODULE_PATH'] = temporary_directory
             program = RsyncSystemBackup()
             assert program.destination.directory == temporary_directory
             assert not program.destination.hostname
             assert not program.destination.username
             assert not program.destination.module
         finally:
             os.environ.pop('RSYNC_MODULE_PATH')
Ejemplo n.º 13
0
 def test_select_entry(self):
     """Test password selection."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, "foo.gpg"))
         touch(os.path.join(directory, "bar.gpg"))
         touch(os.path.join(directory, "baz.gpg"))
         program = PasswordStore(directory=directory)
         # Substring search.
         entry = program.select_entry("fo")
         assert entry.name == "foo"
         # Fuzzy search.
         entry = program.select_entry("bz")
         assert entry.name == "baz"
Ejemplo n.º 14
0
 def test_write_contents_create(self):
     """Test write_contents()."""
     expected_contents = u"Hello world!"
     with TemporaryDirectory() as directory:
         # Create the file.
         filename = os.path.join(directory, 'file-to-create')
         assert not os.path.exists(filename)
         write_contents(filename, expected_contents)
         # Make sure the file exists.
         assert os.path.exists(filename)
         # Validate the file's contents.
         with codecs.open(filename, 'r', 'UTF-8') as handle:
             assert handle.read() == expected_contents
Ejemplo n.º 15
0
 def test_select_entry_interactive(self):
     """Test interactive password selection."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, 'foo.gpg'))
         touch(os.path.join(directory, 'bar.gpg'))
         touch(os.path.join(directory, 'baz.gpg'))
         # Select entries using the command line filter 'a' and then use
         # interactive selection to narrow the choice down to 'baz' by
         # specifying the unique substring 'z'.
         program = PasswordStore(directory=directory)
         with CaptureOutput(input='z'):
             entry = program.select_entry('a')
             assert entry.name == 'baz'
Ejemplo n.º 16
0
 def test_password_discovery(self):
     """Test password discovery."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, 'foo.gpg'))
         touch(os.path.join(directory, 'foo/bar.gpg'))
         touch(os.path.join(directory, 'foo/bar/baz.gpg'))
         touch(os.path.join(directory, 'Also with spaces.gpg'))
         program = PasswordStore(directory=directory)
         assert len(program.entries) == 4
         assert program.entries[0].name == 'Also with spaces'
         assert program.entries[1].name == 'foo'
         assert program.entries[2].name == 'foo/bar'
         assert program.entries[3].name == 'foo/bar/baz'
Ejemplo n.º 17
0
 def test_select_entry(self):
     """Test password selection."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, 'foo.gpg'))
         touch(os.path.join(directory, 'bar.gpg'))
         touch(os.path.join(directory, 'baz.gpg'))
         program = PasswordStore(directory=directory)
         # Substring search.
         entry = program.select_entry('fo')
         assert entry.name == 'foo'
         # Fuzzy search.
         entry = program.select_entry('bz')
         assert entry.name == 'baz'
Ejemplo n.º 18
0
 def test_touch(self):
     """Test :func:`humanfriendly.testing.touch()`."""
     with TemporaryDirectory() as directory:
         # Create a file in the temporary directory.
         filename = os.path.join(directory, random_string())
         assert not os.path.isfile(filename)
         touch(filename)
         assert os.path.isfile(filename)
         # Create a file in a subdirectory.
         filename = os.path.join(directory, random_string(), random_string())
         assert not os.path.isfile(filename)
         touch(filename)
         assert os.path.isfile(filename)
Ejemplo n.º 19
0
 def test_cli_list(self):
     """Test the output of ``qpass --list``."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, 'foo.gpg'))
         touch(os.path.join(directory, 'foo/bar.gpg'))
         touch(os.path.join(directory, 'Also with spaces.gpg'))
         returncode, output = run_cli(main,
                                      '--password-store=%s' % directory,
                                      '--list')
         assert returncode == 0
         entries = output.splitlines()
         assert 'foo' in entries
         assert 'foo/bar' in entries
         assert 'Also with spaces' in entries
Ejemplo n.º 20
0
 def test_exclude_list(self):
     """Test exclude list logic."""
     # These are the backups expected to be preserved. After each backup
     # I've noted which rotation scheme it falls in and the number of
     # preserved backups within that rotation scheme (counting up as we
     # progress through the backups sorted by date).
     expected_to_be_preserved = set([
         '2013-10-10@20:07',  # monthly (1), yearly (1)
         '2013-11-01@20:06',  # monthly (2)
         '2013-12-01@20:07',  # monthly (3)
         '2014-01-01@20:07',  # monthly (4), yearly (2)
         '2014-02-01@20:05',  # monthly (5)
         '2014-03-01@20:04',  # monthly (6)
         '2014-04-01@20:03',  # monthly (7)
         '2014-05-01@20:06',  # monthly (8)
         '2014-05-19@20:02',  # weekly (1)
         '2014-05-26@20:05',  # weekly (2)
         '2014-06-01@20:01',  # monthly (9)
         '2014-06-09@20:01',  # weekly (3)
         '2014-06-16@20:02',  # weekly (4)
         '2014-06-23@20:04',  # weekly (5)
         '2014-06-26@20:04',  # daily (1)
         '2014-06-27@20:02',  # daily (2)
         '2014-06-28@20:02',  # daily (3)
         '2014-06-29@20:01',  # daily (4)
         '2014-06-30@20:03',  # daily (5), weekly (6)
         '2014-07-01@20:02',  # daily (6), monthly (10)
         '2014-07-02@20:03',  # hourly (1), daily (7)
         'some-random-directory',  # no recognizable time stamp, should definitely be preserved
     ])
     for name in SAMPLE_BACKUP_SET:
         if name.startswith('2014-05-'):
             expected_to_be_preserved.add(name)
     with TemporaryDirectory(prefix='rotate-backups-',
                             suffix='-test-suite') as root:
         self.create_sample_backup_set(root)
         run_cli(
             main,
             '--verbose',
             '--ionice=idle',
             '--hourly=24',
             '--daily=7',
             '--weekly=4',
             '--monthly=12',
             '--yearly=always',
             '--exclude=2014-05-*',
             root,
         )
         backups_that_were_preserved = set(os.listdir(root))
         assert backups_that_were_preserved == expected_to_be_preserved
Ejemplo n.º 21
0
 def test_prefer_new(self):
     """Test the alternative preference for the newest backup in each time slot."""
     with TemporaryDirectory(prefix='rotate-backups-',
                             suffix='-test-suite') as root:
         os.mkdir(os.path.join(root, 'backup-2016-01-10_21-15-00'))
         os.mkdir(os.path.join(root, 'backup-2016-01-10_21-30-00'))
         os.mkdir(os.path.join(root, 'backup-2016-01-10_21-45-00'))
         run_cli(main, '--hourly=1', '--prefer-recent', root)
         assert not os.path.exists(
             os.path.join(root, 'backup-2016-01-10_21-15-00'))
         assert not os.path.exists(
             os.path.join(root, 'backup-2016-01-10_21-30-00'))
         assert os.path.exists(
             os.path.join(root, 'backup-2016-01-10_21-45-00'))
Ejemplo n.º 22
0
 def test_minutely_rotation(self):
     """Test rotation with multiple backups per hour."""
     with TemporaryDirectory(prefix='rotate-backups-',
                             suffix='-test-suite') as root:
         os.mkdir(os.path.join(root, 'backup-2016-01-10_21-15-00'))
         os.mkdir(os.path.join(root, 'backup-2016-01-10_21-30-00'))
         os.mkdir(os.path.join(root, 'backup-2016-01-10_21-45-00'))
         run_cli(main, '--prefer-recent', '--relaxed', '--minutely=2', root)
         assert not os.path.exists(
             os.path.join(root, 'backup-2016-01-10_21-15-00'))
         assert os.path.exists(
             os.path.join(root, 'backup-2016-01-10_21-30-00'))
         assert os.path.exists(
             os.path.join(root, 'backup-2016-01-10_21-45-00'))
Ejemplo n.º 23
0
 def test_cli_exclude(self):
     """Test the output of ``qpass --exclude=... --list``."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, "foo.gpg"))
         touch(os.path.join(directory, "foo/bar.gpg"))
         touch(os.path.join(directory, "Also with spaces.gpg"))
         returncode, output = run_cli(main,
                                      "--password-store=%s" % directory,
                                      "--exclude=*bar*", "--list")
         assert returncode == 0
         entries = output.splitlines()
         assert "foo" in entries
         assert "foo/bar" not in entries
         assert "Also with spaces" in entries
Ejemplo n.º 24
0
 def test_make_dirs(self):
     """Test make_dirs()."""
     with TemporaryDirectory() as directory:
         subdirectory = os.path.join(directory, 'a', 'b', 'c')
         make_dirs(subdirectory)
         # Make sure the subdirectory was created.
         assert os.path.isdir(subdirectory)
         # Make sure existing directories don't raise an exception.
         make_dirs(subdirectory)
         # Make sure that errors other than EEXIST aren't swallowed. For the
         # purpose of this test we assume that /proc is the Linux `process
         # information pseudo-file system' whose top level directories
         # aren't writable (with or without superuser privileges).
         self.assertRaises(OSError, make_dirs, '/proc/linux-utils-test')
Ejemplo n.º 25
0
 def test_invalid_dates(self):
     """Make sure filenames with invalid dates don't cause an exception."""
     with TemporaryDirectory(prefix='rotate-backups-',
                             suffix='-test-suite') as root:
         file_with_valid_date = os.path.join(
             root, 'snapshot-201808030034.tar.gz')
         file_with_invalid_date = os.path.join(
             root, 'snapshot-180731150101.tar.gz')
         for filename in file_with_valid_date, file_with_invalid_date:
             touch(filename)
         program = RotateBackups(rotation_scheme=dict(monthly='always'))
         backups = program.collect_backups(root)
         assert len(backups) == 1
         assert backups[0].pathname == file_with_valid_date
Ejemplo n.º 26
0
 def test_touch(self):
     """Test touch()."""
     expected_contents = u"Hello world!"
     with TemporaryDirectory() as directory:
         # Test that touch() creates files.
         filename = os.path.join(directory, 'file-to-touch')
         touch(filename)
         assert os.path.isfile(filename)
         # Test that touch() doesn't change a file's contents.
         with open(filename, 'w') as handle:
             handle.write(expected_contents)
         touch(filename)
         with open(filename) as handle:
             assert handle.read() == expected_contents
Ejemplo n.º 27
0
 def test_smart_search(self):
     """Test smart searching."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, 'abcdef.gpg'))
         touch(os.path.join(directory, 'aabbccddeeff.gpg'))
         touch(os.path.join(directory, 'Google.gpg'))
         program = PasswordStore(directory=directory)
         # Test a substring match that avoids fuzzy matching.
         matches = program.smart_search('abc')
         assert len(matches) == 1
         assert matches[0].name == 'abcdef'
         # Test a fuzzy match to confirm that the fall back works.
         matches = program.smart_search('gg')
         assert len(matches) == 1
         assert matches[0].name == 'Google'
Ejemplo n.º 28
0
 def test_refuse_to_overwrite(self):
     """Test that local modifications are not overwritten."""
     with TemporaryDirectory() as temporary_directory:
         filename = os.path.join(temporary_directory, 'config')
         # Create the configuration file and directory.
         write_file(filename, "Original content.\n")
         # Use the command line interface to initialize the directory.
         returncode, output = run_cli(main, filename)
         assert returncode == 0
         # Modify the generated configuration file.
         write_file(filename, "Not the same thing.\n")
         # Use the command line interface to update the configuration file.
         returncode, output = run_cli(main, filename, merged=True)
         assert returncode != 0
         assert "refusing to overwrite" in output
Ejemplo n.º 29
0
 def test_rotate_backups(self):
     """Test the :func:`.rotate_backups()` function."""
     # These are the backups expected to be preserved. After each backup
     # I've noted which rotation scheme it falls in and the number of
     # preserved backups within that rotation scheme (counting up as we
     # progress through the backups sorted by date).
     expected_to_be_preserved = set([
         '2013-10-10@20:07',  # monthly (1), yearly (1)
         '2013-11-01@20:06',  # monthly (2)
         '2013-12-01@20:07',  # monthly (3)
         '2014-01-01@20:07',  # monthly (4), yearly (2)
         '2014-02-01@20:05',  # monthly (5)
         '2014-03-01@20:04',  # monthly (6)
         '2014-04-01@20:03',  # monthly (7)
         '2014-05-01@20:06',  # monthly (8)
         '2014-06-01@20:01',  # monthly (9)
         '2014-06-09@20:01',  # weekly (1)
         '2014-06-16@20:02',  # weekly (2)
         '2014-06-23@20:04',  # weekly (3)
         '2014-06-26@20:04',  # daily (1)
         '2014-06-27@20:02',  # daily (2)
         '2014-06-28@20:02',  # daily (3)
         '2014-06-29@20:01',  # daily (4)
         '2014-06-30@20:03',  # daily (5), weekly (4)
         '2014-07-01@20:02',  # daily (6), monthly (10)
         '2014-07-02@20:03',  # hourly (1), daily (7)
         'some-random-directory',  # no recognizable time stamp, should definitely be preserved
         'rotate-backups.ini',  # no recognizable time stamp, should definitely be preserved
     ])
     with TemporaryDirectory(prefix='rotate-backups-',
                             suffix='-test-suite') as root:
         # Specify the rotation scheme and options through a configuration file.
         config_file = os.path.join(root, 'rotate-backups.ini')
         parser = configparser.RawConfigParser()
         parser.add_section(root)
         parser.set(root, 'hourly', '24')
         parser.set(root, 'daily', '7')
         parser.set(root, 'weekly', '4')
         parser.set(root, 'monthly', '12')
         parser.set(root, 'yearly', 'always')
         parser.set(root, 'ionice', 'idle')
         with open(config_file, 'w') as handle:
             parser.write(handle)
         self.create_sample_backup_set(root)
         run_cli(main, '--verbose', '--config=%s' % config_file)
         backups_that_were_preserved = set(os.listdir(root))
         assert backups_that_were_preserved == expected_to_be_preserved
Ejemplo n.º 30
0
 def test_simple_search(self):
     """Test simple substring searching."""
     with TemporaryDirectory() as directory:
         touch(os.path.join(directory, 'foo.gpg'))
         touch(os.path.join(directory, 'bar.gpg'))
         touch(os.path.join(directory, 'baz.gpg'))
         program = PasswordStore(directory=directory)
         matches = program.simple_search('fo')
         assert len(matches) == 1
         assert matches[0].name == 'foo'
         matches = program.simple_search('a')
         assert len(matches) == 2
         assert matches[0].name == 'bar'
         assert matches[1].name == 'baz'
         matches = program.simple_search('b', 'z')
         assert len(matches) == 1
         assert matches[0].name == 'baz'