content: /*
   * Copyright (C) 2016-2023 ActionTech.
   * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
   */
  
  package com.actiontech.dble.config;
  
  import com.actiontech.dble.backend.datasource.PhysicalDbGroup;
  import com.actiontech.dble.backend.datasource.PhysicalDbInstance;
  import com.actiontech.dble.cluster.values.RawJson;
  import com.actiontech.dble.config.converter.DBConverter;
  import com.actiontech.dble.config.converter.ShardingConverter;
  import com.actiontech.dble.config.model.sharding.table.ERTable;
  import com.actiontech.dble.plan.node.JoinNode;
  import com.actiontech.dble.plan.optimizer.ERJoinChooser;
  import org.junit.Assert;
  import org.junit.Test;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Method;
  import java.util.Map;
  import java.util.Set;
  
  public class ConfigTest {
  
      private Map<ERTable, Set<ERTable>> erRealtions;
  
      private DBConverter dbConverter;
  
      public ConfigTest() throws Exception {
  
          RawJson dbXmlToJson = DBConverter.dbXmlToJson("./config/db.xml");
          this.dbConverter = new DBConverter();
          dbConverter.dbJsonToMap(dbXmlToJson, null, false);
          ShardingConverter shardingConverter = new ShardingConverter();
          RawJson shardingXmlToJson = shardingConverter.shardingXmlToJson("./config/sharding.xml");
          shardingConverter.shardingJsonToMap(shardingXmlToJson, dbConverter.getDbGroupMap(), null, null);
          this.erRealtions = shardingConverter.getErRelations();
  
      }
  
      /**
       * test FKERmap
       * <p>
       * <sharding name="dbtest">
       * <table name="tb1" shardingNode="dnTest2,dnTest1" rule="rule1" />
       * <table name="tb2" shardingNode="dnTest2,dnTest3" rule="rule1" />
       * <table name="tb3" shardingNode="dnTest1,dnTest2" rule="rule1" />
       * </sharding>
       * <sharding name="ertest">
       * <table name="er_parent" dataNode="dnTest1,dnTest2" rule="rule1">
       * <childTable name="er_child1" joinColumn="child1_id" parentColumn="id" >
       * <childTable name="er_grandson" joinColumn="grandson_id" parentColumn="child1_id" />
       * </childTable>
       * <childTable name="er_child2" joinColumn="child2_id" parentColumn="id2" />
       * <childTable name="er_child3" joinColumn="child_char" parentColumn="c_char" />
       * <childTable name="er_child4" joinColumn="child4_id" parentColumn="id2" >
       * <childTable name="er_grandson2" joinColumn="grandson2_id" parentColumn="child4_id2" />
       * </childTable>
       * <childTable name="er_child5" joinColumn="child5_id" parentColumn="id" >
       * <childTable name="er_grandson3" joinColumn="grandson3_id" parentColumn="child5_id2" />
       * </childTable>
       * </table>
       * </sharding>
       */
      @Test
      public void testErRelations() {
          String schemaName1 = "dbtest";
          String schemaName2 = "ertest";
          ERTable er_parent0 = new ERTable(schemaName2, "er_parent", "ID");
          ERTable er_dbtest_tb1 = new ERTable(schemaName1, "tb1", "ID");
          Assert.assertFalse(testERjoin(er_parent0, er_dbtest_tb1));
          Assert.assertFalse(testERjoin(er_dbtest_tb1, er_parent0));
          ERTable er_dbtest_tb2 = new ERTable(schemaName1, "tb2", "ID");
          Assert.assertFalse(testERjoin(er_parent0, er_dbtest_tb2));
          Assert.assertFalse(testERjoin(er_dbtest_tb2, er_parent0));
          ERTable er_dbtest_tb3 = new ERTable(schemaName1, "tb3", "ID");
          Assert.assertTrue(testSymmetryERJoin(er_parent0, er_dbtest_tb3));
          ERTable er_child1 = new ERTable(schemaName2, "er_child1", "child1_id");
          ERTable er_grandson = new ERTable(schemaName2, "er_grandson", "grandson_id");
          Assert.assertTrue(testSymmetryERJoin(er_parent0, er_child1));
          Assert.assertTrue(testSymmetryERJoin(er_parent0, er_grandson));
          Assert.assertTrue(testSymmetryERJoin(er_child1, er_grandson));
  
  
          ERTable er_parent1 = new ERTable(schemaName2, "er_parent", "ID2");
          ERTable er_child2 = new ERTable(schemaName2, "er_child2", "CHILD2_ID");
          Assert.assertTrue(testSymmetryERJoin(er_parent1, er_child2));
          ERTable er_child4 = new ERTable(schemaName2, "er_child4", "CHILD4_ID");
          Assert.assertTrue(testSymmetryERJoin(er_parent1, er_child4));
          ERTable er_child4_2 = new ERTable(schemaName2, "er_child4", "child4_id2");
          ERTable er_grandson2 = new ERTable(schemaName2, "er_grandson2", "grandson2_id");
          Assert.assertTrue(testSymmetryERJoin(er_child4_2, er_grandson2));
          ERTable er_parent2 = new ERTable(schemaName2, "er_parent", "c_char");
          ERTable er_child3 = new ERTable(schemaName2, "er_child3", "child_char");
          Assert.assertTrue(testSymmetryERJoin(er_parent2, er_child3));
          ERTable er_child5 = new ERTable(schemaName2, "er_child5", "child5_id");
          Assert.assertTrue(testSymmetryERJoin(er_parent0, er_child5));
          ERTable er_child5_2 = new ERTable(schemaName2, "er_child5", "child5_id2");
          ERTable er_grandson3 = new ERTable(schemaName2, "er_grandson3", "grandson3_id");
          Assert.assertTrue(testSymmetryERJoin(er_child5_2, er_grandson3));
  
          Assert.assertTrue(testSymmetryERJoin(er_child1, er_child5));
          Assert.assertTrue(testSymmetryERJoin(er_grandson, er_child5));
  
      }
  
      private boolean testSymmetryERJoin(ERTable er0, ERTable er1) {
          return testERjoin(er0, er1) && testERjoin(er1, er0);
      }
  
      private boolean testERjoin(ERTable er0, ERTable er1) {
          Class<ERJoinChooser> classERJoin = ERJoinChooser.class;
          try {
              Constructor<ERJoinChooser> construtor = classERJoin.getConstructor(new Class[]{JoinNode.class, Map.class});
              Object instance = construtor.newInstance(new Object[]{new JoinNode(63), this.erRealtions});
              Method isERRelstionMethod = classERJoin.getDeclaredMethod("isErRelation", new Class[]{ERTable.class, ERTable.class});
              isERRelstionMethod.setAccessible(true);
              Object result = isERRelstionMethod.invoke(instance, new Object[]{er0, er1});
              return (Boolean) result;
          } catch (Exception e) {
              System.out.println(e);
              return false;
          }
      }
  
      /**
       * testReadHostWeight
       *
       * @throws Exception
       */
      @Test
      public void testReadHostWeight() throws Exception {
          Map<String, PhysicalDbGroup> dbGroups = dbConverter.getDbGroupMap();
          PhysicalDbGroup pool = dbGroups.get("localhost2");
  
          PhysicalDbInstance source = pool.rwSelect(true, null);
          Assert.assertNotNull(source);
      }
  
  }
  