Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ agent-service:

engine:
# Non-Python, non-integration parts of amber/. Pure Python changes
# under amber/src/main/python/** intentionally fall through to the
# `python` label (which the labeler also matches via **/*.py), so
# they only trigger the python + amber-integration stacks rather
# under amber/src/{main,test}/python/** intentionally fall through to
# the `python` label (which the labeler also matches via **/*.py),
# so they only trigger the python + amber-integration stacks rather
# than the full Scala-only `amber` stack. Integration specs live
# under amber/src/test/integration/** (added to sbt's Test sources
# via amber/build.sbt) and are caught by the `amber-integration`
Expand Down Expand Up @@ -88,6 +88,8 @@ python:
- changed-files:
- any-glob-to-any-file:
- 'amber/src/main/python/**'
- 'amber/src/test/python/**'
- 'amber/pyproject.toml'
- '**/*.py'
- '**/requirements.txt'
- '**/*-requirements.txt'
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ jobs:
PGPASSWORD: postgres
- name: Lint with Ruff
run: |
cd amber/src/main/python && ruff check . && ruff format --check .
cd amber && ruff check src/main/python src/test/python && ruff format --check src/main/python src/test/python
- name: Install dev dependencies
# Test-only deps live in amber/dev-requirements.txt and are
# installed after the LICENSE-binary snapshot above so they never
Expand All @@ -516,13 +516,13 @@ jobs:
if [ -f amber/dev-requirements.txt ]; then uv pip install --system -r amber/dev-requirements.txt; fi
- name: Test with pytest
run: |
cd amber/src/main/python && pytest --cov=. --cov-report=xml -sv
cd amber && pytest --cov=src/main/python --cov-report=xml -sv
- name: Upload python coverage to Codecov
if: matrix.python-version == '3.12' && always()
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5.5.4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./amber/src/main/python/coverage.xml
files: ./amber/coverage.xml
flags: python
fail_ci_if_error: false

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/required-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ jobs:
// amber-integration runs the Scala tests tagged
// @org.apache.texera.amber.tags.IntegrationTest (e2e specs that
// spawn Python UDF workers). The labeler attaches `python` to
// any *.py change (including amber/src/main/python/**), so
// `engine` does not need to fire the python stack itself —
// any *.py change (including amber/src/{main,test}/python/**),
// so `engine` does not need to fire the python stack itself —
// pure-Python amber changes pick up `python` directly. The
// `amber-integration` label catches *IntegrationSpec.scala
// edits so a test-only change does not trigger the full
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ __pycache__/
*$py.class
.ipynb_checkpoints
.pytype/
.coverage
coverage.xml
.pytest_cache/

# Ignoring python generated files
*.model
Expand Down
8 changes: 4 additions & 4 deletions amber/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ Compile / unmanagedSourceDirectories += baseDirectory.value / "src" / "main" / "

// `amber/src/test/integration` holds Scala specs that exercise both
// Scala and Python end-to-end (tagged @org.apache.texera.amber.tags.IntegrationTest).
// Sits next to `src/test/scala` and `src/test/java`; a future `src/test/python`
// can drop in the same way. Adding it to Test/unmanagedSourceDirectories means
// scalafmtCheckAll / scalafixAll --check naturally cover these sources, and
// the AMBER_TEST_FILTER env var below routes which tagged subset runs.
// Sits next to `src/test/scala`, `src/test/java`, and `src/test/python`.
// Adding it to Test/unmanagedSourceDirectories means scalafmtCheckAll /
// scalafixAll --check naturally cover these sources, and the
// AMBER_TEST_FILTER env var below routes which tagged subset runs.
Test / unmanagedSourceDirectories += baseDirectory.value / "src" / "test" / "integration"

// Test-filter switch driven by the AMBER_TEST_FILTER env var so the
Expand Down
17 changes: 16 additions & 1 deletion amber/src/main/python/pyproject.toml → amber/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,19 @@ extend-exclude = ["proto"]
ignore = ["F403", "F405", "E203"]

[tool.ruff.lint.mccabe]
max-complexity = 10
max-complexity = 10

# Layout follows the Maven source-set convention used by Scala
# (`src/main/scala` + `src/test/scala`): production code lives in
# `src/main/python` and tests in `src/test/python`. Pytest is invoked
# from `amber/`, so `pythonpath = ["src/main/python"]` keeps
# `from core.x import y` and `from pytexera.x import y` working.
[tool.pytest.ini_options]
pythonpath = ["src/main/python"]
testpaths = ["src/test/python"]
# `importlib` import mode loads each test module by file path without
# inserting it into a parent package, so `src/test/python` doesn't need
# to mirror `src/main/python`'s __init__.py layout to avoid duplicate
# package names. Required for src-style test layouts per the pytest
# docs (https://docs.pytest.org/en/stable/explanation/goodpractices.html).
addopts = "--import-mode=importlib"
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
from pyarrow import ArrowNotImplementedError, Table
from queue import Queue

from .proxy_client import ProxyClient
from .proxy_server import ProxyServer
from core.proxy.proxy_client import ProxyClient
from core.proxy.proxy_server import ProxyServer


class TestProxyClient:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import pytest
from pyarrow.flight import Action

from .proxy_server import ProxyServer
from core.proxy.proxy_server import ProxyServer


class TestProxyServer:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import datetime
import pytest
import random
import tempfile
import uuid
from concurrent.futures import as_completed
from concurrent.futures.thread import ThreadPoolExecutor
Expand All @@ -35,7 +36,11 @@
PhysicalOpIdentity,
)

# Hardcoded storage config only for test purposes.
# Hardcoded storage config only for test purposes. The iceberg warehouse
# directory must be a writable absolute path; using `tempfile.mkdtemp()`
# avoids depending on pytest's cwd (an earlier `"../../../../../../amber/
# user-resources/..."` value silently relied on CWD = amber/src/main/python
# and broke when the cwd moved up to amber/).
StorageConfig.initialize(
catalog_type="postgres",
postgres_uri_without_scheme="localhost:5432/texera_iceberg_catalog",
Expand All @@ -44,7 +49,7 @@
rest_catalog_uri="http://localhost:8181/catalog/",
rest_catalog_warehouse_name="texera",
table_result_namespace="operator-port-result",
directory_path="../../../../../../amber/user-resources/workflow-results",
directory_path=tempfile.mkdtemp(prefix="texera-iceberg-warehouse-"),
commit_batch_size=4096,
s3_endpoint="http://localhost:9000",
s3_region="us-east-1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def __init__(self):
expression="a",
value_ref="a",
value_str=(
"<core.util.expression_evaluator.test_expression_evaluator."
f"<{A.__module__}."
"TestExpressionEvaluator.test_evaluate_object_expression.<locals>.A"
f" object at {hex(id(a))}>"
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from collections import deque

from pytexera import *
from .count_batch_operator import CountBatchOperator
from pytexera.udf.examples.count_batch_operator import CountBatchOperator


class TestCountBatchOperator:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import pytest

from pytexera import Tuple
from .echo_operator import EchoOperator
from pytexera.udf.examples.echo_operator import EchoOperator


class TestEchoOperator:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

from core.models.table import all_output_to_tuple
from pytexera import Tuple
from .echo_table_operator import EchoTableOperator
from pytexera.udf.examples.echo_table_operator import EchoTableOperator


class TestEchoTableOperator:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import pytest

from pytexera import Tuple
from .generator_operator_binary import GeneratorOperatorBinary
from pytexera.udf.examples.generator_operator_binary import GeneratorOperatorBinary


class TestEchoOperator:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import pytest

from pytexera import Tuple
from .generator_operator_integer import GeneratorOperatorInteger
from pytexera.udf.examples.generator_operator_integer import GeneratorOperatorInteger


class TestEchoOperator:
Expand Down
11 changes: 6 additions & 5 deletions bin/fix-format.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ fi

# --- Key directories ---
FRONTEND_DIR="$TEXERA_HOME/frontend"
AMBER_PY_DIR="$TEXERA_HOME/amber/src/main/python"
AMBER_DIR="$TEXERA_HOME/amber"

[[ -d "$FRONTEND_DIR" ]] || { tx_error "Frontend directory not found: $FRONTEND_DIR"; exit 1; }
[[ -d "$AMBER_PY_DIR" ]] || { tx_error "Amber Python directory not found: $AMBER_PY_DIR"; exit 1; }
[[ -d "$AMBER_DIR/src/main/python" ]] || { tx_error "Amber Python directory not found: $AMBER_DIR/src/main/python"; exit 1; }
[[ -d "$AMBER_DIR/src/test/python" ]] || { tx_error "Amber Python test directory not found: $AMBER_DIR/src/test/python"; exit 1; }

# --- Argument parsing ---
TARGET="${1:-all}"
Expand Down Expand Up @@ -95,14 +96,14 @@ fi

# --- 3) Python formatting ---
if $run_python; then
tx_info "Running ruff in amber/src/main/python..."
tx_info "Running ruff in amber/src/{main,test}/python..."
if ! command -v ruff >/dev/null 2>&1; then
tx_error "ruff not found. Install with: pip install ruff"
exit 1
fi
(
cd "$AMBER_PY_DIR"
ruff format .
cd "$AMBER_DIR"
ruff format src/main/python src/test/python
)
tx_success "Python formatting completed."
fi
Expand Down
Loading