v2 / vlib / v / generics / new_generics_regression_test.v
250 lines · 239 sloc · 13.55 KB · 395b1ff3dd4be3c612b7a22b25fce64ece791116
Raw
1// vtest build: !docker-ubuntu-musl && !sanitize-memory-gcc && !sanitize-address-gcc && !sanitize-address-clang && !gcc-windows && !msvc-windows
2// This test ensures the -new-generic-solver option, and its corresponding compiler stage, will not regress silently,
3// as V continues to change. If you make changes to the generics stage to improve it, once you spot a failure here, or
4// some of the expected tests starts passing (which will be also a failure as far as this _test.v file is concerned),
5// you have to edit new_generics_regression_test.v, and remove the corresponding entry inside `failing_tests`. You also
6// need to update the summary line too, so that it matches the current result of running:
7// `./v -new-generic-solver test vlib/v/tests/generics/`
8// `./v -new-generic-solver test vlib/math/vec`
9// on your local working branch.
10// TODO: investigate what exact test fails on msvc only and record it in a separate skip list.
11// TODO: remove this test, once -new-generic-solver has improved so much, that it becomes the new default, since it is slow (~32s on m1).
12import os
13import log
14import term
15
16const vexe = @VEXE
17const vroot = @VEXEROOT
18const vtrace_output = os.getenv('VTRACE_OUTPUT').int() != 0
19
20fn testsuite_begin() {
21 unbuffer_stdout()
22 os.chdir(vroot)!
23 os.setenv('VJOBS', '1', true)
24 // important, when this test itself is run through `v test`; this simplify the handling of the output of the inner `v test` commands
25 os.setenv('VCOLORS', 'never', true)
26 // The nested `v test` runs should validate their full target sets, not inherit outer runner filters/retry state.
27 for key in ['VTEST_ONLY', 'VTEST_ONLY_FN', 'VTEST_FAIL_FAST', 'VTEST_RETRY', 'VTEST_RETRY_MAX'] {
28 os.unsetenv(key)
29 }
30}
31
32fn test_new_generic_solver_does_not_regress_silently() {
33 run_new_generic_solver_tests('vlib/math/vec',
34 '${os.quoted_path(vexe)} -new-generic-solver test vlib/math/vec', expected_summary_vec,
35 expected_summsvc_vec, failing_math_vec_tests[..])
36 run_new_generic_solver_tests('vlib/flag',
37 '${os.quoted_path(vexe)} -new-generic-solver test vlib/flag/', expected_summary_flag,
38 expected_summsvc_flag, failing_flag_tests[..])
39 run_new_generic_solver_tests('vlib/v/tests/generics/',
40 '${os.quoted_path(vexe)} -new-generic-solver test vlib/v/tests/generics/',
41 expected_summary_generics, expected_summsvc_generics, failing_tests[..])
42}
43
44fn run_new_generic_solver_tests(root_label string, test_cmd string, expected_summary string,
45 expected_summsvc string, expected_failures []string) {
46 log.info('>>> running ${term.colorize(term.magenta, test_cmd)} ...')
47 res := os.execute(test_cmd)
48 log.info('>>> done running ${test_cmd} ; exit_code: ${res.exit_code}')
49
50 res_lines := res.output.split_into_lines()
51 if vtrace_output {
52 for tline in res_lines {
53 eprintln('>>>>> tline: ${tline}')
54 }
55 }
56
57 failure_lines := res_lines.filter(it.starts_with('FAIL'))
58 summary_lines := res_lines.filter(it.starts_with('Summary'))
59
60 actual_expected_summary := $if msvc { expected_summsvc } $else { expected_summary }
61 actual_clean_summary := if root_label == 'vlib/flag' {
62 $if msvc { expected_summsvc_flag_clean } $else { expected_summary_flag_clean }
63 } else {
64 ''
65 }
66 found_expected_summary := summary_lines.any(it.contains(actual_expected_summary))
67 found_clean_summary := actual_clean_summary != ''
68 && summary_lines.any(it.contains(actual_clean_summary))
69 if !found_expected_summary && !found_clean_summary {
70 // Before failing, check if the actual failure count falls within an acceptable range.
71 // Different compilers (gcc, tcc, clang, msvc) may produce slightly different failure
72 // counts due to compiler-specific C code generation differences.
73 mut found_acceptable := false
74 for sline in summary_lines {
75 count_str := sline.all_after('files: ').all_before(' failed')
76 actual_count := count_str.int()
77 expected_str := actual_expected_summary.all_after('files: ').all_before(' failed')
78 expected_count := expected_str.int()
79 if actual_count > 0 && expected_count > 0 && actual_count >= expected_count - 2
80 && actual_count <= expected_count + 2 {
81 found_acceptable = true
82 break
83 }
84 }
85 if !found_acceptable {
86 eprintln('----------------------------------------------------------------')
87 eprintln('----------------------------------------------------------------')
88 for tline in res_lines {
89 eprintln('>>>>> tline: ${tline}')
90 }
91 eprintln('----------------------------------------------------------------')
92 eprintln('----------------------------------------------------------------')
93 eprintln('Could not find an accepted summary in: ${summary_lines}')
94 eprintln('actual_expected_summary: ${actual_expected_summary}')
95 if actual_clean_summary != '' {
96 eprintln('actual_clean_summary: ${actual_clean_summary}')
97 }
98 exit(1)
99 }
100 }
101 if found_clean_summary {
102 log.info('>>> Found an accepted clean summary: ${term.colorize(term.yellow,
103 actual_clean_summary)}, OK')
104 println('')
105 return
106 }
107
108 for idx, known in expected_failures {
109 found_expected_failure := failure_lines.any(it.contains(known))
110 assert found_expected_failure, 'expected failing test ${known} , was not found.\nRun `v -new-generic-solver test ${root_label}` manually to verify, and then edit ${@FILE} to reflect the new state.'
111
112 if vtrace_output {
113 eprintln('>>>>> found_expected_failure ${idx + 1} `${term.colorize(term.green, known)}`, OK')
114 }
115 }
116 log.info('>>> Found the expected summary: ${term.colorize(term.yellow, actual_expected_summary)}, OK')
117 println('')
118}
119
120const expected_summsvc_generics = 'Summary for all V _test.v files: 117 failed, 180 passed, 297 total.'
121// The exact failure count varies slightly across compilers.
122const expected_summary_generics = 'Summary for all V _test.v files: 113 failed, 183 passed, 296 total.'
123const expected_summsvc_vec = 'Summary for all V _test.v files: 3 failed, 3 total.'
124const expected_summary_vec = 'Summary for all V _test.v files: 3 failed, 3 total.'
125const expected_summsvc_flag = 'Summary for all V _test.v files: 21 passed, 21 total.'
126const expected_summary_flag = 'Summary for all V _test.v files: 21 passed, 21 total.'
127const expected_summsvc_flag_clean = 'Summary for all V _test.v files: 21 passed, 21 total.'
128const expected_summary_flag_clean = 'Summary for all V _test.v files: 21 passed, 21 total.'
129const failing_tests = [
130 'vlib/v/tests/generics/checks_for_operator_overrides_should_happen_on_the_concrete_types_when_using_generics_test.v',
131 'vlib/v/tests/generics/dump_heap_generic_linked_list_test.v',
132 'vlib/v/tests/generics/generic_array_of_alias_test.v',
133 'vlib/v/tests/generics/generic_array_of_sumtype_push_test.v',
134 'vlib/v/tests/generics/generic_array_ret_test.v',
135 'vlib/v/tests/generics/generic_array_test.v',
136 'vlib/v/tests/generics/generic_comptime_arg_test.v',
137 'vlib/v/tests/generics/generic_default_expression_in_or_block_test.v',
138 'vlib/v/tests/generics/generic_different_type_test.v',
139 'vlib/v/tests/generics/generic_dump_test.v',
140 'vlib/v/tests/generics/generic_fn_assign_generics_struct_test.v',
141 'vlib/v/tests/generics/generic_fn_call_with_reference_argument_test.v',
142 'vlib/v/tests/generics/generic_fn_infer_multi_paras_test.v',
143 'vlib/v/tests/generics/generic_fn_infer_nested_struct_test.v',
144 'vlib/v/tests/generics/generic_fn_multi_return_test.v',
145 'vlib/v/tests/generics/generic_fn_short_syntax_struct_param_test.v',
146 'vlib/v/tests/generics/generic_fn_typeof_name_test.v',
147 'vlib/v/tests/generics/generic_function_error_propagation_test.v',
148 'vlib/v/tests/generics/generic_if_guard_string_interpolation_test.v',
149 'vlib/v/tests/generics/generic_interface_field_test.v',
150 'vlib/v/tests/generics/generic_interface_infer_test.v',
151 'vlib/v/tests/generics/generic_interface_map_value_test.v',
152 'vlib/v/tests/generics/generic_interface_nested_generic_type_infer_test.v',
153 'vlib/v/tests/generics/generic_interface_nested_struct_infer_test.v',
154 'vlib/v/tests/generics/generic_interface_test.v',
155 'vlib/v/tests/generics/generic_lambda_expr_test.v',
156 'vlib/v/tests/generics/generic_linked_list_ref_push_test.v',
157 'vlib/v/tests/generics/generic_map_alias_test.v',
158 'vlib/v/tests/generics/generic_match_expr_test.v',
159 'vlib/v/tests/generics/generic_match_generic_interface_type_test.v',
160 'vlib/v/tests/generics/generic_method_fn_field_result_recheck_test.v',
161 'vlib/v/tests/generics/generic_method_slice_two_param_sibling_test.v',
162 'vlib/v/tests/generics/generic_method_with_variadic_generic_args_test.v',
163 'vlib/v/tests/generics/generic_mut_pointer_param_test.v',
164 'vlib/v/tests/generics/generic_operator_overload_test.v',
165 'vlib/v/tests/generics/generic_receiver_embed_test.v',
166 'vlib/v/tests/generics/generic_resolve_test.v',
167 'vlib/v/tests/generics/generic_return_test.v',
168 'vlib/v/tests/generics/generic_selector_field_test.v',
169 'vlib/v/tests/generics/generic_selector_indexexpr_test.v',
170 'vlib/v/tests/generics/generic_selector_infix_test.v',
171 'vlib/v/tests/generics/generic_selector_test.v',
172 'vlib/v/tests/generics/generic_selector_type_test.v',
173 'vlib/v/tests/generics/generic_smartcast_test.v',
174 'vlib/v/tests/generics/generic_sort_multi_instantiation_test.v',
175 'vlib/v/tests/generics/generic_spawn_test.v',
176 'vlib/v/tests/generics/generic_static_call_test.v',
177 'vlib/v/tests/generics/generic_struct_cstruct_test.v',
178 'vlib/v/tests/generics/generic_struct_field_fn_with_multiple_instantiations_test.v',
179 'vlib/v/tests/generics/generic_struct_init_with_reference_struct_type_test.v',
180 'vlib/v/tests/generics/generic_struct_init_with_update_expr_test.v',
181 'vlib/v/tests/generics/generic_struct_return_test.v',
182 'vlib/v/tests/generics/generic_struct_test.v',
183 'vlib/v/tests/generics/generic_struct_with_linked_list_of_refs_field_test.v',
184 'vlib/v/tests/generics/generic_sumtype_str_test.v',
185 'vlib/v/tests/generics/generic_typeof_test.v',
186 'vlib/v/tests/generics/generics_array_builtin_method_call_test.v',
187 'vlib/v/tests/generics/generics_array_delete_test.v',
188 'vlib/v/tests/generics/generics_array_of_interface_method_call_test.v',
189 'vlib/v/tests/generics/generics_array_of_threads_test.v',
190 'vlib/v/tests/generics/generics_assign_reference_generic_struct_test.v',
191 'vlib/v/tests/generics/generics_call_with_reference_arg_test.v',
192 'vlib/v/tests/generics/generics_fn_field_multi_instance_test.v',
193 'vlib/v/tests/generics/generics_fn_return_generic_interface_test.v',
194 'vlib/v/tests/generics/generics_fn_return_result_test.v',
195 'vlib/v/tests/generics/generics_fn_variable_3_test.v',
196 'vlib/v/tests/generics/generics_for_in_iterate_test.v',
197 'vlib/v/tests/generics/generics_interface_cross_module_recheck_test.v',
198 'vlib/v/tests/generics/generics_interface_method_test.v',
199 'vlib/v/tests/generics/generics_interface_with_generic_method_using_generic_struct_test.v',
200 'vlib/v/tests/generics/generics_interface_with_generic_sumtype_test.v',
201 'vlib/v/tests/generics/generics_interface_with_multi_generic_structs_test.v',
202 'vlib/v/tests/generics/generics_interface_with_multi_generic_types_test.v',
203 'vlib/v/tests/generics/generics_map_with_reference_arg_test.v',
204 'vlib/v/tests/generics/generics_method_call_with_short_syntax_args_test.v',
205 'vlib/v/tests/generics/generics_method_chaining_call_test.v',
206 'vlib/v/tests/generics/generics_method_on_generic_structs_test.v',
207 'vlib/v/tests/generics/generics_method_on_nested_struct2_test.v',
208 'vlib/v/tests/generics/generics_method_on_receiver_aliases_types_test.v',
209 'vlib/v/tests/generics/generics_method_on_receiver_types_test.v',
210 'vlib/v/tests/generics/generics_method_str_overload_test.v',
211 'vlib/v/tests/generics/generics_method_test.v',
212 'vlib/v/tests/generics/generics_method_variable_test.v',
213 'vlib/v/tests/generics/generics_method_with_diff_generic_names_test.v',
214 'vlib/v/tests/generics/generics_method_with_generic_anon_fn_argument_test.v',
215 'vlib/v/tests/generics/generics_mut_receiver_local_copy_regression_test.v',
216 'vlib/v/tests/generics/generics_nested_struct_init_test.v',
217 'vlib/v/tests/generics/generics_params_nested_generic_struct_short_syntax_test.v',
218 'vlib/v/tests/generics/generics_return_closure_test.v',
219 'vlib/v/tests/generics/generics_return_generics_struct_test.v',
220 'vlib/v/tests/generics/generics_stack_of_sumtype_push_test.v',
221 'vlib/v/tests/generics/generics_str_intp_test.v',
222 'vlib/v/tests/generics/generics_struct_anon_fn_type_test.v',
223 'vlib/v/tests/generics/generics_struct_free_test.v',
224 'vlib/v/tests/generics/generics_struct_inst_method_call_test.v',
225 'vlib/v/tests/generics/generics_struct_parent_has_str_to_string_test.v',
226 'vlib/v/tests/generics/generics_struct_to_string_test.v',
227 'vlib/v/tests/generics/generics_struct_with_array_test.v',
228 'vlib/v/tests/generics/generics_struct_with_inconsistent_generic_types_1_test.v',
229 'vlib/v/tests/generics/generics_struct_with_non_generic_interface_test.v',
230 'vlib/v/tests/generics/generics_struct_with_option_fn_test.v',
231 'vlib/v/tests/generics/generics_unused_specialized_fn_array_param_test.v',
232 'vlib/v/tests/generics/generics_with_anon_generics_fn_test.v',
233 'vlib/v/tests/generics/generics_with_assign_nested_generics_call_test.v',
234 'vlib/v/tests/generics/generics_with_embed_generics_method_call_test.v',
235 'vlib/v/tests/generics/generics_with_generics_fn_return_generics_map_type_test.v',
236 'vlib/v/tests/generics/generics_with_generics_struct_receiver_test.v',
237 'vlib/v/tests/generics/generics_with_multi_generics_struct_types_test.v',
238 'vlib/v/tests/generics/generics_with_multi_nested_generic_method_call_ref_arg_test.v',
239 'vlib/v/tests/generics/generics_with_multi_nested_generic_method_call_test.v',
240 'vlib/v/tests/generics/generics_with_multiple_generics_struct_receiver_test.v',
241 'vlib/v/tests/generics/generics_with_nested_external_generics_fn_test.v',
242 'vlib/v/tests/generics/generics_with_nested_generic_method_call_test.v',
243]!
244const failing_math_vec_tests = [
245 'vlib/math/vec/vec2_test.v',
246 'vlib/math/vec/vec3_test.v',
247 'vlib/math/vec/vec4_test.v',
248]!
249
250const failing_flag_tests = []string{}
251