def test_security_indicator_scoring_missing_secure(
            self, recommendation_type) -> None:
        """Make sure we don't accept package if si info is missing when recommendation is secure."""
        flexmock(GraphDatabase)
        GraphDatabase.should_receive(
            "get_si_aggregated_python_package_version").with_args(
                package_name="flask",
                package_version="0.12.0",
                index_url="https://pypi.org/simple").and_raise(
                    NotFoundError).once()

        package_version = PackageVersion(
            name="flask",
            version="==0.12.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        context = flexmock(graph=GraphDatabase(), stack_info=[])
        context.recommendation_type = recommendation_type
        with pytest.raises(NotAcceptable):
            with SecurityIndicatorStep.assigned_context(context):
                step = SecurityIndicatorStep()
                step.run(None, package_version)

        assert len(context.stack_info) == 1
        assert set(context.stack_info[0].keys()) == {"message", "type", "link"}
    def test_remove_package_tuple_transitive_error(self) -> None:
        """Remove a transitive dependency which will cause error during removal."""
        direct_dependencies = {
            ("flask", "0.12.1", "https://pypi.org/simple"):
            PackageVersion(
                name="flask",
                version="==0.12.1",
                index=Source("https://pypi.org/simple"),
                develop=False,
            )
        }

        paths = {
            ("flask", "0.12.1", "https://pypi.org/simple"): [
                (("flask", "0.12.1", "https://pypi.org/simple"),
                 ("werkzeug", "0.13", "https://pypi.org/simple")),
                (("werkzeug", "0.13", "https://pypi.org/simple"),
                 ("six", "1.0.0", "https://pypi.org/simple")),
            ]
        }

        step_context = StepContext.from_paths(direct_dependencies, paths=paths)

        with pytest.raises(CannotRemovePackage):
            with step_context.remove_package_tuples(
                ("six", "1.0.0", "https://pypi.org/simple")):
                pass
    def test_not_resolved(self) -> None:
        direct_dependencies = {
            ("flask", "1.12.0", "https://pypi.org/simple"):
            PackageVersion(
                name="flask",
                version="==1.12.0",
                index="https://pypi.org/simple",
                develop=False,
            )
        }
        paths = {
            ("flask", "1.12.0", "https://pypi.org/simple"):
            [(("flask", "1.12.0", "https://pypi.org/simple"), ("werkzeug",
                                                               "0.13", None))]
        }
        step_context = StepContext.from_paths(direct_dependencies, paths)
        assert ("werkzeug", "0.13",
                None) in step_context.iter_transitive_dependencies_tuple()
        assert ("werkzeug", "0.13", None) in step_context.unsolved_packages
        assert step_context.unsolved_packages.get(
            ("werkzeug", "0.13", None)) is not None

        assert len(
            list(step_context.iter_transitive_dependencies(develop=None))) == 1
        assert len(
            list(
                step_context.iter_transitive_dependencies(develop=False))) == 1
        assert len(
            list(step_context.iter_transitive_dependencies(develop=True))) == 0
        direct_dependencies = list(step_context.iter_direct_dependencies())
        assert len(direct_dependencies) == 1
        assert direct_dependencies[0].name == "flask"
Exemple #4
0
    def test_no_rule(self, context: Context) -> None:
        """Test if no rule is configured for the given package."""
        package_version = PackageVersion(
            name="flask",
            version="==1.1.2",
            index=Source("https://pypi.org/simple"),
            develop=False)
        (GraphDatabase.should_receive(
            "get_python_package_version_solver_rules_all").with_args(
                "flask",
                "1.1.2",
                "https://pypi.org/simple",
            ).and_return([]))
        (GraphDatabase.should_receive(
            "get_python_package_version_solver_rules_all").with_args(
                "flask",
                "1.1.2",
            ).and_return([]))

        context.graph = GraphDatabase()

        assert not context.stack_info, "No stack info should be provided before test run"

        sieve = self.UNIT_TESTED()
        sieve.pre_run()

        with self.UNIT_TESTED.assigned_context(context):
            assert list(sieve.run(
                p for p in [package_version])) == [package_version]

        assert not context.stack_info, "No stack info should be provided by the pipeline unit"
    def test_remove_package_tuple_transitive_with_direct_error(self) -> None:
        """Test removal of a package which does not have any candidate of direct dependency."""
        paths = {}
        direct_dependencies = {}
        source = Source("https://pypi.org/simple")
        for version_identifier in ("0.12.1", "1.0.1"):
            package_tuple = ("flask", version_identifier, source.url)

            direct_dependencies[package_tuple] = PackageVersion(
                name="flask",
                version="==" + version_identifier,
                index=source.url,
                develop=False,
            )

            paths[package_tuple] = [
                (package_tuple, ("werkzeug", "0.13",
                                 "https://pypi.org/simple")),
                (package_tuple, ("werkzeug", "0.14",
                                 "https://pypi.org/simple")),
                (("werkzeug", "0.13", "https://pypi.org/simple"),
                 ("six", "1.0.0", "https://pypi.org/simple")),
                (("werkzeug", "0.14", "https://pypi.org/simple"),
                 ("six", "1.0.0", "https://pypi.org/simple")),
            ]

        step_context = StepContext.from_paths(direct_dependencies, paths)

        with pytest.raises(CannotRemovePackage):
            with step_context.remove_package_tuples(
                ("six", "1.0.0", "https://pypi.org/simple")):
                pass
Exemple #6
0
    def test_run_develop_not_match(self, context: Context, state: State,
                                   develop: bool) -> None:
        """Test not running the prescription if develop flag is set."""
        prescription_str = f"""
name: StepUnit
type: step
should_include:
  times: 1
  adviser_pipeline: true
match:
  package_version:
    name: numpy
    develop: {'true' if develop else 'false'}
run:
  score: 0.5
"""
        prescription = yaml.safe_load(prescription_str)
        PRESCRIPTION_STEP_SCHEMA(prescription)
        StepPrescription.set_prescription(prescription)
        package_version = PackageVersion(
            name="numpy",
            version="==1.19.1",
            index=Source("https://thoth-station.ninja/simple"),
            develop=not develop,
        )

        unit = StepPrescription()
        unit.pre_run()
        with unit.assigned_context(context):
            assert unit.run(state, package_version) is None
Exemple #7
0
    def test_cve_not_acceptable(self) -> None:
        """Test raising an exception if a secure software stack should be resolved."""
        flexmock(GraphDatabase)
        GraphDatabase.should_receive("get_python_cve_records_all").with_args(
            package_name="flask",
            package_version="0.12.0").and_return([self._FLASK_CVE]).once()

        package_version = PackageVersion(
            name="flask",
            version="==0.12.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        context = flexmock(graph=GraphDatabase(),
                           recommendation_type=RecommendationType.SECURITY,
                           stack_info=[])
        step = CvePenalizationStep()
        with CvePenalizationStep.assigned_context(context):
            assert not step._messages_logged
            with pytest.raises(NotAcceptable):
                step.run(None, package_version)

        assert len(step._messages_logged) == 1
        assert ("flask", "0.12.0",
                "https://pypi.org/simple") in step._messages_logged
        assert len(context.stack_info) == 1
        assert set(context.stack_info[0].keys()) == {"message", "link", "type"}
        assert self.verify_justification_schema(context.stack_info)
Exemple #8
0
    def test_cve_sieve_allow_cve(self, context: Context) -> None:
        """Make sure a CVE filtering allows allow-cve configuration."""
        context.graph.should_receive("get_python_cve_records_all").with_args(
            package_name="flask",
            package_version="0.12.0").and_return([self._FLASK_CVE])

        pv = PackageVersion(
            name="flask",
            version="==0.12.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        assert not context.stack_info

        context.recommendation_type = RecommendationType.SECURITY

        context.labels["allow-cve"] = self._FLASK_CVE["cve_id"]
        with self.UNIT_TESTED.assigned_context(context):
            unit = self.UNIT_TESTED()
            unit.pre_run()
            result = list(unit.run((p for p in (pv, ))))

        assert result == [pv]
        assert context.stack_info == []
Exemple #9
0
    def test_run_log(self, caplog, context: Context, log_level: str) -> None:
        """Check logging messages."""
        prescription_str = f"""
name: SieveUnit
type: sieve
should_include:
  times: 1
  adviser_pipeline: true
match:
  package_version:
    name: flask
    version: '>1.0,<=1.1.0'
    index_url: 'https://pypi.org/simple'
run:
  log:
    message: Some stack warning message printed by a sieve
    type: {log_level}
"""
        prescription = yaml.safe_load(prescription_str)
        PRESCRIPTION_SIEVE_SCHEMA(prescription)
        SievePrescription.set_prescription(prescription)
        package_version = PackageVersion(
            name="flask",
            version="==1.1.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )
        self.check_run_log(
            caplog, context, log_level, SievePrescription, package_versions=(pv for pv in [package_version])
        )
Exemple #10
0
    def test_cut_unsolved_error(self):
        """Test error cutting if dependency graph cannot be constructed."""
        source = Source("https://pypi.org/simple")
        direct_dependencies = {
            ("flask", "0.12.1", source.url): PackageVersion(
                name="flask",
                version="==0.12.1",
                index=source,
                develop=False,
            ),
        }

        paths = {
            ("flask", "0.12.1", "https://pypi.org/simple"): [
                (("flask", "0.12.1", "https://pypi.org/simple"),
                 ("werkzeug", "0.15.5", None)),
            ],
        }

        step_context = StepContext.from_paths(direct_dependencies, paths)

        cut_unsolved = CutUnsolved(
            graph=None,
            project=None,
            library_usage=None,
        )

        with pytest.raises(CannotRemovePackage):
            cut_unsolved.run(step_context)
    def test_tf_avx2(self) -> None:
        """Test recommending TensorFlow with AVX2 support."""
        package_version = PackageVersion(
            name="tensorflow",
            version="==2.2.0",
            develop=False,
            index=Source(
                "https://tensorflow.pypi.thoth-station.ninja/index/manylinux2010/AVX2/simple"
            ),
        )

        # State and context are unused in the actual pipeline run.
        state, context = flexmock(), flexmock()
        with TensorFlowAVX2Step.assigned_context(context):
            unit = TensorFlowAVX2Step()
            result = unit.run(state, package_version)
            assert len(result[1]) == 1
            assert result[1][0].pop(
                "link",
                None) is not None, "No link to justification document provided"
            assert result == (
                0.2,
                [{
                    "message":
                    "AICoE TensorFlow builds are optimized for AVX2 instruction "
                    "sets supported in the CPU identified",
                    "type":
                    "INFO",
                }],
            )
            assert self.verify_justification_schema(result[1])
Exemple #12
0
    def test_no_cve_record(self,
                           recommendation_type: RecommendationType) -> None:
        """Make sure no CVEs do not affect CVE scoring."""
        flexmock(GraphDatabase)
        GraphDatabase.should_receive("get_python_cve_records_all").with_args(
            package_name="flask",
            package_version="0.12.0").and_return([]).once()

        package_version = PackageVersion(
            name="flask",
            version="==0.12.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        context = flexmock(graph=GraphDatabase(),
                           recommendation_type=recommendation_type)
        with CvePenalizationStep.assigned_context(context):
            step = CvePenalizationStep()
            result = step.run(None, package_version)

        assert isinstance(result, tuple)
        assert len(result) == 2
        assert result[0] == 0.0
        assert result[1] == [{
            "link": "https://thoth-station.ninja/j/no_cve",
            "message": "No known CVE known for 'flask' in version '0.12.0'",
            "package_name": "flask",
            "type": "INFO",
        }]
Exemple #13
0
    def test_pre_releases_disallowed_removal(self, context: Context,
                                             package_name: str,
                                             package_version: str) -> None:
        """Test no removals if pre-releases are allowed."""
        pv = PackageVersion(
            name=package_name,
            version=f"=={package_version}",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        project = Project.from_strings(self._CASE_GLOBAL_DISALLOWED_PIPFILE)
        context.project = project
        sieve = self.UNIT_TESTED()
        sieve.update_configuration({
            "package_name":
            None,
            "allow_prereleases":
            project.pipfile.thoth.allow_prereleases
        })

        assert not context.stack_info
        with self.UNIT_TESTED.assigned_context(context):
            assert list(sieve.run(p for p in [pv])) == []

        assert len(context.stack_info) == 1
        assert self.verify_justification_schema(context.stack_info)
Exemple #14
0
    def test_remove_pre_releases_disallowed_noop(self, context: Context,
                                                 package_name: str,
                                                 package_version: str) -> None:
        """Test NOT removing dependencies based on pre-release configuration."""
        pv = PackageVersion(
            name=package_name,
            version=f"=={package_version}",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        project = Project.from_strings(self._CASE_GLOBAL_DISALLOWED_PIPFILE)
        context.project = project
        sieve = self.UNIT_TESTED()
        sieve.update_configuration({
            "package_name":
            None,
            "allow_prereleases":
            project.pipfile.thoth.allow_prereleases
        })

        assert not context.stack_info
        with self.UNIT_TESTED.assigned_context(context):
            assert list(sieve.run(p for p in [pv])) == [pv]

        assert not context.stack_info, "No stack information should be provided"
Exemple #15
0
    def test_run_not_acceptable(self, context: Context, state: State) -> None:
        """Check raising not acceptable."""
        prescription_str = """
name: StepUnit
type: step
should_include:
  times: 1
  adviser_pipeline: true
  dependency_monkey_pipeline: true
match:
  package_version:
      name: flask
      version: "~=0.0"
      index_url: "https://pypi.org/simple"
run:
  not_acceptable: This is exception message reported
"""
        prescription = yaml.safe_load(prescription_str)
        PRESCRIPTION_STEP_SCHEMA(prescription)
        StepPrescription.set_prescription(prescription)
        package_version = PackageVersion(
            name="flask",
            version="==0.12",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )
        self.check_run_not_acceptable(context,
                                      StepPrescription,
                                      state=state,
                                      package_version=package_version)
Exemple #16
0
    def test_run_stack_info(self, context: Context) -> None:
        """Check assigning stack info."""
        prescription_str = """
name: SieveUnit
type: sieve
should_include:
  times: 1
  adviser_pipeline: true
match:
  package_version:
    name: flask
    version: '>1.0,<=1.1.0'
    index_url: 'https://pypi.org/simple'
run:
  stack_info:
    - type: WARNING
      message: Some stack warning message printed by a sieve
      link: https://thoth-station.ninja
"""
        prescription = yaml.safe_load(prescription_str)
        PRESCRIPTION_SIEVE_SCHEMA(prescription)
        SievePrescription.set_prescription(prescription)
        package_version = PackageVersion(
            name="flask",
            version="==1.1.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        self.check_run_stack_info(context, SievePrescription, package_versions=(pv for pv in [package_version]))
Exemple #17
0
    def test_run_stack_info(self, context: Context, state: State) -> None:
        """Check assigning stack info."""
        prescription_str = """
name: StepUnit
type: step
should_include:
  times: 1
  adviser_pipeline: true
match:
  package_version:
    index_url: 'https://thoth-station.ninja/simple'
run:
  stack_info:
    - type: WARNING
      message: Some message
      link: https://thoth-station.ninja
"""
        prescription = yaml.safe_load(prescription_str)
        PRESCRIPTION_STEP_SCHEMA(prescription)
        StepPrescription.set_prescription(prescription)
        package_version = PackageVersion(
            name="flask",
            version="==1.1.0",
            index=Source("https://thoth-station.ninja/simple"),
            develop=False,
        )

        self.check_run_stack_info(context,
                                  StepPrescription,
                                  state=state,
                                  package_version=package_version)
Exemple #18
0
    def test_indexes_in_meta(self):
        """Check indexes being adjusted when inserting a new package."""
        package_version = PackageVersion(
            name="tensorflow",
            version="==1.9.0",
            develop=False,
            index=Source(
                "http://tensorflow.pypi.thoth-station.ninja/index/fedora28/jemalloc/simple/tensorflow/"
            ),
        )

        project = Project.from_package_versions([package_version])

        project_dict = project.to_dict()
        pipfile_dict = project_dict["requirements"]
        pipfile_lock_dict = project_dict["requirements_locked"]

        assert pipfile_lock_dict is None

        assert len(pipfile_dict["source"]) == 1
        assert pipfile_dict["source"] == [{
            "url":
            "http://tensorflow.pypi.thoth-station.ninja/index/fedora28/jemalloc/simple/tensorflow/",
            "verify_ssl":
            True,
            "name":
            "tensorflow-pypi-thoth-station-ninja",
        }]
Exemple #19
0
    def test_run_log(self, caplog, context: Context, state: State,
                     log_level: str) -> None:
        """Check logging messages."""
        prescription_str = f"""
name: StepUnit
type: step
should_include:
  times: 1
  adviser_pipeline: true
match:
  package_version:
    name: flask
run:
  log:
    message: Seen flask during resolution
    type: {log_level}
"""
        prescription = yaml.safe_load(prescription_str)
        PRESCRIPTION_STEP_SCHEMA(prescription)
        StepPrescription.set_prescription(prescription)
        package_version = PackageVersion(
            name="flask",
            version="==1.1.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )
        self.check_run_log(caplog,
                           context,
                           log_level,
                           StepPrescription,
                           state=state,
                           package_version=package_version)
Exemple #20
0
    def test_run_noop(self, context: Context, tf_versions: List[str]) -> None:
        """Test not adding a pseudonym for TensorFlow if no alternative releases found."""
        unit = self.UNIT_TESTED()

        package_version = PackageVersion(
            name=unit.configuration["package_name"],
            version="==1.0.0",
            develop=False,
            index=Source("https://pypi.org/simple"),
        )

        context.graph.should_receive(
            "get_solved_python_package_versions_all"
        ).with_args(
            package_name="tensorflow-gpu",
            package_version=None,
            index_url="https://pypi.org/simple",
            count=None,
            os_name=context.project.runtime_environment.operating_system.name,
            os_version=context.project.runtime_environment.operating_system.
            version,
            python_version=context.project.runtime_environment.python_version,
            distinct=True,
            is_missing=False,
        ).and_return(tf_versions).once()

        with unit.assigned_context(context):
            unit.pre_run()
            assert list(unit.run(package_version)) == []
Exemple #21
0
    def test_cve_penalization(self) -> None:
        """Make sure a CVE affects stack score."""
        flexmock(GraphDatabase)
        GraphDatabase.should_receive("get_python_cve_records_all").with_args(
            package_name="flask",
            package_version="0.12.0").and_return([self._FLASK_CVE]).once()

        package_version = PackageVersion(
            name="flask",
            version="==0.12.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        context = flexmock(graph=GraphDatabase(),
                           recommendation_type=RecommendationType.TESTING)
        with CvePenalizationStep.assigned_context(context):
            step = CvePenalizationStep()
            result = step.run(None, package_version)

        assert result is not None
        assert isinstance(result, tuple) and len(result) == 2
        assert isinstance(result[0], float)
        assert result[0] == 1 * CvePenalizationStep.CONFIGURATION_DEFAULT[
            "cve_penalization"]
        assert isinstance(result[1], list)
        assert result[1] == [self._FLASK_CVE]
        assert self.verify_justification_schema(result[1])
Exemple #22
0
    def test_os_sieve_no_error(self):
        """Test no error raised if no packages satisfy OS specific requirements."""
        package_versions = [
            PackageVersion(
                name="tensorflow",
                version="==1.9.0",
                index=Source(
                    "https://tensorflow.pypi.thoth-station.ninja/index/fedora/30/jemalloc/simple/"
                ),
                develop=False,
            )
        ]

        sieve_context = SieveContext.from_package_versions(package_versions)
        project = Project.from_strings(
            pipfile_str=self._PIPFILE_CONTENT_AICOE,
            runtime_environment=RuntimeEnvironment.from_dict(
                {"operating_system": {
                    "name": "ubi",
                    "version": "9"
                }}))
        os_sieve = OperatingSystemSieve(graph=None, project=project)
        os_sieve.run(sieve_context)

        assert set(sieve_context.iter_direct_dependencies_tuple()) == {
            ("tensorflow", "1.9.0",
             "https://tensorflow.pypi.thoth-station.ninja/index/fedora/30/jemalloc/simple/"
             ),
        }
Exemple #23
0
    def test_run_noop(
        self, context: Context, pv_version: str, pv_index_url: str, conf_version: str, conf_index_url: str
    ) -> None:
        """Test not adding a pseudonym for the given package."""
        unit = self.UNIT_TESTED()
        unit.update_configuration(
            {
                "package_name": "tensorflow",
                "package_version": conf_version,
                "index_url": conf_index_url,
                "aliases": [
                    {
                        "package_name": "intel-tensorflow",
                        "package_version": "2.2.0",
                        "index_url": "https://pypi.org/simple",
                    },
                    {
                        "package_name": "tensorflow-gpu",
                        "package_version": "2.2.0",
                        "index_url": "https://pypi.org/simple",
                    },
                    {
                        "package_name": "tensorflow",
                        "package_version": "2.2.0",
                        "index_url": "https://thoth-station.ninja/simple",
                    },
                ],
            }
        )

        package_version = PackageVersion(
            name="tensorflow", version=pv_version, index=Source(pv_index_url), develop=False
        )
        result = list(unit.run(package_version))
        assert len(result) == 0
Exemple #24
0
    def test_security_indicator_scoring_missing_stable(
            self, recommendation_type) -> None:
        """Make sure package is kept even if no score exists for security indicators and add justification."""
        flexmock(GraphDatabase)
        GraphDatabase.should_receive(
            "get_si_aggregated_python_package_version").with_args(
                package_name="flask",
                package_version="0.12.0",
                index_url="https://pypi.org/simple").and_raise(
                    NotFoundError).once()

        package_version = PackageVersion(
            name="flask",
            version="==0.12.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        context = flexmock(graph=GraphDatabase())
        context.recommendation_type = recommendation_type
        with SecurityIndicatorStep.assigned_context(context):
            step = SecurityIndicatorStep()
            result = step.run(None, package_version)

        assert result is not None
        assert isinstance(result, tuple) and len(result) == 2
        assert result[0] == 0
        assert len(result[1]) == 1
        assert self.verify_justification_schema(result[1])
        assert result[1][0]["type"] == "WARNING"
        assert (result[1][0]["message"] ==
                "flask===0.12.0 on https://pypi.org/simple has no "
                "gathered information regarding security.")
    def test_remove_package_tuple_transitive_with_direct_diamond_error(
            self) -> None:
        """Test removal of a package which does not have any candidate of direct dependency."""
        direct_dependencies = {
            ("flask", "0.12.1", "https://pypi.org/simple"):
            PackageVersion(
                name="flask",
                version="==0.12.1",
                index=Source("https://pypi.org/simple"),
                develop=False,
            )
        }

        paths = {
            ("flask", "0.12.1", "https://pypi.org/simple"): [
                (("flask", "0.12.1", "https://pypi.org/simple"),
                 ("werkzeug", "0.13", "https://pypi.org/simple")),
                (("werkzeug", "0.13", "https://pypi.org/simple"),
                 ("six", "1.0.0", "https://pypi.org/simple")),
                (("flask", "0.12.1", "https://pypi.org/simple"),
                 ("werkzeug", "0.14", "https://pypi.org/simple")),
                (("werkzeug", "0.14", "https://pypi.org/simple"),
                 ("six", "1.0.0", "https://pypi.org/simple")),
            ],
        }

        step_context = StepContext.from_paths(direct_dependencies, paths)

        with pytest.raises(CannotRemovePackage):
            with step_context.remove_package_tuples(
                ("six", "1.0.0", "https://pypi.org/simple")):
                pass
Exemple #26
0
    def test_security_indicator_with_high_confidence(self) -> None:
        """Make sure we don't accept package if si info is missing when recommendation is secure."""
        flexmock(GraphDatabase)
        GraphDatabase.should_receive(
            "get_si_aggregated_python_package_version").with_args(
                package_name="flask",
                package_version="0.12.0",
                index_url="https://pypi.org/simple").and_return(
                    self._HIGH_HIGH_SECURITY_INFO).once()

        package_version = PackageVersion(
            name="flask",
            version="==0.12.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        context = flexmock(graph=GraphDatabase(), stack_info=[])
        context.recommendation_type = RecommendationType.SECURITY
        with pytest.raises(NotAcceptable):
            with SecurityIndicatorStep.assigned_context(context):
                step = SecurityIndicatorStep()
                step.run(None, package_version)
        assert len(context.stack_info) == 1
        assert self.verify_justification_schema(context.stack_info)
    def _prepare_step_context() -> StepContext:
        """Prepare step context for test scenarios."""
        direct_dependencies = {}
        paths = {}
        source = Source("https://pypi.org/simple")

        for version_identifier in ("0.12.1", "1.0.1"):
            package_tuple = ("flask", version_identifier, source.url)
            direct_dependencies[package_tuple] = PackageVersion(
                name="flask",
                version="==" + version_identifier,
                index=source.url,
                develop=False,
            )

            paths[package_tuple] = [
                (package_tuple, ("werkzeug", "0.13",
                                 "https://pypi.org/simple")),
                (package_tuple, ("werkzeug", "0.14",
                                 "https://pypi.org/simple")),
                (("werkzeug", "0.13", "https://pypi.org/simple"),
                 ("six", "1.7.0", "https://pypi.org/simple")),
                (("werkzeug", "0.13", "https://pypi.org/simple"),
                 ("six", "1.8.0", "https://pypi.org/simple")),
                (("werkzeug", "0.14", "https://pypi.org/simple"),
                 ("six", "1.7.0", "https://pypi.org/simple")),
                (("werkzeug", "0.14", "https://pypi.org/simple"),
                 ("six", "1.8.0", "https://pypi.org/simple")),
            ]

        return StepContext.from_paths(direct_dependencies, paths)
Exemple #28
0
    def test_security_indicator_scoring(self) -> None:
        """Make sure we do score security indicators when the info is available."""
        flexmock(GraphDatabase)
        GraphDatabase.should_receive(
            "get_si_aggregated_python_package_version").with_args(
                package_name="flask",
                package_version="0.12.0",
                index_url="https://pypi.org/simple").and_return(
                    self._SECURITY_INFO_EXISTS).once()

        package_version = PackageVersion(
            name="flask",
            version="==0.12.0",
            index=Source("https://pypi.org/simple"),
            develop=False,
        )

        context = flexmock(graph=GraphDatabase())
        context.recommendation_type = RecommendationType.STABLE
        with SecurityIndicatorStep.assigned_context(context):
            step = SecurityIndicatorStep()
            result = step.run(None, package_version)

        assert result is not None
        assert isinstance(result, tuple) and len(result) == 2
        assert isinstance(result[0], float)
        assert self.verify_justification_schema(result[1])
Exemple #29
0
    def test_remove_all_transitive_error(self):
        """Test raising of an error if all the transitive deps of a type were removed."""
        source = Source("https://pypi.org/simple")
        direct_dependencies = {
            ("tensorflow", "2.0.0", source.url):
            PackageVersion(
                name="tensorflow",
                version="==2.0.0",
                index=source,
                develop=False,
            )
        }

        paths = {
            ("tensorflow", "2.0.0", "https://pypi.org/simple"): [
                (("tensorflow", "2.0.0", "https://pypi.org/simple"),
                 ("numpy", "1.0.0rc1", "https://thoth-station.ninja/simple")),
            ]
        }

        step_context = StepContext.from_paths(direct_dependencies, paths)

        project = Project.from_strings(self._CASE_PIPFILE)
        restrict_indexes = CutPreReleases(
            graph=None,
            project=project,
            library_usage=None,
        )

        with pytest.raises(CannotRemovePackage):
            restrict_indexes.run(step_context)
Exemple #30
0
    def test_run_pseudonym(self, context: Context) -> None:
        """Test adding a pseudonym for TensorFlow."""
        unit = self.UNIT_TESTED()

        package_version = PackageVersion(
            name=unit.configuration["package_name"],
            version="==1.0.0",
            develop=False,
            index=Source("https://pypi.org/simple"),
        )

        context.graph.should_receive("get_solved_python_package_versions_all").with_args(
            package_name="tensorflow-gpu",
            package_version=None,
            index_url="https://pypi.org/simple",
            count=None,
            os_name=context.project.runtime_environment.operating_system.name,
            os_version=context.project.runtime_environment.operating_system.version,
            python_version=context.project.runtime_environment.python_version,
            distinct=True,
            is_missing=False,
        ).and_return(
            [
                ("tensorflow-gpu", "1.0.0", "https://pypi.org/simple"),
                ("tensorflow-gpu", "2.0.0", "https://pypi.org/simple"),
            ]
        ).once()

        with unit.assigned_context(context):
            unit.pre_run()
            result = unit.run(package_version)
            assert list(result) == [("tensorflow-gpu", package_version.locked_version, package_version.index.url)]