public void start() {
    // Create a copy of the HiveConf for the metastore
    metastore.start(new HiveConf(hs2Conf), 20);
    hs2Conf.setVar(HiveConf.ConfVars.METASTORE_URIS, metastore.hiveConf().getVar(HiveConf.ConfVars.METASTORE_URIS));
    hs2Conf.setVar(HiveConf.ConfVars.METASTORE_WAREHOUSE,
        metastore.hiveConf().getVar(HiveConf.ConfVars.METASTORE_WAREHOUSE));
    hs2Conf.setVar(HiveConf.ConfVars.HIVE_METASTORE_WAREHOUSE_EXTERNAL,
        metastore.hiveConf().getVar(HiveConf.ConfVars.HIVE_METASTORE_WAREHOUSE_EXTERNAL));

    // Initializing RpcMetrics in a single JVM multiple times can cause issues
    DefaultMetricsSystem.setMiniClusterMode(true);

    hs2.init(hs2Conf);
    hs2.start();
    client = hs2.getServices().stream()
            .filter(CLIService.class::isInstance)
            .findFirst()
            .map(CLIService.class::cast)
            .get();
    started = true;
  }
Test class for running HiveQL queries, essentially acting like a Beeline shell in tests.

It spins up both an HS2 and a Metastore instance to work with. The shell will only accept
queries if it has been previously initialized via {@link #start()}, and a session has been opened via
{@link #openSession()}. Prior to calling {@link #start()}, the shell should first be configured with props that apply
across all test cases by calling {@link #setHiveConfValue(String, String)} ()}. On the other hand, session-level conf
can be applied anytime via {@link #setHiveSessionValue(String, String)} ()}, once we've opened an active session.
iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveShell.java