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.

@@ -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.165
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.165)
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=PgC3Zuu5Ml9C18Uz_nLVFRXd3IFJhNZ3TbfAUaMANoE,1231
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=E1H1enkPqJz0tfenEOQC4noNZlm8oCWupPfVnlxkzDM,2415
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=8sb80WiFdi2WWBWw5OWCR56HW6K1y062bWFiLOKeSU0,2430
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.165.dist-info/METADATA,sha256=7XS6zhNqrnu856EPJgAVnwZcDZa8G_MfvdPduXFzofw,8998
354
- codemie_test_harness-0.1.165.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
355
- codemie_test_harness-0.1.165.dist-info/entry_points.txt,sha256=n98t-EOM5M1mnMl_j2X4siyeO9zr0WD9a5LF7JyElIM,73
356
- codemie_test_harness-0.1.165.dist-info/RECORD,,
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,,