예제 #1
0
    def test_force_download_before_install(self):
        """Test two deps on the same spec with installation and download.

        Same as test_force_download_after_install but in a different
        order. The end result should be the same.
        """
        env = BaseEnv()
        env.set_build("x86_64-linux", "rhes8", "mylinux")
        asr = AnodSpecRepository(self.spec_dir)
        ac = AnodContext(asr, default_env=env)
        ac.add_anod_action("spec_download_dep",
                           env=ac.default_env,
                           primitive="build")
        result = ac.schedule(ac.always_create_source_resolver)

        assert set(result.vertex_data.keys()) == {
            "root",
            "mylinux.x86_64-linux.spec_download_dep.build",
            "mylinux.x86_64-linux.spec_build.install",
            "mylinux.x86_64-linux.spec_build.download_bin",
        }
        ac.add_anod_action("spec_install_dep",
                           env=ac.default_env,
                           primitive="build")
        ac.schedule(ac.always_create_source_resolver)
        result = ac.schedule(ac.always_create_source_resolver)

        assert set(result.vertex_data.keys()) == {
            "root",
            "mylinux.x86_64-linux.spec_install_dep.build",
            "mylinux.x86_64-linux.spec_download_dep.build",
            "mylinux.x86_64-linux.spec_build.install",
            "mylinux.x86_64-linux.spec_build.download_bin",
        }
예제 #2
0
    def test_force_download_after_build(self):
        """Test two deps on the same spec with build and download.

        Here we have two specs having an "build_tree" and a "download"
        depdendency on the same spec (spec_build). When the two are set
        together the scheduler cannot find a solution.
        """
        env = BaseEnv()
        env.set_build("x86_64-linux", "rhes8", "mylinux")
        asr = AnodSpecRepository(self.spec_dir)
        ac = AnodContext(asr, default_env=env)
        ac.add_anod_action("spec_build_dep",
                           env=ac.default_env,
                           primitive="build")

        # Verify that, when scheduling this plan, the scheduler ask for
        # having an explicit build
        with pytest.raises(SchedulingError) as err:
            ac.schedule(ac.always_create_source_resolver)
        assert "A spec in the plan has a build_tree dependency on spec_build" in str(
            err)

        # Verify that after adding a download dep, the scheduler now
        # warns that he cannot resolve the plan
        ac.add_anod_action("spec_download_dep",
                           env=ac.default_env,
                           primitive="build")
        with pytest.raises(SchedulingError) as err:
            ac.schedule(ac.always_create_source_resolver)
        assert "explicit DownloadBinary decision made" in str(err)
예제 #3
0
    def test_force_download_after_install(self):
        """Test two deps on the same spec with installation and download.

        Here we have two specs having an "installation" and a "download"
        depdendency on the same spec (spec_build). When the two are set
        together the scheduler find the proper solution: download.
        """
        env = BaseEnv()
        env.set_build("x86_64-linux", "rhes8", "mylinux")
        asr = AnodSpecRepository(self.spec_dir)
        ac = AnodContext(asr, default_env=env)
        ac.add_anod_action("spec_install_dep",
                           env=ac.default_env,
                           primitive="build")
        with pytest.raises(SchedulingError) as err:
            ac.schedule(ac.always_create_source_resolver)
        assert "This plan resolver cannot decide" in str(err)

        ac.add_anod_action("spec_download_dep",
                           env=ac.default_env,
                           primitive="build")
        result = ac.schedule(ac.always_create_source_resolver)

        assert set(result.vertex_data.keys()) == {
            "root",
            "mylinux.x86_64-linux.spec_install_dep.build",
            "mylinux.x86_64-linux.spec_download_dep.build",
            "mylinux.x86_64-linux.spec_build.install",
            "mylinux.x86_64-linux.spec_build.download_bin",
        }
예제 #4
0
 def get_source_closure(self,
                        name,
                        expand_packages=True,
                        other_builds=None):
     asr = AnodSpecRepository(self.spec_dir)
     ac = AnodContext(asr)
     anod_instance = ac.add_anod_action(name, primitive="build").data
     anod_instance = get_build_node(anod_instance, ac, anod_instance)
     if other_builds is not None:
         for b in other_builds:
             ac.add_anod_action(b, primitive="build")
     return SourceClosure(anod_instance=anod_instance,
                          context=ac,
                          expand_packages=expand_packages)
예제 #5
0
 def test_context_init(self):
     # Create a context using:
     # 1. the local default configuration
     # 2. forcing a x86-linux configuration
     asr = AnodSpecRepository(self.spec_dir)
     ac = AnodContext(asr)
     assert ac.default_env.build == BaseEnv().build
     assert ac.default_env.host == BaseEnv().host
     assert ac.default_env.target == BaseEnv().target
     self.create_context()
예제 #6
0
 def create_context(self):
     # Create a context for a x86-linux machine
     asr = AnodSpecRepository(self.spec_dir)
     asr.repos['spec1-git'] = 'spec1-git'
     asr.repos['spec8-git'] = 'spec8-git'
     asr.repos['spec2-git'] = 'spec2-git'
     env = BaseEnv()
     env.set_build('x86-linux', 'rhes6', 'mylinux')
     ac = AnodContext(asr, default_env=env)
     return ac
예제 #7
0
    def test_force_download_without_download_primitive(self):
        """Test that the force download do not require the download primitive.

        Having a download() primitive or not should not impact this feature.
        """
        env = BaseEnv()
        env.set_build("x86_64-linux", "rhes8", "mylinux")
        asr = AnodSpecRepository(self.spec_dir)
        ac = AnodContext(asr, default_env=env)
        ac.add_anod_action(
            "spec_download_dep_for_nodownloadprimitive",
            env=ac.default_env,
            primitive="build",
        )
        result = ac.schedule(ac.always_create_source_resolver)

        assert set(result.vertex_data.keys()) == {
            "root",
            "mylinux.x86_64-linux.spec_download_dep_for_nodownloadprimitive.build",
            "mylinux.x86_64-linux.spec_nodownloadprimitive.install",
            "mylinux.x86_64-linux.spec_nodownloadprimitive.download_bin",
        }
예제 #8
0
    def test_force_download_before_build(self):
        """Test two deps on the same spec with build and download.

        Same as test_force_download_after_build but in a different order.
        The expected result is the same: an error should be raised.
        """
        env = BaseEnv()
        env.set_build("x86_64-linux", "rhes8", "mylinux")
        asr = AnodSpecRepository(self.spec_dir)
        ac = AnodContext(asr, default_env=env)
        ac.add_anod_action("spec_download_dep",
                           env=ac.default_env,
                           primitive="build")
        ac.add_anod_action("spec_build_dep",
                           env=ac.default_env,
                           primitive="build")
        with pytest.raises(SchedulingError) as err:
            ac.schedule(ac.always_create_source_resolver)
        assert "explicit DownloadBinary decision made" in str(err)
예제 #9
0
    def create_context(self, reject_duplicates=True):
        """Create a spec repository and anod context.

        :param reject_duplicates: whether to reject duplicates in plan
        :type reject_duplicates: bool

        :rtype: AnodContext
        """
        # Create a context for a x86-linux machine
        asr = AnodSpecRepository(self.spec_dir)
        asr.repos['spec1-git'] = 'spec1-git'
        asr.repos['spec8-git'] = 'spec8-git'
        asr.repos['spec2-git'] = 'spec2-git'
        env = BaseEnv()
        env.set_build('x86-linux', 'rhes6', 'mylinux')
        ac = AnodContext(asr,
                         default_env=env,
                         reject_duplicates=reject_duplicates)
        return ac
예제 #10
0
    def create_context(self, reject_duplicates: bool = True) -> AnodContext:
        """Create a spec repository and anod context.

        :param reject_duplicates: whether to reject duplicates in plan
        """

        def repo_conf(name: str) -> dict[str, str]:
            return {"vcs": "git", "url": name, "branch": "master"}

        # Create a context for a x86-linux machine
        asr = AnodSpecRepository(self.spec_dir)
        asr.repos["spec1-git"] = repo_conf("spec1")
        asr.repos["spec8-git"] = repo_conf("spec8")
        asr.repos["spec2-git"] = repo_conf("spec2")
        asr.repos["a-git"] = repo_conf("a")
        env = BaseEnv()
        env.set_build("x86-linux", "rhes6", "mylinux")
        ac = AnodContext(asr, default_env=env, reject_duplicates=reject_duplicates)
        return ac
예제 #11
0
    def run(self, args):
        sandbox = SandBox()
        sandbox.root_dir = args.sandbox

        if args.specs_dir:
            sandbox.specs_dir = args.specs_dir

        if args.create_sandbox:
            sandbox.create_dirs()

        if args.create_sandbox and args.spec_git_url:
            mkdir(sandbox.specs_dir)
            g = GitRepository(sandbox.specs_dir)
            if e3.log.default_output_stream is not None:
                g.log_stream = e3.log.default_output_stream
            g.init()
            g.update(args.spec_git_url, args.spec_git_branch, force=True)

        sandbox.dump_configuration()
        sandbox.write_scripts()

        asr = AnodSpecRepository(sandbox.specs_dir)
        check_api_version(asr.api_version)

        # Load plan content if needed
        if args.plan:
            if not os.path.isfile(args.plan):
                raise SandBoxError("plan file %s does not exist" % args.plan,
                                   origin="SandBoxExec.run")
            with open(args.plan, "r") as plan_fd:
                plan_content = ["def main_entry_point():"]
                plan_content += [
                    "    %s" % line for line in plan_fd.read().splitlines()
                ]
                plan_content = "\n".join(plan_content)

            env = BaseEnv()
            cm = PlanContext(server=env)
            store = None
            resolver = getattr(
                AnodContext,
                str(args.resolver),
                AnodContext.always_create_source_resolver,
            )
            logger.debug("Using resolver %s", resolver.__name__)

            # Declare available actions and their signature
            def anod_action(module,
                            build=None,
                            host=None,
                            target=None,
                            qualifier=None):
                pass  # all: no cover

            for a in ("anod_install", "anod_build", "anod_test"):
                cm.register_action(a, anod_action)

            # Load the plan and execute
            plan = Plan(data={})
            plan.load_chunk(plan_content)
            actions = cm.execute(plan, "main_entry_point")

            ac = AnodContext(asr, default_env=env)
            for action in actions:
                ac.add_anod_action(
                    action.module,
                    action,
                    action.action.replace("anod_", "", 1),
                    action.qualifier,
                )

            # Check if machine plan is locally schedulable
            action_list = ac.schedule(resolver)
            e = ElectrolytJobFactory(sandbox, asr, store, dry_run=args.dry_run)
            e.run(action_list)
예제 #12
0
    def test_force_download_without_require_condition(self):
        """Test that the force download can be done thanks to require=xxx.

        A require condition can be added to the build primitive to disable the
        build primitive for some qualifiers.
        """
        env = BaseEnv()
        env.set_build("x86_64-linux", "rhes8", "mylinux")
        asr = AnodSpecRepository(self.spec_dir)

        # We start with a dependency on spec_nobuild where build primitive
        # require condition is True
        ac = AnodContext(asr, default_env=env)
        ac.add_anod_action(
            "spec_nobuild_dep",
            env=ac.default_env,
            primitive="build",
        )

        # If both build and install are allowed the resolver will
        # complain and ask for an explicit choice
        with pytest.raises(SchedulingError) as err:
            ac.schedule(ac.always_create_source_resolver)
        assert "what to do for resolving" in str(err)

        # Now with a dependency making require return False, and so
        # disable the build primitive, the resolver will not have any
        # conflict: the only allowed action will be download.
        ac2 = AnodContext(asr, default_env=env)
        ac2.add_anod_action(
            "spec_nobuild_stable_dep",
            env=ac.default_env,
            primitive="build",
        )
        result = ac2.schedule(ac.always_create_source_resolver)

        assert set(result.vertex_data.keys()) == {
            "root",
            "mylinux.x86_64-linux.spec_nobuild.download_bin",
            "mylinux.x86_64-linux.spec_nobuild_stable_dep.build",
            "mylinux.x86_64-linux.spec_nobuild.install",
        }
예제 #13
0
 def no_resolver(action, decision):
     return AnodContext.decision_error(action, decision)
예제 #14
0
def create_anod_context(spec_dir: str) -> AnodContext:
    return AnodContext(AnodSpecRepository(spec_dir))