Copilot commented on code in PR #425:
URL: https://github.com/apache/atlas/pull/425#discussion_r2270244477


##########
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/events/DropDatabaseTest.java:
##########
@@ -0,0 +1,273 @@
+package org.apache.atlas.hive.hook.events;
+
+import org.apache.atlas.hive.hook.AtlasHiveHookContext;
+import org.apache.atlas.model.notification.HookNotification;
+import 
org.apache.atlas.model.notification.HookNotification.EntityDeleteRequestV2;
+import org.apache.hadoop.hive.metastore.api.Database;
+import org.apache.hadoop.hive.metastore.events.DropDatabaseEvent;
+import org.apache.hadoop.hive.ql.hooks.Entity;
+import org.apache.hadoop.hive.ql.hooks.WriteEntity;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.*;
+
+import static org.mockito.Mockito.*;
+import static org.testng.AssertJUnit.*;
+
+public class DropDatabaseTest {
+    private static final Logger LOG = 
LoggerFactory.getLogger(DropDatabaseTest.class);
+
+    @Mock
+    private AtlasHiveHookContext context;
+
+    private DropDatabase dropDatabase;
+
+    @BeforeMethod
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testConstructor() {
+        // Test constructor
+        dropDatabase = new DropDatabase(context);
+        assertNotNull(dropDatabase);
+        assertEquals(context, dropDatabase.getContext());
+        LOG.info("Constructor test passed");
+    }
+
+    @Test
+    public void testGetNotificationMessages_MetastoreHook_WithValidDatabase() {
+        // Setup
+        when(context.isMetastoreHook()).thenReturn(true);
+        
+        DropDatabaseEvent dbEvent = mock(DropDatabaseEvent.class);
+        Database db = mock(Database.class);
+        
+        when(dbEvent.getDatabase()).thenReturn(db);
+        when(db.getName()).thenReturn("testDb");
+        when(context.getMetastoreEvent()).thenReturn(dbEvent);
+        when(context.getMetadataNamespace()).thenReturn("test_cluster");
+        
+        dropDatabase = new DropDatabase(context);
+
+        // Execute
+        List<HookNotification> notifications = 
dropDatabase.getNotificationMessages();
+
+        // Verify
+        assertNotNull(notifications);
+        assertEquals(1, notifications.size());
+        assertTrue(notifications.get(0) instanceof EntityDeleteRequestV2);
+        
+//        verify(context).removeFromKnownDatabase(anyString());

Review Comment:
   Remove commented-out verification code or uncomment it if the verification 
is needed for the test.
   ```suggestion
           verify(context).removeFromKnownDatabase(anyString());
   ```



##########
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/events/CreateTableTest.java:
##########
@@ -0,0 +1,790 @@
+package org.apache.atlas.hive.hook.events;
+
+import org.apache.atlas.hive.hook.AtlasHiveHookContext;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
+import org.apache.atlas.model.notification.HookNotification;
+import org.apache.hadoop.hive.metastore.TableType;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
+import org.apache.hadoop.hive.metastore.events.AlterTableEvent;
+import org.apache.hadoop.hive.metastore.events.CreateTableEvent;
+import org.apache.hadoop.hive.ql.hooks.Entity;
+import org.apache.hadoop.hive.ql.hooks.WriteEntity;
+import org.apache.hadoop.hive.ql.metadata.Hive;
+import org.apache.hadoop.hive.ql.metadata.Table;
+import org.apache.hadoop.hive.ql.plan.HiveOperation;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertNotNull;
+
+public class CreateTableTest {
+
+    @Mock
+    AtlasHiveHookContext context;
+
+    @Mock
+    CreateTableEvent createTableEvent;
+
+    @Mock
+    AlterTableEvent alterTableEvent;
+
+    @Mock
+    Hive hive;
+
+    CreateTable createTable;
+
+    @BeforeMethod
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        createTable = new CreateTable(context);
+    }
+
+    // =================== Constructor Tests ===================
+    @Test
+    public void testConstructor() {
+        CreateTable createTable = new CreateTable(context);
+        AssertJUnit.assertNotNull("CreateTable instance should be created", 
createTable);
+    }
+
+    // =================== getNotificationMessages Tests ===================
+    @Test
+    public void testGetNotificationMessages_MetastoreHook_WithEntities() 
throws Exception {
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        CreateTable createTable = spy(new CreateTable(context));
+
+        AtlasEntitiesWithExtInfo mockEntities = new AtlasEntitiesWithExtInfo();
+        AtlasEntity tblEntity = new AtlasEntity("hive_table");
+        tblEntity.setAttribute("qualifiedName", "default.test_table@cm");
+        mockEntities.addEntity(tblEntity);
+
+        doReturn(mockEntities).when(createTable).getHiveMetastoreEntities();
+        doReturn("test_user").when(createTable).getUserName();
+
+        List<HookNotification> notifications = 
createTable.getNotificationMessages();
+
+        AssertJUnit.assertNotNull(notifications);
+        AssertJUnit.assertEquals(1, notifications.size());
+        AssertJUnit.assertTrue(notifications.get(0) instanceof 
HookNotification.EntityCreateRequestV2);
+    }
+
+    @Test
+    public void testGetNotificationMessages_NonMetastoreHook_WithEntities() 
throws Exception {
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        CreateTable createTable = spy(new CreateTable(context));
+
+        AtlasEntitiesWithExtInfo mockEntities = new AtlasEntitiesWithExtInfo();
+        AtlasEntity tblEntity = new AtlasEntity("hive_table");
+        tblEntity.setAttribute("qualifiedName", "default.test_table@cm");
+        mockEntities.addEntity(tblEntity);
+
+        doReturn(mockEntities).when(createTable).getHiveEntities();
+        doReturn("test_user").when(createTable).getUserName();
+
+        List<HookNotification> notifications = 
createTable.getNotificationMessages();
+
+        AssertJUnit.assertNotNull(notifications);
+        AssertJUnit.assertEquals(1, notifications.size());
+        AssertJUnit.assertTrue(notifications.get(0) instanceof 
HookNotification.EntityCreateRequestV2);
+    }
+
+    @Test
+    public void testGetNotificationMessages_EmptyEntities() throws Exception {
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        CreateTable createTable = spy(new CreateTable(context));
+
+        AtlasEntitiesWithExtInfo emptyEntities = new 
AtlasEntitiesWithExtInfo();
+        doReturn(emptyEntities).when(createTable).getHiveMetastoreEntities();
+
+        List<HookNotification> notifications = 
createTable.getNotificationMessages();
+
+        AssertJUnit.assertNull("Expected null notifications for empty 
entities", notifications);
+    }
+
+    @Test
+    public void testGetNotificationMessages_NullEntities() throws Exception {
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        CreateTable createTable = spy(new CreateTable(context));
+        doReturn(null).when(createTable).getHiveMetastoreEntities();
+
+        List<HookNotification> notifications = 
createTable.getNotificationMessages();
+
+        AssertJUnit.assertNull("Expected null notifications for null 
entities", notifications);
+    }
+
+    @Test
+    public void testGetNotificationMessages_NonMetastoreHook_NullEntities() 
throws Exception {
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        CreateTable createTable = spy(new CreateTable(context));
+        doReturn(null).when(createTable).getHiveEntities();
+
+        List<HookNotification> notifications = 
createTable.getNotificationMessages();
+
+        AssertJUnit.assertNull("Expected null notifications for null 
entities", notifications);
+    }
+
+    // =================== getHiveMetastoreEntities Tests ===================
+/*    @Test

Review Comment:
   Multiple commented-out test methods should be removed or properly 
implemented. This reduces code maintainability and can cause confusion.



##########
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/events/BaseHiveEventTest.java:
##########
@@ -0,0 +1,1328 @@
+package org.apache.atlas.hive.hook.events;
+
+import org.apache.atlas.hive.hook.AtlasHiveHookContext;
+import org.apache.atlas.hive.hook.HiveHook.PreprocessAction;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.notification.HookNotification;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hive.metastore.TableType;
+import org.apache.hadoop.hive.metastore.api.Database;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.SerDeInfo;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
+import org.apache.hadoop.hive.ql.hooks.Entity;
+import org.apache.hadoop.hive.ql.hooks.HookContext;
+import org.apache.hadoop.hive.ql.hooks.LineageInfo;
+import org.apache.hadoop.hive.ql.hooks.LineageInfo.BaseColumnInfo;
+import org.apache.hadoop.hive.ql.hooks.LineageInfo.DependencyKey;
+import org.apache.hadoop.hive.ql.hooks.ReadEntity;
+import org.apache.hadoop.hive.ql.hooks.WriteEntity;
+import org.apache.hadoop.hive.ql.metadata.Hive;
+import org.apache.hadoop.hive.ql.metadata.Table;
+import org.apache.hadoop.hive.ql.plan.HiveOperation;
+import org.apache.hadoop.hive.ql.session.SessionState;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.*;
+import java.util.HashMap;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doNothing;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class BaseHiveEventTest {
+
+    @Mock
+    AtlasHiveHookContext context;
+
+    @Mock
+    Hive hive;
+
+    Table table;
+
+    @Mock
+    Database database;
+
+    @Mock
+    HookContext hookContext;
+
+    @Mock
+    Entity entity;
+
+    @Mock
+    ReadEntity readEntity;
+
+    @Mock
+    WriteEntity writeEntity;
+
+    @Mock
+    LineageInfo lineageInfo;
+
+    @Mock
+    UserGroupInformation ugi;
+
+    @Mock
+    SessionState sessionState;
+
+    // Concrete implementation of BaseHiveEvent for testing
+    private static class TestableBaseHiveEvent extends BaseHiveEvent {
+        public TestableBaseHiveEvent(AtlasHiveHookContext context) {
+            super(context);
+        }
+
+        @Override
+        public List<HookNotification> getNotificationMessages() throws 
Exception {
+            return Collections.emptyList();
+        }
+    }
+
+    private TestableBaseHiveEvent baseHiveEvent;
+
+    @BeforeMethod
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        
+        // Create a real Table object with a mocked tTable to avoid NPE issues
+        org.apache.hadoop.hive.metastore.api.Table tTable = 
mock(org.apache.hadoop.hive.metastore.api.Table.class);
+        when(tTable.getTableName()).thenReturn("test_table");
+        when(tTable.getCreateTime()).thenReturn(1000);
+        when(tTable.getDbName()).thenReturn("default");
+        
+        // Create a real Table object and then spy on it
+        table = spy(new Table(tTable));
+        
+        // Mock required context methods for BaseHiveEvent constructor
+        when(context.isSkipTempTables()).thenReturn(false);
+        when(context.isMetastoreHook()).thenReturn(false); // Ensure it's not 
a metastore hook
+        baseHiveEvent = new TestableBaseHiveEvent(context);
+    }
+
+    // ========== CONSTRUCTOR TESTS ==========
+
+    @Test
+    public void testConstructor() {
+        when(context.isSkipTempTables()).thenReturn(true);
+        TestableBaseHiveEvent event = new TestableBaseHiveEvent(context);
+
+        AssertJUnit.assertNotNull("BaseHiveEvent should be instantiated", 
event);
+        AssertJUnit.assertEquals("Context should be set", context, 
event.getContext());
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testConstructorWithNullContext() {
+        new TestableBaseHiveEvent(null);
+    }
+
+    // ========== UTILITY METHOD TESTS ==========
+
+    @Test
+    public void testGetTableCreateTime() {
+        org.apache.hadoop.hive.metastore.api.Table metastoreTable = 
mock(org.apache.hadoop.hive.metastore.api.Table.class);
+        when(metastoreTable.getCreateTime()).thenReturn(1000);
+        when(table.getTTable()).thenReturn(metastoreTable);
+
+        long createTime = BaseHiveEvent.getTableCreateTime(table);
+
+        AssertJUnit.assertEquals("Create time should be converted from seconds 
to milliseconds",
+                1000 * BaseHiveEvent.MILLIS_CONVERT_FACTOR, createTime);
+    }
+
+    @Test
+    public void testGetTableCreateTime_NullTTable() {
+        when(table.getTTable()).thenReturn(null);
+
+        long createTime = BaseHiveEvent.getTableCreateTime(table);
+
+        AssertJUnit.assertTrue("Should return current time when TTable is 
null",
+                createTime > 0 && createTime <= System.currentTimeMillis());
+    }
+
+    @Test
+    public void testGetTableOwner() {
+        org.apache.hadoop.hive.metastore.api.Table metastoreTable = 
mock(org.apache.hadoop.hive.metastore.api.Table.class);
+        when(table.getTTable()).thenReturn(metastoreTable);
+        when(table.getOwner()).thenReturn("test_user");
+
+        String owner = BaseHiveEvent.getTableOwner(table);
+
+        AssertJUnit.assertEquals("Should return table owner", "test_user", 
owner);
+    }
+
+    @Test
+    public void testGetTableOwner_NullTTable() {
+        when(table.getTTable()).thenReturn(null);
+
+        String owner = BaseHiveEvent.getTableOwner(table);
+
+        AssertJUnit.assertEquals("Should return empty string when TTable is 
null", "", owner);
+    }
+
+    @Test
+    public void testGetObjectIds() {
+        AtlasEntity entity1 = new AtlasEntity("type1");
+        entity1.setAttribute("qualifiedName", "entity1@cluster");
+        AtlasEntity entity2 = new AtlasEntity("type2");
+        entity2.setAttribute("qualifiedName", "entity2@cluster");
+
+        List<AtlasEntity> entities = Arrays.asList(entity1, entity2);
+
+        List<AtlasObjectId> objectIds = BaseHiveEvent.getObjectIds(entities);
+
+        AssertJUnit.assertEquals("Should return correct number of object IDs", 
2, objectIds.size());
+        AssertJUnit.assertEquals("First object ID type should match", "type1", 
objectIds.get(0).getTypeName());
+        AssertJUnit.assertEquals("Second object ID type should match", 
"type2", objectIds.get(1).getTypeName());
+    }
+
+    @Test
+    public void testGetObjectIds_EmptyList() {
+        List<AtlasObjectId> objectIds = 
BaseHiveEvent.getObjectIds(Collections.emptyList());
+
+        AssertJUnit.assertTrue("Should return empty list", 
objectIds.isEmpty());
+    }
+
+    @Test
+    public void testGetObjectIds_NullList() {
+        List<AtlasObjectId> objectIds = BaseHiveEvent.getObjectIds(null);
+
+        AssertJUnit.assertTrue("Should return empty list for null input", 
objectIds.isEmpty());
+    }
+
+    // ========== ENTITY PROCESSING TESTS ==========
+
+    @Test
+    public void testAddProcessedEntities() throws Exception {
+        AtlasEntitiesWithExtInfo entitiesWithExtInfo = new 
AtlasEntitiesWithExtInfo();
+
+        AtlasEntity contextEntity = new AtlasEntity("test_type");
+        contextEntity.setAttribute("qualifiedName", "test@cluster");
+        List<AtlasEntity> contextEntities = Arrays.asList(contextEntity);
+
+        when(context.getEntities()).thenReturn(contextEntities);
+
+        // Use generic safe matcher instead of anyCollection()
+        
doNothing().when(context).addToKnownEntities(Mockito.<Collection<AtlasEntity>>any());
+
+        baseHiveEvent.addProcessedEntities(entitiesWithExtInfo);
+
+
+        AssertJUnit.assertEquals("Should have referred entities", 1,
+                entitiesWithExtInfo.getReferredEntities().size());
+    }
+
+
+
+
+    @Test
+    public void testGetInputOutputEntity_DfsDir() throws Exception {
+        URI location = URI.create("hdfs://namenode:9000/test/path");
+        when(entity.getType()).thenReturn(Entity.Type.DFS_DIR);
+        when(entity.getLocation()).thenReturn(location);
+
+        when(context.getMetadataNamespace()).thenReturn("cluster");
+        when(context.isConvertHdfsPathToLowerCase()).thenReturn(true);
+        when(context.getQNameToEntityMap()).thenReturn(new HashMap<>());
+        
when(context.getAwsS3AtlasModelVersion()).thenReturn(String.valueOf(1));
+
+        AtlasEntity result = baseHiveEvent.getInputOutputEntity(entity, new 
AtlasEntitiesWithExtInfo(), false);
+
+        AssertJUnit.assertNotNull("Should return path entity", result);
+    }
+
+    @Test
+    public void testGetInputOutputEntity_SkipTempTable() throws Exception {
+        // Mock the underlying metastore Table
+
+        org.apache.hadoop.hive.metastore.api.Table metastoreTable = 
mock(org.apache.hadoop.hive.metastore.api.Table.class);
+        Table tableSpy = spy(new Table(metastoreTable));
+        when(entity.getType()).thenReturn(Entity.Type.TABLE);
+        when(entity.getTable()).thenReturn(tableSpy);
+        when(tableSpy.isTemporary()).thenReturn(true);
+        when(metastoreTable.getTableName()).thenReturn("test_table");
+        when(context.isSkipTempTables()).thenReturn(true);
+        when(tableSpy.getDbName()).thenReturn("default"); // Mock getDbName to 
avoid potential NPE
+        when(context.getEntity(any(String.class))).thenReturn(null); // Mock 
entity lookup
+        doNothing().when(context).putEntity(any(String.class), 
any(AtlasEntity.class)); // Mock entity storage
+
+        // Debug: Verify mock setup
+        AssertJUnit.assertEquals("Verify entity type", Entity.Type.TABLE, 
entity.getType());
+//        AssertJUnit.assertEquals("Verify table is temporary", true, 
table.isTemporary());
+        AssertJUnit.assertEquals("Verify table name", "test_table", 
metastoreTable.getTableName());
+
+        AtlasEntity result = baseHiveEvent.getInputOutputEntity(entity, new 
AtlasEntitiesWithExtInfo(), true);
+
+        AssertJUnit.assertNull("Should return null for temp table when 
skipTempTables=true", result);
+    }
+
+    // ========== DATABASE ENTITY TESTS ==========
+
+    @Test
+    public void testToDbEntity() throws Exception {
+        when(database.getName()).thenReturn("test_db");
+        when(database.getDescription()).thenReturn("Test database");
+        when(database.getOwnerName()).thenReturn("test_owner");
+        
when(database.getLocationUri()).thenReturn("hdfs://namenode:9000/warehouse/test_db");
+        when(database.getParameters()).thenReturn(new HashMap<>());
+
+        when(context.getQualifiedName(database)).thenReturn("test_db@cluster");
+        when(context.getMetadataNamespace()).thenReturn("cluster");
+        when(context.isKnownDatabase(anyString())).thenReturn(false);
+        when(context.getEntity(anyString())).thenReturn(null);
+        doNothing().when(context).putEntity(anyString(), 
any(AtlasEntity.class));
+
+        AtlasEntity result = baseHiveEvent.toDbEntity(database);
+
+        AssertJUnit.assertNotNull("Should return database entity", result);
+        AssertJUnit.assertEquals("Should be hive_db type", "hive_db", 
result.getTypeName());
+        AssertJUnit.assertEquals("Should have correct name", "test_db", 
result.getAttribute("name"));
+        AssertJUnit.assertEquals("Should have correct owner", "test_owner", 
result.getAttribute("owner"));
+        AssertJUnit.assertEquals("Should have correct description", "Test 
database", result.getAttribute("description"));
+    }
+
+    @Test
+    public void testToDbEntity_KnownDatabase() throws Exception {
+        when(database.getName()).thenReturn("test_db");
+        when(context.getQualifiedName(database)).thenReturn("test_db@cluster");
+        when(context.isKnownDatabase("test_db@cluster")).thenReturn(true);
+        when(context.getEntity("test_db@cluster")).thenReturn(null);
+        when(context.getMetadataNamespace()).thenReturn("cluster");
+        doNothing().when(context).putEntity(anyString(), 
any(AtlasEntity.class));
+
+        AtlasEntity result = baseHiveEvent.toDbEntity(database);
+
+        AssertJUnit.assertNotNull("Should return database entity", result);
+        AssertJUnit.assertNull("Should have null guid for known database", 
result.getGuid());
+    }
+
+    // ========== TABLE ENTITY TESTS ==========
+
+    @Test
+    public void testToTableEntity() throws Exception {
+        setupTableMocks();
+        setupDatabaseMocks();
+
+        when(context.getHive()).thenReturn(hive);
+        when(hive.getDatabase("default")).thenReturn(database);
+
+        // Mock dbEntity for AtlasTypeUtil.getObjectId(dbEntity)
+        AtlasEntity dbEntity = new AtlasEntity("hive_db");
+        dbEntity.setAttribute("qualifiedName", "default@cluster");
+        when(context.getEntity("default@cluster")).thenReturn(dbEntity);
+
+        // Debug: Verify mock setup
+        AssertJUnit.assertEquals("Verify table name", "test_table", 
table.getTTable().getTableName());
+        AssertJUnit.assertEquals("Verify db name", "default", 
table.getDbName());
+        
+        AssertJUnit.assertEquals("Verify qualified name", 
"default.test_table@cluster", context.getQualifiedName(table));
+
+        AtlasEntityWithExtInfo result = baseHiveEvent.toTableEntity(table);
+
+        AssertJUnit.assertNotNull("Should return table entity with ext info", 
result);
+        AssertJUnit.assertNotNull("Should have entity", result.getEntity());
+        AssertJUnit.assertEquals("Should be hive_table type", "hive_table", 
result.getEntity().getTypeName());
+    }
+
+
+
+   /* @Test

Review Comment:
   Multiple large blocks of commented-out test methods should be removed to 
improve code maintainability.



##########
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/events/DropTableTest.java:
##########
@@ -0,0 +1,481 @@
+package org.apache.atlas.hive.hook.events;
+
+import org.apache.atlas.hive.hook.AtlasHiveHookContext;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.notification.HookNotification;
+import 
org.apache.atlas.model.notification.HookNotification.EntityDeleteRequestV2;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.SerDeInfo;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
+import org.apache.hadoop.hive.metastore.events.DropTableEvent;
+import org.apache.hadoop.hive.ql.hooks.Entity;
+import org.apache.hadoop.hive.ql.hooks.WriteEntity;
+import org.apache.hadoop.hive.ql.metadata.Table;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.*;
+
+import static org.apache.hadoop.hive.metastore.TableType.MANAGED_TABLE;
+import static org.mockito.Mockito.*;
+
+public class DropTableTest {
+    private static final Logger LOG = 
LoggerFactory.getLogger(DropTableTest.class);
+
+    @Mock
+    AtlasHiveHookContext context;
+
+    @Mock
+    DropTableEvent dropTableEvent;
+
+    @Mock
+    Table table;
+
+    @BeforeMethod
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    // ========== CONSTRUCTOR TESTS ==========
+
+    @Test
+    public void testConstructor() {
+        DropTable dropTable = new DropTable(context);
+        AssertJUnit.assertNotNull("DropTable should be instantiated", 
dropTable);
+        AssertJUnit.assertTrue("DropTable should extend BaseHiveEvent",
+                dropTable instanceof BaseHiveEvent);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testConstructorWithNullContext() {
+        new DropTable(null);
+    }
+
+    // ========== getNotificationMessages() TESTS ==========
+
+    @Test
+    public void testGetNotificationMessages_MetastoreHook() throws Exception {
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        DropTable dropTable = spy(new DropTable(context));
+        
+        // Mock getHiveMetastoreEntities to return some entities
+        List<AtlasObjectId> mockEntities = Arrays.asList(
+                new AtlasObjectId("hive_table", "qualifiedName", 
"default.test_table@cluster")
+        );
+        doReturn(mockEntities).when(dropTable).getHiveMetastoreEntities();
+
+        // Mock getUserName
+        doReturn("test_user").when(dropTable).getUserName();
+
+        List<HookNotification> notifications = 
dropTable.getNotificationMessages();
+
+        AssertJUnit.assertNotNull("Notifications should not be null", 
notifications);
+        AssertJUnit.assertEquals("Should have one notification", 1, 
notifications.size());
+        AssertJUnit.assertTrue("Should be EntityDeleteRequestV2",
+                notifications.get(0) instanceof EntityDeleteRequestV2);
+        
+        EntityDeleteRequestV2 deleteRequest = (EntityDeleteRequestV2) 
notifications.get(0);
+        AssertJUnit.assertEquals("User should be test_user", "test_user", 
deleteRequest.getUser());
+        AssertJUnit.assertEquals("Should have one entity to delete", 1, 
deleteRequest.getEntities().size());
+
+        verify(dropTable).getHiveMetastoreEntities();
+        verify(dropTable, never()).getHiveEntities();
+    }
+
+    @Test
+    public void testGetNotificationMessages_NonMetastoreHook() throws 
Exception {
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        DropTable dropTable = spy(new DropTable(context));
+        
+        // Mock getHiveEntities to return some entities
+        List<AtlasObjectId> mockEntities = Arrays.asList(
+                new AtlasObjectId("hive_table", "qualifiedName", 
"default.test_table@cluster")
+        );
+        doReturn(mockEntities).when(dropTable).getHiveEntities();
+
+        // Mock getUserName
+        doReturn("test_user").when(dropTable).getUserName();
+
+        List<HookNotification> notifications = 
dropTable.getNotificationMessages();
+
+        AssertJUnit.assertNotNull("Notifications should not be null", 
notifications);
+        AssertJUnit.assertEquals("Should have one notification", 1, 
notifications.size());
+        AssertJUnit.assertTrue("Should be EntityDeleteRequestV2",
+                notifications.get(0) instanceof EntityDeleteRequestV2);
+
+        verify(dropTable).getHiveEntities();
+        verify(dropTable, never()).getHiveMetastoreEntities();
+    }
+
+    @Test
+    public void testGetNotificationMessages_EmptyEntities() throws Exception {
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        DropTable dropTable = spy(new DropTable(context));
+        
+        // Mock getHiveMetastoreEntities to return empty list
+        
doReturn(Collections.emptyList()).when(dropTable).getHiveMetastoreEntities();
+
+        List<HookNotification> notifications = 
dropTable.getNotificationMessages();
+
+        AssertJUnit.assertNull("Notifications should be null when no 
entities", notifications);
+    }
+
+    @Test
+    public void testGetNotificationMessages_NullEntities() throws Exception {
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        DropTable dropTable = spy(new DropTable(context));
+        
+        // Mock getHiveEntities to return null
+        doReturn(null).when(dropTable).getHiveEntities();
+
+        List<HookNotification> notifications = 
dropTable.getNotificationMessages();
+
+        AssertJUnit.assertNull("Notifications should be null when entities are 
null", notifications);
+    }
+
+    @Test
+    public void testGetNotificationMessages_MultipleEntities() throws 
Exception {
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        DropTable dropTable = spy(new DropTable(context));
+        
+        // Mock getHiveMetastoreEntities to return multiple entities
+        List<AtlasObjectId> mockEntities = Arrays.asList(
+                new AtlasObjectId("hive_table", "qualifiedName", 
"default.table1@cluster"),
+                new AtlasObjectId("hive_table", "qualifiedName", 
"default.table2@cluster")
+        );
+        doReturn(mockEntities).when(dropTable).getHiveMetastoreEntities();
+
+        // Mock getUserName
+        doReturn("test_user").when(dropTable).getUserName();
+
+        List<HookNotification> notifications = 
dropTable.getNotificationMessages();
+
+        AssertJUnit.assertNotNull("Notifications should not be null", 
notifications);
+        AssertJUnit.assertEquals("Should have two notifications", 2, 
notifications.size());
+        
+        // Verify each notification is correct
+        for (HookNotification notification : notifications) {
+            AssertJUnit.assertTrue("Should be EntityDeleteRequestV2",
+                    notification instanceof EntityDeleteRequestV2);
+            EntityDeleteRequestV2 deleteRequest = (EntityDeleteRequestV2) 
notification;
+            AssertJUnit.assertEquals("User should be test_user", "test_user", 
deleteRequest.getUser());
+            AssertJUnit.assertEquals("Should have one entity to delete", 1, 
deleteRequest.getEntities().size());
+        }
+    }
+
+    // ========== getHiveMetastoreEntities() TESTS ==========
+
+    @Test
+    public void testGetHiveMetastoreEntities_Success() throws Exception {
+        // Setup metastore event
+        when(context.getMetastoreEvent()).thenReturn(dropTableEvent);
+
+        // Create mock metastore table
+        org.apache.hadoop.hive.metastore.api.Table metastoreTable = 
createMockMetastoreTable("test_table");
+        when(dropTableEvent.getTable()).thenReturn(metastoreTable);
+
+        DropTable dropTable = spy(new DropTable(context));
+        
+        // Mock getQualifiedName to avoid complex dependencies
+        
doReturn("default.test_table@cluster").when(dropTable).getQualifiedName(any(Table.class));
+
+        List<AtlasObjectId> entities = dropTable.getHiveMetastoreEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        AssertJUnit.assertEquals("Should have one entity", 1, entities.size());
+        
+        AtlasObjectId entity = entities.get(0);
+        AssertJUnit.assertEquals("Should be hive_table type", "hive_table", 
entity.getTypeName());
+        AssertJUnit.assertEquals("Should have correct qualified name", 
"default.test_table@cluster",
+                entity.getUniqueAttributes().get("qualifiedName"));
+
+        // Verify context.removeFromKnownTable was called
+        verify(context).removeFromKnownTable("default.test_table@cluster");
+    }
+
+    @Test
+    public void testGetHiveMetastoreEntities_DifferentTableName() throws 
Exception {
+        // Setup metastore event
+        when(context.getMetastoreEvent()).thenReturn(dropTableEvent);
+
+        // Create mock metastore table with different name
+        org.apache.hadoop.hive.metastore.api.Table metastoreTable = 
createMockMetastoreTable("another_table");
+        when(dropTableEvent.getTable()).thenReturn(metastoreTable);
+
+        DropTable dropTable = spy(new DropTable(context));
+        
+        // Mock getQualifiedName
+        
doReturn("prod.another_table@cluster2").when(dropTable).getQualifiedName(any(Table.class));
+
+        List<AtlasObjectId> entities = dropTable.getHiveMetastoreEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        AssertJUnit.assertEquals("Should have one entity", 1, entities.size());
+        
+        AtlasObjectId entity = entities.get(0);
+        AssertJUnit.assertEquals("Should be hive_table type", "hive_table", 
entity.getTypeName());
+        AssertJUnit.assertEquals("Should have correct qualified name", 
"prod.another_table@cluster2",
+                entity.getUniqueAttributes().get("qualifiedName"));
+
+        // Verify context.removeFromKnownTable was called with correct name
+        verify(context).removeFromKnownTable("prod.another_table@cluster2");
+    }
+
+    // ========== getHiveEntities() TESTS ==========
+
+    @Test
+    public void testGetHiveEntities_Success() throws Exception {
+        // Setup output entities
+        WriteEntity outputEntity = mock(WriteEntity.class);
+        when(outputEntity.getType()).thenReturn(Entity.Type.TABLE);
+        when(outputEntity.getTable()).thenReturn(table);
+        Set<WriteEntity> outputs = Collections.singleton(outputEntity);
+
+        DropTable dropTable = spy(new DropTable(context));
+        doReturn(outputs).when(dropTable).getOutputs();
+        
+        // Mock getQualifiedName
+        
doReturn("default.test_table@cluster").when(dropTable).getQualifiedName(table);
+
+        List<AtlasObjectId> entities = dropTable.getHiveEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        AssertJUnit.assertEquals("Should have one entity", 1, entities.size());
+        
+        AtlasObjectId entity = entities.get(0);
+        AssertJUnit.assertEquals("Should be hive_table type", "hive_table", 
entity.getTypeName());
+        AssertJUnit.assertEquals("Should have correct qualified name", 
"default.test_table@cluster",
+                entity.getUniqueAttributes().get("qualifiedName"));
+
+        // Verify context.removeFromKnownTable was called
+        verify(context).removeFromKnownTable("default.test_table@cluster");
+    }
+
+    @Test
+    public void testGetHiveEntities_EmptyOutputs() throws Exception {
+        DropTable dropTable = spy(new DropTable(context));
+        doReturn(Collections.emptySet()).when(dropTable).getOutputs();
+
+        List<AtlasObjectId> entities = dropTable.getHiveEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        AssertJUnit.assertTrue("Entities should be empty", entities.isEmpty());
+
+        // Verify no calls to removeFromKnownTable
+        verify(context, never()).removeFromKnownTable(any(String.class));
+    }
+
+    @Test
+    public void testGetHiveEntities_NonTableEntity() throws Exception {
+        // Setup output entities with non-table type
+        WriteEntity outputEntity = mock(WriteEntity.class);
+        when(outputEntity.getType()).thenReturn(Entity.Type.DATABASE);
+        Set<WriteEntity> outputs = Collections.singleton(outputEntity);
+
+        DropTable dropTable = spy(new DropTable(context));
+        doReturn(outputs).when(dropTable).getOutputs();
+
+        List<AtlasObjectId> entities = dropTable.getHiveEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        AssertJUnit.assertTrue("Entities should be empty", entities.isEmpty());
+
+        // Verify no calls to removeFromKnownTable
+        verify(context, never()).removeFromKnownTable(any(String.class));
+    }
+
+    @Test
+    public void testGetHiveEntities_MultipleTables() throws Exception {
+        // Setup multiple table entities
+        WriteEntity table1Entity = mock(WriteEntity.class);
+        when(table1Entity.getType()).thenReturn(Entity.Type.TABLE);
+        Table table1 = mock(Table.class);
+        when(table1Entity.getTable()).thenReturn(table1);
+
+        WriteEntity table2Entity = mock(WriteEntity.class);
+        when(table2Entity.getType()).thenReturn(Entity.Type.TABLE);
+        Table table2 = mock(Table.class);
+        when(table2Entity.getTable()).thenReturn(table2);
+
+        Set<WriteEntity> outputs = new HashSet<>(Arrays.asList(table1Entity, 
table2Entity));
+
+        DropTable dropTable = spy(new DropTable(context));
+        doReturn(outputs).when(dropTable).getOutputs();
+        
+        // Mock getQualifiedName for both tables
+        
doReturn("default.table1@cluster").when(dropTable).getQualifiedName(table1);
+        
doReturn("default.table2@cluster").when(dropTable).getQualifiedName(table2);
+
+        List<AtlasObjectId> entities = dropTable.getHiveEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        AssertJUnit.assertEquals("Should have two entities", 2, 
entities.size());
+        
+        // Verify both entities have correct type
+        for (AtlasObjectId entity : entities) {
+            AssertJUnit.assertEquals("Should be hive_table type", 
"hive_table", entity.getTypeName());
+        }
+
+        // Verify context.removeFromKnownTable was called for both tables
+        verify(context).removeFromKnownTable("default.table1@cluster");
+        verify(context).removeFromKnownTable("default.table2@cluster");
+    }
+
+    @Test
+    public void testGetHiveEntities_MixedEntityTypes() throws Exception {
+        // Setup mixed entity types
+        WriteEntity tableEntity = mock(WriteEntity.class);
+        when(tableEntity.getType()).thenReturn(Entity.Type.TABLE);
+        when(tableEntity.getTable()).thenReturn(table);
+
+        WriteEntity dbEntity = mock(WriteEntity.class);
+        when(dbEntity.getType()).thenReturn(Entity.Type.DATABASE);
+
+        WriteEntity partitionEntity = mock(WriteEntity.class);
+        when(partitionEntity.getType()).thenReturn(Entity.Type.PARTITION);
+
+        Set<WriteEntity> outputs = new HashSet<>(Arrays.asList(tableEntity, 
dbEntity, partitionEntity));
+
+        DropTable dropTable = spy(new DropTable(context));
+        doReturn(outputs).when(dropTable).getOutputs();
+        
+        // Mock getQualifiedName for table only
+        
doReturn("default.test_table@cluster").when(dropTable).getQualifiedName(table);
+
+        List<AtlasObjectId> entities = dropTable.getHiveEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        AssertJUnit.assertEquals("Should have one entity (only table)", 1, 
entities.size());
+        
+        AtlasObjectId entity = entities.get(0);
+        AssertJUnit.assertEquals("Should be hive_table type", "hive_table", 
entity.getTypeName());
+        AssertJUnit.assertEquals("Should have correct qualified name", 
"default.test_table@cluster",
+                entity.getUniqueAttributes().get("qualifiedName"));
+
+        // Verify context.removeFromKnownTable was called only for table
+        verify(context).removeFromKnownTable("default.test_table@cluster");
+        verify(context, times(1)).removeFromKnownTable(any(String.class));
+    }
+
+/*    @Test

Review Comment:
   Remove commented-out test method or uncomment and implement it properly. 
Commented code reduces maintainability.
   ```suggestion
       @Test
   ```



##########
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/events/CreateDatabaseTest.java:
##########
@@ -0,0 +1,184 @@
+package org.apache.atlas.hive.hook.events;
+
+import org.apache.atlas.hive.bridge.HiveMetaStoreBridge;
+import org.apache.atlas.hive.hook.AtlasHiveHookContext;
+import org.apache.atlas.hive.hook.HiveHook;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.notification.HookNotification;
+import org.apache.atlas.type.AtlasTypeUtil;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.Database;
+//import org.apache.hadoop.hive.metastore.api.DatabaseType;
+import org.apache.hadoop.hive.metastore.api.PrincipalType;
+import org.apache.hadoop.hive.metastore.events.CreateDatabaseEvent;
+import org.apache.hadoop.hive.ql.hooks.Entity;
+import org.apache.hadoop.hive.ql.hooks.HookContext;
+import org.apache.hadoop.hive.ql.hooks.WriteEntity;
+import org.apache.hadoop.hive.ql.metadata.Hive;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import java.util.*;
+
+import static org.mockito.Mockito.*;
+import static org.testng.AssertJUnit.*;
+
+public class CreateDatabaseTest {
+    private static final Logger LOG = 
LoggerFactory.getLogger(CreateDatabaseTest.class);
+
+    CreateDatabase createDatabase;
+
+    @Mock
+    AtlasHiveHookContext context;
+
+    @Test
+    public void testGetNotificationMessagesGHMS() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        CreateDatabaseEvent createDatabaseEvent = 
mock(CreateDatabaseEvent.class);
+        when(context.getMetastoreEvent()).thenReturn(createDatabaseEvent);
+
+        HiveHook hook = mock(HiveHook.class);
+        when(hook.getMetadataNamespace()).thenReturn("cm");
+
+        Database database = mock(Database.class);
+        when(createDatabaseEvent.getDatabase()).thenReturn(database);
+        database.setName("hive");
+        when(database.getName()).thenReturn("jacocoDb");
+        when(database.getDescription()).thenReturn(null);
+        
when(database.getLocationUri()).thenReturn("hdfs://ccycloud-1.fsknox.root.comops.site:8020/warehouse/tablespace/external/hive/jacocoDb");
+
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put("comment", "Similar to Default Hive database");
+        parameters.put("owner_name", "public");
+        parameters.put("owner_type", "ROLE");
+        when(database.getParameters()).thenReturn(parameters);
+
+        when(database.getOwnerName()).thenReturn("hive");
+        when(database.getOwnerType()).thenReturn(PrincipalType.USER);
+
+        when(database.getCatalogName()).thenReturn("hive");
+//        when(database.getCreateTime()).thenReturn(1753349206);

Review Comment:
   Remove commented-out mock setup code or uncomment it if needed for the test.
   ```suggestion
   
   ```



##########
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/events/CreateTableTest.java:
##########
@@ -0,0 +1,790 @@
+package org.apache.atlas.hive.hook.events;
+
+import org.apache.atlas.hive.hook.AtlasHiveHookContext;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
+import org.apache.atlas.model.notification.HookNotification;
+import org.apache.hadoop.hive.metastore.TableType;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
+import org.apache.hadoop.hive.metastore.events.AlterTableEvent;
+import org.apache.hadoop.hive.metastore.events.CreateTableEvent;
+import org.apache.hadoop.hive.ql.hooks.Entity;
+import org.apache.hadoop.hive.ql.hooks.WriteEntity;
+import org.apache.hadoop.hive.ql.metadata.Hive;
+import org.apache.hadoop.hive.ql.metadata.Table;
+import org.apache.hadoop.hive.ql.plan.HiveOperation;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertNotNull;

Review Comment:
   [nitpick] Mixed usage of TestNG and JUnit assertions. The file primarily 
uses TestNG's AssertJUnit but also imports JUnit's Assert. Consider 
standardizing on one assertion library for consistency.
   ```suggestion
   
   ```



##########
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/events/CreateDatabaseTest.java:
##########
@@ -0,0 +1,184 @@
+package org.apache.atlas.hive.hook.events;
+
+import org.apache.atlas.hive.bridge.HiveMetaStoreBridge;
+import org.apache.atlas.hive.hook.AtlasHiveHookContext;
+import org.apache.atlas.hive.hook.HiveHook;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.notification.HookNotification;
+import org.apache.atlas.type.AtlasTypeUtil;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.Database;
+//import org.apache.hadoop.hive.metastore.api.DatabaseType;

Review Comment:
   Remove unused commented import statement.
   ```suggestion
   
   ```



##########
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/events/CreateHiveProcessTest.java:
##########
@@ -0,0 +1,1770 @@
+package org.apache.atlas.hive.hook.events;
+
+import org.apache.atlas.hive.hook.AtlasHiveHookContext;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
+import org.apache.atlas.model.notification.HookNotification;
+import 
org.apache.atlas.model.notification.HookNotification.EntityCreateRequestV2;
+import org.apache.hadoop.hive.ql.hooks.Entity;
+import org.apache.hadoop.hive.ql.hooks.LineageInfo;
+import org.apache.hadoop.hive.ql.hooks.LineageInfo.BaseColumnInfo;
+import org.apache.hadoop.hive.ql.hooks.LineageInfo.Dependency;
+import org.apache.hadoop.hive.ql.hooks.LineageInfo.DependencyKey;
+import org.apache.hadoop.hive.ql.hooks.ReadEntity;
+import org.apache.hadoop.hive.ql.hooks.WriteEntity;
+import org.apache.hadoop.hive.ql.plan.HiveOperation;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+import static org.mockito.Mockito.*;
+import static org.testng.AssertJUnit.*;
+
+public class CreateHiveProcessTest {
+    private static final Logger LOG = 
LoggerFactory.getLogger(CreateHiveProcessTest.class);
+
+    @Mock
+    AtlasHiveHookContext context;
+
+    @Mock
+    ReadEntity readEntity;
+
+    @Mock
+    WriteEntity writeEntity;
+
+    @Mock
+    LineageInfo lineageInfo;
+
+    @Mock
+    DependencyKey dependencyKey;
+
+    @Mock
+    Dependency dependency;
+
+    @Mock
+    BaseColumnInfo baseColumnInfo;
+
+
+
+    @BeforeMethod
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        
+        // Mock context.getHiveOperation() to prevent NPEs in isDdlOperation 
method
+        when(context.getHiveOperation()).thenReturn(HiveOperation.QUERY);
+    }
+
+    // ========== CONSTRUCTOR TESTS ==========
+
+    @Test
+    public void testConstructor() {
+        CreateHiveProcess createHiveProcess = new CreateHiveProcess(context);
+        AssertJUnit.assertNotNull("CreateHiveProcess should be instantiated", 
createHiveProcess);
+        assertTrue("CreateHiveProcess should extend BaseHiveEvent",
+                createHiveProcess instanceof BaseHiveEvent);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testConstructorWithNullContext() {
+        new CreateHiveProcess(null);
+    }
+
+    // ========== getNotificationMessages() TESTS ==========
+
+    @Test
+    public void testGetNotificationMessages_WithEntities() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock getEntities to return some entities
+        AtlasEntitiesWithExtInfo mockEntities = new AtlasEntitiesWithExtInfo();
+        AtlasEntity entity = new AtlasEntity("hive_process");
+        entity.setAttribute("qualifiedName", "test.process@cluster");
+        mockEntities.addEntity(entity);
+
+        doReturn(mockEntities).when(createHiveProcess).getEntities();
+        doReturn("test_user").when(createHiveProcess).getUserName();
+
+        List<HookNotification> notifications = 
createHiveProcess.getNotificationMessages();
+
+        AssertJUnit.assertNotNull("Notifications should not be null", 
notifications);
+        AssertJUnit.assertEquals("Should have one notification", 1, 
notifications.size());
+        assertTrue("Should be EntityCreateRequestV2",
+                notifications.get(0) instanceof EntityCreateRequestV2);
+
+        EntityCreateRequestV2 createRequest = (EntityCreateRequestV2) 
notifications.get(0);
+        AssertJUnit.assertEquals("User should be test_user", "test_user", 
createRequest.getUser());
+        AssertJUnit.assertNotNull("Entities should not be null", 
createRequest.getEntities());
+    }
+
+    @Test
+    public void testGetNotificationMessages_EmptyEntities() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock getEntities to return empty entities
+        AtlasEntitiesWithExtInfo mockEntities = new AtlasEntitiesWithExtInfo();
+        doReturn(mockEntities).when(createHiveProcess).getEntities();
+
+        List<HookNotification> notifications = 
createHiveProcess.getNotificationMessages();
+
+        assertNull("Notifications should be null when entities are empty", 
notifications);
+    }
+
+    @Test
+    public void testGetNotificationMessages_NullEntities() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock getEntities to return null
+        doReturn(null).when(createHiveProcess).getEntities();
+
+        List<HookNotification> notifications = 
createHiveProcess.getNotificationMessages();
+
+        assertNull("Notifications should be null when entities are null", 
notifications);
+    }
+
+    // ========== getEntities() TESTS ==========
+
+    @Test
+    public void testGetEntities_SkipProcess() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Set up empty inputs and outputs to make skipProcess return true
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(Collections.emptySet()).when(createHiveProcess).getOutputs();
+
+        // Use reflection to call private method 'skipProcess'
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+
+        // Now skipProcess should return true due to empty inputs/outputs
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        assertTrue("skipProcess() should return true for empty 
inputs/outputs", skip);
+
+        // Now call getEntities (it will internally call skipProcess())
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        assertNull("Entities should be null when process is skipped", 
entities);
+    }
+
+
+    @Test
+    public void testGetEntities_EmptyInputsAndOutputs() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Prepare empty inputs/outputs
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(Collections.emptySet()).when(createHiveProcess).getOutputs();
+
+        // Mock context methods
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        // Use reflection to ensure skipProcess returns true (due to empty 
inputs/outputs)
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        assertTrue("skipProcess should return true for empty inputs/outputs", 
skip);
+
+        // Now run getEntities()
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        assertNull("Entities should be null when inputs and outputs are 
empty", entities);
+    }
+
+
+    @Test
+    public void testGetEntities_WithSkippedInputEntity() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Prepare empty inputs but some outputs
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock getQualifiedName and getInputOutputEntity
+        
doReturn("default.test_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // Mock context methods
+        when(context.isSkippedInputEntity()).thenReturn(true);
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        // Reflection: ensure skipProcess returns false (has outputs but no 
inputs)
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        assertFalse("skipProcess should return false when there are outputs 
but no inputs", skip);
+
+        // Reflection: ensure isDdlOperation returns false
+        Method isDdlOperationMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        isDdlOperationMethod.setAccessible(true);
+        boolean ddlOp = (boolean) 
isDdlOperationMethod.invoke(createHiveProcess, outputEntity);
+        assertFalse("isDdlOperation should return false in this scenario", 
ddlOp);
+
+        // Now run getEntities()
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        assertNull("Entities should be null when input entity is skipped", 
entities);
+    }
+
+
+
+    @Test
+    public void testGetEntities_WithSkippedOutputEntity() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Prepare some inputs but empty outputs
+        Set<ReadEntity> inputs = Collections.singleton(readEntity);
+        doReturn(inputs).when(createHiveProcess).getInputs();
+        doReturn(Collections.emptySet()).when(createHiveProcess).getOutputs();
+
+        // Mock getQualifiedName to avoid NPE in BaseHiveEvent.getQualifiedName
+        
doReturn("default.input_table@cluster").when(createHiveProcess).getQualifiedName(readEntity);
+
+        // Mock getInputOutputEntity to avoid NPE in 
BaseHiveEvent.getInputOutputEntity
+        AtlasEntity inputEntity = new AtlasEntity("hive_table");
+        
doReturn(inputEntity).when(createHiveProcess).getInputOutputEntity(eq(readEntity),
 any(), anyBoolean());
+
+        // Mock entity type and direct flag
+        
when(readEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+        when(readEntity.isDirect()).thenReturn(true);
+
+        // Mock context methods
+        when(context.isSkippedOutputEntity()).thenReturn(true);
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        // Reflection: ensure skipProcess returns false (has inputs but no 
outputs)
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        assertFalse("skipProcess should return false when there are inputs but 
no outputs", skip);
+
+        // Now run getEntities()
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        assertNull("Entities should be null when output entity is skipped", 
entities);
+    }
+
+
+    @Test
+    public void testGetEntities_SuccessfulProcessCreation() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock inputs and outputs
+        Set<ReadEntity> inputs = Collections.singleton(readEntity);
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(inputs).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock getQualifiedName for entities
+        
doReturn("default.input_table@cluster").when(createHiveProcess).getQualifiedName(readEntity);
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        // Mock getInputOutputEntity
+        AtlasEntity inputEntity = new AtlasEntity("hive_table");
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(inputEntity).when(createHiveProcess).getInputOutputEntity(eq(readEntity),
 any(), anyBoolean());
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // Mock entity types and flags
+        
when(readEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+        when(readEntity.isDirect()).thenReturn(true);
+
+        // Mock context methods
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        // Reflection: ensure skipProcess returns false (has both inputs and 
outputs)
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        assertFalse("skipProcess should return false when there are both 
inputs and outputs", skip);
+
+        // Reflection: ensure isDdlOperation returns false
+        Method isDdlMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        isDdlMethod.setAccessible(true);
+        boolean isDdl = (boolean) isDdlMethod.invoke(createHiveProcess, 
outputEntity);
+        assertFalse("isDdlOperation should return false in this scenario", 
isDdl);
+
+        // Mock process creation methods
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        // Mock methods needed by getHiveProcessExecutionEntity
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        // Reflection: invoke processColumnLineage without doing anything
+        Method processColumnLineageMethod =
+                
CreateHiveProcess.class.getDeclaredMethod("processColumnLineage", 
AtlasEntity.class, AtlasEntitiesWithExtInfo.class);
+        processColumnLineageMethod.setAccessible(true);
+        // No-op, we don't actually execute it in the test
+
+        // Mock addProcessedEntities to do nothing
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        // Now run getEntities()
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        AssertJUnit.assertNotNull("Entities list should not be null", 
entities.getEntities());
+        assertTrue("Should contain process entities", 
entities.getEntities().size() >= 2);
+
+        // Verify process and process execution entities exist
+        boolean hasProcess = entities.getEntities().stream()
+                .anyMatch(entity -> 
"hive_process".equals(entity.getTypeName()));
+        boolean hasProcessExecution = entities.getEntities().stream()
+                .anyMatch(entity -> 
"hive_process_execution".equals(entity.getTypeName()));
+
+        assertTrue("Should contain hive_process entity", hasProcess);
+        assertTrue("Should contain hive_process_execution entity", 
hasProcessExecution);
+    }
+
+
+    @Test
+    public void testGetEntities_MetastoreHook() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock outputs
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock getQualifiedName
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        // Mock getInputOutputEntity
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // Reflection: ensure skipProcess returns false (has outputs but no 
inputs)
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        assertFalse("skipProcess should return false when there are outputs 
but no inputs", skip);
+
+        // Reflection: ensure isDdlOperation returns false
+        Method isDdlMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        isDdlMethod.setAccessible(true);
+        boolean isDdl = (boolean) isDdlMethod.invoke(createHiveProcess, 
outputEntity);
+        assertFalse("isDdlOperation should return false in this scenario", 
isDdl);
+
+        // Mock context methods - metastore hook
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        // Call method under test
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        // Verify
+        assertNull("Entities should be null for metastore hook with empty 
inputs", entities);
+    }
+
+
+    @Test
+    public void testGetEntities_WithDDLOperation() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock outputs
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock getQualifiedName
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        // Mock getInputOutputEntity
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // --- Reflection to make skipProcess return false ---
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        assertFalse((boolean) skipProcessMethod.invoke(createHiveProcess));
+
+        // Mock context to return a DDL operation
+        
when(context.getHiveOperation()).thenReturn(HiveOperation.CREATETABLE_AS_SELECT);
+        
+        // --- Reflection to make isDdlOperation return true ---
+        Method isDdlMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        isDdlMethod.setAccessible(true);
+        assertTrue("Expected DDL operation", (boolean) 
isDdlMethod.invoke(createHiveProcess, outputEntity));
+
+        // Mock createHiveDDLEntity (this is public/protected so mocking is 
fine)
+        AtlasEntity ddlEntity = new AtlasEntity("hive_ddl");
+        
doReturn(ddlEntity).when(createHiveProcess).createHiveDDLEntity(outputEntity);
+
+        // Mock context methods
+        when(context.isMetastoreHook()).thenReturn(true);
+
+        // Call method under test
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        // Assert expected behavior
+        assertNull("Entities should be null for metastore hook with empty 
inputs", entities);
+    }
+
+
+    // ========== HELPER METHOD TESTS ==========
+
+    @Test
+    public void testCheckIfOnlySelfLineagePossible_True() throws Exception {
+        CreateHiveProcess createHiveProcess = new CreateHiveProcess(context);
+
+        // Use reflection to access private method
+        Method method = CreateHiveProcess.class.getDeclaredMethod(
+                "checkIfOnlySelfLineagePossible", String.class, Map.class);
+        method.setAccessible(true);
+
+        Map<String, Entity> inputByQualifiedName = new HashMap<>();
+        inputByQualifiedName.put("default.table@cluster", readEntity);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, 
"default.table@cluster", inputByQualifiedName);
+
+        assertTrue("Should return true for self lineage", result);
+    }
+
+    @Test
+    public void testCheckIfOnlySelfLineagePossible_False() throws Exception {
+        CreateHiveProcess createHiveProcess = new CreateHiveProcess(context);
+
+        // Use reflection to access private method
+        Method method = CreateHiveProcess.class.getDeclaredMethod(
+                "checkIfOnlySelfLineagePossible", String.class, Map.class);
+        method.setAccessible(true);
+
+        Map<String, Entity> inputByQualifiedName = new HashMap<>();
+        inputByQualifiedName.put("default.input_table@cluster", readEntity);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, 
"default.output_table@cluster", inputByQualifiedName);
+
+        assertFalse("Should return false for different table", result);
+    }
+
+    @Test
+    public void testCheckIfOnlySelfLineagePossible_MultipleInputs() throws 
Exception {
+        CreateHiveProcess createHiveProcess = new CreateHiveProcess(context);
+
+        // Use reflection to access private method
+        Method method = CreateHiveProcess.class.getDeclaredMethod(
+                "checkIfOnlySelfLineagePossible", String.class, Map.class);
+        method.setAccessible(true);
+
+        Map<String, Entity> inputByQualifiedName = new HashMap<>();
+        inputByQualifiedName.put("default.table1@cluster", readEntity);
+        inputByQualifiedName.put("default.table2@cluster", 
mock(ReadEntity.class));
+
+        boolean result = (boolean) method.invoke(createHiveProcess, 
"default.table1@cluster", inputByQualifiedName);
+
+        assertFalse("Should return false for multiple inputs", result);
+    }
+
+    @Test
+    public void testSkipProcess_EmptyInputsAndOutputs() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock empty inputs and outputs
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(Collections.emptySet()).when(createHiveProcess).getOutputs();
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess);
+
+        assertTrue("Should skip process when inputs and outputs are empty", 
result);
+    }
+
+    @Test
+    public void testSkipProcess_QueryWithTempDirectory() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock inputs and outputs
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+
+        WriteEntity tempOutput = mock(WriteEntity.class);
+        when(tempOutput.getType()).thenReturn(Entity.Type.DFS_DIR);
+        
when(tempOutput.getWriteType()).thenReturn(WriteEntity.WriteType.PATH_WRITE);
+        when(tempOutput.isTempURI()).thenReturn(true);
+
+        Set<WriteEntity> outputs = Collections.singleton(tempOutput);
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock context
+        doReturn(context).when(createHiveProcess).getContext();
+        when(context.getHiveOperation()).thenReturn(HiveOperation.QUERY);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess);
+
+        assertTrue("Should skip process for query with temp directory", 
result);
+    }
+
+    @Test
+    public void testSkipProcess_DeleteOperation() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock inputs and outputs
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+
+        WriteEntity deleteOutput = mock(WriteEntity.class);
+        when(deleteOutput.getType()).thenReturn(Entity.Type.TABLE);
+        
when(deleteOutput.getWriteType()).thenReturn(WriteEntity.WriteType.DELETE);
+
+        Set<WriteEntity> outputs = Collections.singleton(deleteOutput);
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock context
+        doReturn(context).when(createHiveProcess).getContext();
+        when(context.getHiveOperation()).thenReturn(HiveOperation.QUERY);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess);
+
+        assertTrue("Should skip process for DELETE operation", result);
+    }
+
+    @Test
+    public void testSkipProcess_UpdateOperation() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock inputs and outputs
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+
+        WriteEntity updateOutput = mock(WriteEntity.class);
+        when(updateOutput.getType()).thenReturn(Entity.Type.TABLE);
+        
when(updateOutput.getWriteType()).thenReturn(WriteEntity.WriteType.UPDATE);
+
+        Set<WriteEntity> outputs = Collections.singleton(updateOutput);
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock context
+        doReturn(context).when(createHiveProcess).getContext();
+        when(context.getHiveOperation()).thenReturn(HiveOperation.QUERY);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess);
+
+        assertTrue("Should skip process for UPDATE operation", result);
+    }
+
+    @Test
+    public void testSkipProcess_RegularQuery() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock inputs and outputs
+        Set<ReadEntity> inputs = Collections.singleton(readEntity);
+        doReturn(inputs).when(createHiveProcess).getInputs();
+
+        WriteEntity normalOutput = mock(WriteEntity.class);
+        when(normalOutput.getType()).thenReturn(Entity.Type.TABLE);
+        
when(normalOutput.getWriteType()).thenReturn(WriteEntity.WriteType.INSERT);
+
+        Set<WriteEntity> outputs = Collections.singleton(normalOutput);
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess);
+
+        assertFalse("Should not skip process for regular query", result);
+    }
+
+    @Test
+    public void testIsDdlOperation_CreateTableAsSelect() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        AtlasEntity entity = new AtlasEntity("hive_table");
+
+        // Mock context
+        when(context.isMetastoreHook()).thenReturn(false);
+        
when(context.getHiveOperation()).thenReturn(HiveOperation.CREATETABLE_AS_SELECT);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, entity);
+
+        assertTrue("Should be DDL operation for CREATETABLE_AS_SELECT", 
result);
+    }
+
+    @Test
+    public void testIsDdlOperation_CreateView() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        AtlasEntity entity = new AtlasEntity("hive_table");
+
+        // Mock context
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.getHiveOperation()).thenReturn(HiveOperation.CREATEVIEW);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, entity);
+
+        assertTrue("Should be DDL operation for CREATEVIEW", result);
+    }
+
+    @Test
+    public void testIsDdlOperation_AlterViewAs() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        AtlasEntity entity = new AtlasEntity("hive_table");
+
+        // Mock context
+        when(context.isMetastoreHook()).thenReturn(false);
+        
when(context.getHiveOperation()).thenReturn(HiveOperation.ALTERVIEW_AS);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, entity);
+
+        assertTrue("Should be DDL operation for ALTERVIEW_AS", result);
+    }
+
+    @Test
+    public void testIsDdlOperation_CreateMaterializedView() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        AtlasEntity entity = new AtlasEntity("hive_table");
+
+        // Mock context
+        when(context.isMetastoreHook()).thenReturn(false);
+        
when(context.getHiveOperation()).thenReturn(HiveOperation.CREATE_MATERIALIZED_VIEW);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, entity);
+
+        assertTrue("Should be DDL operation for CREATE_MATERIALIZED_VIEW", 
result);
+    }
+
+    @Test
+    public void testIsDdlOperation_MetastoreHook() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        AtlasEntity entity = new AtlasEntity("hive_table");
+
+        // Mock context - metastore hook
+        when(context.isMetastoreHook()).thenReturn(true);
+        
when(context.getHiveOperation()).thenReturn(HiveOperation.CREATETABLE_AS_SELECT);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, entity);
+
+        assertFalse("Should not be DDL operation for metastore hook", result);
+    }
+
+    @Test
+    public void testIsDdlOperation_RegularOperation() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        AtlasEntity entity = new AtlasEntity("hive_table");
+
+        // Mock context
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.getHiveOperation()).thenReturn(HiveOperation.QUERY);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, entity);
+
+        assertFalse("Should not be DDL operation for regular query", result);
+    }
+
+    @Test
+    public void testIsDdlOperation_NullEntity() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        method.setAccessible(true);
+
+        boolean result = (boolean) method.invoke(createHiveProcess, 
(AtlasEntity) null);
+
+        assertFalse("Should not be DDL operation for null entity", result);
+    }
+
+    // ========== COLUMN LINEAGE TESTS ==========
+
+    @Test
+    public void testProcessColumnLineage_NullLineageInfo() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Prepare inputs/outputs first
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // --- Reflection to force skipProcess to return false ---
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        assertFalse("skipProcess should return false", (boolean) 
skipProcessMethod.invoke(createHiveProcess));
+
+        // Mock getQualifiedName
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        // Mock getInputOutputEntity
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // --- Reflection to force isDdlOperation to return false ---
+        Method ddlMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        ddlMethod.setAccessible(true);
+        assertFalse("Expected non-DDL operation", (boolean) 
ddlMethod.invoke(createHiveProcess, outputEntity));
+
+        // Mock entity type
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+
+        // Context settings
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+
+        // Mock process entity creation
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        // Mock required getters
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        // Null lineage info (triggers early return in processColumnLineage)
+        doReturn(null).when(createHiveProcess).getLineageInfo();
+
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        // Run test
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        assertNotNull("Entities should not be null", entities);
+        // We don't assert column lineage here because getLineageInfo is null
+    }
+
+
+    @Test
+    public void testProcessColumnLineage_EmptyLineageInfo() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Just call skipProcess via reflection to verify it's false (no 
stubbing needed)
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        assertFalse((boolean) skipProcessMethod.invoke(createHiveProcess));
+
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // Check isDdlOperation via reflection instead of stubbing
+        Method ddlMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        ddlMethod.setAccessible(true);
+        assertFalse((boolean) ddlMethod.invoke(createHiveProcess, 
outputEntity));
+
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        LineageInfo emptyLineageInfo = new LineageInfo();
+        doReturn(emptyLineageInfo).when(createHiveProcess).getLineageInfo();
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        assertNotNull("Entities should not be null", entities);
+    }
+
+
+    @Test
+    public void testGetBaseCols_NullDependency() throws Exception {
+        CreateHiveProcess createHiveProcess = new CreateHiveProcess(context);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("getBaseCols", Dependency.class);
+        method.setAccessible(true);
+
+        Collection<BaseColumnInfo> result = (Collection<BaseColumnInfo>) 
method.invoke(createHiveProcess, (Dependency) null);
+
+        AssertJUnit.assertNotNull("Result should not be null", result);
+        assertTrue("Result should be empty", result.isEmpty());
+    }
+
+    @Test
+    public void testGetBaseCols_ValidDependency() throws Exception {
+        CreateHiveProcess createHiveProcess = new CreateHiveProcess(context);
+
+        // Create a mock dependency that has getBaseCols method
+        Dependency mockDependency = mock(Dependency.class);
+        BaseColumnInfo baseCol1 = mock(BaseColumnInfo.class);
+        BaseColumnInfo baseCol2 = mock(BaseColumnInfo.class);
+        Collection<BaseColumnInfo> expectedBaseCols = Arrays.asList(baseCol1, 
baseCol2);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("getBaseCols", Dependency.class);
+        method.setAccessible(true);
+
+        // Since we can't easily mock the reflection, let's just test that it 
doesn't crash
+        Collection<BaseColumnInfo> result = (Collection<BaseColumnInfo>) 
method.invoke(createHiveProcess, mockDependency);
+
+        AssertJUnit.assertNotNull("Result should not be null", result);
+        // Result will be empty because the mock doesn't have the actual 
getBaseCols method
+        assertTrue("Result should be empty for mock dependency", 
result.isEmpty());
+    }
+
+    @Test
+    public void testGetBaseCols_NonCollectionReturn() throws Exception {
+        CreateHiveProcess createHiveProcess = new CreateHiveProcess(context);
+
+        // Test with a dependency that would return non-Collection type
+        Dependency mockDependency = mock(Dependency.class);
+
+        // Use reflection to access private method
+        Method method = 
CreateHiveProcess.class.getDeclaredMethod("getBaseCols", Dependency.class);
+        method.setAccessible(true);
+
+        Collection<BaseColumnInfo> result = (Collection<BaseColumnInfo>) 
method.invoke(createHiveProcess, mockDependency);
+
+        AssertJUnit.assertNotNull("Result should not be null", result);
+        assertTrue("Result should be empty due to reflection limitations", 
result.isEmpty());
+    }
+
+    private static Object invokePrivate(Object target, String methodName, 
Class<?>[] paramTypes, Object... args) throws Exception {
+        // Get the method from the original class, not the spy class
+        Method m = CreateHiveProcess.class.getDeclaredMethod(methodName, 
paramTypes);
+        m.setAccessible(true);
+        return m.invoke(target, args);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testProcessColumnLineage_WithValidLineageInfo() throws 
Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Call skipProcess via reflection to assert its result instead of 
stubbing
+        assertFalse((boolean) invokePrivate(createHiveProcess, "skipProcess", 
new Class<?>[]{}));
+
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // Call isDdlOperation via reflection instead of stubbing
+        assertFalse((boolean) invokePrivate(createHiveProcess, 
"isDdlOperation", new Class<?>[]{AtlasEntity.class}, outputEntity));
+
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        LineageInfo lineageInfo = mock(LineageInfo.class);
+        DependencyKey depKey = mock(DependencyKey.class);
+        Dependency dependency = mock(Dependency.class);
+        BaseColumnInfo baseColInfo = mock(BaseColumnInfo.class);
+
+        Map<DependencyKey, Dependency> lineageMap = new HashMap<>();
+        lineageMap.put(depKey, dependency);
+        when(lineageInfo.entrySet()).thenReturn(lineageMap.entrySet());
+
+        
doReturn("default.output_table.col1@cluster").when(createHiveProcess).getQualifiedName(depKey);
+        
doReturn("default.input_table.col1@cluster").when(createHiveProcess).getQualifiedName(baseColInfo);
+
+        // Instead of stubbing getBaseCols (private), set up reflection check
+        Collection<BaseColumnInfo> baseCols = Arrays.asList(baseColInfo);
+        // call: (Collection<BaseColumnInfo>) invokePrivate(createHiveProcess, 
"getBaseCols", new Class<?>[]{Dependency.class}, dependency)
+        // For actual testing, you might need to restructure code so 
getBaseCols isn't private.
+
+        
when(dependency.getType()).thenReturn(LineageInfo.DependencyType.SIMPLE);
+        when(dependency.getExpr()).thenReturn("col1");
+
+        AtlasEntity outputColumn = new AtlasEntity("hive_column");
+        outputColumn.setAttribute("name", "col1");
+        outputColumn.setAttribute("qualifiedName", 
"default.output_table.col1@cluster");
+
+        AtlasEntity inputColumn = new AtlasEntity("hive_column");
+        inputColumn.setAttribute("name", "col1");
+        inputColumn.setAttribute("qualifiedName", 
"default.input_table.col1@cluster");
+
+        
when(context.getEntity("default.output_table.col1@cluster")).thenReturn(outputColumn);
+        
when(context.getEntity("default.input_table.col1@cluster")).thenReturn(inputColumn);
+
+        when(context.getSkipHiveColumnLineageHive20633()).thenReturn(false);
+
+        doReturn(lineageInfo).when(createHiveProcess).getLineageInfo();
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        assertNotNull("Entities should not be null", entities);
+//        assertTrue("Should contain column lineage entities",
+//                entities.getEntities().stream()
+//                        .anyMatch(entity -> 
entity.getTypeName().contains("column_lineage")));
+    }
+
+
+    @Test
+    public void testProcessColumnLineage_NonExistentOutputColumn() throws 
Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Use reflection to ensure skipProcess() returns false
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+        // Here you don't actually change the method — but you can test its 
return
+        // Or if you want to bypass logic, you'll have to structure inputs so 
skipProcess naturally returns false.
+
+        // Prepare inputs/outputs
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+
+        // Call private isDdlOperation(AtlasEntity) via reflection
+        Method isDdlOperationMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        isDdlOperationMethod.setAccessible(true);
+        boolean isDdl = (boolean) 
isDdlOperationMethod.invoke(createHiveProcess, outputEntity);
+        AssertJUnit.assertFalse("Expected isDdlOperation to return false", 
isDdl);
+
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        // Mock methods needed for process execution
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        // Create mock lineage info with dependencies
+        LineageInfo lineageInfo = mock(LineageInfo.class);
+        DependencyKey depKey = mock(DependencyKey.class);
+        Dependency dependency = mock(Dependency.class);
+
+        Map<DependencyKey, Dependency> lineageMap = new HashMap<>();
+        lineageMap.put(depKey, dependency);
+        when(lineageInfo.entrySet()).thenReturn(lineageMap.entrySet());
+
+        
doReturn("default.output_table.non_existent_col@cluster").when(createHiveProcess).getQualifiedName(depKey);
+
+        // Mock context.getEntity to return null for non-existent column
+        
when(context.getEntity("default.output_table.non_existent_col@cluster")).thenReturn(null);
+
+        doReturn(lineageInfo).when(createHiveProcess).getLineageInfo();
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        boolean hasColumnLineage = entities.getEntities().stream()
+                .anyMatch(entity -> 
entity.getTypeName().contains("column_lineage"));
+        assertFalse("Should not contain column lineage entities due to 
non-existent output column", hasColumnLineage);
+    }
+
+
+    @Test
+    public void testProcessColumnLineage_SkipDueToThreshold() throws Exception 
{
+        // Mock common Hive context stuff
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+        when(context.getHostName()).thenReturn("test_host");
+
+        // Create mock lineage objects
+        BaseColumnInfo baseColInfo1 = mock(BaseColumnInfo.class);
+        BaseColumnInfo baseColInfo2 = mock(BaseColumnInfo.class);
+        BaseColumnInfo baseColInfo3 = mock(BaseColumnInfo.class);
+        DependencyKey depKey = mock(DependencyKey.class);
+        Dependency dependency = mock(Dependency.class);
+
+        // Use spy instead of anonymous subclass
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+        
+        // Create mock dependency with getBaseCols method
+        Dependency testDependency = mock(Dependency.class);
+        
when(testDependency.getType()).thenReturn(LineageInfo.DependencyType.SIMPLE);
+        when(testDependency.getExpr()).thenReturn("col1 + col2 + col3");
+        // Add getBaseCols method to the mock
+        doReturn(new HashSet<>(Arrays.asList(baseColInfo1, baseColInfo2, 
baseColInfo3))).when(testDependency).getBaseCols();
+
+        // Outputs and inputs
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // Mock Hive process entities
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        // Mock user/query info
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+
+        // Setup LineageInfo with concrete dependency
+        LineageInfo lineageInfo = mock(LineageInfo.class);
+        Map<DependencyKey, Dependency> lineageMap = new HashMap<>();
+        lineageMap.put(depKey, testDependency);
+        when(lineageInfo.entrySet()).thenReturn(lineageMap.entrySet());
+
+        
doReturn("default.output_table.col1@cluster").when(createHiveProcess).getQualifiedName(depKey);
+        
doReturn("default.input_table.col1@cluster").when(createHiveProcess).getQualifiedName(baseColInfo1);
+        
doReturn("default.input_table.col2@cluster").when(createHiveProcess).getQualifiedName(baseColInfo2);
+        
doReturn("default.input_table.col3@cluster").when(createHiveProcess).getQualifiedName(baseColInfo3);
+
+        // Mock context entities for columns
+        AtlasEntity outputColumn = new AtlasEntity("hive_column");
+        outputColumn.setAttribute("name", "col1");
+        outputColumn.setAttribute("qualifiedName", 
"default.output_table.col1@cluster");
+
+        AtlasEntity inputColumn1 = new AtlasEntity("hive_column");
+        AtlasEntity inputColumn2 = new AtlasEntity("hive_column");
+        AtlasEntity inputColumn3 = new AtlasEntity("hive_column");
+
+        
when(context.getEntity("default.output_table.col1@cluster")).thenReturn(outputColumn);
+        
when(context.getEntity("default.input_table.col1@cluster")).thenReturn(inputColumn1);
+        
when(context.getEntity("default.input_table.col2@cluster")).thenReturn(inputColumn2);
+        
when(context.getEntity("default.input_table.col3@cluster")).thenReturn(inputColumn3);
+
+        // Skip column lineage threshold settings
+        when(context.getSkipHiveColumnLineageHive20633()).thenReturn(true);
+        
when(context.getSkipHiveColumnLineageHive20633InputsThreshold()).thenReturn(2); 
// lower than actual cols
+
+        doReturn(lineageInfo).when(createHiveProcess).getLineageInfo();
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        // Execute
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        boolean hasColumnLineage = entities.getEntities().stream()
+                .anyMatch(entity -> 
entity.getTypeName().contains("column_lineage"));
+        assertFalse("Should not contain column lineage entities due to 
threshold", hasColumnLineage);
+    }
+
+
+    @Test
+    public void testProcessColumnLineage_DuplicateOutputColumn() throws 
Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Prepare reflection for private methods
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+
+        Method isDdlOperationMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        isDdlOperationMethod.setAccessible(true);
+
+        Method getBaseColsMethod = 
CreateHiveProcess.class.getDeclaredMethod("getBaseCols", 
LineageInfo.Dependency.class);
+        getBaseColsMethod.setAccessible(true);
+
+        // ---- Setup for test ----
+        // We want skipProcess() to return false (no skip)
+//        assertFalse((boolean) skipProcessMethod.invoke(createHiveProcess));
+
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // We want isDdlOperation(outputEntity) to return false
+        assertFalse((boolean) isDdlOperationMethod.invoke(createHiveProcess, 
outputEntity));
+
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        // Mock methods needed for process execution
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        // Create mock lineage info with duplicate dependencies
+        LineageInfo lineageInfo = mock(LineageInfo.class);
+        DependencyKey depKey1 = mock(DependencyKey.class);
+        DependencyKey depKey2 = mock(DependencyKey.class);
+        Dependency dependency1 = mock(Dependency.class);
+        Dependency dependency2 = mock(Dependency.class);
+        BaseColumnInfo baseColInfo = mock(BaseColumnInfo.class);
+
+        Map<DependencyKey, Dependency> lineageMap = new LinkedHashMap<>();
+        lineageMap.put(depKey1, dependency1);
+        lineageMap.put(depKey2, dependency2); // Duplicate output column
+        when(lineageInfo.entrySet()).thenReturn(lineageMap.entrySet());
+
+        String outputColName = "default.output_table.col1@cluster";
+        
doReturn(outputColName).when(createHiveProcess).getQualifiedName(depKey1);
+        
doReturn(outputColName).when(createHiveProcess).getQualifiedName(depKey2);
+        
doReturn("default.input_table.col1@cluster").when(createHiveProcess).getQualifiedName(baseColInfo);
+
+        // Mock getBaseCols method for both dependencies
+        doReturn(new 
HashSet<>(Arrays.asList(baseColInfo))).when(dependency1).getBaseCols();
+        doReturn(new 
HashSet<>(Arrays.asList(baseColInfo))).when(dependency2).getBaseCols();
+
+        
when(dependency1.getType()).thenReturn(LineageInfo.DependencyType.SIMPLE);
+        when(dependency1.getExpr()).thenReturn("col1");
+        
when(dependency2.getType()).thenReturn(LineageInfo.DependencyType.SIMPLE);
+        when(dependency2.getExpr()).thenReturn("col1");
+
+        // Mock context.getEntity for columns
+        AtlasEntity outputColumn = new AtlasEntity("hive_column");
+        outputColumn.setAttribute("name", "col1");
+        outputColumn.setAttribute("qualifiedName", outputColName);
+
+        AtlasEntity inputColumn = new AtlasEntity("hive_column");
+        inputColumn.setAttribute("name", "col1");
+        inputColumn.setAttribute("qualifiedName", 
"default.input_table.col1@cluster");
+
+        when(context.getEntity(outputColName)).thenReturn(outputColumn);
+        
when(context.getEntity("default.input_table.col1@cluster")).thenReturn(inputColumn);
+
+        when(context.getSkipHiveColumnLineageHive20633()).thenReturn(false);
+
+        doReturn(lineageInfo).when(createHiveProcess).getLineageInfo();
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        // ---- Execute & Verify ----
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+        assertNotNull("Entities should not be null", entities);
+
+        long columnLineageCount = entities.getEntities().stream()
+                .filter(entity -> 
entity.getTypeName().contains("column_lineage"))
+                .count();
+        assertEquals("Should contain only one column lineage entity due to 
duplicate handling", 1, columnLineageCount);
+    }
+
+
+
+
+    @Test
+    public void testProcessColumnLineage_EmptyInputColumns() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Prepare reflection for private methods
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+
+        Method isDdlOperationMethod = 
CreateHiveProcess.class.getDeclaredMethod("isDdlOperation", AtlasEntity.class);
+        isDdlOperationMethod.setAccessible(true);
+
+        Method getBaseColsMethod = 
CreateHiveProcess.class.getDeclaredMethod("getBaseCols", 
LineageInfo.Dependency.class);
+        getBaseColsMethod.setAccessible(true);
+
+        // ---- Test scenario where input columns list is empty ----
+        // Call skipProcess() to ensure no skip (false)
+//        assertFalse((boolean) skipProcessMethod.invoke(createHiveProcess));
+
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(Collections.emptySet()).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        doReturn(outputEntity).when(createHiveProcess)
+                .getInputOutputEntity(eq(writeEntity), any(), anyBoolean());
+
+        // Call isDdlOperation(outputEntity) to ensure it's false
+        assertFalse((boolean) isDdlOperationMethod.invoke(createHiveProcess, 
outputEntity));
+
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+
+        when(context.isMetastoreHook()).thenReturn(false);
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        // Mock methods needed for process execution
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        // Create mock lineage info with dependencies
+        LineageInfo lineageInfo = mock(LineageInfo.class);
+        DependencyKey depKey = mock(DependencyKey.class);
+        Dependency dependency = mock(Dependency.class);
+        BaseColumnInfo baseColInfo = mock(BaseColumnInfo.class);
+
+        Map<DependencyKey, Dependency> lineageMap = new HashMap<>();
+        lineageMap.put(depKey, dependency);
+        when(lineageInfo.entrySet()).thenReturn(lineageMap.entrySet());
+
+        
doReturn("default.output_table.col1@cluster").when(createHiveProcess).getQualifiedName(depKey);
+        
doReturn("default.input_table.non_existent_col@cluster").when(createHiveProcess).getQualifiedName(baseColInfo);
+
+        // Call getBaseCols(dependency) via reflection (instead of mocking)
+        @SuppressWarnings("unchecked")
+        Collection<BaseColumnInfo> baseCols = (Collection<BaseColumnInfo>)
+                getBaseColsMethod.invoke(createHiveProcess, dependency);
+
+        // We still need a predictable baseCols here for the test scenario:
+        // Force baseCols to return the mocked BaseColumnInfo even though real 
method runs
+        baseCols = Arrays.asList(baseColInfo);
+
+        // Mock context.getEntity for columns
+        AtlasEntity outputColumn = new AtlasEntity("hive_column");
+        outputColumn.setAttribute("name", "col1");
+        outputColumn.setAttribute("qualifiedName", 
"default.output_table.col1@cluster");
+
+        
when(context.getEntity("default.output_table.col1@cluster")).thenReturn(outputColumn);
+        
when(context.getEntity("default.input_table.non_existent_col@cluster")).thenReturn(null);
+
+        // Mock skip column lineage settings
+        when(context.getSkipHiveColumnLineageHive20633()).thenReturn(false);
+
+        doReturn(lineageInfo).when(createHiveProcess).getLineageInfo();
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        // ---- Execute & Verify ----
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        assertNotNull("Entities should not be null", entities);
+        boolean hasColumnLineage = entities.getEntities().stream()
+                .anyMatch(entity -> 
entity.getTypeName().contains("column_lineage"));
+        assertFalse("Should not contain column lineage entities due to empty 
input columns", hasColumnLineage);
+    }
+
+
+    // ========== INTEGRATION TESTS ==========
+
+    @Test
+    public void testFullWorkflow_SimpleProcess() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // --- Reflection for private methods ---
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+
+        Method isDdlOperationMethod = 
CreateHiveProcess.class.getDeclaredMethod(
+                "isDdlOperation", AtlasEntity.class
+        );
+        isDdlOperationMethod.setAccessible(true);
+
+        Method processColumnLineageMethod = 
CreateHiveProcess.class.getDeclaredMethod(
+                "processColumnLineage", AtlasEntity.class, 
AtlasEntitiesWithExtInfo.class
+        );
+        processColumnLineageMethod.setAccessible(true);
+
+        // --- Mock inputs and outputs ---
+        Set<ReadEntity> inputs = Collections.singleton(readEntity);
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(inputs).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock getQualifiedName
+        
doReturn("default.input_table@cluster").when(createHiveProcess).getQualifiedName(readEntity);
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        // Mock getInputOutputEntity
+        AtlasEntity inputEntity = new AtlasEntity("hive_table");
+        inputEntity.setAttribute("qualifiedName", 
"default.input_table@cluster");
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        outputEntity.setAttribute("qualifiedName", 
"default.output_table@cluster");
+        
doReturn(inputEntity).when(createHiveProcess).getInputOutputEntity(eq(readEntity),
 any(), anyBoolean());
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // Use reflection to assert isDdlOperation == false
+        boolean ddl = (boolean) isDdlOperationMethod.invoke(createHiveProcess, 
outputEntity);
+        AssertJUnit.assertFalse("isDdlOperation should be false", ddl);
+
+        // Mock entity types
+        
when(readEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+
+        // Mock isDirect
+        when(readEntity.isDirect()).thenReturn(true);
+
+        // Mock context methods
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        // Mock process creation
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        // Mock methods needed by getHiveProcessExecutionEntity
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        // Instead of mocking processColumnLineage, just call it via reflection
+        AtlasEntitiesWithExtInfo entities = new AtlasEntitiesWithExtInfo();
+        processColumnLineageMethod.invoke(createHiveProcess, processEntity, 
entities);
+
+        // Also test skipProcess via reflection
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        AssertJUnit.assertFalse("skipProcess should be false", skip);
+
+        // Execute workflow
+        List<HookNotification> notifications = 
createHiveProcess.getNotificationMessages();
+
+        // Verify results
+        AssertJUnit.assertNotNull("Notifications should not be null", 
notifications);
+        AssertJUnit.assertEquals("Should have one notification", 1, 
notifications.size());
+        assertTrue("Should be EntityCreateRequestV2",
+                notifications.get(0) instanceof EntityCreateRequestV2);
+
+        EntityCreateRequestV2 createRequest = (EntityCreateRequestV2) 
notifications.get(0);
+        AssertJUnit.assertEquals("User should be test_user", "test_user", 
createRequest.getUser());
+        AssertJUnit.assertNotNull("Entities should not be null", 
createRequest.getEntities());
+        assertTrue("Should contain entities",
+                createRequest.getEntities().getEntities().size() > 0);
+    }
+
+
+
+    // ========== ADDITIONAL COVERAGE TESTS ==========
+
+    @Test
+    public void testGetEntities_WithNonDirectInput() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // --- Reflection access to private methods ---
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+
+        Method isDdlOperationMethod = 
CreateHiveProcess.class.getDeclaredMethod(
+                "isDdlOperation", AtlasEntity.class
+        );
+        isDdlOperationMethod.setAccessible(true);
+
+        Method processColumnLineageMethod = 
CreateHiveProcess.class.getDeclaredMethod(
+                "processColumnLineage", AtlasEntity.class, 
AtlasEntitiesWithExtInfo.class
+        );
+        processColumnLineageMethod.setAccessible(true);
+
+        // --- Mock inputs and outputs ---
+        Set<ReadEntity> inputs = Collections.singleton(readEntity);
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(inputs).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock getQualifiedName
+        
doReturn("default.input_table@cluster").when(createHiveProcess).getQualifiedName(readEntity);
+        
doReturn("default.output_table@cluster").when(createHiveProcess).getQualifiedName(writeEntity);
+
+        // Mock getInputOutputEntity
+        AtlasEntity inputEntity = new AtlasEntity("hive_table");
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(inputEntity).when(createHiveProcess).getInputOutputEntity(eq(readEntity),
 any(), anyBoolean());
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // --- Directly verify private methods before execution ---
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        AssertJUnit.assertFalse("skipProcess should return false", skip);
+
+        boolean ddl = (boolean) isDdlOperationMethod.invoke(createHiveProcess, 
outputEntity);
+        AssertJUnit.assertFalse("isDdlOperation should return false", ddl);
+
+        // Mock entity types to avoid switch NPE
+        
when(readEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+
+        // isDirect = false means input should be excluded
+        when(readEntity.isDirect()).thenReturn(false);
+
+        // Mock context methods
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        // Mock process creation
+        AtlasEntity processEntity = new AtlasEntity("hive_process");
+        processEntity.setAttribute("qualifiedName", "test_process@cluster");
+        
doReturn(processEntity).when(createHiveProcess).getHiveProcessEntity(anyList(), 
anyList());
+
+        AtlasEntity processExecutionEntity = new 
AtlasEntity("hive_process_execution");
+        
doReturn(processExecutionEntity).when(createHiveProcess).getHiveProcessExecutionEntity(processEntity);
+
+        // Mock other helper methods for process creation
+        doReturn("test_user").when(createHiveProcess).getUserName();
+        doReturn("query_123").when(createHiveProcess).getQueryId();
+        doReturn("SELECT * FROM 
table").when(createHiveProcess).getQueryString();
+        doReturn(System.currentTimeMillis() - 
5000).when(createHiveProcess).getQueryStartTime();
+        when(context.getHostName()).thenReturn("test_host");
+
+        // Instead of mocking processColumnLineage, just call it via reflection
+        AtlasEntitiesWithExtInfo entitiesForReflection = new 
AtlasEntitiesWithExtInfo();
+        processColumnLineageMethod.invoke(createHiveProcess, processEntity, 
entitiesForReflection);
+
+        // We still mock addProcessedEntities (not private)
+        doNothing().when(createHiveProcess).addProcessedEntities(any());
+
+        // Execute
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        AssertJUnit.assertNotNull("Entities should not be null", entities);
+        // Should still create process with output but no inputs due to 
isDirect=false
+    }
+
+
+    @Test
+    public void testGetEntities_NullQualifiedName() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // --- Reflection for skipProcess() ---
+        Method skipProcessMethod = 
CreateHiveProcess.class.getDeclaredMethod("skipProcess");
+        skipProcessMethod.setAccessible(true);
+
+        // Call skipProcess() and assert expected
+        boolean skip = (boolean) skipProcessMethod.invoke(createHiveProcess);
+        AssertJUnit.assertTrue("skipProcess should return true for empty 
inputs/outputs", skip);
+
+        // --- Mock inputs and outputs ---
+        Set<ReadEntity> inputs = Collections.singleton(readEntity);
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(inputs).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Mock getQualifiedName to return null (both input and output)
+        doReturn(null).when(createHiveProcess).getQualifiedName(readEntity);
+        doReturn(null).when(createHiveProcess).getQualifiedName(writeEntity);
+
+        // Mock context methods
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        // Execute
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        // Assert outcome
+        assertNull("Entities should be null when qualified names are null", 
entities);
+    }
+
+ /*     @Test
+    public void testGetEntities_SelfLineageScenario() throws Exception {
+        CreateHiveProcess createHiveProcess = spy(new 
CreateHiveProcess(context));
+
+        // Mock skipProcess to return false
+        doReturn(false).when(createHiveProcess).skipProcess();
+
+        // Mock inputs and outputs with same qualified name (self lineage)
+        Set<ReadEntity> inputs = Collections.singleton(readEntity);
+        Set<WriteEntity> outputs = Collections.singleton(writeEntity);
+        doReturn(inputs).when(createHiveProcess).getInputs();
+        doReturn(outputs).when(createHiveProcess).getOutputs();
+
+        // Same qualified name for input and output (this triggers the 
self-lineage logic)
+        String sameQualifiedName = "default.same_table@cluster";
+        
doReturn(sameQualifiedName).when(createHiveProcess).getQualifiedName(readEntity);
+        
doReturn(sameQualifiedName).when(createHiveProcess).getQualifiedName(writeEntity);
+
+        // Mock getInputOutputEntity for output - this gets called first
+        AtlasEntity outputEntity = new AtlasEntity("hive_table");
+        
doReturn(outputEntity).when(createHiveProcess).getInputOutputEntity(eq(writeEntity),
 any(), anyBoolean());
+
+        // Mock isDdlOperation to avoid NPE
+        doReturn(false).when(createHiveProcess).isDdlOperation(outputEntity);
+
+        // Mock entity types to avoid switch statement NPE
+        
when(readEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+        
when(writeEntity.getType()).thenReturn(org.apache.hadoop.hive.ql.hooks.Entity.Type.TABLE);
+
+        // Mock isDirect
+        when(readEntity.isDirect()).thenReturn(true);
+
+        // Mock context methods
+        when(context.isSkippedInputEntity()).thenReturn(false);
+        when(context.isSkippedOutputEntity()).thenReturn(false);
+        when(context.isMetastoreHook()).thenReturn(false);
+
+        AtlasEntitiesWithExtInfo entities = createHiveProcess.getEntities();
+
+        // The checkIfOnlySelfLineagePossible method should detect this as 
self-lineage and skip processing
+        // So we should get null result due to skipProcess logic
+        AssertJUnit.assertNull("Entities should be null for self lineage 
scenario", entities);
+    }*/
+

Review Comment:
   Large block of commented-out test code should be removed to improve 
maintainability.
   ```suggestion
   
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to