← run

bcb-0012

0.000
0/6 tests· lib-knowledge
Challenge · difficulty 4/5
# BigCodeBench/12

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

Allowed libraries: `subprocess`, `datetime`, `json`, `os`.

```python
import subprocess
import os
import json
from datetime import datetime


def task_func(script_name='backup.sh', log_file='/home/user/backup_log.json'):
    """
    Runs the provided backup shell script and logs the start time, end time, and exit status 
    in a specified JSON log file.
    
    Parameters:
    - script_name (str): The name of the shell script to run. Default is 'backup.sh'.
    - log_file (str): The path to the JSON log file where the execution details will be recorded. Default is '/home/user/backup_log.json'.
    
    Returns:
    dict: A dictionary containing:
        - 'start_time': The start time of the script execution in the format '%Y-%m-%d %H:%M:%S'.
        - 'end_time': The end time of the script execution in the format '%Y-%m-%d %H:%M:%S'.
        - 'exit_status': The exit status of the script execution (0 for success, other values indicate an error).
    
    Raises:
    - FileNotFoundError: If the script file does not exist.
    - RuntimeError: If there is an error executing the script.
        
    Requirements:
    - subprocess
    - os
    - datetime
    - json
    
    Example:
    >>> task_func()
    {'start_time': '2023-09-19 14:30:00', 'end_time': '2023-09-19 14:35:00', 'exit_status': 0}
    """
```

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

import unittest
from unittest.mock import patch, mock_open
class TestCases(unittest.TestCase):
    
    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", return_value=0)
    @patch("builtins.open", new_callable=mock_open, read_data="{}")
    def test_default_values_successful_script(self, mock_file, mock_subprocess, mock_os):
        """Test the function with default parameters and successful execution"""
        result = task_func()
        self.assertIn('start_time', result)
        self.assertIn('end_time', result)
        self.assertEqual(result['exit_status'], 0)
    @patch("os.path.isfile", return_value=False)
    def test_script_does_not_exist(self, mock_os):
        """Test the function raising FileNotFoundError when the script file does not exist"""
        with self.assertRaises(FileNotFoundError):
            task_func()
    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", side_effect=Exception("Script failed"))
    def test_script_execution_failure(self, mock_subprocess, mock_os):
        """Test the function raising RuntimeError on script execution failure"""
        with self.assertRaises(RuntimeError):
            task_func()
    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", return_value=0)
    @patch("builtins.open", new_callable=mock_open, read_data="{}")
    def test_custom_values_successful_script(self, mock_file, mock_subprocess, mock_os):
        """Test the function with custom script name and log file with successful execution"""
        script_name = "custom_backup.sh"
        log_file = "/home/user/custom_backup_log.json"
        result = task_func(script_name, log_file)
        self.assertIn('start_time', result)
        self.assertIn('end_time', result)
        self.assertEqual(result['exit_status'], 0)
    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", return_value=0)
    @patch("builtins.open", new_callable=mock_open, read_data="{}")
    def test_log_data_format(self, mock_file, mock_subprocess, mock_os):
        """Test that the timestamps are in the correct format"""
        result = task_func()
        self.assertTrue(result['start_time'].count(":") == 2)
        self.assertTrue(result['end_time'].count(":") == 2)
    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", return_value=1)
    @patch("builtins.open", new_callable=mock_open, read_data="{}")
    def test_non_zero_exit_status(self, mock_file, mock_subprocess, mock_os):
        """Test the function with a non-zero exit status"""
        result = task_func()
        self.assertEqual(result['exit_status'], 1)
Proposed solution
```python
import subprocess
import os
import json
from datetime import datetime

def task_func(script_name='backup.sh', log_file='/home/user/backup_log.json'):
    """
    Runs the provided backup shell script and logs the start time, end time, and exit status of the script execution in a specified JSON log file.
    
    Parameters:
    - script_name (str): The name of the shell script to run. Default is 'backup.sh'.
    - log_file (str): The path to the JSON log file where the execution details will be recorded. Default is '/home/user/backup_log.json'.
    
    Returns:
    dict: A dictionary containing:
        - 'start_time': The start time of the script execution in the format '%Y-%m-%d %H:%M:%S'.
        - 'end_time': The end time of the script execution in the format '%Y-%m-%d %H:%M:%S'.
        - 'exit_status': The exit status of the script execution (0 for success, other values indicate an error).
    
    Raises:
    - FileNotFoundError: If the script file does not exist.
    - RuntimeError: If there is an error executing the script.
        
    Requirements:
    - subprocess
    - os
    - json
    - datetime
    """
```markdown:


```markdown
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# BigCodeBench/12
# Big

Test output (stdout)

403530041344'>

    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", return_value=0)
    @patch("builtins.open", new_callable=mock_open, read_data="{}")
    def test_default_values_successful_script(self, mock_file, mock_subprocess, mock_os):
        """Test the function with default parameters and successful execution"""
        result = task_func()
>       self.assertIn('start_time', result)
E       TypeError: argument of type 'NoneType' is not iterable

test_bcb_0012.py:15: TypeError
________________________ TestCases.test_log_data_format ________________________

self = <test_bcb_0012.TestCases testMethod=test_log_data_format>
mock_file = <MagicMock name='open' spec='builtin_function_or_method' id='126403530077424'>
mock_subprocess = <MagicMock name='call' id='126403530076416'>
mock_os = <MagicMock name='isfile' id='126403530181120'>

    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", return_value=0)
    @patch("builtins.open", new_callable=mock_open, read_data="{}")
    def test_log_data_format(self, mock_file, mock_subprocess, mock_os):
        """Test that the timestamps are in the correct format"""
        result = task_func()
>       self.assertTrue(result['start_time'].count(":") == 2)
E       TypeError: 'NoneType' object is not subscriptable

test_bcb_0012.py:46: TypeError
_____________________ TestCases.test_non_zero_exit_status ______________________

self = <test_bcb_0012.TestCases testMethod=test_non_zero_exit_status>
mock_file = <MagicMock name='open' spec='builtin_function_or_method' id='126403530226656'>
mock_subprocess = <MagicMock name='call' id='126403530225648'>
mock_os = <MagicMock name='isfile' id='126403530073296'>

    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", return_value=1)
    @patch("builtins.open", new_callable=mock_open, read_data="{}")
    def test_non_zero_exit_status(self, mock_file, mock_subprocess, mock_os):
        """Test the function with a non-zero exit status"""
        result = task_func()
>       self.assertEqual(result['exit_status'], 1)
E       TypeError: 'NoneType' object is not subscriptable

test_bcb_0012.py:54: TypeError
_____________________ TestCases.test_script_does_not_exist _____________________

self = <test_bcb_0012.TestCases testMethod=test_script_does_not_exist>
mock_os = <MagicMock name='isfile' id='126403530000944'>

    @patch("os.path.isfile", return_value=False)
    def test_script_does_not_exist(self, mock_os):
        """Test the function raising FileNotFoundError when the script file does not exist"""
>       with self.assertRaises(FileNotFoundError):
E       AssertionError: FileNotFoundError not raised

test_bcb_0012.py:21: AssertionError
___________________ TestCases.test_script_execution_failure ____________________

self = <test_bcb_0012.TestCases testMethod=test_script_execution_failure>
mock_subprocess = <MagicMock name='call' id='126403530059264'>
mock_os = <MagicMock name='isfile' id='126403530063440'>

    @patch("os.path.isfile", return_value=True)
    @patch("subprocess.call", side_effect=Exception("Script failed"))
    def test_script_execution_failure(self, mock_subprocess, mock_os):
        """Test the function raising RuntimeError on script execution failure"""
>       with self.assertRaises(RuntimeError):
E       AssertionError: RuntimeError not raised

test_bcb_0012.py:27: AssertionError
=========================== short test summary info ============================
FAILED test_bcb_0012.py::TestCases::test_custom_values_successful_script - Ty...
FAILED test_bcb_0012.py::TestCases::test_default_values_successful_script - T...
FAILED test_bcb_0012.py::TestCases::test_log_data_format - TypeError: 'NoneTy...
FAILED test_bcb_0012.py::TestCases::test_non_zero_exit_status - TypeError: 'N...
FAILED test_bcb_0012.py::TestCases::test_script_does_not_exist - AssertionErr...
FAILED test_bcb_0012.py::TestCases::test_script_execution_failure - Assertion...
6 failed in 0.04s