You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/07/30 01:07:09 UTC
(texera) branch main updated (bf25dd2d47 -> ff82157989)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
from bf25dd2d47 fix(user): Add user email as part of registration in authentication (#6402)
new 6cb4a0487e chore(ci): exclude release/v1.1.0-incubating from branch protection, drop stale xuang7 bypass (#7086)
new ff82157989 test(pyamber): add unit tests for stoppable_queue_blocking_thread (#6669)
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.asf.yaml | 37 +++--
.../test_stoppable_queue_blocking_thread.py | 159 +++++++++++++++++++++
2 files changed, 175 insertions(+), 21 deletions(-)
create mode 100644 amber/src/test/python/core/util/stoppable/test_stoppable_queue_blocking_thread.py
(texera) 01/02: chore(ci): exclude release/v1.1.0-incubating from branch protection, drop stale xuang7 bypass (#7086)
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
commit 6cb4a0487e2f7e8483611dd9809d154ec450d3fd
Author: Yicong Huang <17...@users.noreply.github.com>
AuthorDate: Wed Jul 29 20:50:06 2026 -0400
chore(ci): exclude release/v1.1.0-incubating from branch protection, drop stale xuang7 bypass (#7086)
### What changes were proposed in this PR?
Rework the `Default Branch Protection` ruleset in `.asf.yaml`:
1. **Exclude one release branch for maintenance.** Add
`release/v1.1.0-incubating` to the ruleset's `branches.excludes`, so
`deletion` / `non_fast_forward` are no longer enforced on that branch —
enabling manual release-branch maintenance. All other `release/*` and
`rel/*` branches and the default branch stay protected (exclude wins
over include only for the listed ref). Remove the exclude entry to
restore protection.
2. **Drop the stale `xuang7` bypass.** Remove the `xuang7` bypass actor,
granted as the v1.2 release manager and no longer used.
3. **Use the default notation for the Infra bypass.** Express the
retained ASF Infra bypass via the asfyaml convenience syntax
(`bypass_teams: [root]`) instead of a raw numeric `actor_id`. asfyaml
rejects mixing convenience keys into a raw payload, so the whole ruleset
moves to convenience form; the resulting GitHub ruleset is unchanged
apart from the exclude.
> **Temporary:** item 1 is meant to be reverted once the release-branch
work is done.
### Any related issues, documentation, discussions?
Fixes #7085.
### How was this PR tested?
Parsed `.asf.yaml` with a YAML loader to confirm valid syntax and the
resulting ruleset: `branches.includes` is `[~DEFAULT_BRANCH, release/*,
rel/*]` and `branches.excludes` is `[release/v1.1.0-incubating]`,
`bypass_teams` is `[root]`. Cross-checked the raw-vs-convenience
handling against the asfyaml source
(`asfyaml/feature/github/rulesets.py`): the convenience form normalizes
to the same GitHub Rulesets API payload as the existing raw `Merge
Queue` ruleset. `.asf.yaml` is not covered by unit tests; ASF Infra
applies it from the default branch.
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Claude Opus 4.8)
Co-authored-by: Claude Opus 4.8 (1M context) <no...@anthropic.com>
---
.asf.yaml | 37 ++++++++++++++++---------------------
1 file changed, 16 insertions(+), 21 deletions(-)
diff --git a/.asf.yaml b/.asf.yaml
index c0f520b666..84436d0347 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -108,27 +108,22 @@ github:
- context: Validate PR title
- name: "Default Branch Protection"
- target: branch
- enforcement: active
- conditions:
- ref_name:
- include:
- - "~DEFAULT_BRANCH"
- - "refs/heads/release/*"
- - "refs/heads/rel/*"
- exclude: []
- bypass_actors:
- # apache/root — ASF Infra team.
- - actor_id: 118420
- actor_type: Team
- bypass_mode: always
- # xuang7 — granted bypass as the v1.2 release manager.
- - actor_id: 162244362
- actor_type: User
- bypass_mode: always
- rules:
- - type: deletion
- - type: non_fast_forward
+ type: branch
+ branches:
+ includes:
+ - "~DEFAULT_BRANCH"
+ - "release/*"
+ - "rel/*"
+ excludes:
+ # TEMPORARY: exclude release/v1.1.0-incubating for manual
+ # release-branch maintenance; remove this entry to restore its
+ # deletion / force-push protection. All other release/* and
+ # rel/* branches stay protected.
+ - "release/v1.1.0-incubating"
+ bypass_teams:
+ - "root" # apache/root — ASF Infra team
+ restrict_deletion: true
+ restrict_force_push: true
notifications:
commits: commits@texera.apache.org
issues: notifications@texera.apache.org
(texera) 02/02: test(pyamber): add unit tests for stoppable_queue_blocking_thread (#6669)
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
commit ff82157989fffae8f28fd5d0de1dd822b298bd1e
Author: Matthew B. <mg...@uci.edu>
AuthorDate: Wed Jul 29 17:52:07 2026 -0700
test(pyamber): add unit tests for stoppable_queue_blocking_thread (#6669)
### What changes were proposed in this PR?
- Add unit tests for StoppableQueueBlockingRunnable.
- Cover stop() enqueuing the RUNNABLE_STOP sentinel and
interruptible_get() raising InterruptRunnable only on that exact
control.
- Cover run() processing entries until interrupted and always calling
post_stop(), including on unexpected errors.
### Any related issues, documentation, discussions?
Closes: #6668
### How was this PR tested?
- Run: `cd amber && python -m pytest
src/test/python/core/util/stoppable/test_stoppable_queue_blocking_thread.py`,
expect all 7 tests passing.
- Test-only change; no production code is modified.
### Was this PR authored or co-authored using generative AI tooling?
Co-authored with Claude Opus 4.8 in compliance with ASF
---------
Signed-off-by: Xinyuan Lin <xi...@uci.edu>
Co-authored-by: Xinyuan Lin <xi...@uci.edu>
Co-authored-by: Copilot Autofix powered by AI <17...@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <no...@anthropic.com>
---
.../test_stoppable_queue_blocking_thread.py | 159 +++++++++++++++++++++
1 file changed, 159 insertions(+)
diff --git a/amber/src/test/python/core/util/stoppable/test_stoppable_queue_blocking_thread.py b/amber/src/test/python/core/util/stoppable/test_stoppable_queue_blocking_thread.py
new file mode 100644
index 0000000000..c6558ca084
--- /dev/null
+++ b/amber/src/test/python/core/util/stoppable/test_stoppable_queue_blocking_thread.py
@@ -0,0 +1,159 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from collections import deque
+
+import pytest
+
+from core.util.customized_queue.queue_base import QueueControl, QueueElement
+from core.util.stoppable.stoppable_queue_blocking_thread import (
+ StoppableQueueBlockingRunnable,
+)
+
+
+class FakeQueue:
+ """An in-memory stand-in for IQueue.
+
+ ``get`` pops entries in FIFO order so ``run`` can be driven to completion
+ without real threads or blocking: once the stop sentinel is popped the
+ loop is interrupted before the queue is ever exhausted.
+ """
+
+ def __init__(self):
+ self.items: deque = deque()
+
+ def put(self, item) -> None:
+ self.items.append(item)
+
+ def get(self):
+ return self.items.popleft()
+
+ def is_empty(self) -> bool:
+ return not self.items
+
+
+class RecordingRunnable(StoppableQueueBlockingRunnable):
+ """Records the lifecycle callbacks so their order can be asserted."""
+
+ def __init__(self, name: str, queue: FakeQueue):
+ super().__init__(name=name, queue=queue)
+ self.events: list = []
+
+ def pre_start(self) -> None:
+ self.events.append(("pre_start",))
+
+ def receive(self, next_entry) -> None:
+ self.events.append(("receive", next_entry))
+
+ def post_stop(self) -> None:
+ self.events.append(("post_stop",))
+
+
+class RaisingRunnable(StoppableQueueBlockingRunnable):
+ """receive() raises an unexpected error to probe the finally: clause."""
+
+ def __init__(self, name: str, queue: FakeQueue):
+ super().__init__(name=name, queue=queue)
+ self.post_stop_called = 0
+
+ def receive(self, next_entry) -> None:
+ raise ValueError("boom")
+
+ def post_stop(self) -> None:
+ self.post_stop_called += 1
+
+
+class TestStop:
+ def test_stop_enqueues_the_runnable_stop_sentinel(self):
+ queue = FakeQueue()
+ runnable = StoppableQueueBlockingRunnable(name="r", queue=queue)
+
+ runnable.stop()
+
+ assert list(queue.items) == [StoppableQueueBlockingRunnable.RUNNABLE_STOP]
+ # The sentinel is exactly the marker control, not merely truthy.
+ assert queue.items[0] is StoppableQueueBlockingRunnable.RUNNABLE_STOP
+
+
+class TestInterruptibleGet:
+ def test_returns_a_normal_entry_unchanged(self):
+ queue = FakeQueue()
+ entry = QueueElement()
+ queue.put(entry)
+ runnable = StoppableQueueBlockingRunnable(name="r", queue=queue)
+
+ assert runnable.interruptible_get() is entry
+
+ def test_raises_interrupt_on_the_stop_sentinel(self):
+ queue = FakeQueue()
+ queue.put(StoppableQueueBlockingRunnable.RUNNABLE_STOP)
+ runnable = StoppableQueueBlockingRunnable(name="r", queue=queue)
+
+ with pytest.raises(StoppableQueueBlockingRunnable.InterruptRunnable):
+ runnable.interruptible_get()
+
+ def test_only_the_exact_sentinel_message_interrupts(self):
+ # A control whose message differs from the marker is a normal entry
+ # and must flow through, so unrelated controls do not stop the loop.
+ queue = FakeQueue()
+ other = QueueControl(msg="something-else")
+ queue.put(other)
+ runnable = StoppableQueueBlockingRunnable(name="r", queue=queue)
+
+ assert runnable.interruptible_get() is other
+
+
+class TestRun:
+ def test_processes_entries_until_interrupted_then_posts_stop(self):
+ queue = FakeQueue()
+ first, second = QueueElement(), QueueElement()
+ queue.put(first)
+ queue.put(second)
+ queue.put(StoppableQueueBlockingRunnable.RUNNABLE_STOP)
+ runnable = RecordingRunnable(name="r", queue=queue)
+
+ runnable.run()
+
+ # pre_start first, both entries received in FIFO order (by identity), post_stop last.
+ assert len(runnable.events) == 4
+ assert runnable.events[0] == ("pre_start",)
+ assert runnable.events[1][0] == "receive" and runnable.events[1][1] is first
+ assert runnable.events[2][0] == "receive" and runnable.events[2][1] is second
+ assert runnable.events[3] == ("post_stop",)
+
+ def test_post_stop_runs_even_when_receive_raises(self):
+ queue = FakeQueue()
+ queue.put(QueueElement())
+ runnable = RaisingRunnable(name="r", queue=queue)
+
+ # An unexpected error is not swallowed as an interruption; it
+ # propagates, but the finally: clause still tears down via post_stop.
+ with pytest.raises(ValueError, match="boom"):
+ runnable.run()
+
+ assert runnable.post_stop_called == 1
+
+ def test_stop_then_run_terminates_immediately(self):
+ # Enqueuing the sentinel via stop() must be enough to end a run with
+ # no entries processed in between.
+ queue = FakeQueue()
+ runnable = RecordingRunnable(name="r", queue=queue)
+ runnable.stop()
+
+ runnable.run()
+
+ assert runnable.events == [("pre_start",), ("post_stop",)]