code: def test_join_multi_to_multi(self, join_type):
      # GH 20475
      leftindex = MultiIndex.from_product(
          [list("abc"), list("xy"), [1, 2]], names=["abc", "xy", "num"]
      )
      left = DataFrame({"v1": range(12)}, index=leftindex)
  
      rightindex = MultiIndex.from_product(
          [list("abc"), list("xy")], names=["abc", "xy"]
      )
      right = DataFrame(
          {"v2": [100 * i for i in range(1, 7)]}, index=rightindex
      )
  
      result = left.join(right, on=["abc", "xy"], how=join_type)
      expected = (
          left.reset_index()
          .merge(right.reset_index(), on=["abc", "xy"], how=join_type)
          .set_index(["abc", "xy", "num"])
      )
      tm.assert_frame_equal(expected, result)
  
      msg = r'len\(left_on\) must equal the number of levels in the index of "right"'
      with pytest.raises(ValueError, match=msg):
          left.join(right, on="xy", how=join_type)
  
      with pytest.raises(ValueError, match=msg):
          right.join(left, on=["abc", "xy"], how=join_type)
  
imports: import re
  import numpy
  import pytest
  import pandas.util._test_decorators
  import pandas
  from pandas import Categorical, DataFrame, Index, MultiIndex, Series, Timestamp, bdate_range, concat, merge, option_context
  import pandas._testing
label_desc: Use image node_id 37 for calling the TestJoin obj's underlying member method code with example usage: obj.test_join_multi_to_multi(join_type) without return types