Skip to content

Commit 2c82631

Browse files
committed
Added prepare state to test implementation
1 parent 2a5fddc commit 2c82631

9 files changed

Lines changed: 269 additions & 2 deletions

codeplain_REST_api.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,42 @@ def prepare_implementation(
191191

192192
return self.post_request(endpoint_url, headers, payload, run_state)
193193

194+
def prepare_conformance_implementation(
195+
self,
196+
frid: str,
197+
functional_requirement_id: str,
198+
plain_source_tree: dict,
199+
linked_resources: dict,
200+
existing_files_content: dict,
201+
memory_files_content: dict,
202+
module_name: str,
203+
required_modules: dict,
204+
conformance_tests_folder_name: str,
205+
conformance_tests_json: dict,
206+
all_acceptance_tests: list[str],
207+
run_state: RunState,
208+
prepare_conformance_implementation_script: str,
209+
) -> dict:
210+
endpoint_url = f"{self.api_url}/prepare_conformance_implementation"
211+
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
212+
213+
payload = {
214+
"frid": frid,
215+
"functional_requirement_id": functional_requirement_id,
216+
"plain_source_tree": plain_source_tree,
217+
"linked_resources": linked_resources,
218+
"existing_files_content": existing_files_content,
219+
"memory_files_content": memory_files_content,
220+
"module_name": module_name,
221+
"required_modules": required_modules,
222+
"conformance_tests_folder_name": conformance_tests_folder_name,
223+
"conformance_tests_json": conformance_tests_json,
224+
"all_acceptance_tests": all_acceptance_tests,
225+
"prepare_conformance_implementation_script": prepare_conformance_implementation_script,
226+
}
227+
228+
return self.post_request(endpoint_url, headers, payload, run_state)
229+
194230
def render_functional_requirement(
195231
self,
196232
frid: str,
@@ -343,6 +379,7 @@ def render_conformance_tests(
343379
conformance_tests_json,
344380
all_acceptance_tests,
345381
run_state: RunState,
382+
conformance_test_fix_information: Optional[str] = None,
346383
):
347384
endpoint_url = f"{self.api_url}/render_conformance_tests"
348385
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
@@ -361,6 +398,9 @@ def render_conformance_tests(
361398
"all_acceptance_tests": all_acceptance_tests,
362399
}
363400

401+
if conformance_test_fix_information is not None:
402+
payload["conformance_test_fix_information"] = conformance_test_fix_information
403+
364404
response = self.post_request(endpoint_url, headers, payload, run_state)
365405
return response["patched_response_files"], response["conformance_tests_plan_summary_string"]
366406

@@ -496,6 +536,7 @@ def render_acceptance_tests(
496536
required_modules,
497537
acceptance_test,
498538
run_state: RunState,
539+
conformance_test_fix_information: Optional[str] = None,
499540
):
500541
"""
501542
Renders acceptance tests based on the provided parameters.
@@ -513,6 +554,8 @@ def render_acceptance_tests(
513554
required_modules (dict): A dictionary where the keys represent module names
514555
and the values are lists of functionalities implemented in those modules.
515556
acceptance_test (dict): A dictionary containing acceptance test information.
557+
conformance_test_fix_information (str, optional): Additional information produced by the
558+
prepare_conformance_test_fix_script.
516559
517560
Returns:
518561
dict: The rendered acceptance tests.
@@ -535,6 +578,9 @@ def render_acceptance_tests(
535578
"acceptance_test": acceptance_test,
536579
}
537580

581+
if conformance_test_fix_information is not None:
582+
payload["conformance_test_fix_information"] = conformance_test_fix_information
583+
538584
return self.post_request(endpoint_url, headers, payload, run_state)
539585

540586
def analyze_rendering(
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from typing import Any
2+
3+
import plain_spec
4+
import render_machine.render_utils as render_utils
5+
from memory_management import MemoryManager
6+
from render_machine.actions.base_action import BaseAction
7+
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
8+
from render_machine.render_context import RenderContext
9+
from render_machine.render_types import RenderError
10+
11+
12+
class PrepareConformanceImplementationInformation(BaseAction):
13+
SUCCESSFUL_OUTCOME = "conformance_implementation_information_prepared"
14+
FAILED_OUTCOME = "conformance_implementation_information_preparation_failed"
15+
16+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
17+
_, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(render_context.build_folder)
18+
_, memory_files_content = MemoryManager.fetch_memory_files(render_context.memory_manager.memory_folder)
19+
20+
with open(render_context.prepare_conformance_test_fix_script, "r", encoding="utf-8") as f:
21+
prepare_conformance_implementation_script_content = f.read()
22+
23+
# Check if conformance tests folder exists yet
24+
if render_context.conformance_tests_running_context.current_conformance_tests_exist():
25+
conformance_tests_folder_name = (
26+
render_context.conformance_tests_running_context.get_current_conformance_test_folder_name()
27+
)
28+
else:
29+
# Folder will be generated later by RenderConformanceTests action
30+
conformance_tests_folder_name = ""
31+
32+
# Determine which acceptance tests to include based on phase
33+
# Phase 0 = rendering conformance tests (include all acceptance tests)
34+
# Phase > 0 = rendering specific acceptance test (include only that one)
35+
if render_context.conformance_tests_running_context.conformance_test_phase_index == 0:
36+
# Preparing for conformance tests rendering - include all acceptance tests
37+
all_acceptance_tests = render_context.frid_context.specifications.get(plain_spec.ACCEPTANCE_TESTS, [])
38+
else:
39+
# Preparing for acceptance test rendering - include only the current one
40+
acceptance_test = render_context.conformance_tests_running_context.get_current_acceptance_test()
41+
all_acceptance_tests = [acceptance_test] if acceptance_test else []
42+
43+
api_response = render_context.codeplain_api.prepare_conformance_implementation(
44+
frid=render_context.frid_context.frid,
45+
functional_requirement_id=render_context.conformance_tests_running_context.current_testing_frid,
46+
plain_source_tree=render_context.plain_source_tree,
47+
linked_resources=render_context.frid_context.linked_resources,
48+
existing_files_content=existing_files_content,
49+
memory_files_content=memory_files_content,
50+
module_name=render_context.module_name,
51+
required_modules=render_context.get_required_modules_functionalities(),
52+
conformance_tests_folder_name=conformance_tests_folder_name,
53+
conformance_tests_json=render_context.conformance_tests_running_context.get_conformance_tests_json(
54+
render_context.conformance_tests_running_context.current_testing_module_name
55+
),
56+
all_acceptance_tests=all_acceptance_tests,
57+
run_state=render_context.run_state,
58+
prepare_conformance_implementation_script=prepare_conformance_implementation_script_content,
59+
)
60+
instructions = api_response.get("instructions", "")
61+
62+
exit_code, conformance_implementation_information, script_output_path = render_utils.execute_script(
63+
render_context.prepare_conformance_test_fix_script,
64+
[instructions],
65+
render_context.verbose,
66+
"Prepare Conformance Implementation Information",
67+
timeout=render_context.test_script_timeout,
68+
stop_event=render_context.stop_event,
69+
)
70+
71+
if exit_code == 0 or exit_code == render_utils.TIMEOUT_ERROR_EXIT_CODE:
72+
render_context.conformance_tests_running_context.conformance_implementation_information = (
73+
conformance_implementation_information
74+
)
75+
render_context.script_execution_history.latest_prepare_conformance_implementation_output_path = (
76+
script_output_path
77+
)
78+
render_context.script_execution_history.should_update_script_outputs = True
79+
return self.SUCCESSFUL_OUTCOME, None
80+
81+
return (
82+
self.FAILED_OUTCOME,
83+
RenderError.encode(
84+
message="Prepare conformance implementation information failed. Please check the prepare_conformance_test_fix_script.",
85+
error_type="PREPARE_CONFORMANCE_IMPLEMENTATION_ERROR",
86+
exit_code=exit_code,
87+
script=render_context.prepare_conformance_test_fix_script,
88+
).to_payload(),
89+
)
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from typing import Any
2+
3+
import render_machine.render_utils as render_utils
4+
from memory_management import MemoryManager
5+
from plain2code_console import console
6+
from plain2code_exceptions import InternalClientError
7+
from render_machine.actions.base_action import BaseAction
8+
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
9+
from render_machine.render_context import RenderContext
10+
from render_machine.render_types import RenderError
11+
12+
13+
class PrepareConformanceTestFix(BaseAction):
14+
SUCCESSFUL_OUTCOME = "conformance_test_fix_prepared"
15+
FAILED_OUTCOME = "conformance_test_fix_preparation_failed"
16+
17+
def execute(self, render_context: RenderContext, previous_action_payload: Any | None):
18+
if render_context.verbose:
19+
console.info(
20+
f"Running prepare_conformance_test_fix_script for FRID "
21+
f"{render_context.conformance_tests_running_context.current_testing_frid}."
22+
)
23+
24+
if not previous_action_payload or not previous_action_payload.get("previous_conformance_tests_issue"):
25+
raise InternalClientError("Previous action payload does not contain previous conformance tests issue.")
26+
previous_conformance_tests_issue = previous_action_payload["previous_conformance_tests_issue"]
27+
28+
_, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(render_context.build_folder)
29+
_, memory_files_content = MemoryManager.fetch_memory_files(render_context.memory_manager.memory_folder)
30+
(
31+
_,
32+
existing_conformance_test_files_content,
33+
) = render_context.conformance_tests.fetch_existing_conformance_test_files(
34+
render_context.module_name,
35+
render_context.required_modules,
36+
render_context.conformance_tests_running_context.current_testing_module_name,
37+
render_context.conformance_tests_running_context.get_current_conformance_test_folder_name(),
38+
)
39+
previous_frid_code_diff = ImplementationCodeHelpers.get_code_diff(
40+
render_context.build_folder, render_context.plain_source_tree, render_context.frid_context.frid
41+
)
42+
43+
with open(render_context.prepare_conformance_test_fix_script, "r", encoding="utf-8") as f:
44+
script_content = f.read()
45+
46+
api_response = render_context.codeplain_api.prepare_conformance_test_fix(
47+
frid=render_context.frid_context.frid,
48+
functional_requirement_id=render_context.conformance_tests_running_context.current_testing_frid,
49+
plain_source_tree=render_context.plain_source_tree,
50+
linked_resources=render_context.frid_context.linked_resources,
51+
existing_files_content=existing_files_content,
52+
memory_files_content=memory_files_content,
53+
module_name=render_context.module_name,
54+
conformance_tests_module_name=(
55+
render_context.conformance_tests_running_context.current_testing_module_name
56+
),
57+
required_modules=render_context.get_required_modules_functionalities(),
58+
code_diff=previous_frid_code_diff,
59+
conformance_tests_files=existing_conformance_test_files_content,
60+
acceptance_tests=render_context.conformance_tests_running_context.get_current_acceptance_tests(),
61+
conformance_tests_issue=previous_conformance_tests_issue,
62+
implementation_fix_count=render_context.conformance_tests_running_context.fix_attempts,
63+
conformance_tests_folder_name=(
64+
render_context.conformance_tests_running_context.get_current_conformance_test_folder_name()
65+
),
66+
current_testing_frid_high_level_implementation_plan=(
67+
render_context.conformance_tests_running_context.current_testing_frid_high_level_implementation_plan
68+
),
69+
run_state=render_context.run_state,
70+
prepare_conformance_test_fix_script=script_content,
71+
)
72+
73+
instructions = api_response.get("instructions", "")
74+
75+
exit_code, conformance_test_fix_information, script_output_path = render_utils.execute_script(
76+
render_context.prepare_conformance_test_fix_script,
77+
[instructions],
78+
render_context.verbose,
79+
"Prepare Conformance Test Fix",
80+
timeout=render_context.test_script_timeout,
81+
stop_event=render_context.stop_event,
82+
)
83+
84+
if exit_code == 0 or exit_code == render_utils.TIMEOUT_ERROR_EXIT_CODE:
85+
render_context.conformance_tests_running_context.conformance_test_fix_information = (
86+
conformance_test_fix_information
87+
)
88+
render_context.script_execution_history.latest_prepare_conformance_test_fix_output_path = script_output_path
89+
render_context.script_execution_history.should_update_script_outputs = True
90+
return (
91+
self.SUCCESSFUL_OUTCOME,
92+
{"previous_conformance_tests_issue": previous_conformance_tests_issue},
93+
)
94+
95+
return (
96+
self.FAILED_OUTCOME,
97+
RenderError.encode(
98+
message="Prepare conformance test fix failed. Please check the prepare_conformance_test_fix_script.",
99+
error_type="PREPARE_CONFORMANCE_TEST_FIX_ERROR",
100+
exit_code=exit_code,
101+
script=render_context.prepare_conformance_test_fix_script,
102+
).to_payload(),
103+
)

render_machine/actions/render_conformance_tests.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ def _render_conformance_tests(self, render_context: RenderContext):
113113
)
114114

115115
all_acceptance_tests = render_context.frid_context.specifications.get(plain_spec.ACCEPTANCE_TESTS, [])
116-
117116
response_files, implementation_plan_summary = render_context.codeplain_api.render_conformance_tests(
118117
render_context.frid_context.frid,
119118
render_context.conformance_tests_running_context.current_testing_frid,
@@ -129,6 +128,7 @@ def _render_conformance_tests(self, render_context: RenderContext):
129128
),
130129
all_acceptance_tests,
131130
run_state=render_context.run_state,
131+
conformance_test_fix_information=render_context.conformance_tests_running_context.conformance_implementation_information,
132132
)
133133

134134
render_context.conformance_tests_running_context.current_testing_frid_high_level_implementation_plan = (
@@ -183,6 +183,7 @@ def _render_acceptance_test(self, render_context: RenderContext):
183183
render_context.get_required_modules_functionalities(),
184184
acceptance_test,
185185
run_state=render_context.run_state,
186+
conformance_test_fix_information=render_context.conformance_tests_running_context.conformance_implementation_information,
186187
)
187188
conformance_tests_folder_name = (
188189
render_context.conformance_tests_running_context.get_current_conformance_test_folder_name()

render_machine/render_context.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,10 @@ def start_prepare_conformance_test_fix(self):
355355
if self.prepare_conformance_test_fix_script is None:
356356
self.machine.dispatch(triggers.MARK_CONFORMANCE_TEST_FIX_PREPARED)
357357

358+
def start_prepare_conformance_implementation_information(self):
359+
if self.prepare_conformance_test_fix_script is None:
360+
self.machine.dispatch(triggers.MARK_CONFORMANCE_IMPLEMENTATION_INFORMATION_PREPARED)
361+
358362
def start_testing_environment_preparation(self):
359363
if (
360364
self.prepare_environment_script is None

render_machine/render_types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def __init__(
9191
self.regenerating_conformance_tests: bool = False
9292

9393
self.current_testing_frid_high_level_implementation_plan: Optional[str] = None
94+
self.conformance_implementation_information: Optional[str] = None
9495
self.previous_conformance_tests_issue_old: Optional[str] = None
9596
self.previous_conformance_tests_issue_frid: Optional[str] = None
9697
self.previous_conformance_tests_issue_module: Optional[str] = None
@@ -159,6 +160,7 @@ class ScriptExecutionHistory:
159160
latest_testing_environment_output_path: Optional[str] = None
160161
latest_prepare_implementation_output_path: Optional[str] = None
161162
latest_prepare_conformance_test_fix_output_path: Optional[str] = None
163+
latest_prepare_conformance_implementation_output_path: Optional[str] = None
162164
should_update_script_outputs: bool = False
163165

164166

0 commit comments

Comments
 (0)