@@ -59,6 +59,111 @@ function(add_test_bin name)
5959 add_san(${name} )
6060endfunction ()
6161
62+ # Convert a CMake list to a JSON array of strings
63+ function (_cmake_list_to_json_array LIST_VAR OUTPUT_VAR)
64+ set (JSON_STR "[" )
65+ set (FIRST TRUE )
66+ foreach (ITEM IN LISTS LIST_VAR)
67+ if (FIRST)
68+ set (FIRST FALSE )
69+ else ()
70+ string (APPEND JSON_STR ", " )
71+ endif ()
72+ # Escape backslashes and quotes for JSON
73+ string (REPLACE "\\ " "\\\\ " ITEM "${ITEM} " )
74+ string (REPLACE "\" " "\\\" " ITEM "${ITEM} " )
75+ string (APPEND JSON_STR "\" ${ITEM} \" " )
76+ endforeach ()
77+ string (APPEND JSON_STR "]" )
78+ set (${OUTPUT_VAR}
79+ "${JSON_STR} "
80+ PARENT_SCOPE
81+ )
82+ endfunction ()
83+
84+ # Extract values from a flag-value list (e.g. --constitution /path1
85+ # --constitution /path2) Returns only the values, filtering out the flag tokens.
86+ function (_extract_flag_values FLAG_NAME INPUT_LIST OUTPUT_VAR)
87+ set (RESULT "" )
88+ set (TAKE_NEXT FALSE )
89+ foreach (ITEM IN LISTS INPUT_LIST)
90+ if (TAKE_NEXT)
91+ list (APPEND RESULT "${ITEM} " )
92+ set (TAKE_NEXT FALSE )
93+ elseif ("${ITEM} " STREQUAL "${FLAG_NAME} " )
94+ set (TAKE_NEXT TRUE )
95+ endif ()
96+ endforeach ()
97+ set (${OUTPUT_VAR}
98+ "${RESULT} "
99+ PARENT_SCOPE
100+ )
101+ endfunction ()
102+
103+ # Accumulate a test entry into the global e2e test config. Call
104+ # write_e2e_test_configs() after all tests are defined.
105+ function (_accumulate_e2e_test_config)
106+ cmake_parse_arguments (
107+ PARSE_ARGV 0 CFG "" "NAME;PYTHON_SCRIPT;LABEL"
108+ "CONSTITUTION;ADDITIONAL_ARGS;ENV"
109+ )
110+
111+ # Extract constitution file paths (strip --constitution flags)
112+ _extract_flag_values(
113+ "--constitution" "${CFG_CONSTITUTION} " CONSTITUTION_PATHS
114+ )
115+ _cmake_list_to_json_array("${CONSTITUTION_PATHS} " CONSTITUTION_JSON)
116+
117+ # Additional args as flat array
118+ _cmake_list_to_json_array("${CFG_ADDITIONAL_ARGS} " ADDITIONAL_ARGS_JSON)
119+
120+ # Env vars
121+ _cmake_list_to_json_array("${CFG_ENV} " ENV_JSON)
122+
123+ set (LABEL_VALUE "${CFG_LABEL} " )
124+ if (NOT LABEL_VALUE)
125+ set (LABEL_VALUE "" )
126+ endif ()
127+
128+ # Escape the python script path
129+ string (REPLACE "\\ " "\\\\ " SCRIPT "${CFG_PYTHON_SCRIPT} " )
130+ string (REPLACE "\" " "\\\" " SCRIPT "${SCRIPT} " )
131+
132+ set (ENTRY
133+ " \" ${CFG_NAME} \" : {\n\
134+ \" python_script\" : \" ${SCRIPT} \" ,\n\
135+ \" label\" : \" ${LABEL_VALUE} \" ,\n\
136+ \" constitution\" : ${CONSTITUTION_JSON} ,\n\
137+ \" additional_args\" : ${ADDITIONAL_ARGS_JSON} ,\n\
138+ \" env\" : ${ENV_JSON} \n\
139+ }"
140+ )
141+
142+ set_property (GLOBAL APPEND PROPERTY _E2E_TEST_CONFIG_ENTRIES "${ENTRY} " )
143+ endfunction ()
144+
145+ # Write the consolidated e2e_tests.json to the build directory. Must be called
146+ # after all add_e2e_test() invocations.
147+ function (write_e2e_test_configs)
148+ get_property (ENTRIES GLOBAL PROPERTY _E2E_TEST_CONFIG_ENTRIES)
149+
150+ set (JSON_CONTENT "{\n " )
151+ list (LENGTH ENTRIES NUM_ENTRIES)
152+ math (EXPR LAST_INDEX "${NUM_ENTRIES} - 1" )
153+ set (INDEX 0)
154+ foreach (ENTRY IN LISTS ENTRIES)
155+ string (APPEND JSON_CONTENT "${ENTRY} " )
156+ if (INDEX LESS LAST_INDEX)
157+ string (APPEND JSON_CONTENT "," )
158+ endif ()
159+ string (APPEND JSON_CONTENT "\n " )
160+ math (EXPR INDEX "${INDEX} + 1" )
161+ endforeach ()
162+ string (APPEND JSON_CONTENT "}\n " )
163+
164+ file (WRITE "${CMAKE_BINARY_DIR} /e2e_tests.json" "${JSON_CONTENT} " )
165+ endfunction ()
166+
62167# Helper for building end-to-end function tests using the python infrastructure
63168function (add_e2e_test)
64169 cmake_parse_arguments (
@@ -98,12 +203,23 @@ function(add_e2e_test)
98203 set (PARSED_ARGS_PERF_LABEL ${PARSED_ARGS_NAME} )
99204 endif ()
100205
206+ # Build the full argument list for the test (everything after the python
207+ # script)
208+ set (FULL_TEST_ARGS
209+ -b
210+ .
211+ --label
212+ ${PARSED_ARGS_NAME}
213+ ${CCF_NETWORK_TEST_ARGS}
214+ ${PARSED_ARGS_CONSTITUTION}
215+ ${PARSED_ARGS_ADDITIONAL_ARGS}
216+ --tick-ms
217+ ${NODE_TICK_MS}
218+ )
219+
101220 add_test (
102221 NAME ${PARSED_ARGS_NAME}
103- COMMAND
104- ${PYTHON_WRAPPER} ${PARSED_ARGS_PYTHON_SCRIPT} -b . --label
105- ${PARSED_ARGS_NAME} ${CCF_NETWORK_TEST_ARGS} ${PARSED_ARGS_CONSTITUTION}
106- ${PARSED_ARGS_ADDITIONAL_ARGS} --tick-ms ${NODE_TICK_MS}
222+ COMMAND ${PYTHON_WRAPPER} ${PARSED_ARGS_PYTHON_SCRIPT} ${FULL_TEST_ARGS}
107223 CONFIGURATIONS ${PARSED_ARGS_CONFIGURATIONS}
108224 )
109225
@@ -114,12 +230,15 @@ function(add_e2e_test)
114230 PROPERTY ENVIRONMENT "PYTHONPATH=${CCF_DIR} /tests:$ENV{PYTHONPATH} "
115231 )
116232
233+ set (TEST_ENV_VARS "PYTHONPATH=${CCF_DIR} /tests:$ENV{PYTHONPATH} " )
234+
117235 if (SHUFFLE_SUITE)
118236 set_property (
119237 TEST ${PARSED_ARGS_NAME}
120238 APPEND
121239 PROPERTY ENVIRONMENT "SHUFFLE_SUITE=1"
122240 )
241+ list (APPEND TEST_ENV_VARS "SHUFFLE_SUITE=1" )
123242 endif ()
124243
125244 if ("${PARSED_ARGS_LABEL} " STREQUAL "partitions" )
@@ -128,6 +247,7 @@ function(add_e2e_test)
128247 APPEND
129248 PROPERTY ENVIRONMENT "PYTHONDONTWRITEBYTECODE=1"
130249 )
250+ list (APPEND TEST_ENV_VARS "PYTHONDONTWRITEBYTECODE=1" )
131251 endif ()
132252
133253 add_san_test_properties(${PARSED_ARGS_NAME} )
@@ -149,7 +269,24 @@ function(add_e2e_test)
149269 APPEND
150270 PROPERTY ENVIRONMENT "CURL_CLIENT=ON"
151271 )
272+ list (APPEND TEST_ENV_VARS "CURL_CLIENT=ON" )
152273 endif ()
274+
275+ # Accumulate JSON configuration for the test
276+ _accumulate_e2e_test_config(
277+ NAME
278+ "${PARSED_ARGS_NAME} "
279+ PYTHON_SCRIPT
280+ "${PARSED_ARGS_PYTHON_SCRIPT} "
281+ LABEL
282+ "${PARSED_ARGS_LABEL} "
283+ CONSTITUTION
284+ ${PARSED_ARGS_CONSTITUTION}
285+ ADDITIONAL_ARGS
286+ ${PARSED_ARGS_ADDITIONAL_ARGS}
287+ ENV
288+ ${TEST_ENV_VARS}
289+ )
153290 endif ()
154291endfunction ()
155292
0 commit comments