Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
run: |
uv venv .venv
source .venv/bin/activate
uv sync
uv sync --all-extras
uv pip install -e .

- name: Run unit tests with pytest
Expand Down
46 changes: 44 additions & 2 deletions docs/docs/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,47 @@ app = CloudApp(name="veadk-agent", endpoint=ENDPOINT)
cloud_app.invoke(user_id=USER_ID, session_id=SESSION_ID, message=...)
```

- 更新自身代码
- 删除自身
## 更新云应用

### 通过 CloudAgentEngine 更新

当您需要更新已部署的Agent代码时,可以使用`update_function_code`方法:

```python
from veadk.cloud.cloud_agent_engine import CloudAgentEngine

engine = CloudAgentEngine()

# 更新现有应用的代码,保持相同的访问端点
updated_cloud_app = engine.update_function_code(
application_name="my-agent-app", # 现有应用名称
path="/my-agent-project" # 本地项目路径
)

print(f"应用已更新,访问地址:{updated_cloud_app.vefaas_endpoint}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to a comment statement rather than a print statement:

可以使用updated_cloud_app.vefaas_endpoint访问你的项目

```

**注意事项:**
- 更新操作会保持相同的访问端点URL
- 确保项目路径包含`agent.py`文件


## 删除云应用

### 通过 CloudAgentEngine 删除

```python
from veadk.cloud.cloud_agent_engine import CloudAgentEngine

engine = CloudAgentEngine()

# 删除指定的云应用
engine.remove("my-agent-app")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

engine.remove(xxx="xxx")

```

执行时会提示确认:
```
Confirm delete cloud app my-agent-app? (y/N): y
```

输入`y`确认删除,输入其他任何字符或直接回车则取消删除。
125 changes: 125 additions & 0 deletions tests/test_cloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
#
# Licensed 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.

import os
import tempfile
import pytest

from unittest.mock import Mock, patch, AsyncMock

os.environ["VOLCENGINE_ACCESS_KEY"] = "test_access_key"
os.environ["VOLCENGINE_SECRET_KEY"] = "test_secret_key"

from veadk.cloud.cloud_agent_engine import CloudAgentEngine


@pytest.mark.asyncio
async def test_cloud():
app_name = "test-app"
key = "CloudTestIdentifier123"
test_endpoint = "https://test-endpoint.volcengine.com"
test_message = "Hello cloud agent"

# Create temporary directory with required agent.py file for testing
with tempfile.TemporaryDirectory() as temp_dir:
with open(os.path.join(temp_dir, "agent.py"), "w") as f:
f.write(f"# Test agent implementation with {key}")

# 这里不再需要 patch.dict,因为环境变量已经设置
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments should be in English rather than Chinese

# Mock shutil.copy to avoid template file copying issues
with patch("shutil.copy"):
with patch("veadk.cloud.cloud_agent_engine.VeFaaS") as mock_vefaas_class:
# Setup mock VeFaaS service for all operations
mock_vefaas_service = Mock()
mock_vefaas_class.return_value = mock_vefaas_service

# Mock deploy operation
mock_vefaas_service.deploy.return_value = (
test_endpoint,
"app-123",
"func-456",
)

# Mock update operation
mock_vefaas_service._update_function_code.return_value = (
test_endpoint,
"app-123",
"func-456",
)

# Mock remove operation
mock_vefaas_service.find_app_id_by_name.return_value = "app-123"
mock_vefaas_service.delete.return_value = None

# Test CloudAgentEngine creation and deploy functionality
engine = CloudAgentEngine()

# Test deploy operation
cloud_app = engine.deploy(application_name=app_name, path=temp_dir)

# Verify deployment result contains expected values
assert cloud_app.vefaas_application_name == app_name
assert cloud_app.vefaas_endpoint == test_endpoint
assert cloud_app.vefaas_application_id == "app-123"

# Test update_function_code operation
updated_app = engine.update_function_code(
application_name=app_name, path=temp_dir
)

# Verify update result maintains same endpoint
assert updated_app.vefaas_endpoint == test_endpoint

# Test remove operation with mocked user input
with patch("builtins.input", return_value="y"):
engine.remove(app_name)
mock_vefaas_service.find_app_id_by_name.assert_called_with(app_name)
mock_vefaas_service.delete.assert_called_with("app-123")

# Test CloudApp message_send functionality
mock_response = Mock()
mock_message = Mock()
mock_response.root.result = mock_message

with patch.object(cloud_app, "_get_a2a_client") as mock_get_client:
mock_client = AsyncMock()
mock_client.send_message = AsyncMock(return_value=mock_response)
mock_get_client.return_value = mock_client

# Test message sending to cloud agent
result = await cloud_app.message_send(
message=test_message,
session_id="session-123",
user_id="user-456",
)

# Verify message sending result
assert result == mock_message
mock_client.send_message.assert_called_once()

# Test CloudApp delete_self functionality
with patch("builtins.input", return_value="y"):
with patch(
"veadk.cli.services.vefaas.vefaas.VeFaaS"
) as mock_vefaas_in_app:
mock_vefaas_client = Mock()
mock_vefaas_in_app.return_value = mock_vefaas_client
mock_vefaas_client.delete.return_value = None

cloud_app.delete_self()
mock_vefaas_client.delete.assert_called_with("app-123")

# Verify all mocks were called as expected
mock_vefaas_service.deploy.assert_called_once()
mock_vefaas_service._update_function_code.assert_called_once()