3535import org .junit .jupiter .api .condition .EnabledIfEnvironmentVariable ;
3636import org .junit .jupiter .api .extension .ExtendWith ;
3737import org .junit .jupiter .params .ParameterizedTest ;
38+ import org .junit .jupiter .params .provider .Arguments ;
3839import org .junit .jupiter .params .provider .MethodSource ;
3940import org .junitpioneer .jupiter .RestoreSystemProperties ;
4041import org .junitpioneer .jupiter .SetSystemProperty ;
@@ -211,52 +212,31 @@ void test_the_provideComponent_with_properties(String testFolder) throws IOExcep
211212 assertThat (dropIgnored (new String (content .buffer ))).isEqualTo (dropIgnored (expectedSbom ));
212213 }
213214
214- @ Test
215- @ RestoreSystemProperties
216- void test_marker_constrained_uninstalled_packages_are_skipped_in_component_analysis ()
217- throws IOException {
218- var testFolder = "pip_requirements_txt_marker_skip" ;
219- var targetRequirements =
220- String .format ("src/test/resources/tst_manifests/pip/%s/requirements.txt" , testFolder );
221-
222- // load expected SBOM
223- String expectedSbom ;
224- try (var is =
225- getResourceAsStreamDecision (
226- this .getClass (),
227- String .format ("tst_manifests/pip/%s/expected_component_sbom.json" , testFolder ))) {
228- expectedSbom = new String (is .readAllBytes ());
229- }
230-
231- // pip environment where only six and certifi are installed (pywin32 is Windows-only)
232- String pipFreezeContent = "six==1.16.0\n certifi==2023.7.22\n " ;
233- String pipShowContent =
234- "Name: certifi\n Version: 2023.7.22\n Summary: Python package for providing Mozilla's CA"
235- + " Bundle.\n Requires: \n Required-by: \n ---\n Name: six\n Version: 1.16.0\n Summary:"
236- + " Python 2 and 3 compatibility utilities\n Requires: \n Required-by: " ;
237- System .setProperty (
238- PROP_TRUSTIFY_DA_PIP_FREEZE ,
239- new String (Base64 .getEncoder ().encode (pipFreezeContent .getBytes ())));
240- System .setProperty (
241- PROP_TRUSTIFY_DA_PIP_SHOW ,
242- new String (Base64 .getEncoder ().encode (pipShowContent .getBytes ())));
243-
244- // when providing component content for a manifest with a Windows-only marker package
245- var content = new PythonPipProvider (Path .of (targetRequirements )).provideComponent ();
246-
247- // then SBOM contains six and certifi but not pywin32
248- assertThat (content .type ).isEqualTo (Api .CYCLONEDX_MEDIA_TYPE );
249- assertThat (dropIgnored (new String (content .buffer ))).isEqualTo (dropIgnored (expectedSbom ));
215+ static Stream <Arguments > markerTestCases () {
216+ return Stream .of (
217+ Arguments .of (
218+ "pip_requirements_txt_marker_skip" ,
219+ "six==1.16.0\n certifi==2023.7.22\n " ,
220+ "Name: certifi\n Version: 2023.7.22\n Summary: Python package for providing Mozilla's CA"
221+ + " Bundle.\n Requires: \n Required-by: \n ---\n Name: six\n Version: 1.16.0\n Summary:"
222+ + " Python 2 and 3 compatibility utilities\n Requires: \n Required-by: " ),
223+ Arguments .of (
224+ "pip_requirements_txt_marker_installed" ,
225+ "six==1.16.0\n colorama==0.4.6\n " ,
226+ "Name: six\n Version: 1.16.0\n Summary: Python 2 and 3 compatibility utilities\n Requires:"
227+ + " \n Required-by: \n ---\n Name: colorama\n Version: 0.4.6\n Summary: Cross-platform"
228+ + " colored terminal text\n Requires: \n Required-by: " ));
250229 }
251230
252231 /**
253- * Verifies that marker-only packages (no version operator) that ARE installed appear in the SBOM.
232+ * Verifies that PEP 508 marker-constrained packages are handled correctly: skipped when not
233+ * installed (marker didn't match) and included when installed (marker matched or marker-only).
254234 */
255- @ Test
235+ @ ParameterizedTest
236+ @ MethodSource ("markerTestCases" )
256237 @ RestoreSystemProperties
257- void test_marker_only_installed_packages_are_included_in_component_analysis () throws IOException {
258- // Given a requirements.txt with a marker-only dep that IS installed
259- var testFolder = "pip_requirements_txt_marker_installed" ;
238+ void test_marker_constrained_packages_in_component_analysis (
239+ String testFolder , String pipFreezeContent , String pipShowContent ) throws IOException {
260240 var targetRequirements =
261241 String .format ("src/test/resources/tst_manifests/pip/%s/requirements.txt" , testFolder );
262242
@@ -268,12 +248,6 @@ void test_marker_only_installed_packages_are_included_in_component_analysis() th
268248 expectedSbom = new String (is .readAllBytes ());
269249 }
270250
271- // When pip freeze and pip show include colorama (the marker-only package)
272- String pipFreezeContent = "six==1.16.0\n colorama==0.4.6\n " ;
273- String pipShowContent =
274- "Name: six\n Version: 1.16.0\n Summary: Python 2 and 3 compatibility utilities\n Requires:"
275- + " \n Required-by: \n ---\n Name: colorama\n Version: 0.4.6\n Summary: Cross-platform"
276- + " colored terminal text\n Requires: \n Required-by: " ;
277251 System .setProperty (
278252 PROP_TRUSTIFY_DA_PIP_FREEZE ,
279253 new String (Base64 .getEncoder ().encode (pipFreezeContent .getBytes ())));
@@ -283,7 +257,6 @@ void test_marker_only_installed_packages_are_included_in_component_analysis() th
283257
284258 var content = new PythonPipProvider (Path .of (targetRequirements )).provideComponent ();
285259
286- // Then SBOM contains both six and colorama
287260 assertThat (content .type ).isEqualTo (Api .CYCLONEDX_MEDIA_TYPE );
288261 assertThat (dropIgnored (new String (content .buffer ))).isEqualTo (dropIgnored (expectedSbom ));
289262 }
0 commit comments