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
40 changes: 21 additions & 19 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@ jobs:
working-directory: ./backend
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.cargo/env
source "$HOME/.cargo/env"
uv sync --dev

- name: Run backend tests
working-directory: ./backend
env:
PYTHONPATH: ${{ github.workspace }}
run: |
source $HOME/.cargo/env
source "$HOME/.cargo/env"
uv run pytest tests/ --cov=app --cov-report=xml --cov-report=term-missing -v

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
with:
files: ./backend/coverage.xml
flags: backend
Expand All @@ -68,12 +68,14 @@ jobs:
contents: read
env:
CARGO_PROFILE_TEST_DEBUG: 0
CARGO_TARGET_DIR: ${{ runner.temp }}/executor-target

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Configure executor target directory
run: echo "CARGO_TARGET_DIR=$RUNNER_TEMP/executor-target" >> "$GITHUB_ENV"

- name: Free executor runner disk space
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
Expand Down Expand Up @@ -134,7 +136,7 @@ jobs:
working-directory: ./executor_manager
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.cargo/env
source "$HOME/.cargo/env"
uv sync --dev

- name: Run executor manager tests
Expand All @@ -145,11 +147,11 @@ jobs:
PYTHONUNBUFFERED: "1"
PYTHONFAULTHANDLER: "1"
run: |
source $HOME/.cargo/env
source "$HOME/.cargo/env"
uv run pytest tests/ --cov=executors --cov-report=xml --cov-report=term-missing -v -s

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
with:
files: ./executor_manager/coverage.xml
flags: executor-manager
Expand Down Expand Up @@ -180,7 +182,7 @@ jobs:
working-directory: ./shared
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.cargo/env
source "$HOME/.cargo/env"
uv sync --dev

- name: Run shared tests
Expand All @@ -190,24 +192,24 @@ jobs:
PYTHONUNBUFFERED: "1"
PYTHONFAULTHANDLER: "1"
run: |
source $HOME/.cargo/env
source "$HOME/.cargo/env"
# Run pytest and capture exit code, ignoring thread cleanup errors
set +e
uv run pytest tests/ --cov=utils --cov-config=.coveragerc --cov-report=xml --cov-report=term-missing -v -p no:cacheprovider 2>&1
PYTEST_EXIT=$?
set -e
# Exit code 0 = success, others indicate test failures
# Thread cleanup errors cause exit 134 but tests pass, so check coverage.xml exists
if [ $PYTEST_EXIT -eq 0 ] || ([ $PYTEST_EXIT -eq 134 ] && [ -f coverage.xml ]); then
if [ "$PYTEST_EXIT" -eq 0 ] || { [ "$PYTEST_EXIT" -eq 134 ] && [ -f coverage.xml ]; }; then
echo "Tests completed successfully"
exit 0
else
echo "Tests failed with exit code $PYTEST_EXIT"
exit $PYTEST_EXIT
exit "$PYTEST_EXIT"
fi

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
with:
files: ./shared/coverage.xml
flags: shared
Expand Down Expand Up @@ -238,7 +240,7 @@ jobs:
working-directory: ./knowledge_engine
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.cargo/env
source "$HOME/.cargo/env"
uv sync --dev

- name: Run knowledge engine tests
Expand All @@ -248,11 +250,11 @@ jobs:
PYTHONUNBUFFERED: "1"
PYTHONFAULTHANDLER: "1"
run: |
source $HOME/.cargo/env
source "$HOME/.cargo/env"
uv run pytest tests/ --cov=knowledge_engine --cov-report=xml --cov-report=term-missing -v

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
with:
files: ./knowledge_engine/coverage.xml
flags: knowledge-engine
Expand Down Expand Up @@ -298,7 +300,7 @@ jobs:
run: pnpm --filter wecode-ai-assistant run test --coverage --passWithNoTests

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
with:
files: ./frontend/coverage/coverage-final.json
flags: frontend
Expand Down Expand Up @@ -331,7 +333,7 @@ jobs:
run: pnpm --filter wework exec vitest run --coverage --passWithNoTests

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
with:
files: ./wework/coverage/coverage-final.json
flags: wework
Expand Down Expand Up @@ -371,7 +373,7 @@ jobs:
pytest tests/ --ignore=tests/test_integration.py --cov=wegent --cov-report=xml --cov-report=term-missing -v

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
with:
files: ./wegent-cli/coverage.xml
flags: wegent-cli
Expand Down Expand Up @@ -427,7 +429,7 @@ jobs:
working-directory: ./backend
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.cargo/env
source "$HOME/.cargo/env"
uv sync

- name: Install shared module
Expand Down
48 changes: 19 additions & 29 deletions docs/en/developer-guide/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,35 +232,25 @@ The `.github/workflows/test.yml` workflow runs automatically on:

### Workflow Jobs

1. **test-backend**: Python backend tests
- Matrix strategy: Python 3.10 and 3.11
- Coverage reports uploaded to Codecov
- Dependency caching for faster builds

2. **test-executor**: Executor engine tests
- Python 3.10
- Coverage for agents module
- Tests AI agent factory and base classes

3. **test-executor-manager**: Task manager tests
- Python 3.10
- Coverage for executors module
- Tests Docker executor and dispatcher

4. **test-shared**: Shared utilities tests
- Python 3.10
- Coverage for utils module
- Tests cryptography and data masking

5. **test-frontend**: Frontend tests (Node.js 20.x)
- Jest with React Testing Library
- Runs with `--passWithNoTests` flag
- Coverage uploaded to Codecov

6. **test-summary**: Aggregate results
- Depends on all test jobs
- Fails if any test job fails
- Always runs regardless of individual job status
Regular PR checks must cover module tests; E2E jobs do not replace them:

1. **test-backend** runs the Backend suite with Python 3.11 and `uv run pytest`.
2. **test-executor** runs `cargo fmt --check`, `cargo test --all-features`, and
Clippy for the Rust Executor. It places `CARGO_TARGET_DIR` under the runner's
temporary directory to avoid shared build contamination and workspace disk pressure.
3. **test-executor-manager**, **test-shared**, and **test-knowledge-engine** run
their Python suites with `uv run pytest`.
4. **test-frontend** runs the Chat Core and Frontend unit tests.
5. **test-wework** runs the Wework unit suite with Vitest and generates coverage.
6. **test-wegent-cli** and **test-wegent-cli-integration** run CLI unit tests and
integration tests backed by MySQL, Redis, and a real Backend, respectively.
7. **test-summary** always runs and depends on every job above. It must fail when
any module test job fails.

E2E coverage lives in dedicated workflows: `.github/workflows/e2e-tests.yml`
covers product end-to-end flows, while `.github/workflows/wework-e2e.yml` covers
Wework flows. They add cross-module verification and do not replace the module
tests in `.github/workflows/test.yml`.

### Coverage Reports

Expand Down
46 changes: 17 additions & 29 deletions docs/zh/developer-guide/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,35 +232,23 @@ frontend/src/__tests__/

### 工作流任务

1. **test-backend**:Python 后端测试
- 矩阵策略:Python 3.10 和 3.11
- 覆盖率报告上传至 Codecov
- 依赖缓存以加快构建速度

2. **test-executor**:执行器引擎测试
- Python 3.10
- agents 模块的覆盖率
- 测试 AI agent 工厂和基础类

3. **test-executor-manager**:任务管理器测试
- Python 3.10
- executors 模块的覆盖率
- 测试 Docker 执行器和调度器

4. **test-shared**:共享工具库测试
- Python 3.10
- utils 模块的覆盖率
- 测试加密和数据脱敏

5. **test-frontend**:前端测试(Node.js 20.x)
- 使用 React Testing Library 的 Jest
- 使用 `--passWithNoTests` 标志运行
- 覆盖率上传至 Codecov

6. **test-summary**:汇总结果
- 依赖于所有测试任务
- 如果任何测试任务失败则失败
- 始终运行,无论单个任务的状态如何
常规 PR 测试必须覆盖各模块测试,不能用 E2E 任务代替:

1. **test-backend**:使用 Python 3.11 和 `uv run pytest` 运行 Backend 测试。
2. **test-executor**:运行 Rust Executor 的 `cargo fmt --check`、
`cargo test --all-features` 和 Clippy。该任务把 `CARGO_TARGET_DIR` 设置到 runner
临时目录,避免共享构建目录污染或占满工作区。
3. **test-executor-manager**、**test-shared** 和 **test-knowledge-engine**:使用
`uv run pytest` 运行对应 Python 模块测试。
4. **test-frontend**:运行 Chat Core 与 Frontend 单元测试。
5. **test-wework**:使用 Vitest 运行 Wework 单元测试并生成覆盖率。
6. **test-wegent-cli** 与 **test-wegent-cli-integration**:分别运行 CLI 单元测试,
以及依赖 MySQL、Redis 和真实 Backend 的集成测试。
7. **test-summary**:始终运行并依赖以上所有任务;任何模块测试失败时,汇总任务必须失败。

E2E 使用独立 workflow:`.github/workflows/e2e-tests.yml` 覆盖产品端到端流程,
`.github/workflows/wework-e2e.yml` 覆盖 Wework 流程。它们提供额外的跨模块验证,
不会替代 `.github/workflows/test.yml` 中的模块测试。

### 覆盖率报告

Expand Down
8 changes: 6 additions & 2 deletions executor/src/bin/wegent-executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async fn main() {
fn install_termination_signal_diagnostics() {
unsafe {
let mut action: libc::sigaction = std::mem::zeroed();
action.sa_sigaction = termination_signal_handler as usize;
action.sa_sigaction = termination_signal_handler as *const () as usize;
action.sa_flags = libc::SA_SIGINFO;
libc::sigemptyset(&mut action.sa_mask);
libc::sigaction(libc::SIGTERM, &action, std::ptr::null_mut());
Expand All @@ -46,7 +46,11 @@ extern "C" fn termination_signal_handler(
let process_id = unsafe { libc::getpid() };
let mut line = [0_u8; 128];
let mut length = 0;
append_signal_text(&mut line, &mut length, b"wegent-executor received SIGTERM sender_pid=");
append_signal_text(
&mut line,
&mut length,
b"wegent-executor received SIGTERM sender_pid=",
);
append_signal_number(&mut line, &mut length, sender_pid);
append_signal_text(&mut line, &mut length, b" process_id=");
append_signal_number(&mut line, &mut length, process_id);
Expand Down
2 changes: 1 addition & 1 deletion executor/src/browser_mcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ mod tests {
#[tokio::test]
async fn exposes_expected_browser_tools() {
let request = json!({ "jsonrpc": "2.0", "id": 1, "method": "tools/list" });
let response = handle_request(&reqwest::Client::new(), &request)
let response = handle_request(&reqwest::Client::new(), &request, 1, Instant::now())
.await
.unwrap();
let names = response["result"]["tools"]
Expand Down
Loading
Loading