1515
1616load ("@rules_testing//lib:analysis_test.bzl" , "analysis_test" )
1717load ("@rules_testing//lib:test_suite.bzl" , "test_suite" )
18+ load ("@rules_testing//lib:truth.bzl" , "matching" )
1819load ("//python:py_runtime_info.bzl" , "PyRuntimeInfo" )
20+ load ("//tests/support:py_runtime_info_subject.bzl" , "py_runtime_info_subject" )
1921
2022def _create_py_runtime_info_without_interpreter_version_info_impl (ctx ):
2123 return [PyRuntimeInfo (
@@ -35,6 +37,57 @@ _create_py_runtime_info_without_interpreter_version_info = rule(
3537 },
3638)
3739
40+ def _simple_binary_impl (ctx ):
41+ executable = ctx .actions .declare_file (ctx .label .name )
42+ ctx .actions .write (executable , "" , is_executable = True )
43+ return [DefaultInfo (
44+ executable = executable ,
45+ files = depset ([executable ]),
46+ )]
47+
48+ _simple_binary = rule (
49+ implementation = _simple_binary_impl ,
50+ executable = True ,
51+ )
52+
53+ def _file_target_impl (ctx ):
54+ output = ctx .actions .declare_file (ctx .label .name + ".txt" )
55+ ctx .actions .write (output , "" )
56+ return [DefaultInfo (files = depset ([output ]))]
57+
58+ _file_target = rule (
59+ implementation = _file_target_impl ,
60+ )
61+
62+ def _create_py_runtime_info_with_interpreter_files_to_run_impl (ctx ):
63+ files_to_run = ctx .attr .files_to_run [DefaultInfo ].files_to_run
64+ kwargs = dict (
65+ bootstrap_template = ctx .file .bootstrap_template ,
66+ interpreter_files_to_run = files_to_run ,
67+ python_version = "PY3" ,
68+ )
69+ if ctx .attr .use_interpreter_path :
70+ kwargs ["interpreter_path" ] = "/python"
71+ else :
72+ kwargs ["files" ] = depset ()
73+ kwargs ["interpreter" ] = ctx .executable .interpreter
74+
75+ return [PyRuntimeInfo (** kwargs )]
76+
77+ _create_py_runtime_info_with_interpreter_files_to_run = rule (
78+ implementation = _create_py_runtime_info_with_interpreter_files_to_run_impl ,
79+ attrs = {
80+ "bootstrap_template" : attr .label (allow_single_file = True , default = "bootstrap.txt" ),
81+ "files_to_run" : attr .label (mandatory = True ),
82+ "interpreter" : attr .label (
83+ cfg = "target" ,
84+ executable = True ,
85+ mandatory = True ,
86+ ),
87+ "use_interpreter_path" : attr .bool (),
88+ },
89+ )
90+
3891_tests = []
3992
4093def _test_can_create_py_runtime_info_without_interpreter_version_info (name ):
@@ -53,6 +106,112 @@ def _test_can_create_py_runtime_info_without_interpreter_version_info_impl(env,
53106
54107_tests .append (_test_can_create_py_runtime_info_without_interpreter_version_info )
55108
109+ def _test_interpreter_files_to_run_with_interpreter (name ):
110+ _simple_binary (
111+ name = name + "_interpreter" ,
112+ )
113+ _create_py_runtime_info_with_interpreter_files_to_run (
114+ name = name + "_subject" ,
115+ files_to_run = name + "_interpreter" ,
116+ interpreter = name + "_interpreter" ,
117+ )
118+ analysis_test (
119+ name = name ,
120+ target = name + "_subject" ,
121+ impl = _test_interpreter_files_to_run_with_interpreter_impl ,
122+ )
123+
124+ def _test_interpreter_files_to_run_with_interpreter_impl (env , target ):
125+ info = env .expect .that_target (target ).provider (
126+ PyRuntimeInfo ,
127+ factory = py_runtime_info_subject ,
128+ )
129+ info .interpreter ().short_path_equals ("{package}/{test_name}_interpreter" )
130+ info .interpreter_files_to_run ().executable ().short_path_equals (
131+ "{package}/{test_name}_interpreter" ,
132+ )
133+
134+ _tests .append (_test_interpreter_files_to_run_with_interpreter )
135+
136+ def _test_interpreter_files_to_run_disallows_interpreter_path (name ):
137+ _simple_binary (
138+ name = name + "_interpreter" ,
139+ )
140+ _create_py_runtime_info_with_interpreter_files_to_run (
141+ name = name + "_subject" ,
142+ files_to_run = name + "_interpreter" ,
143+ interpreter = name + "_interpreter" ,
144+ tags = ["manual" ],
145+ use_interpreter_path = True ,
146+ )
147+ analysis_test (
148+ name = name ,
149+ target = name + "_subject" ,
150+ impl = _test_interpreter_files_to_run_disallows_interpreter_path_impl ,
151+ expect_failure = True ,
152+ )
153+
154+ def _test_interpreter_files_to_run_disallows_interpreter_path_impl (env , target ):
155+ env .expect .that_target (target ).failures ().contains_predicate (
156+ matching .str_matches ("*interpreter_files_to_run*interpreter_path*" ),
157+ )
158+
159+ _tests .append (_test_interpreter_files_to_run_disallows_interpreter_path )
160+
161+ def _test_interpreter_files_to_run_requires_executable (name ):
162+ _simple_binary (
163+ name = name + "_interpreter" ,
164+ )
165+ _file_target (
166+ name = name + "_files_to_run" ,
167+ )
168+ _create_py_runtime_info_with_interpreter_files_to_run (
169+ name = name + "_subject" ,
170+ files_to_run = name + "_files_to_run" ,
171+ interpreter = name + "_interpreter" ,
172+ tags = ["manual" ],
173+ )
174+ analysis_test (
175+ name = name ,
176+ target = name + "_subject" ,
177+ impl = _test_interpreter_files_to_run_requires_executable_impl ,
178+ expect_failure = True ,
179+ )
180+
181+ def _test_interpreter_files_to_run_requires_executable_impl (env , target ):
182+ env .expect .that_target (target ).failures ().contains_predicate (
183+ matching .str_matches ("*interpreter_files_to_run*executable*" ),
184+ )
185+
186+ _tests .append (_test_interpreter_files_to_run_requires_executable )
187+
188+ def _test_interpreter_files_to_run_requires_matching_interpreter (name ):
189+ _simple_binary (
190+ name = name + "_interpreter" ,
191+ )
192+ _simple_binary (
193+ name = name + "_other_interpreter" ,
194+ )
195+ _create_py_runtime_info_with_interpreter_files_to_run (
196+ name = name + "_subject" ,
197+ files_to_run = name + "_other_interpreter" ,
198+ interpreter = name + "_interpreter" ,
199+ tags = ["manual" ],
200+ )
201+ analysis_test (
202+ name = name ,
203+ target = name + "_subject" ,
204+ impl = _test_interpreter_files_to_run_requires_matching_interpreter_impl ,
205+ expect_failure = True ,
206+ )
207+
208+ def _test_interpreter_files_to_run_requires_matching_interpreter_impl (env , target ):
209+ env .expect .that_target (target ).failures ().contains_predicate (
210+ matching .str_matches ("*interpreter_files_to_run.executable*interpreter*" ),
211+ )
212+
213+ _tests .append (_test_interpreter_files_to_run_requires_matching_interpreter )
214+
56215def py_runtime_info_test_suite (name ):
57216 test_suite (
58217 name = name ,
0 commit comments