codemie-test-harness 0.1.165__py3-none-any.whl → 0.1.167__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codemie-test-harness might be problematic. Click here for more details.
- codemie_test_harness/tests/assistant/tools/mcp/test_single_assistant_dual_time_plugins.py +160 -0
- codemie_test_harness/tests/enums/model_types.py +1 -0
- codemie_test_harness/tests/test_data/llm_test_data.py +1 -0
- codemie_test_harness/tests/test_data/plugin_tools_test_data.py +33 -0
- {codemie_test_harness-0.1.165.dist-info → codemie_test_harness-0.1.167.dist-info}/METADATA +2 -2
- {codemie_test_harness-0.1.165.dist-info → codemie_test_harness-0.1.167.dist-info}/RECORD +8 -7
- {codemie_test_harness-0.1.165.dist-info → codemie_test_harness-0.1.167.dist-info}/WHEEL +0 -0
- {codemie_test_harness-0.1.165.dist-info → codemie_test_harness-0.1.167.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This test verifies that a single assistant can have multiple instances of the same
|
|
3
|
+
MCP server plugin running with different configurations under the same plugin-key.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
import subprocess
|
|
9
|
+
import uuid
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from time import sleep
|
|
12
|
+
from typing import Tuple, List
|
|
13
|
+
|
|
14
|
+
import pytest
|
|
15
|
+
|
|
16
|
+
from codemie_test_harness.tests.enums.tools import Toolkit
|
|
17
|
+
from codemie_sdk.models.integration import CredentialTypes
|
|
18
|
+
from codemie_test_harness.tests.conftest import cleanup_plugin_process
|
|
19
|
+
from codemie_test_harness.tests.test_data.plugin_tools_test_data import (
|
|
20
|
+
dual_time_plugin_test_data,
|
|
21
|
+
)
|
|
22
|
+
from codemie_test_harness.tests.utils.credentials_manager import CredentialsManager
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
CACHE_DIR = Path.home() / ".cache" / "uv" / "archive-v0"
|
|
26
|
+
SERVERS_JSON_PATH = "lib/python3.12/site-packages/toolkits/mcp/servers.json"
|
|
27
|
+
CODEMIE_PLUGINS_PATH = "bin/codemie-plugins"
|
|
28
|
+
PLUGIN_INIT_DELAY = 15
|
|
29
|
+
|
|
30
|
+
TIME_CONFIGS = {
|
|
31
|
+
"time-kyiv": {"timezone": "Europe/Kiev", "label": "time-kyiv"},
|
|
32
|
+
"time-tokyo": {"timezone": "Asia/Tokyo", "label": "time-tokyo"},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def find_cache_paths() -> Tuple[Path, Path]:
|
|
37
|
+
"""Find required cache paths for servers.json and codemie-plugins."""
|
|
38
|
+
for cache_subdir in CACHE_DIR.glob("*"):
|
|
39
|
+
if not cache_subdir.is_dir():
|
|
40
|
+
continue
|
|
41
|
+
|
|
42
|
+
servers_json = cache_subdir / SERVERS_JSON_PATH
|
|
43
|
+
codemie_plugins = cache_subdir / CODEMIE_PLUGINS_PATH
|
|
44
|
+
|
|
45
|
+
if servers_json.exists() and codemie_plugins.exists():
|
|
46
|
+
return servers_json, codemie_plugins
|
|
47
|
+
|
|
48
|
+
raise FileNotFoundError("Required cache files not found")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def configure_mcp_servers(servers_json_path: Path) -> None:
|
|
52
|
+
"""Configure MCP servers in servers.json."""
|
|
53
|
+
with open(servers_json_path, "r+") as f:
|
|
54
|
+
config = json.load(f)
|
|
55
|
+
mcp_servers = config.get("mcpServers", {})
|
|
56
|
+
|
|
57
|
+
for server_name, server_config in TIME_CONFIGS.items():
|
|
58
|
+
if server_name not in mcp_servers:
|
|
59
|
+
mcp_servers[server_name] = {
|
|
60
|
+
"command": "uvx",
|
|
61
|
+
"args": [
|
|
62
|
+
"mcp-server-time",
|
|
63
|
+
f"--local-timezone={server_config['timezone']}",
|
|
64
|
+
],
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
f.seek(0)
|
|
68
|
+
json.dump(config, f, indent=2)
|
|
69
|
+
f.truncate()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def create_plugin_process(
|
|
73
|
+
server_name: str, plugin_key: str, codemie_plugins_path: Path
|
|
74
|
+
) -> subprocess.Popen:
|
|
75
|
+
"""Create a plugin process for given server configuration."""
|
|
76
|
+
config = TIME_CONFIGS[server_name]
|
|
77
|
+
|
|
78
|
+
env = os.environ.copy()
|
|
79
|
+
env.update(
|
|
80
|
+
{"PLUGIN_LABEL": config["label"], "PLUGIN_EXPERIMENTAL_PROTOCOL": "true"}
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
command = [
|
|
84
|
+
str(codemie_plugins_path),
|
|
85
|
+
"--plugin-key",
|
|
86
|
+
plugin_key,
|
|
87
|
+
"--plugin-engine-uri",
|
|
88
|
+
CredentialsManager.get_parameter("NATS_URL"),
|
|
89
|
+
"mcp",
|
|
90
|
+
"run",
|
|
91
|
+
"-s",
|
|
92
|
+
server_name,
|
|
93
|
+
"-e",
|
|
94
|
+
f"{server_name}=PLUGIN_LABEL",
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
return subprocess.Popen(command, env=env)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def cleanup_processes(processes: List[subprocess.Popen]) -> None:
|
|
101
|
+
"""Clean up all managed processes."""
|
|
102
|
+
for process in processes:
|
|
103
|
+
cleanup_plugin_process(process)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@pytest.fixture(scope="module")
|
|
107
|
+
def dual_time_plugins(integration_utils):
|
|
108
|
+
"""Create two time plugin instances with different configurations."""
|
|
109
|
+
plugin_key = str(uuid.uuid4())
|
|
110
|
+
processes = []
|
|
111
|
+
|
|
112
|
+
# Setup integration
|
|
113
|
+
credential_values = CredentialsManager.plugin_credentials(plugin_key)
|
|
114
|
+
settings = integration_utils.create_integration(
|
|
115
|
+
credential_type=CredentialTypes.PLUGIN, credential_values=credential_values
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Download codemie-tools
|
|
119
|
+
download_process = subprocess.Popen(["uvx", "codemie-tools"])
|
|
120
|
+
processes.append(download_process)
|
|
121
|
+
|
|
122
|
+
# Find paths and configure servers
|
|
123
|
+
servers_json_path, codemie_plugins_path = find_cache_paths()
|
|
124
|
+
configure_mcp_servers(servers_json_path)
|
|
125
|
+
|
|
126
|
+
# Start plugin processes for each time config
|
|
127
|
+
for server_name in TIME_CONFIGS.keys():
|
|
128
|
+
process = create_plugin_process(server_name, plugin_key, codemie_plugins_path)
|
|
129
|
+
processes.append(process)
|
|
130
|
+
|
|
131
|
+
# Wait for plugin initialization
|
|
132
|
+
sleep(PLUGIN_INIT_DELAY)
|
|
133
|
+
|
|
134
|
+
yield settings
|
|
135
|
+
cleanup_processes(processes)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@pytest.mark.assistant
|
|
139
|
+
@pytest.mark.mcp
|
|
140
|
+
@pytest.mark.plugin
|
|
141
|
+
@pytest.mark.regression
|
|
142
|
+
@pytest.mark.parametrize(
|
|
143
|
+
"prompt,expected_response",
|
|
144
|
+
dual_time_plugin_test_data,
|
|
145
|
+
ids=["Get Tools Available", "Get Kyiv time", "Get Tokyo time"],
|
|
146
|
+
)
|
|
147
|
+
def test_single_assistant_dual_time_plugins(
|
|
148
|
+
dual_time_plugins,
|
|
149
|
+
assistant_utils,
|
|
150
|
+
assistant,
|
|
151
|
+
similarity_check,
|
|
152
|
+
prompt,
|
|
153
|
+
expected_response,
|
|
154
|
+
):
|
|
155
|
+
assistant_instance = assistant(
|
|
156
|
+
Toolkit.PLUGIN, Toolkit.PLUGIN, settings=dual_time_plugins
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
response = assistant_utils.ask_assistant(assistant_instance, prompt)
|
|
160
|
+
similarity_check.check_similarity(response, expected_response)
|
|
@@ -24,6 +24,7 @@ class ModelTypes(str, Enum):
|
|
|
24
24
|
CLAUDE_SONNET_V2_VERTEX = "claude-sonnet-v2-vertex"
|
|
25
25
|
GEMINI_15_PRO = "gemini-1.5-pro"
|
|
26
26
|
GEMINI_20_FLASH = "gemini-2.0-flash"
|
|
27
|
+
GEMINI_25_FLASH = "gemini-2.5-flash"
|
|
27
28
|
GEMINI_25_PRO = "gemini-2.5-pro"
|
|
28
29
|
CLAUDE_SONNET_37_VERTEX = "claude-sonnet-3-7-vertex"
|
|
29
30
|
|
|
@@ -41,6 +41,7 @@ MODEL_RESPONSES = [
|
|
|
41
41
|
GCP_ENVS,
|
|
42
42
|
),
|
|
43
43
|
LlmResponseData(ModelTypes.GEMINI_20_FLASH, GCP_ENVS),
|
|
44
|
+
LlmResponseData(ModelTypes.GEMINI_25_FLASH, GCP_ENVS),
|
|
44
45
|
LlmResponseData(ModelTypes.GEMINI_25_PRO, GCP_ENVS),
|
|
45
46
|
LlmResponseData(
|
|
46
47
|
ModelTypes.CLAUDE_SONNET_37_VERTEX,
|
|
@@ -73,3 +73,36 @@ CREATE_READ_DELETE_FILE_TEST_DATA = {
|
|
|
73
73
|
"remove_file_prompt": "execute command: git rm -f {}.properties",
|
|
74
74
|
"remove_file_response": "The file `{}.properties` has been removed from the git repository.",
|
|
75
75
|
}
|
|
76
|
+
|
|
77
|
+
"""Test data for dual time plugin MCP server tests."""
|
|
78
|
+
|
|
79
|
+
dual_time_plugin_test_data = [
|
|
80
|
+
(
|
|
81
|
+
"Show tools with their name and description",
|
|
82
|
+
"""
|
|
83
|
+
Sure, here are the tools available with their name and description:
|
|
84
|
+
|
|
85
|
+
1. **functions._get_current_time_2f90**:
|
|
86
|
+
- **Description**: Get current time in a specific timezone. If no timezone is provided by the user, it uses 'Asia/Tokyo' as the local timezone.
|
|
87
|
+
|
|
88
|
+
2. **functions._convert_time_2f90**:
|
|
89
|
+
- **Description**: Convert time between timezones. If no source timezone is provided by the user, it uses 'Asia/Tokyo' as the local timezone. Similarly, if no target timezone is provided, it uses 'Asia/Tokyo' as the local timezone.
|
|
90
|
+
|
|
91
|
+
3. **functions._get_current_time_5cba**:
|
|
92
|
+
- **Description**: Similar to `_get_current_time_2f90`, this gets the current time in a specific timezone, defaulting to 'Asia/Tokyo' if no timezone is provided.
|
|
93
|
+
|
|
94
|
+
4. **functions._convert_time_5cba**:
|
|
95
|
+
- **Description**: Similar to `_convert_time_2f90`, this converts time between timezones, defaulting to 'Asia/Tokyo' if no source or target timezone is provided.
|
|
96
|
+
|
|
97
|
+
These tools are designed to help manage and convert timezone-related data efficiently.
|
|
98
|
+
""",
|
|
99
|
+
),
|
|
100
|
+
(
|
|
101
|
+
"What is the current time in Kyiv? Return in format: The current time in Kyiv (Europe/Kiev timezone) is: $time_here",
|
|
102
|
+
"The current time in Kyiv (Europe/Kiev timezone) is",
|
|
103
|
+
),
|
|
104
|
+
(
|
|
105
|
+
"What is the current time in Tokyo? Return in format: The current time in Tokyo (Asia/Tokyo timezone) is: $time_here",
|
|
106
|
+
"The current time in Tokyo (Asia/Tokyo timezone) is",
|
|
107
|
+
),
|
|
108
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: codemie-test-harness
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.167
|
|
4
4
|
Summary: Autotest for CodeMie backend and UI
|
|
5
5
|
Author: Anton Yeromin
|
|
6
6
|
Author-email: anton_yeromin@epam.com
|
|
@@ -13,7 +13,7 @@ Requires-Dist: aws-assume-role-lib (>=2.10.0,<3.0.0)
|
|
|
13
13
|
Requires-Dist: boto3 (>=1.39.8,<2.0.0)
|
|
14
14
|
Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
15
15
|
Requires-Dist: codemie-plugins (>=0.1.123,<0.2.0)
|
|
16
|
-
Requires-Dist: codemie-sdk-python (==0.1.
|
|
16
|
+
Requires-Dist: codemie-sdk-python (==0.1.167)
|
|
17
17
|
Requires-Dist: pytest (>=8.4.1,<9.0.0)
|
|
18
18
|
Requires-Dist: pytest-playwright (>=0.7.0,<0.8.0)
|
|
19
19
|
Requires-Dist: pytest-reportportal (>=5.5.2,<6.0.0)
|
|
@@ -42,6 +42,7 @@ codemie_test_harness/tests/assistant/tools/git/test_assistant_with_git_tools.py,
|
|
|
42
42
|
codemie_test_harness/tests/assistant/tools/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
43
|
codemie_test_harness/tests/assistant/tools/mcp/test_cli_mcp_server.py,sha256=nf8j8d5L9hXriqzh1o1b1IUclEW5jY-s1YHKovnWMh0,2642
|
|
44
44
|
codemie_test_harness/tests/assistant/tools/mcp/test_mcp_servers.py,sha256=6G07SddfjZ0ilnJVSeS3yK-OSge9224I-6BQhbQxvZo,1386
|
|
45
|
+
codemie_test_harness/tests/assistant/tools/mcp/test_single_assistant_dual_time_plugins.py,sha256=_rBXI-45DZyFAlaTfv_3LkIc7mS8RAsfE2En3aWIpwY,4897
|
|
45
46
|
codemie_test_harness/tests/assistant/tools/notification/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
47
|
codemie_test_harness/tests/assistant/tools/notification/test_assistant_notification_tools.py,sha256=0HrrCwwwU0U_2qrJPeURmqetOGt2FuBLoCxLEHzXV1k,2651
|
|
47
48
|
codemie_test_harness/tests/assistant/tools/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -67,7 +68,7 @@ codemie_test_harness/tests/e2e/test_e2e.py,sha256=DavQToIg5SR38xw3AqhwNGzp5hli0n
|
|
|
67
68
|
codemie_test_harness/tests/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
68
69
|
codemie_test_harness/tests/enums/environment.py,sha256=R3z7VetKeaJorUyrB5hKmlZVMyjHiAw4R5vREcBfdpU,3051
|
|
69
70
|
codemie_test_harness/tests/enums/integrations.py,sha256=hG_cEKN0N5gtGHyrh3wuCpNAWhPyNOJaKsAw16iNshg,164
|
|
70
|
-
codemie_test_harness/tests/enums/model_types.py,sha256=
|
|
71
|
+
codemie_test_harness/tests/enums/model_types.py,sha256=XtLT0breZ1y6QWjmzc6Qw664ZY0lklGRZ_u1AxyXLN4,1272
|
|
71
72
|
codemie_test_harness/tests/enums/tools.py,sha256=7vZeQFo9FYgNt2q7LVpAvzyKDLbqtxapIeZo-g3cE2s,5772
|
|
72
73
|
codemie_test_harness/tests/integrations/__init__.py,sha256=5vnZbxvYQ1Y91O8DJG3QfBHWcdYsMii59cMBzsvHBCg,237
|
|
73
74
|
codemie_test_harness/tests/integrations/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -144,13 +145,13 @@ codemie_test_harness/tests/test_data/google_datasource_test_data.py,sha256=fhMJV
|
|
|
144
145
|
codemie_test_harness/tests/test_data/index_test_data.py,sha256=VZJC_Fmko32EHaybUwCy0mWMiwAeUAAmhRa0Xt4oTHQ,1115
|
|
145
146
|
codemie_test_harness/tests/test_data/integrations_test_data.py,sha256=1YecCRnrBq5NiM9HEnyKFZ17nuFEnZUlNzKcwo09SDM,13050
|
|
146
147
|
codemie_test_harness/tests/test_data/keycloak_tool_test_data.py,sha256=uF8YqHGgLpQVxKdpKXLe-7F-ipEGQiHHh28nZvvVGM8,1244
|
|
147
|
-
codemie_test_harness/tests/test_data/llm_test_data.py,sha256=
|
|
148
|
+
codemie_test_harness/tests/test_data/llm_test_data.py,sha256=akJYX36GfR1s5gHKOaWbTGB-4XBjCh1pc00quCjHFoQ,2474
|
|
148
149
|
codemie_test_harness/tests/test_data/mcp_server_test_data.py,sha256=m6PImS_J2gPNY5ijf9MG_eOX_LxJjTZ23AXQDgaK_Oc,7151
|
|
149
150
|
codemie_test_harness/tests/test_data/notification_tools_test_data.py,sha256=D7KLP-cyQljU2Io21CukphnzMadJ7VJ0FhXFdU3GfGk,794
|
|
150
151
|
codemie_test_harness/tests/test_data/open_api_tools_test_data.py,sha256=XhVzelRXgLXHF2iIvhI70SP6qHQjT7QW70S06dF6XJI,2480
|
|
151
152
|
codemie_test_harness/tests/test_data/openapi.json,sha256=X4uqtfjpTUuMifefQRf8mHI1k8pspp8-L0rpJlhLOI4,10459
|
|
152
153
|
codemie_test_harness/tests/test_data/output_schema_test_data.py,sha256=4l7AvXbMl9hIvoFxu1LPPSGz9hb5Uz2_is4zTm77ARY,261
|
|
153
|
-
codemie_test_harness/tests/test_data/plugin_tools_test_data.py,sha256=
|
|
154
|
+
codemie_test_harness/tests/test_data/plugin_tools_test_data.py,sha256=bVamztyQ4bAVo1CRSrtu6f5H-gkjhAN2nq5Jbc0erqM,4168
|
|
154
155
|
codemie_test_harness/tests/test_data/pm_tools_test_data.py,sha256=ctPwLSJYy7xPg4B-uwAAhRwIogdxTgBn-PPY2rN0llc,3248
|
|
155
156
|
codemie_test_harness/tests/test_data/project_management_test_data.py,sha256=Sd5MEO0hnUeyF-WIIGW4qEAHR5hvhJcs0DE1ytqdveM,1692
|
|
156
157
|
codemie_test_harness/tests/test_data/report_portal_tools_test_data.py,sha256=P3Z1B1-iNxXAcMIFlb9robhHQSXQtzSRUz59ivvTrG8,13646
|
|
@@ -350,7 +351,7 @@ codemie_test_harness/tests/workflow/virtual_assistant_tools/servicenow/__init__.
|
|
|
350
351
|
codemie_test_harness/tests/workflow/virtual_assistant_tools/servicenow/test_workflow_with_servicenow_tools.py,sha256=vq6tucNBxiNIQSmIj_pYiiPm0lipU9X3kzeCd6xEbRM,966
|
|
351
352
|
codemie_test_harness/tests/workflow/virtual_assistant_tools/vcs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
352
353
|
codemie_test_harness/tests/workflow/virtual_assistant_tools/vcs/test_workflow_with_vcs_tools.py,sha256=uD2qs361j6Egp4UumfoQ4gC24-NioXfiW0IF53N9hVA,1175
|
|
353
|
-
codemie_test_harness-0.1.
|
|
354
|
-
codemie_test_harness-0.1.
|
|
355
|
-
codemie_test_harness-0.1.
|
|
356
|
-
codemie_test_harness-0.1.
|
|
354
|
+
codemie_test_harness-0.1.167.dist-info/METADATA,sha256=QYEsiXDnm8tybx4tFo5nJZnEwNhb58eJVfLUSJHZreU,8998
|
|
355
|
+
codemie_test_harness-0.1.167.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
356
|
+
codemie_test_harness-0.1.167.dist-info/entry_points.txt,sha256=n98t-EOM5M1mnMl_j2X4siyeO9zr0WD9a5LF7JyElIM,73
|
|
357
|
+
codemie_test_harness-0.1.167.dist-info/RECORD,,
|
|
File without changes
|
{codemie_test_harness-0.1.165.dist-info → codemie_test_harness-0.1.167.dist-info}/entry_points.txt
RENAMED
|
File without changes
|