code: def test_custom_aggregation():
      class MockReduction1(CustomReduction):
          def agg(self, v1):
              return v1.sum()
  
      class MockReduction2(CustomReduction):
          def pre(self, value):
              return value + 1, value**2
  
          def agg(self, v1, v2):
              return v1.sum(), v2.prod()
  
          def post(self, v1, v2):
              return v1 + v2
  
      for ndim in [1, 2]:
          compiler = ReductionCompiler()
          compiler.add_function(MockReduction1(), ndim=ndim)
          result = compiler.compile()
          # check agg_funcs
          assert len(result.agg_funcs) == 1
          assert result.agg_funcs[0].map_func_name == "custom_reduction"
          assert result.agg_funcs[0].agg_func_name == "custom_reduction"
          assert isinstance(
              result.agg_funcs[0].custom_reduction, MockReduction1
          )
          assert result.agg_funcs[0].output_limit == 1
  
          compiler = ReductionCompiler()
          compiler.add_function(MockReduction2(), ndim=ndim)
          result = compiler.compile()
          # check agg_funcs
          assert len(result.agg_funcs) == 1
          assert result.agg_funcs[0].map_func_name == "custom_reduction"
          assert result.agg_funcs[0].agg_func_name == "custom_reduction"
          assert isinstance(
              result.agg_funcs[0].custom_reduction, MockReduction2
          )
          assert result.agg_funcs[0].output_limit == 2
  
imports: import functools
  import operator
  from functools import reduce
  from typing import NamedTuple
  import numpy
  import pandas
  import pytest
  from ....None import dataframe
  from ....core import tile
  from ....core.operand import OperandStage
  from ....tensor import Tensor
  from ...core import DataFrame, IndexValue, Series, OutputType
  from ...datasource.series import from_pandas
  from ...datasource.dataframe import from_pandas
  from ...merge import DataFrameConcat
  from ..None import DataFrameSum, DataFrameProd, DataFrameMin, DataFrameMax, DataFrameCount, DataFrameMean, DataFrameVar, DataFrameAll, DataFrameAny, DataFrameSkew, DataFrameKurtosis, DataFrameSem, DataFrameAggregate, DataFrameCummin, DataFrameCummax, DataFrameCumprod, DataFrameCumsum, DataFrameNunique, CustomReduction
  from ..aggregation import where_function
  from ..core import ReductionCompiler
label_desc: Use image node_id 9 for calling a global function with example usage: test_custom_aggregation() and returns: v1, unknown,  unknown, v1,  v2, unknown