← run

bcb-0016

1.000
4/4 tests· lib-knowledge
Challenge · difficulty 3/5
# BigCodeBench/16

Implement a file **`solution.py`** that completes the function below. Keep the given name and signature; define `task_func` at module level.

Allowed libraries: `glob`, `subprocess`, `os`.

```python
import os
import glob
import subprocess

def task_func(directory, backup_dir='/path/to/backup'):
    """
    Backup all '.log' files in a specified directory to a tar.gz file and delete the original files after backup.
    The backup file is named 'logs_backup.tar.gz' and placed in the specified backup directory.
    
    Parameters:
    - directory (str): The directory that contains the log files to be backed up.
    - backup_dir (str, optional): The directory where the backup file will be saved.
                                  Default is '/path/to/backup'.
    
    Returns:
    - str: The path to the backup file if logs are found, otherwise returns a message 'No logs found to backup'.
    
    Raises:
    - FileNotFoundError: If the specified directory does not exist.
    
    Requirements:
    - subprocess
    - glob
    - os
    
    Example:
    >>> task_func('/path/to/logs')
    '/path/to/backup/logs_backup.tar.gz'
    >>> task_func('/path/to/logs', '/alternative/backup/dir')
    '/alternative/backup/dir/logs_backup.tar.gz'
    """
```

<!-- imported from BigCodeBench (BigCodeBench/16) -->
tests/test_bcb_0016.py
# Auto-generated from BigCodeBench BigCodeBench/16. Do not edit by hand.
import pathlib as _pathlib
exec(_pathlib.Path(__file__).with_name("solution.py").read_text(), globals())

import unittest
import tempfile
import os
import subprocess
import glob
import shutil
class TestCases(unittest.TestCase):
    def setUp(self):
        self.temp_dir = tempfile.mkdtemp()
        self.temp_backup_dir = tempfile.mkdtemp()
        
        # Create some log files and some non-log files
        for i in range(5):
            with open(os.path.join(self.temp_dir, f"file_{i}.log"), "w") as f:
                f.write(f"Mock log content for file_{i}")
            with open(os.path.join(self.temp_dir, f"file_{i}.txt"), "w") as f:
                f.write(f"Mock content for file_{i}.txt")
    def tearDown(self):
        shutil.rmtree(self.temp_dir)
        shutil.rmtree(self.temp_backup_dir)
    def test_backup_creation_and_log_file_deletion(self):
        # Test the creation of the backup file and deletion of original log files.
        backup_path = task_func(self.temp_dir, self.temp_backup_dir)
        self.assertTrue(os.path.exists(backup_path))
        self.assertEqual(backup_path, os.path.join(self.temp_backup_dir, 'logs_backup.tar.gz'))
        self.assertFalse(any(file.endswith('.log') for file in os.listdir(self.temp_dir)))
    def test_no_log_files_to_backup(self):
        # Test behavior when no log files are present in the directory.
        empty_dir = tempfile.mkdtemp()
        result = task_func(empty_dir, self.temp_backup_dir)
        self.assertEqual(result, "No logs found to backup")
        shutil.rmtree(empty_dir)
    def test_non_log_files_remain(self):
        # Ensure that non-log files are not deleted or included in the backup.
        backup_path = task_func(self.temp_dir, self.temp_backup_dir)
        self.assertEqual(len(glob.glob(os.path.join(self.temp_dir, '*.txt'))), 5)  # Check only non-log files remain
    def test_handle_non_existing_directory(self):
        # Verify that a FileNotFoundError is raised for a non-existing source directory.
        with self.assertRaises(FileNotFoundError):
            task_func('/non/existing/directory', self.temp_backup_dir)
System prompt
You are an expert programmer. Solve the task exactly as specified. Output your solution as fenced code blocks using the required file name(s) and the exact function/type signatures requested. Prefer correctness; do not include prose outside code unless asked.
Proposed solution
```python
import os
import glob
import subprocess

def task_func(directory, backup_dir='/path/to/backup'):
    """
    Backup all '.log' files in a specified directory to a tar.gz file and delete the original files after backup.
    The backup file is named 'logs_backup.tar.gz' and placed in the specified backup directory.
    
    Parameters:
    - directory (str): The directory that contains the log files to be backed up.
    - backup_dir (str, optional): The directory where the backup file will be saved.
                                  Default is '/path/to/backup'.
    
    Returns:
    - str: The path to the backup file if logs are found, otherwise returns a message 'No logs found to backup'.
    
    Raises:
    - FileNotFoundError: If the specified directory does not exist.
    
    Requirements:
    - subprocess
    - glob
    - os
    
    Example:
    >>> task_func('/path/to/logs')
    '/path/to/backup/logs_backup.tar.gz'
    >>> task_func('/path/to/logs', '/alternative/backup/dir')
    '/alternative/backup/dir/logs_backup.tar.gz'
    """
    # Check if directory exists
    if not os.path.exists(directory):
        raise FileNotFoundError(f"The directory '{directory}' does not exist.")
    
    # Find all .log files in the specified directory
    log_files = glob.glob(os.path.join(directory, '*.log'))
    
    # If no log files found, return message
    if not log_files:
        return 'No logs found to backup'
    
    # Ensure backup directory exists
    os.makedirs(backup_dir, exist_ok=True)
    
    # Create the path for the backup file
    backup_file_path = os.path.join(backup_dir, 'logs_backup.tar.gz')
    
    # Create tar.gz archive with the log files
    # Using subprocess to run tar command
    try:
        # Create tar archive first
        subprocess.run(['tar', '-cvf', os.path.join(backup_dir, 'logs_backup.tar'), 
                       '--transform', f's|.*/||',] + log_files, 
                      check=True, cwd=directory)
        
        # Compress the tar file to gzip
        subprocess.run(['gzip', '-f', os.path.join(backup_dir, 'logs_backup.tar')], 
                      check=True, cwd=backup_dir)
    except subprocess.CalledProcessError as e:
        raise RuntimeError(f"Failed to create backup archive: {e}")
    
    # Delete the original log files after successful backup
    for log_file in log_files:
        os.remove(log_file)
    
    return backup_file_path
```

Test output (stdout)

....                                                                     [100%]
4 passed in 0.03s