def test_clean(self, build_backup_directory):
        backup_dir = str(build_backup_directory["backup_dir"])
        group = CompleteBackupGroup(name="test",
                                    backup_dir=backup_dir,
                                    hosts=["r:.*"])
        group.scan_backup_dir()
        nb_initial_backups = sum(len(b) for b in group.backups.values())

        cleaned = group.clean(hourly=2, daily=3, weekly=1, monthly=1, yearly=2)
        backups_def = list_backups_by_domain(str(backup_dir))
        expected_dates = sorted((
            arrow.get("2016-07-08 19:40:02").to("local"),
            arrow.get("2016-07-08 18:30:02").to("local"),
            arrow.get("2016-07-08 17:40:02").to("local"),
            arrow.get("2016-07-07 19:40:02").to("local"),
            arrow.get("2016-07-06 20:40:02").to("local"),
            arrow.get("2016-03-08 14:28:13").to("local"),
            arrow.get("2014-05-01 00:30:00").to("local"),
        ))

        for domain, backups in group.backups.items():
            dates = sorted(b.date for b in backups)
            assert dates == expected_dates
            assert len(backups_def[domain]) == len(backups)

        nb_remaining_backups = sum(len(b) for b in group.backups.values())
        assert len(cleaned) == nb_initial_backups - nb_remaining_backups
    def prepare_get_backup_at_date(self, build_backup_directory):
        backup_dir = str(build_backup_directory["backup_dir"])
        group = CompleteBackupGroup(name="test",
                                    backup_dir=backup_dir,
                                    hosts=["r:.*"])
        group.scan_backup_dir()

        return group
    def test_scan_backup_dir_without_host(self, build_backup_directory):
        backup_dir = str(build_backup_directory["backup_dir"])

        group = CompleteBackupGroup(name="test",
                                    backup_dir=backup_dir,
                                    hosts=tuple())
        group.scan_backup_dir()

        assert not group.backups.keys()
    def test_scan_backup_dir_without_host(self, build_backup_directory):
        backup_dir = str(build_backup_directory["backup_dir"])
        backups_def = list_backups_by_domain(str(backup_dir))

        group = CompleteBackupGroup(
            name="test", backup_dir=backup_dir, hosts=[]
        )
        group.scan_backup_dir()

        assert not group.backups.keys()
    def test_scan_backup_dir(self, build_backup_directory):
        backup_dir = str(build_backup_directory["backup_dir"])
        backups_def = list_backups_by_domain(str(backup_dir))

        group = CompleteBackupGroup(name="test",
                                    backup_dir=backup_dir,
                                    hosts=("r:.*", ))
        group.scan_backup_dir()

        assert sorted(group.backups.keys()) == sorted(backups_def.keys())
        for dom in group.backups:
            assert len(group.backups[dom]) == len(backups_def[dom])
    def test_scan_backup_dir_several_patterns(self, build_backup_directory):
        backup_dir = str(build_backup_directory["backup_dir"])
        backups_def = list_backups_by_domain(str(backup_dir))

        # g: should do nothing for now, but test if passing
        group = CompleteBackupGroup(name="test",
                                    backup_dir=backup_dir,
                                    hosts=("a", "r:^[b-z].*", "g:all"))
        group.scan_backup_dir()

        assert group.backups
        assert sorted(group.backups.keys()) == sorted(backups_def.keys())
        for dom in group.backups:
            assert len(group.backups[dom]) == len(backups_def[dom])
    def test_get_nearest_backup_of(self, build_backup_directory):
        backup_dir = str(build_backup_directory["backup_dir"])
        group = CompleteBackupGroup(name="test",
                                    backup_dir=backup_dir,
                                    hosts=["r:.*"])
        group.scan_backup_dir()

        domain_name = next(iter(group.backups.keys()))
        testing_date = arrow.get("2015")
        nearest_backup = group.get_n_nearest_backup(domain_name, testing_date,
                                                    1)[0]

        difference = abs(testing_date - nearest_backup.date)
        for b in group.backups[domain_name]:
            assert abs(testing_date - b.date) >= difference
    def test_clean_broken(self, build_backup_directory, build_mock_domain,
                          build_mock_libvirtconn, mocker):
        build_mock_libvirtconn._domains.append(build_mock_domain)
        backup_dir = build_backup_directory["backup_dir"]
        group = CompleteBackupGroup(name="test",
                                    backup_dir=str(backup_dir),
                                    hosts=["r:.*"],
                                    conn=build_mock_libvirtconn)

        dombkup = DomBackup(dom=build_mock_domain,
                            target_dir=str(
                                backup_dir.mkdir(build_mock_domain.name())))
        dombkup.pending_info["domain_name"] = build_mock_domain.name()
        dombkup.pending_info["date"] = 0
        dombkup._dump_pending_info()

        group.scan_backup_dir()
        nb_initial_backups = sum(len(b) for b in group.broken_backups.values())
        assert nb_initial_backups == 1

        broken_backup = group.broken_backups[build_mock_domain.name()][0]
        mocker.spy(broken_backup, "clean_aborted")

        group.clean_broken_backups()
        assert not group.broken_backups[build_mock_domain.name()]
        assert broken_backup.clean_aborted.called
    def test_clean_unset_period(self, build_backup_directory):
        """
        Test if cleaning works if some periods are not set.

        Related to issue #27
        """
        backup_dir = str(build_backup_directory["backup_dir"])
        group = CompleteBackupGroup(name="test",
                                    backup_dir=backup_dir,
                                    hosts=["r:.*"])
        group.scan_backup_dir()

        group.clean(daily=3, monthly=1, yearly=2)
        expected_dates = sorted((
            arrow.get("2014-05-01 00:30:00").to("local"),
            arrow.get("2016-03-08 14:28:13").to("local"),
            arrow.get("2016-04-08 19:40:02").to("local"),
            arrow.get("2016-07-06 20:40:02").to("local"),
            arrow.get("2016-07-07 19:40:02").to("local"),
            arrow.get("2016-07-07 21:40:02").to("local"),
            arrow.get("2016-07-08 17:40:02").to("local"),
            arrow.get("2016-07-08 18:30:02").to("local"),
            arrow.get("2016-07-08 19:40:02").to("local"),
        ))

        for domain, backups in group.backups.items():
            dates = sorted(b.date for b in backups)
            assert dates == expected_dates
    def test_clean_broken(self, build_backup_directory, build_mock_domain,
                          build_mock_libvirtconn, mocker):
        build_mock_libvirtconn._domains.append(build_mock_domain)
        callbacks_registrer = DomExtSnapshotCallbackRegistrer(
            build_mock_libvirtconn)
        backup_dir = build_backup_directory["backup_dir"]
        group = CompleteBackupGroup(
            name="test",
            backup_dir=str(backup_dir),
            hosts=["r:.*"],
            conn=build_mock_libvirtconn,
            callbacks_registrer=callbacks_registrer,
        )

        dombkup = DomBackup(
            dom=build_mock_domain,
            backup_dir=str(backup_dir.mkdir(build_mock_domain.name())),
            callbacks_registrer=callbacks_registrer,
        )
        dombkup.pending_info = dombkup.get_definition()
        dombkup.pending_info["domain_name"] = build_mock_domain.name()
        dombkup.pending_info["date"] = 0
        dombkup.pending_info["disks"] = {}
        dombkup.pending_info["name"] = "test"
        dombkup.pending_info["packager"] = {"type": "directory", "opts": {}}
        dombkup._dump_pending_info()

        group.scan_backup_dir()
        nb_initial_backups = sum(len(b) for b in group.broken_backups.values())
        assert nb_initial_backups == 1

        broken_backup = group.broken_backups[build_mock_domain.name()][0]
        mocker.spy(broken_backup, "clean_aborted")

        group.clean_broken_backups()
        assert not group.broken_backups[build_mock_domain.name()]
        assert broken_backup.clean_aborted.called