@Test
  public void testConcurrentIcebergCommitsAndHiveAlterTableCalls() throws Exception {
    Assume.assumeTrue(testTableType.equals(TestTables.TestTableType.HIVE_CATALOG));
    TableIdentifier identifier = TableIdentifier.of("default", "customers");

    testTables.createTable(
        shell,
        identifier.name(),
        HiveIcebergStorageHandlerTestUtils.CUSTOMER_SCHEMA,
        SPEC,
        FileFormat.PARQUET,
        ImmutableList.of());

    org.apache.iceberg.Table icebergTable = testTables.loadTable(identifier);

    // Avoid commit retry limits preventing any changes from being committed.
    icebergTable.updateProperties().set("commit.retry.num-retries", "1000000").commit();

    // Swap metastore client used by TestHiveShell with our test stub
    IMetaStoreClient realMSC = shell.getSession().getMetaStoreClient();
    IMetaStoreClient spyMSC = spy(realMSC);
    shell.getSession().getSessionHive().setMSC(spyMSC);

    // Simulate delay on alter table calls from Hive queries to ensure they will have worked on outdated Table objects
    // by the time they intend to persist their changes into HMS
    doAnswer(i -> {
      Thread.sleep(3000);
      return i.callRealMethod();
    }).when(spyMSC).alter_table(any(String.class), any(String.class), any(String.class),
        any(org.apache.hadoop.hive.metastore.api.Table.class), any(EnvironmentContext.class), isNull());

    ExecutorService executorService =
        MoreExecutors.getExitingExecutorService(
            (ThreadPoolExecutor) Executors.newFixedThreadPool(1));

    // Concurrent Insert
    executorService.submit(
        () -> {
          try {
            testTables.appendIcebergTable(
                shell.getHiveConf(),
                icebergTable,
                FileFormat.PARQUET,
                null,
                HiveIcebergStorageHandlerTestUtils.CUSTOMER_RECORDS);
          } catch (IOException e) {
            throw new RuntimeException(e);
          }
        });

    // Concurrent ALTER TABLE properties change
    shell.executeStatement("ALTER TABLE default.customers SET TBLPROPERTIES ('dummyKey'='dummyValue')");

    executorService.shutdown();
    executorService.awaitTermination(1, TimeUnit.MINUTES);

    // Verify that the insert was effective
    Assert.assertEquals(((BaseTable) testTables.loadTable(identifier)).operations().current().metadataFileLocation(),
        (long) HiveIcebergStorageHandlerTestUtils.CUSTOMER_RECORDS.size(),
        shell.executeStatement("select count(*) from customers").get(0)[0]
    );

    // Verify that the alter table call was effective
    Assert.assertEquals("dummyValue", shell.metastore().getTable(identifier).getParameters().get("dummyKey"));

    // Should be the 4rd metadata version (1 empty base + 1 commit retry change + 1 insert + 1 property change)
    Assert.assertEquals(3,
        ((BaseTable) testTables.loadTable(identifier)).operations().current().previousFiles().size());
  }
Checks that HiveIcebergMetaHook doesn't run into failures with undefined alter operation type (e.g. stat updates)
@throws Exception - any test failure
iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergStorageHandlerNoScan.java