aurangzaib048 commented on code in PR #64770:
URL: https://github.com/apache/airflow/pull/64770#discussion_r3067088726


##########
providers/amazon/src/airflow/providers/amazon/aws/triggers/emr.py:
##########
@@ -190,9 +197,133 @@ def __init__(
             waiter_max_attempts=waiter_max_attempts,
             aws_conn_id=aws_conn_id,
         )
+        self.virtual_cluster_id = virtual_cluster_id
+        self.job_id = job_id
+        self.cancel_on_kill = cancel_on_kill
 
     def hook(self) -> AwsGenericHook:
-        return EmrContainerHook(aws_conn_id=self.aws_conn_id)
+        return EmrContainerHook(aws_conn_id=self.aws_conn_id, 
virtual_cluster_id=self.virtual_cluster_id)
+
+    if not AIRFLOW_V_3_0_PLUS:
+
+        @provide_session
+        def get_task_instance(self, session: Session) -> TaskInstance:
+            """Get the task instance for the current trigger (Airflow 2.x 
compatibility)."""
+            from sqlalchemy import select
+
+            query = select(TaskInstance).where(

Review Comment:
   Fixed. Moved `from sqlalchemy import select` to the module-level `if not 
AIRFLOW_V_3_0_PLUS:` block alongside the other conditional imports.



##########
providers/amazon/src/airflow/providers/amazon/aws/triggers/emr.py:
##########
@@ -190,9 +197,133 @@ def __init__(
             waiter_max_attempts=waiter_max_attempts,
             aws_conn_id=aws_conn_id,
         )
+        self.virtual_cluster_id = virtual_cluster_id
+        self.job_id = job_id
+        self.cancel_on_kill = cancel_on_kill
 
     def hook(self) -> AwsGenericHook:
-        return EmrContainerHook(aws_conn_id=self.aws_conn_id)
+        return EmrContainerHook(aws_conn_id=self.aws_conn_id, 
virtual_cluster_id=self.virtual_cluster_id)
+
+    if not AIRFLOW_V_3_0_PLUS:
+
+        @provide_session
+        def get_task_instance(self, session: Session) -> TaskInstance:
+            """Get the task instance for the current trigger (Airflow 2.x 
compatibility)."""
+            from sqlalchemy import select
+
+            query = select(TaskInstance).where(
+                TaskInstance.dag_id == self.task_instance.dag_id,
+                TaskInstance.task_id == self.task_instance.task_id,
+                TaskInstance.run_id == self.task_instance.run_id,
+                TaskInstance.map_index == self.task_instance.map_index,
+            )
+            task_instance = session.scalars(query).one_or_none()
+            if task_instance is None:
+                raise ValueError(
+                    f"TaskInstance with dag_id: {self.task_instance.dag_id}, "
+                    f"task_id: {self.task_instance.task_id}, "
+                    f"run_id: {self.task_instance.run_id} and "
+                    f"map_index: {self.task_instance.map_index} is not found"
+                )
+            return task_instance
+
+    async def get_task_state(self):
+        """Get the current state of the task instance (Airflow 3.x)."""
+        from airflow.sdk.execution_time.task_runner import RuntimeTaskInstance
+
+        task_states_response = await 
sync_to_async(RuntimeTaskInstance.get_task_states)(
+            dag_id=self.task_instance.dag_id,

Review Comment:
   This import is intentionally lazy — `RuntimeTaskInstance` is a heavy Task 
SDK import that should not be loaded at module level in the triggerer process 
(worker isolation boundary). Same pattern used in the reference 
`EmrServerlessStartJobTrigger`.



##########
providers/amazon/tests/unit/amazon/aws/triggers/test_emr.py:
##########
@@ -152,8 +154,179 @@ def test_serialization_default_max_attempts(self):
             "waiter_delay": 30,
             "waiter_max_attempts": sys.maxsize,
             "aws_conn_id": "aws_default",
+            "cancel_on_kill": True,
         }
 
+    def test_serialization_includes_cancel_on_kill(self):
+        """Test that cancel_on_kill=True is correctly serialized."""
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+        classpath, kwargs = trigger.serialize()
+        assert classpath == 
"airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger"
+        assert kwargs["cancel_on_kill"] is True
+
+    def test_serialization_cancel_on_kill_false(self):
+        """Test that cancel_on_kill=False is correctly serialized."""
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=False,
+        )
+        classpath, kwargs = trigger.serialize()
+        assert classpath == 
"airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger"
+        assert kwargs["cancel_on_kill"] is False
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_cancels_job_on_killed_when_safe(self, 
mock_safe_to_cancel, mock_async_wait):
+        """
+        Test that EmrContainerTrigger cancels the job when task is killed
+        and safe_to_cancel returns True.
+        """
+        mock_safe_to_cancel.return_value = True
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+        mock_hook.stop_query.return_value = {"ResponseMetadata": 
{"HTTPStatusCode": 200}}
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()

Review Comment:
   Fixed. All `MagicMock()` instances now use `spec=EmrContainerHook` to catch 
attribute typos.



##########
providers/amazon/tests/unit/amazon/aws/triggers/test_emr.py:
##########
@@ -152,8 +154,179 @@ def test_serialization_default_max_attempts(self):
             "waiter_delay": 30,
             "waiter_max_attempts": sys.maxsize,
             "aws_conn_id": "aws_default",
+            "cancel_on_kill": True,
         }
 
+    def test_serialization_includes_cancel_on_kill(self):
+        """Test that cancel_on_kill=True is correctly serialized."""
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+        classpath, kwargs = trigger.serialize()
+        assert classpath == 
"airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger"
+        assert kwargs["cancel_on_kill"] is True
+
+    def test_serialization_cancel_on_kill_false(self):
+        """Test that cancel_on_kill=False is correctly serialized."""
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=False,
+        )
+        classpath, kwargs = trigger.serialize()
+        assert classpath == 
"airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger"
+        assert kwargs["cancel_on_kill"] is False
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_cancels_job_on_killed_when_safe(self, 
mock_safe_to_cancel, mock_async_wait):
+        """
+        Test that EmrContainerTrigger cancels the job when task is killed
+        and safe_to_cancel returns True.
+        """
+        mock_safe_to_cancel.return_value = True
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+        mock_hook.stop_query.return_value = {"ResponseMetadata": 
{"HTTPStatusCode": 200}}
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+
+        with mock.patch.object(trigger, "hook", return_value=mock_hook):
+            with pytest.raises(asyncio.CancelledError):
+                async for _ in trigger.run():
+                    pass
+
+        mock_hook.stop_query.assert_called_once_with("test_job")
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_no_cancel_when_unsafe(self, mock_safe_to_cancel, 
mock_async_wait):
+        """
+        Test that EmrContainerTrigger does NOT cancel the job when
+        safe_to_cancel returns False (e.g., triggerer shutdown).
+        """
+        mock_safe_to_cancel.return_value = False
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+

Review Comment:
   Fixed in the same commit — all four async test methods now use specced mocks.



##########
providers/amazon/tests/unit/amazon/aws/triggers/test_emr.py:
##########
@@ -152,8 +154,179 @@ def test_serialization_default_max_attempts(self):
             "waiter_delay": 30,
             "waiter_max_attempts": sys.maxsize,
             "aws_conn_id": "aws_default",
+            "cancel_on_kill": True,
         }
 
+    def test_serialization_includes_cancel_on_kill(self):
+        """Test that cancel_on_kill=True is correctly serialized."""
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+        classpath, kwargs = trigger.serialize()
+        assert classpath == 
"airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger"
+        assert kwargs["cancel_on_kill"] is True
+
+    def test_serialization_cancel_on_kill_false(self):
+        """Test that cancel_on_kill=False is correctly serialized."""
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=False,
+        )
+        classpath, kwargs = trigger.serialize()
+        assert classpath == 
"airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger"
+        assert kwargs["cancel_on_kill"] is False
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_cancels_job_on_killed_when_safe(self, 
mock_safe_to_cancel, mock_async_wait):
+        """
+        Test that EmrContainerTrigger cancels the job when task is killed
+        and safe_to_cancel returns True.
+        """
+        mock_safe_to_cancel.return_value = True
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+        mock_hook.stop_query.return_value = {"ResponseMetadata": 
{"HTTPStatusCode": 200}}
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+
+        with mock.patch.object(trigger, "hook", return_value=mock_hook):
+            with pytest.raises(asyncio.CancelledError):
+                async for _ in trigger.run():
+                    pass
+
+        mock_hook.stop_query.assert_called_once_with("test_job")
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_no_cancel_when_unsafe(self, mock_safe_to_cancel, 
mock_async_wait):
+        """
+        Test that EmrContainerTrigger does NOT cancel the job when
+        safe_to_cancel returns False (e.g., triggerer shutdown).
+        """
+        mock_safe_to_cancel.return_value = False
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+
+        with mock.patch.object(trigger, "hook", return_value=mock_hook):
+            with pytest.raises(asyncio.CancelledError):
+                async for _ in trigger.run():
+                    pass
+
+        mock_hook.stop_query.assert_not_called()
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_no_cancel_when_disabled(self, mock_safe_to_cancel, 
mock_async_wait):
+        """
+        Test that EmrContainerTrigger does NOT cancel the job when
+        cancel_on_kill=False.
+        """
+        mock_safe_to_cancel.return_value = True
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=False,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+

Review Comment:
   Fixed — same change applied across all tests.



##########
providers/amazon/tests/unit/amazon/aws/triggers/test_emr.py:
##########
@@ -152,8 +154,179 @@ def test_serialization_default_max_attempts(self):
             "waiter_delay": 30,
             "waiter_max_attempts": sys.maxsize,
             "aws_conn_id": "aws_default",
+            "cancel_on_kill": True,
         }
 
+    def test_serialization_includes_cancel_on_kill(self):
+        """Test that cancel_on_kill=True is correctly serialized."""
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+        classpath, kwargs = trigger.serialize()
+        assert classpath == 
"airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger"
+        assert kwargs["cancel_on_kill"] is True
+
+    def test_serialization_cancel_on_kill_false(self):
+        """Test that cancel_on_kill=False is correctly serialized."""
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=False,
+        )
+        classpath, kwargs = trigger.serialize()
+        assert classpath == 
"airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger"
+        assert kwargs["cancel_on_kill"] is False
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_cancels_job_on_killed_when_safe(self, 
mock_safe_to_cancel, mock_async_wait):
+        """
+        Test that EmrContainerTrigger cancels the job when task is killed
+        and safe_to_cancel returns True.
+        """
+        mock_safe_to_cancel.return_value = True
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+        mock_hook.stop_query.return_value = {"ResponseMetadata": 
{"HTTPStatusCode": 200}}
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+
+        with mock.patch.object(trigger, "hook", return_value=mock_hook):
+            with pytest.raises(asyncio.CancelledError):
+                async for _ in trigger.run():
+                    pass
+
+        mock_hook.stop_query.assert_called_once_with("test_job")
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_no_cancel_when_unsafe(self, mock_safe_to_cancel, 
mock_async_wait):
+        """
+        Test that EmrContainerTrigger does NOT cancel the job when
+        safe_to_cancel returns False (e.g., triggerer shutdown).
+        """
+        mock_safe_to_cancel.return_value = False
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=True,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+
+        with mock.patch.object(trigger, "hook", return_value=mock_hook):
+            with pytest.raises(asyncio.CancelledError):
+                async for _ in trigger.run():
+                    pass
+
+        mock_hook.stop_query.assert_not_called()
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    
@mock.patch("airflow.providers.amazon.aws.triggers.emr.EmrContainerTrigger.safe_to_cancel")
+    async def test_run_no_cancel_when_disabled(self, mock_safe_to_cancel, 
mock_async_wait):
+        """
+        Test that EmrContainerTrigger does NOT cancel the job when
+        cancel_on_kill=False.
+        """
+        mock_safe_to_cancel.return_value = True
+        mock_async_wait.side_effect = asyncio.CancelledError()
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+            cancel_on_kill=False,
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+
+        with mock.patch.object(trigger, "hook", return_value=mock_hook):
+            with pytest.raises(asyncio.CancelledError):
+                async for _ in trigger.run():
+                    pass
+
+        mock_hook.stop_query.assert_not_called()
+
+    @pytest.mark.asyncio
+    @mock.patch("airflow.providers.amazon.aws.triggers.emr.async_wait")
+    async def test_run_yields_error_on_airflow_exception(self, 
mock_async_wait):
+        """Test that an AirflowException yields an error TriggerEvent."""
+        mock_async_wait.side_effect = AirflowException("Something went wrong")
+
+        trigger = EmrContainerTrigger(
+            virtual_cluster_id="test_cluster",
+            job_id="test_job",
+            waiter_delay=30,
+            waiter_max_attempts=60,
+            aws_conn_id="aws_default",
+        )
+
+        mock_hook = mock.MagicMock()
+        mock_hook.get_waiter.return_value = mock.MagicMock()
+
+        mock_client = mock.MagicMock()
+        mock_async_cm = mock.MagicMock()
+        mock_async_cm.__aenter__ = mock.AsyncMock(return_value=mock_client)
+        mock_async_cm.__aexit__ = mock.AsyncMock(return_value=None)
+        mock_hook.get_async_conn = mock.AsyncMock(return_value=mock_async_cm)
+

Review Comment:
   Fixed — all test mocks now specced consistently.



-- 
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