code: def test_cv_error_calculation(df):
      """Tests whether error metrics are properly calculated in CV
      This is done by using backtest to get predicted values, and
      evaluating the error metrics directly.
      """
      pipeline = get_dummy_pipeline()
      # test with and without aggregation
      test_cases = [
          # (agg_periods, agg_func)
          (None, None),
          (7, np.sum),
      ]
      for agg_periods, agg_func in test_cases:
          with warnings.catch_warnings():
              warnings.simplefilter("ignore")
              metric = EvaluationMetricEnum.MeanAbsolutePercentError
              params = dict(
                  pipeline=pipeline,
                  forecast_horizon=20,
                  coverage=None,
                  agg_periods=agg_periods,
                  agg_func=agg_func,
                  score_func=metric.name,
                  score_func_greater_is_better=metric.get_metric_greater_is_better(),
                  cv_report_metrics=CV_REPORT_METRICS_ALL,
                  null_model_params=None,
                  relative_error_tolerance=0.02,
              )
              backtest = forecast_pipeline(
                  df, test_horizon=20, cv_horizon=0, **params
              ).backtest
              # Single CV split. CV test = backtest test
              grid_search = forecast_pipeline(
                  df,
                  test_horizon=0,
                  cv_horizon=20,
                  cv_min_train_periods=df.shape[0] - 20,
                  **params,
              ).grid_search
              df_train = backtest.df_train
              df_test = backtest.df_test
              scorer = metric.get_metric_func()
              if agg_periods is not None:
                  scorer = add_preaggregation_to_scorer(
                      scorer, agg_periods=agg_periods, agg_func=agg_func
                  )
              expected_score = scorer(
                  df_train[ACTUAL_COL], df_train[PREDICTED_COL]
              )
              assert (
                  grid_search.cv_results_[
                      f"mean_train_{metric.get_metric_name()}"
                  ][0]
                  == expected_score
              )
              expected_score = scorer(
                  df_test[ACTUAL_COL], df_test[PREDICTED_COL]
              )
              assert (
                  grid_search.cv_results_[
                      f"mean_test_{metric.get_metric_name()}"
                  ][0]
                  == expected_score
              )
  
imports: import datetime
  import math
  import sys
  import warnings
  import numpy
  import pandas
  import pytest
  from scipy.stats import randint
  from sklearn.metrics import explained_variance_score
  from sklearn.metrics import mean_absolute_error
  from sklearn.metrics import mean_squared_error
  from sklearn.pipeline import Pipeline
  from greykite.common.constants import ACTUAL_COL
  from greykite.common.constants import ADJUSTMENT_DELTA_COL
  from greykite.common.constants import END_TIME_COL
  from greykite.common.constants import FRACTION_OUTSIDE_TOLERANCE
  from greykite.common.constants import METRIC_COL
  from greykite.common.constants import PREDICTED_COL
  from greykite.common.constants import QUANTILE_SUMMARY_COL
  from greykite.common.constants import START_TIME_COL
  from greykite.common.constants import TIME_COL
  from greykite.common.constants import VALUE_COL
  from greykite.common.constants import R2_null_model_score
  from greykite.common.evaluation import EvaluationMetricEnum
  from greykite.common.evaluation import add_finite_filter_to_scorer
  from greykite.common.evaluation import add_preaggregation_to_scorer
  from greykite.common.python_utils import assert_equal
  from greykite.common.python_utils import unique_elements_in_list
  from greykite.common.testing_utils import generate_df_for_tests
  from greykite.common.testing_utils import generate_df_with_reg_for_tests
  from greykite.framework.constants import CV_REPORT_METRICS_ALL
  from greykite.framework.constants import FRACTION_OUTSIDE_TOLERANCE_NAME
  from greykite.framework.input.univariate_time_series import UnivariateTimeSeries
  from greykite.framework.pipeline.pipeline import forecast_pipeline
  from greykite.framework.templates.prophet_template import ProphetTemplate
  from greykite.framework.utils.framework_testing_utils import check_forecast_pipeline_result
  from greykite.framework.utils.framework_testing_utils import mock_pipeline
  from greykite.sklearn.estimator.null_model import DummyEstimator
  from greykite.sklearn.estimator.prophet_estimator import ProphetEstimator
  from greykite.sklearn.estimator.silverkite_estimator import SilverkiteEstimator
  from greykite.sklearn.estimator.simple_silverkite_estimator import SimpleSilverkiteEstimator
  from greykite.sklearn.transform.column_selector import ColumnSelector
  from greykite.sklearn.transform.drop_degenerate_transformer import DropDegenerateTransformer
  from greykite.sklearn.transform.dtype_column_selector import DtypeColumnSelector
  from greykite.sklearn.transform.normalize_transformer import NormalizeTransformer
  from greykite.sklearn.transform.null_transformer import NullTransformer
  from greykite.sklearn.transform.pandas_feature_union import PandasFeatureUnion
  from greykite.sklearn.transform.zscore_outlier_transformer import ZscoreOutlierTransformer
label_desc: Use image node_id 12 for calling a global function with example usage: test_cv_error_calculation(df) without return types