def test_backup_files_dir_multiple_archives(self):

        # create a backup files directory
        with tempfile.TemporaryDirectory() as tmp_dir:

            # create the 1st backup file
            with tempfile.NamedTemporaryFile(dir=tmp_dir) as tmp_file_1:
                with zipfile.ZipFile(tmp_file_1, 'w',
                                     zipfile.ZIP_DEFLATED) as archive:
                    archive.writestr('something1.txt', 'Some Content Here')

                # make sure timestamps of files modification differ
                time.sleep(1)

                # create the 2nd backup file
                with tempfile.NamedTemporaryFile(dir=tmp_dir) as tmp_file_2:
                    with zipfile.ZipFile(tmp_file_2, 'w',
                                         zipfile.ZIP_DEFLATED) as archive:
                        archive.writestr('something2.txt', 'Some Content Here')

                    backup_file = RestoreCommand().parse_backup_files_dir(
                        tmp_dir)

                    self.assertIn(tmp_file_2.name, backup_file,
                                  'Expected the younger file to be chosen.')
    def test_mandatory_option_backup_file_success(self):

        with tempfile.NamedTemporaryFile() as tmp:
            with zipfile.ZipFile(tmp, 'w', zipfile.ZIP_DEFLATED) as archive:
                archive.writestr('something.txt', 'Some Content Here')

            options = {'backup_file': tmp.name}
            RestoreCommand().validate_backup_file_options(**options)
    def test_mandatory_option_failure(self):

        options = {}

        with self.assertRaises(CommandError) as exc:
            RestoreCommand().validate_backup_file_options(**options)

        self.assertIn('Mandatory option', exc.exception.args[0],
                      '"Mandatory option" failure exception expected.')
    def test_mandatory_option_backup_files_dir_failure(self):

        with tempfile.NamedTemporaryFile() as tmp:

            options = {'backup_files_dir': tmp.name}

            with self.assertRaises(CommandError) as exc:
                RestoreCommand().validate_backup_file_options(**options)

            self.assertIn('not a directory', exc.exception.args[0],
                          '"not a directory" failure exception expected.')
    def test_exclusive_option_failure(self):

        options = {
            'backup_file': '/some/random/path/1.zip',
            'backup_files_dir': '/some/random/path'
        }

        with self.assertRaises(CommandError) as exc:
            RestoreCommand().validate_backup_file_options(**options)

        self.assertIn('Exclusive option', exc.exception.args[0],
                      '"Exclusive option" failure exception expected.')
    def test_backup_hash_no_md5_file(self):

        # create the backup file
        with tempfile.NamedTemporaryFile() as tmp_file:
            with zipfile.ZipFile(tmp_file, 'w',
                                 zipfile.ZIP_DEFLATED) as archive:
                archive.writestr('something.txt', 'Some Content Here')

            file_hash = RestoreCommand().validate_backup_file_hash(
                tmp_file.name)

            self.assertIsNotNone(
                file_hash, 'Expected the backup file MD5 hash to be returned.')
    def test_backup_files_dir_with_older_restored_backup(self):

        # create an entry in restoration history with a dump created in the past
        RestoredBackupFactory(creation_date=(datetime.datetime.now()) -
                              datetime.timedelta(days=2))

        # create a backup files directory
        with tempfile.TemporaryDirectory() as tmp_dir:

            # create the backup file
            with tempfile.NamedTemporaryFile(dir=tmp_dir) as tmp_file:
                with zipfile.ZipFile(tmp_file, 'w',
                                     zipfile.ZIP_DEFLATED) as archive:
                    archive.writestr('something.txt', 'Some Content Here')

                backup_file = RestoreCommand().parse_backup_files_dir(tmp_dir)

                self.assertIn(tmp_file.name, backup_file,
                              'Expected the backup to be chosen.')
    def test_backup_hash_success(self):

        # create the backup file
        with tempfile.NamedTemporaryFile() as tmp_file:
            with zipfile.ZipFile(tmp_file, 'w',
                                 zipfile.ZIP_DEFLATED) as archive:
                archive.writestr('something.txt', 'Some Content Here')

            # create a md5 hash file for the backup temporary file
            tmp_hash_file = tmp_file.name + '.md5'
            with open(tmp_hash_file, 'w') as hash_file:
                hash_file.write(md5_file_hash(tmp_file.name))

            try:
                file_hash = RestoreCommand().validate_backup_file_hash(
                    tmp_file.name)

                self.assertIsNotNone(
                    file_hash,
                    'Expected the backup file MD5 hash to be returned.')

            finally:
                # remove temporary hash file
                os.remove(tmp_hash_file)
    def test_backup_hash_failure(self):

        # create the backup file
        with tempfile.NamedTemporaryFile() as tmp_file:
            with zipfile.ZipFile(tmp_file, 'w',
                                 zipfile.ZIP_DEFLATED) as archive:
                archive.writestr('something.txt', 'Some Content Here')

            # create a md5 hash file for the backup temporary file
            tmp_hash_file = tmp_file.name + '.md5'
            with open(tmp_hash_file, 'w') as hash_file:
                hash_file.write('91162629d258a876ee994e9233b2ad87')

            try:
                with self.assertRaises(RuntimeError) as exc:
                    RestoreCommand().validate_backup_file_hash(tmp_file.name)

                self.assertIn(
                    'Backup archive integrity failure', exc.exception.args[0],
                    '"Backup archive integrity failure" exception expected.')

            finally:
                # remove temporary hash file
                os.remove(tmp_hash_file)
    def test_mandatory_option_backup_files_dir_success(self):

        with tempfile.TemporaryDirectory() as tmp:
            options = {'backup_files_dir': tmp}
            RestoreCommand().validate_backup_file_options(**options)
    def test_backup_files_dir_no_archive(self):

        with tempfile.TemporaryDirectory() as tmp:

            backup_file = RestoreCommand().parse_backup_files_dir(tmp)
            self.assertIsNone(backup_file, 'Expecting backup file to be None')