Skip to content

Commit 4b85e11

Browse files
committed
test(vefaas): update Unitest of CloudAgentEngine and CloudApp
1 parent 6c8b658 commit 4b85e11

File tree

2 files changed

+175
-2
lines changed

2 files changed

+175
-2
lines changed

docs/docs/deploy.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,47 @@ app = CloudApp(name="veadk-agent", endpoint=ENDPOINT)
117117
cloud_app.invoke(user_id=USER_ID, session_id=SESSION_ID, message=...)
118118
```
119119

120-
- 更新自身代码
121-
- 删除自身
120+
## 更新云应用
121+
122+
### 通过 CloudAgentEngine 更新
123+
124+
当您需要更新已部署的Agent代码时,可以使用`update_function_code`方法:
125+
126+
```python
127+
from veadk.cloud.cloud_agent_engine import CloudAgentEngine
128+
129+
engine = CloudAgentEngine()
130+
131+
# 更新现有应用的代码,保持相同的访问端点
132+
updated_cloud_app = engine.update_function_code(
133+
application_name="my-agent-app", # 现有应用名称
134+
path="/my-agent-project" # 本地项目路径
135+
)
136+
137+
print(f"应用已更新,访问地址:{updated_cloud_app.vefaas_endpoint}")
138+
```
139+
140+
**注意事项:**
141+
- 更新操作会保持相同的访问端点URL
142+
- 确保项目路径包含`agent.py`文件
143+
144+
145+
## 删除云应用
146+
147+
### 通过 CloudAgentEngine 删除
148+
149+
```python
150+
from veadk.cloud.cloud_agent_engine import CloudAgentEngine
151+
152+
engine = CloudAgentEngine()
153+
154+
# 删除指定的云应用
155+
engine.remove("my-agent-app")
156+
```
157+
158+
执行时会提示确认:
159+
```
160+
Confirm delete cloud app my-agent-app? (y/N): y
161+
```
162+
163+
输入`y`确认删除,输入其他任何字符或直接回车则取消删除。

tests/test_cloud.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
import tempfile
17+
import pytest
18+
from unittest.mock import Mock, patch, AsyncMock
19+
20+
from veadk.cloud.cloud_agent_engine import CloudAgentEngine
21+
22+
23+
@pytest.mark.asyncio
24+
async def test_cloud():
25+
app_name = "test-app"
26+
key = "CloudTestIdentifier123"
27+
test_endpoint = "https://test-endpoint.volcengine.com"
28+
test_message = "Hello cloud agent"
29+
30+
# Create temporary directory with required agent.py file for testing
31+
with tempfile.TemporaryDirectory() as temp_dir:
32+
with open(os.path.join(temp_dir, "agent.py"), "w") as f:
33+
f.write(f"# Test agent implementation with {key}")
34+
35+
with patch.dict(
36+
os.environ,
37+
{
38+
"VOLCENGINE_ACCESS_KEY": "test_access_key",
39+
"VOLCENGINE_SECRET_KEY": "test_secret_key",
40+
},
41+
):
42+
# Mock shutil.copy to avoid template file copying issues
43+
with patch("shutil.copy"):
44+
with patch(
45+
"veadk.cloud.cloud_agent_engine.VeFaaS"
46+
) as mock_vefaas_class:
47+
# Setup mock VeFaaS service for all operations
48+
mock_vefaas_service = Mock()
49+
mock_vefaas_class.return_value = mock_vefaas_service
50+
51+
# Mock deploy operation
52+
mock_vefaas_service.deploy.return_value = (
53+
test_endpoint,
54+
"app-123",
55+
"func-456",
56+
)
57+
58+
# Mock update operation
59+
mock_vefaas_service._update_function_code.return_value = (
60+
test_endpoint,
61+
"app-123",
62+
"func-456",
63+
)
64+
65+
# Mock remove operation
66+
mock_vefaas_service.find_app_id_by_name.return_value = "app-123"
67+
mock_vefaas_service.delete.return_value = None
68+
69+
# Test CloudAgentEngine creation and deploy functionality
70+
engine = CloudAgentEngine()
71+
72+
# Test deploy operation
73+
cloud_app = engine.deploy(application_name=app_name, path=temp_dir)
74+
75+
# Verify deployment result contains expected values
76+
assert cloud_app.vefaas_application_name == app_name
77+
assert cloud_app.vefaas_endpoint == test_endpoint
78+
assert cloud_app.vefaas_application_id == "app-123"
79+
80+
# Test update_function_code operation
81+
updated_app = engine.update_function_code(
82+
application_name=app_name, path=temp_dir
83+
)
84+
85+
# Verify update result maintains same endpoint
86+
assert updated_app.vefaas_endpoint == test_endpoint
87+
88+
# Test remove operation with mocked user input
89+
with patch("builtins.input", return_value="y"):
90+
engine.remove(app_name)
91+
mock_vefaas_service.find_app_id_by_name.assert_called_with(
92+
app_name
93+
)
94+
mock_vefaas_service.delete.assert_called_with("app-123")
95+
96+
# Test CloudApp message_send functionality
97+
mock_response = Mock()
98+
mock_message = Mock()
99+
mock_response.root.result = mock_message
100+
101+
with patch.object(cloud_app, "_get_a2a_client") as mock_get_client:
102+
mock_client = AsyncMock()
103+
mock_client.send_message = AsyncMock(return_value=mock_response)
104+
mock_get_client.return_value = mock_client
105+
106+
# Test message sending to cloud agent
107+
result = await cloud_app.message_send(
108+
message=test_message,
109+
session_id="session-123",
110+
user_id="user-456",
111+
)
112+
113+
# Verify message sending result
114+
assert result == mock_message
115+
mock_client.send_message.assert_called_once()
116+
117+
# Test CloudApp delete_self functionality
118+
with patch("builtins.input", return_value="y"):
119+
with patch(
120+
"veadk.cli.services.vefaas.vefaas.VeFaaS"
121+
) as mock_vefaas_in_app:
122+
mock_vefaas_client = Mock()
123+
mock_vefaas_in_app.return_value = mock_vefaas_client
124+
mock_vefaas_client.delete.return_value = None
125+
126+
cloud_app.delete_self()
127+
mock_vefaas_client.delete.assert_called_with("app-123")
128+
129+
# Verify all mocks were called as expected
130+
mock_vefaas_service.deploy.assert_called_once()
131+
mock_vefaas_service._update_function_code.assert_called_once()

0 commit comments

Comments
 (0)