def test_filter_binary_logs_by_date(self):
        # Create fake binary log files for test.
        test_files = ['test-bin.000001', 'test-relay-bin.000101']
        for filename in test_files:
            test_file = os.path.join(self.tmp_source, filename)
            with open(test_file, 'w') as f_obj:
                f_obj.write("test file (fake binary log)\n")

        # No files older than 1 day.
        expected_files = []
        self.assertEqual(
            filter_binary_logs_by_date(test_files, self.tmp_source, 1),
            expected_files
        )

        # Check error: elapsed days must be > 0.
        self.assertRaises(UtilError, filter_binary_logs_by_date, test_files,
                          self.tmp_source, -1)

        # Check error: invalid date format (yyyy-mm-dd).
        self.assertRaises(UtilError, filter_binary_logs_by_date, test_files,
                          self.tmp_source, 'invalid_date')

        # Check error: invalid date/time format (yyyy-mm-ddThh:mm:ss).
        self.assertRaises(UtilError, filter_binary_logs_by_date, test_files,
                          self.tmp_source, '2014-07-21Tinvalid_time')

        # Hack file modified date/time (set it 2 days and 1 second before).
        test_file = os.path.join(self.tmp_source, test_files[0])
        hacked_time = time.time() - (86400 * 2) - 1
        os.utime(test_file, (hacked_time, hacked_time))

        # Files with last modification +2 days ago.
        expected_files = ['test-bin.000001']
        self.assertEqual(
            filter_binary_logs_by_date(test_files, self.tmp_source, 2),
            expected_files
        )

        # Files with last modification prior to yesterday.
        yesterday = time.localtime(time.time() - 86400)
        yesterday_date = time.strftime('%Y-%m-%d', yesterday)
        yesterday_datetime = time.strftime('%Y-%m-%dT%H:%M:%S', yesterday)
        self.assertEqual(
            filter_binary_logs_by_date(test_files, self.tmp_source,
                                       yesterday_date),
            expected_files
        )
        self.assertEqual(
            filter_binary_logs_by_date(test_files, self.tmp_source,
                                       yesterday_datetime),
            expected_files
        )
예제 #2
0
def _move_binlogs(source,
                  destination,
                  log_type,
                  options,
                  basename=None,
                  index_file=None,
                  skip_latest=False):
    """Move binary log files of the specified type.

    This auxiliary function moves the binary log files of a specific type
    (i.e., binary or relay) from the given source to the specified destination
    directory. It gets the files only for the specified binary log type and
    applies any filtering in accordance to the specified options. Resulting
    files are moved and the respective index file updated accordingly.

    source[in]          Source location of the binary log files to move.
    destination[in]     Destination directory for the binary log files.
    log_type[in]        Type of the binary log files ('bin' or 'relay').
    options[in]         Dictionary of options (modified_before, sequence,
                        verbosity).
    basename[in]        Base name for the binary log files, i.e. filename
                        without the extension (sequence number).
    index_file[in]      Path of the binary log index file. If not specified it
                        is assumed to be located in the source directory and
                        determined based on the basename of the first found
                        binary log file.
    skip_latest[in]     Bool value indication if the latest binary log file
                        (with the higher sequence value; in use by the
                        server) will be skipped or not. By default = False,
                        meaning that no binary log file is skipped.

    Returns the number of files moved.
    """
    verbosity = options['verbosity']
    binlog_files = []
    file_type = '{0}-log'.format(log_type)
    if basename:
        # Ignore path from basename if specified, source is used instead.
        _, basename = os.path.split(basename)
    # Get binary log files to move.
    for _, _, filenames in os.walk(source):
        for f_name in sorted(filenames):
            if is_binary_log_filename(f_name, log_type, basename):
                binlog_files.append(f_name)
        break
    if skip_latest:
        # Skip last file (with the highest sequence).
        # Note; filenames are sorted by ascending order.
        binlog_files = binlog_files[:-1]
    if not binlog_files:
        # No binary log files found to move.
        print(_WARN_MSG_NO_FILE.format(file_type=file_type))
    else:
        # Apply filters.
        sequence = options.get('sequence', None)
        if sequence:
            print("#")
            print(
                _INFO_MSG_APPLY_FILTERS.format(filter_type='sequence',
                                               file_type=file_type))
            binlog_files = filter_binary_logs_by_sequence(
                binlog_files, sequence)
        modified_before = options.get('modified_before', None)
        if modified_before:
            print("#")
            print(
                _INFO_MSG_APPLY_FILTERS.format(filter_type='modified date',
                                               file_type=file_type))
            binlog_files = filter_binary_logs_by_date(binlog_files, source,
                                                      modified_before)
        # Move files.
        print("#")
        if binlog_files:
            if index_file is None:
                # Get binary log index file.
                index_file = get_index_file(source, binlog_files[0])
                if verbosity > 0:
                    print(
                        _INFO_MSG_INDEX_FILE.format(file_type=file_type,
                                                    index_file=index_file))
                    print("#")
            print(_INFO_MSG_MOVE_FILES.format(file_type=file_type))
            for f_name in binlog_files:
                try:
                    print("# - {0}".format(f_name))
                    move_binary_log(source, destination, f_name, index_file)
                except (shutil.Error, IOError) as err:
                    raise UtilError(
                        _ERR_MSG_MOVE_FILE.format(filename=f_name, error=err))
            return len(binlog_files)
        else:
            print(_INFO_MSG_NO_FILES_TO_MOVE.format(file_type=file_type))
            return 0
예제 #3
0
def _move_binlogs(source, destination, log_type, options, basename=None,
                  index_file=None, skip_latest=False):
    """Move binary log files of the specified type.

    This auxiliary function moves the binary log files of a specific type
    (i.e., binary or relay) from the given source to the specified destination
    directory. It gets the files only for the specified binary log type and
    applies any filtering in accordance to the specified options. Resulting
    files are moved and the respective index file updated accordingly.

    source[in]          Source location of the binary log files to move.
    destination[in]     Destination directory for the binary log files.
    log_type[in]        Type of the binary log files ('bin' or 'relay').
    options[in]         Dictionary of options (modified_before, sequence,
                        verbosity).
    basename[in]        Base name for the binary log files, i.e. filename
                        without the extension (sequence number).
    index_file[in]      Path of the binary log index file. If not specified it
                        is assumed to be located in the source directory and
                        determined based on the basename of the first found
                        binary log file.
    skip_latest[in]     Bool value indication if the latest binary log file
                        (with the higher sequence value; in use by the
                        server) will be skipped or not. By default = False,
                        meaning that no binary log file is skipped.

    Returns the number of files moved.
    """
    verbosity = options['verbosity']
    binlog_files = []
    file_type = '{0}-log'.format(log_type)
    if basename:
        # Ignore path from basename if specified, source is used instead.
        _, basename = os.path.split(basename)
    # Get binary log files to move.
    for _, _, filenames in os.walk(source):
        for f_name in sorted(filenames):
            if is_binary_log_filename(f_name, log_type, basename):
                binlog_files.append(f_name)
        break
    if skip_latest:
        # Skip last file (with the highest sequence).
        # Note; filenames are sorted by ascending order.
        binlog_files = binlog_files[:-1]
    if not binlog_files:
        # No binary log files found to move.
        print(_WARN_MSG_NO_FILE.format(file_type=file_type))
    else:
        # Apply filters.
        sequence = options.get('sequence', None)
        if sequence:
            print("#")
            print(_INFO_MSG_APPLY_FILTERS.format(filter_type='sequence',
                                                 file_type=file_type))
            binlog_files = filter_binary_logs_by_sequence(binlog_files,
                                                          sequence)
        modified_before = options.get('modified_before', None)
        if modified_before:
            print("#")
            print(_INFO_MSG_APPLY_FILTERS.format(filter_type='modified date',
                                                 file_type=file_type))
            binlog_files = filter_binary_logs_by_date(binlog_files, source,
                                                      modified_before)
        # Move files.
        print("#")
        if binlog_files:
            if index_file is None:
                # Get binary log index file.
                index_file = get_index_file(source, binlog_files[0])
                if verbosity > 0:
                    print(_INFO_MSG_INDEX_FILE.format(file_type=file_type,
                                                      index_file=index_file))
                    print("#")
            print(_INFO_MSG_MOVE_FILES.format(file_type=file_type))
            for f_name in binlog_files:
                try:
                    print("# - {0}".format(f_name))
                    move_binary_log(source, destination, f_name, index_file)
                except (shutil.Error, IOError) as err:
                    raise UtilError(_ERR_MSG_MOVE_FILE.format(filename=f_name,
                                                              error=err))
            return len(binlog_files)
        else:
            print(_INFO_MSG_NO_FILES_TO_MOVE.format(file_type=file_type))
            return 0