Skip to content

Commit

Permalink
modifications in test_ensemble_manager.py
Browse files Browse the repository at this point in the history
  • Loading branch information
lujzi05 committed Jan 13, 2025
1 parent 31cec1f commit 33a83ae
Showing 1 changed file with 127 additions and 116 deletions.
243 changes: 127 additions & 116 deletions tests/test_ensemble_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ def mock_ensemble_manager(self, mock_model_path, args):
manager.config = mock_update_single_config(args)
manager.config = {"name": "test_model"}
return manager

@pytest.fixture
def mock_read_dataframe(self):
with patch("views_pipeline_core.files.utils.read_dataframe") as mock:
mock.return_value = pd.DataFrame({"mock_column": [1, 2, 3]})
yield mock



Expand Down Expand Up @@ -277,7 +283,7 @@ def test_evaluate_ensemble(self, mock_model_path, args,
patch("views_pipeline_core.files.utils.create_log_file") as mock_create_log_file, \
patch("views_pipeline_core.files.utils.create_specific_log_file") as mock_create_specific_log_file, \
patch("views_pipeline_core.files.utils.read_log_file") as mock_read_log_file, \
patch("views_pipeline_core.managers.model.ModelPath") as mock_model_path_class, \
patch("views_pipeline_core.managers.model.ModelPathManager") as mock_model_path_class, \
patch("views_pipeline_core.managers.model.ModelPathManager._get_model_dir") as mock_get_model_dir, \
patch("views_pipeline_core.managers.model.ModelPathManager._build_absolute_directory") as mock_build_absolute_directory:

Expand Down Expand Up @@ -485,6 +491,7 @@ def test_evaluate_model_artifact(self, mock_model_path, args, expected_command,
patch("views_pipeline_core.managers.ensemble.logger") as mock_logger, \
patch("views_pipeline_core.managers.ensemble.read_log_file") as mock_read_log_file, \
patch("views_pipeline_core.managers.ensemble.create_log_file") as mock_create_log_file, \
patch("views_pipeline_core.managers.ensemble.read_dataframe") as mock_read_dataframe, \
patch("views_pipeline_core.managers.model.ModelPathManager._build_absolute_directory") as mock_build_absolute_directory, \
patch("pathlib.Path.exists") as mock_path_exists, \
patch("builtins.open", unittest.mock.mock_open(read_data=pickle.dumps("mocked_prediction"))) as mock_file_open:
Expand All @@ -501,10 +508,14 @@ def test_evaluate_model_artifact(self, mock_model_path, args, expected_command,
mock_model_manager_instance.configs = {"model_name": "test_model", "run_type": "test_run"}

# Mock the read_log_file function to return a specific log data
mock_read_log_file.return_value = {"Data Fetch Timestamp": "2024-12-11T12:00:00"}
mock_read_log_file.return_value = {"Data Fetch Timestamp": "2024-12-11T12:00:00"}


#mock_model_path_class.get_latest_model_artifact_path.return_value = "predictions_test_run_202401011200000"
mock_get_latest_model_artifact_path.return_value = MagicMock(run_type="test_run",stem="predictions_test_run_202401011200000")
mock_artifact_path = MagicMock()
mock_artifact_path.stem = "predictions_test_run_202401011200000"


mock_get_latest_model_artifact_path.return_value = MagicMock(stem="predictions_test_run_202401011200000")

# Instantiate the manager and set up the config
manager = EnsembleManager(ensemble_path=mock_model_path_instance)
Expand All @@ -515,15 +526,14 @@ def test_evaluate_model_artifact(self, mock_model_path, args, expected_command,
"deployment_status": "test_status",
"aggregation": "mean",
}
#mock_path_exists.side_effect = lambda p: str(p) == f"<MagicMock name='ModelPath().data_generated' id='6344983952'>/predictions_test_run_<MagicMock name='_get_latest_model_artifact().stem.__getitem__()' id='6344929168'>_00.pkl"
# Call the method under test
result = manager._evaluate_model_artifact("test_model", "test_run", eval_type="standard")
mock_logger.info.assert_any_call("Evaluating single model test_model...")
mock_logger.info.assert_any_call("Loading existing test_run predictions from /mock/path/generated/predictions_test_run_202401011200000_00.pkl")
mock_file_open.assert_called_with(
"/mock/path/generated/predictions_test_run_202401011200000_00.pkl", "rb"
)
#self.assertEqual(result, ["mocked_prediction"])
self.assertEqual(result, ["mocked_prediction"])



Expand Down Expand Up @@ -574,96 +584,97 @@ def test_evaluate_model_artifact(self, mock_model_path, args, expected_command,



def test_forecast_model_artifact(self, mock_model_path, args, expected_command, expected_methods_called):
# Mocking required methods and classes
with patch("views_pipeline_core.managers.model.ModelPathManager.get_latest_model_artifact_path") as mock_get_latest_model_artifact_path, \
patch("views_pipeline_core.managers.ensemble.ModelPathManager") as mock_model_path_class, \
patch("views_pipeline_core.managers.ensemble.ModelManager") as mock_model_manager_class, \
patch("views_pipeline_core.managers.ensemble.subprocess.run") as mock_subprocess_run, \
patch("views_pipeline_core.managers.ensemble.logger") as mock_logger, \
patch("views_pipeline_core.managers.ensemble.read_log_file") as mock_read_log_file, \
patch("views_pipeline_core.managers.ensemble.create_log_file") as mock_create_log_file, \
patch("views_pipeline_core.managers.model.ModelPathManager._build_absolute_directory") as mock_build_absolute_directory, \
patch("pathlib.Path.exists") as mock_path_exists, \
patch("builtins.open", unittest.mock.mock_open(read_data=pickle.dumps("mocked_prediction"))) as mock_file_open:
# def test_forecast_model_artifact(self, mock_model_path, args, expected_command, expected_methods_called):
# # Mocking required methods and classes
# with patch("views_pipeline_core.managers.model.ModelPathManager.get_latest_model_artifact_path") as mock_get_latest_model_artifact_path, \
# patch("views_pipeline_core.managers.ensemble.ModelPathManager") as mock_model_path_class, \
# patch("views_pipeline_core.managers.ensemble.ModelManager") as mock_model_manager_class, \
# patch("views_pipeline_core.managers.ensemble.subprocess.run") as mock_subprocess_run, \
# patch("views_pipeline_core.managers.ensemble.logger") as mock_logger, \
# patch("views_pipeline_core.managers.ensemble.read_log_file") as mock_read_log_file, \
# patch("views_pipeline_core.managers.ensemble.create_log_file") as mock_create_log_file, \
# patch("views_pipeline_core.managers.ensemble.read_dataframe") as mock_read_dataframe, \
# patch("views_pipeline_core.managers.model.ModelPathManager._build_absolute_directory") as mock_build_absolute_directory, \
# patch("pathlib.Path.exists") as mock_path_exists, \
# patch("builtins.open", unittest.mock.mock_open(read_data=pickle.dumps("mocked_prediction"))) as mock_file_open:


# Mock the ModelPath instance and its attributes
mock_model_path_instance = mock_model_path_class.return_value
#mock_model_path_instance.data_raw = "/mock/path/raw"
mock_model_path_instance.data_generated = "/mock/path/generated"
# # Mock the ModelPath instance and its attributes
# mock_model_path_instance = mock_model_path_class.return_value
# #mock_model_path_instance.data_raw = "/mock/path/raw"
# mock_model_path_instance.data_generated = "/mock/path/generated"

# Mock the ModelManager instance and its configs
mock_model_manager_instance = mock_model_manager_class.return_value
# # Mock the ModelManager instance and its configs
# mock_model_manager_instance = mock_model_manager_class.return_value

mock_model_manager_instance.configs = {"model_name": "test_model", "run_type": "test_run"}
# mock_model_manager_instance.configs = {"model_name": "test_model", "run_type": "test_run"}

# Mock the read_log_file function to return a specific log data
mock_read_log_file.return_value = {"Data Fetch Timestamp": "2024-12-11T12:00:00"}
# # Mock the read_log_file function to return a specific log data
# mock_read_log_file.return_value = {"Data Fetch Timestamp": "2024-12-11T12:00:00"}


mock_get_latest_model_artifact_path.return_value = MagicMock(stem="predictions_test_run_202401011200000")
# Instantiate the manager and set up the config
manager = EnsembleManager(ensemble_path=mock_model_path_instance)
manager.config = {
"run_type": "test_run",
"models": ["test_model"],
"name": "test_ensemble",
"deployment_status": "test_status",
"aggregation": "mean",
}
#mock_path_exists.side_effect = lambda p: str(p) == f"<MagicMock name='ModelPath().data_generated' id='6344983952'>/predictions_test_run_<MagicMock name='_get_latest_model_artifact().stem.__getitem__()' id='6344929168'>_00.pkl"
# Call the method under test
result = manager._forecast_model_artifact("test_model", "test_run")
print(mock_logger.info.call_count)
mock_logger.info.assert_any_call("Forecasting single model test_model...")
mock_logger.info.assert_any_call("Loading existing test_run predictions from /mock/path/generated/predictions_test_run_202401011200000.pkl")
mock_file_open.assert_called_with(
"/mock/path/generated/predictions_test_run_202401011200000.pkl", "rb"
)
#self.assertEqual(result, ["mocked_prediction"])



mock_path_exists.return_value= False

# Generate the expected shell command
shell_command = EnsembleManager._get_shell_command(
mock_model_path_instance,
"test_run",
train=False,
evaluate=False,
forecast=True,
use_saved=True,
eval_type="standard"
)
#mock_path_exists.side_effect = False # Simulate missing file
result = manager._forecast_model_artifact("test_model", "test_run")
mock_logger.info.assert_any_call("No existing test_run predictions found. Generating new test_run predictions...")

# Assert that subprocess.run is called once with the correct command
mock_subprocess_run.assert_called_once_with(
shell_command, # This should now match the generated shell command
check=True
)
# mock_get_latest_model_artifact_path.return_value = MagicMock(stem="predictions_test_run_202401011200000")

# # Instantiate the manager and set up the config
# manager = EnsembleManager(ensemble_path=mock_model_path_instance)
# manager.config = {
# "run_type": "test_run",
# "models": ["test_model"],
# "name": "test_ensemble",
# "deployment_status": "test_status",
# "aggregation": "mean",
# }
# #mock_path_exists.side_effect = lambda p: str(p) == f"<MagicMock name='ModelPath().data_generated' id='6344983952'>/predictions_test_run_<MagicMock name='_get_latest_model_artifact().stem.__getitem__()' id='6344929168'>_00.pkl"
# # Call the method under test
# result = manager._forecast_model_artifact("test_model", "test_run")
# print(mock_logger.info.call_count)
# mock_logger.info.assert_any_call("Forecasting single model test_model...")
# mock_logger.info.assert_any_call("Loading existing test_run predictions from /mock/path/generated/predictions_test_run_202401011200000.pkl")
# mock_file_open.assert_called_with(
# "/mock/path/generated/predictions_test_run_202401011200000.pkl", "rb"
# )
# #self.assertEqual(result, ["mocked_prediction"])



# mock_path_exists.return_value= False

# # Generate the expected shell command
# shell_command = EnsembleManager._get_shell_command(
# mock_model_path_instance,
# "test_run",
# train=False,
# evaluate=False,
# forecast=True,
# use_saved=True,
# eval_type="standard"
# )
# #mock_path_exists.side_effect = False # Simulate missing file
# result = manager._forecast_model_artifact("test_model", "test_run")
# mock_logger.info.assert_any_call("No existing test_run predictions found. Generating new test_run predictions...")

# # Assert that subprocess.run is called once with the correct command
# mock_subprocess_run.assert_called_once_with(
# shell_command, # This should now match the generated shell command
# check=True
# )



mock_subprocess_run.side_effect = subprocess.CalledProcessError(1, 'command')
mock_exception = subprocess.CalledProcessError(1, 'command')
manager._evaluate_model_artifact("test_model", "test_run", eval_type="standard")
expected_error_message = "Error during shell command execution for model test_model: " + str(mock_exception)
mock_logger.error.assert_called_with(expected_error_message)
# mock_subprocess_run.side_effect = subprocess.CalledProcessError(1, 'command')
# mock_exception = subprocess.CalledProcessError(1, 'command')
# manager._evaluate_model_artifact("test_model", "test_run", eval_type="standard")
# expected_error_message = "Error during shell command execution for model test_model: " + str(mock_exception)
# mock_logger.error.assert_called_with(expected_error_message)

mock_file_open.assert_called_with(
"/mock/path/generated/predictions_test_run_202401011200000_00.pkl", "rb"
)
# mock_file_open.assert_called_with(
# "/mock/path/generated/predictions_test_run_202401011200000_00.pkl", "rb"
# )

assert mock_file_open.call_count == 3
assert mock_create_log_file.call_count==2
assert mock_logger.error.call_count ==1
assert mock_read_log_file.call_count==2
# assert mock_file_open.call_count == 3
# assert mock_create_log_file.call_count==2
# assert mock_logger.error.call_count ==1
# assert mock_read_log_file.call_count==2



Expand All @@ -687,43 +698,43 @@ def test_forecast_model_artifact(self, mock_model_path, args, expected_command,



@pytest.fixture
def sample_data():
"""
Fixture to provide common sample data for the aggregation tests.
"""
df1 = pd.DataFrame({"A": [1, 2], "B": [3, 4]}, index=pd.MultiIndex.from_tuples([(0, 0), (0, 1)]))
df2 = pd.DataFrame({"A": [5, 6], "B": [7, 8]}, index=pd.MultiIndex.from_tuples([(0, 0), (0, 1)]))
return [df1, df2]

def test_get_aggregated_df_mean(sample_data):
"""
Test the _get_aggregated_df method to ensure it correctly aggregates DataFrames using mean.
"""
df_to_aggregate = sample_data

result = EnsembleManager._get_aggregated_df(df_to_aggregate, "mean")
expected = pd.DataFrame({"A": [3.0, 4.0], "B": [5.0, 6.0]}, index=pd.MultiIndex.from_tuples([(0, 0), (0, 1)]))
# @pytest.fixture
# def sample_data():
# """
# Fixture to provide common sample data for the aggregation tests.
# """
# df1 = pd.DataFrame({"A": [1, 2], "B": [3, 4]}, index=pd.MultiIndex.from_tuples([(0, 0), (0, 1)]))
# df2 = pd.DataFrame({"A": [5, 6], "B": [7, 8]}, index=pd.MultiIndex.from_tuples([(0, 0), (0, 1)]))
# return [df1, df2]

# def test_get_aggregated_df_mean(sample_data):
# """
# Test the _get_aggregated_df method to ensure it correctly aggregates DataFrames using mean.
# """
# df_to_aggregate = sample_data

# result = EnsembleManager._get_aggregated_df(df_to_aggregate, "mean")
# expected = pd.DataFrame({"A": [3.0, 4.0], "B": [5.0, 6.0]}, index=pd.MultiIndex.from_tuples([(0, 0), (0, 1)]))

pd.testing.assert_frame_equal(result, expected, check_like=True)
# pd.testing.assert_frame_equal(result, expected, check_like=True)

def test_get_aggregated_df_median(sample_data):
"""
Test the _get_aggregated_df method to ensure it correctly aggregates DataFrames using median.
"""
df_to_aggregate = sample_data
# def test_get_aggregated_df_median(sample_data):
# """
# Test the _get_aggregated_df method to ensure it correctly aggregates DataFrames using median.
# """
# df_to_aggregate = sample_data

result = EnsembleManager._get_aggregated_df(df_to_aggregate, "median")
expected = pd.DataFrame({"A": [3.0, 4.0], "B": [5.0, 6.0]}, index=pd.MultiIndex.from_tuples([(0, 0), (0, 1)]))
# result = EnsembleManager._get_aggregated_df(df_to_aggregate, "median")
# expected = pd.DataFrame({"A": [3.0, 4.0], "B": [5.0, 6.0]}, index=pd.MultiIndex.from_tuples([(0, 0), (0, 1)]))

pd.testing.assert_frame_equal(result, expected, check_like=True)
# pd.testing.assert_frame_equal(result, expected, check_like=True)

def test_get_aggregated_df_invalid_aggregation(sample_data):
"""
Test the _get_aggregated_df method for invalid aggregation method.
"""
# def test_get_aggregated_df_invalid_aggregation(sample_data):
# """
# Test the _get_aggregated_df method for invalid aggregation method.
# """

with pytest.raises(ValueError, match="Invalid aggregation method: invalid_aggregation"):
EnsembleManager._get_aggregated_df(sample_data, "invalid_aggregation")
# with pytest.raises(ValueError, match="Invalid aggregation method: invalid_aggregation"):
# EnsembleManager._get_aggregated_df(sample_data, "invalid_aggregation")


0 comments on commit 33a83ae

Please sign in to comment.