Пример #1
0
def check_equivalent(dep="", path="", url="", commit="", branch=""):
    """
    Run manual and auto and compare outputs
    """
    manual = [False, True]
    p = [None, None]

    for i in [0, 1]:
        init_local_crate()

        # run command
        alr_with(dep=dep,
                 path=path,
                 url=url,
                 commit=commit,
                 branch=branch,
                 force=True,
                 manual=manual[i])

        # get output of solution
        p[i] = run_alr("with", "--solve").out

        if i == 1:
            assert_eq(p[0], p[1])

        # Cleanup
        os.chdir("..")
        shutil.rmtree("xxx")
Пример #2
0
import subprocess
import os

from drivers.alr import run_alr, init_local_crate, alr_with
from drivers.asserts import assert_eq, assert_match, match_solution
from re import escape as e

# This test relies on three crates in the toolchain_index:
# crate_conflict=1.2.3 conflicts with crate_lone* and crate_virtual*
# crate_lone is a regular crate
# crate_virtual has no releases, but is provided by crate_conflict_1
# Crate conflict cannot appear with any of the others in a solution, because of
# its [forbids] table.

init_local_crate("conflict_lone")
alr_with("crate_conflict")
alr_with("crate_lone")
match_solution("crate_(conflict|lone)=.* \(origin:.*\)")  # has origin: solved
match_solution("crate_(conflict|lone)\* \(direct,missed\)")
# Because of load/solving details, we do not know which of the two crates is
# going to be missed/accepted in the solution, so we check there is one of each

init_local_crate("conflict_virtual")
alr_with("crate_conflict")
alr_with("crate_virtual")
match_solution("crate_(conflict|virtual)=.* \(origin:.*\)")
match_solution("crate_(conflict|virtual)\* \(direct,missed\)")

print('SUCCESS')
Пример #3
0
Test solver using the "provides" field for regular crates
"""

import subprocess
import os

from drivers.alr import run_alr, init_local_crate, alr_with
from drivers.asserts import assert_eq, assert_match, match_solution
from re import escape as e

# This test relies on two crates in the index: crate_lone=1.0 is unavailable.
# crate_equiv=2.0 also provides crate_lone=1.0 and crate_virtual=1.0.
# Finally there is crate_lone=2.0 that is available and nobody else provides.

init_local_crate("xxx")
alr_with("crate_lone^1")

# Since crate_lone is unavailable, in the solution we should find crate_equiv:
match_solution("crate_lone=2.0.0 (crate_equiv)", escape=True)

# Likewise, a dependency on crate_virtual will be fulfilled by the same crate
alr_with("crate_virtual")
match_solution("crate_virtual=2.0.0 (crate_equiv)", escape=True)

# Whereas a dependency on crate_equiv will show plainly without equivalence
alr_with("crate_equiv")
match_solution(
    "Dependencies (solution):\n"
    "   crate_equiv=2.0.0 (origin: filesystem)\n"
    "   crate_lone=2.0.0 (crate_equiv) (origin: filesystem)\n"
    "   crate_virtual=2.0.0 (crate_equiv) (origin: filesystem)\n",
Пример #4
0
alr_publish("mychild", "0.0.0", index_path=index_dir)

# Publish also its parent for later test
os.chdir("..")
alr_publish("myparent", "0.0.0", index_path=index_dir)

# Verify that the crate can be got and compiled, and expected location
os.chdir(start_dir)
run_alr("get", "--build", "mychild")
assert os.path.isdir(os.path.join(f"monoproject_{commit[:8]}",
                                  "myparent", "mychild")), \
    "Expected directory does not exist"

# Verify that the crate is usable as a dependency, and expected location
init_local_crate("top")
alr_with("mychild")
run_alr("build")
assert os.path.isdir(os.path.join("alire", "cache", "dependencies",
                                  f"monoproject_{commit[:8]}",
                                  "myparent", "mychild")), \
    "Expected directory does not exist"

# Verify that "with"ing the parent does not result in a new checkout
alr_with("myparent", update=False)
p = run_alr("-v", "update", quiet=False)
assert "Skipping checkout of already available myparent=0.0.0" in p.out, \
    "Expected output not found: " + p.out

# Verify the build is successful. As the dependencies were created with --bin,
# they will be built even if not "with"ed in the Ada code to make their binary
# available to the root crate during the build process.
Пример #5
0
assert_match(
    ".*\n"  # Headers
    "gnat_external.*Available.*Detected.*\n",
    p.out)

# Capture version
version = re.search("gnat_external ([0-9.]+)", p.out, re.MULTILINE).group(1)

# When no compiler is selected, only the gnat_external one should be used
# unless a targeted compiler dependency is used

# Create a crate for our experiments
init_local_crate("xxx")

# Check that a generic dependency results in the external being used
alr_with("gnat")
match_solution(f"gnat={version} (gnat_external) (installed)", escape=True)

# Check that adding a second dependency on native packaged compiler is honored.
# Both dependencies should appear in the solution.
alr_with("gnat_native")
match_solution("gnat=8888.0.0 (gnat_native) (installed)", escape=True)
match_solution("gnat_native=8888.0.0 (installed)", escape=True)

# The previous dependency also should have caused the installation of the
# native compiler as an available compiler, which we will check:
p = run_alr("toolchain")
assert_match(".*gnat_native.*8888.0.0.*Available.*", p.out)

# Move to a new crate
init_local_crate("yyy")
Пример #6
0
        print(f"erroneous path was: {paths[0]}")
        raise


# First we test manual installation
run_alr("toolchain", "--install", "gnat_native")
check_content("gnat_native")

# Uninstall the compiler and verify absence
run_alr("toolchain", "--uninstall", "gnat_native", quiet=False)
paths = contents(cache_dir, "gnat_native")
assert len(paths) == 0, "Unexpected contents: " + str(paths)

# Require the external compiler and verify no trace appears in install folder
# nor in local folder
init_local_crate("xxx")
alr_with("gnat_external")
match_solution("gnat_external=.* \(installed\)")
paths = contents(cache_dir, "gnat_external")
assert len(paths) == 0, "Unexpected contents: " + str(paths)
paths = contents(".", "gnat_external")
assert len(paths) == 0, "Unexpected contents: " + str(paths)

# Require a cross compiler and verify it is automatically installed
alr_with("gnat_external", delete=True, manual=False)
alr_with("gnat_cross_1")
match_solution("gnat_cross_1=.* \(installed\)")
check_content("gnat_cross_1")

print('SUCCESS')
Пример #7
0
"""
Test pinning to a version
"""

from drivers.alr import run_alr, alr_pin, alr_with, init_local_crate
from drivers.asserts import assert_eq, assert_match

init_local_crate()
alr_with("hello")

# Test pinning to the version currently in the solution
alr_pin("hello", manual=False)
p = run_alr("pin")
assert_eq("hello 1.0.1\n", p.out)

# Test pinning to a different explicit version
alr_pin("hello", version="1.0", manual=False, force=True)
p = run_alr("pin")
assert_eq("hello 1.0.0\n", p.out)

# Test that trying to use a non-equal restriction fails
p = run_alr("pin", "hello^1.0", complain_on_error=False)
assert_eq(
    "ERROR: Plain crate name or crate=version argument expected"
    " for pinning, but got: hello^1.0\n", p.out)

# Test that pinning to a non-existent version is doable but solution is missing
p = run_alr("pin", "hello=7.7.7", force=True)
p = run_alr("pin")
assert_eq("hello 7.7.7\n", p.out)
p = run_alr("with", "--solve")
Пример #8
0
# Verify only external compiler available
p = run_alr("toolchain")
assert_match(
    ".*\n"  # Headers
    "gnat_external.*Available.*Detected.*\n",
    p.out)

# Capture version
version = re.search("gnat_external ([0-9.]+)", p.out, re.MULTILINE).group(1)

# Prepare a couple of dependencies, one depending on gnat, and another one
# depending on gnat_native.

init_local_crate("dep_generic")
alr_with("gnat")
os.chdir("..")

init_local_crate("dep_targeted")
alr_with("gnat_native")  # This step also installs the native compiler
os.chdir("..")

# First we check that a root generic dependency mixes well with either of the
# two dependencies

init_local_crate("xxx_generic_generic")
run_alr("with", "--use=../dep_generic")
alr_with("gnat")

# gnat x gnat results in the external available compiler being used, preferred
# over the native also available compiler (but not selected)
Пример #9
0
from drivers.alr import run_alr, alr_with, init_local_crate
from drivers.asserts import assert_eq, assert_match
from drivers.helpers import init_git_repo

import os
import subprocess

# Create a new "remote" repository with a tag that we'll use as reference
init_local_crate("remote")
init_git_repo(".")
subprocess.run(["git", "tag", "v1"]).check_returncode()

# Verify that pinning to a valid reference succeeds
os.chdir("..")
init_local_crate()
alr_with(path="../remote", commit="v1", manual=False)
p = run_alr("pin")
assert_match("remote file:alire/cache/pins/remote_.{,8} ../remote#.{,8}",
             p.out)

# Remove dependency for next test
alr_with("remote", delete=True, manual=False)
p = run_alr("pin")
assert_eq("There are no pins\n", p.out)

# Verify that pinning to an invalid reference fails
p = run_alr("with",
            "--use",
            "../remote",
            "--commit",
            "v2",
Пример #10
0
"""

import subprocess
import os

from drivers.alr import run_alr, init_local_crate, alr_with
from drivers.asserts import assert_eq, assert_match, match_solution
from re import escape as e

# Select the default preferred compiler, which is the native packaged one
run_alr("toolchain", "--select")

# Init a crate depending on gnat

init_local_crate("xxx")
alr_with("gnat*")

# Will appear in the solution as generic fulfilled by the preferred compiler
match_solution("gnat=8888.0.0 (gnat_native) (installed)", escape=True)

# Selecting another default will cause a corresponding change in the solution
run_alr("config", "--set", "toolchain.use.gnat", "gnat_cross_2=1")
run_alr("update")
match_solution("gnat=1.0.0 (gnat_cross_2) (installed)", escape=True)

# Adding another incompatible compiler dependency should result in overriding
# the configured one
alr_with("gnat_cross_1")

# Both dependencies will appear in the solution, matching the same crate
match_solution("gnat=9999.0.0 \(gnat_cross_1\) \(installed\).*"
Пример #11
0
# We are now at monoproject/mycrate.
os.chdir("mycrate")
run_alr("show")  # Verify the crate is detected properly

# This call creates the manifest and puts it in place in the index
alr_publish("mycrate", "0.0.0", index_path=os.path.join(start_dir, "my_index"))

# Verify that the crate can be got and compiled, and expected location
os.chdir(start_dir)
run_alr("get", "--build", "mycrate")
assert os.path.isdir(os.path.join(f"monoproject_{commit[:8]}", "mycrate")), \
    "Expected directory does not exist"

# Verify that the crate is usable as a dependency, and expected binary location
init_local_crate("top")
alr_with("mycrate")
run_alr("build")
assert os.path.isfile(os.path.join(
    "alire", "cache", "dependencies",
    f"monoproject_{commit[:8]}", "mycrate", "bin",
    f"mycrate{'.exe' if on_windows() else ''}")), \
    "Expected binary does not exist"

# Also that the info file is there
assert os.path.isfile(os.path.join(
    "alire", "cache", "dependencies",
    f"mycrate_0.0.0_in_monoproject_{commit[:8]}")), \
    "Expected info file does not exist"

print('SUCCESS')
Пример #12
0
    # pre/post-build expected for successful build
    check(flag_post_fetch, False)
    check(flag_pre_build, True)
    check(flag_post_build, True)
    return

    # updating dependencies causes the post-fetch action to run:
    run_alr('update')
    check(flag_post_fetch, True)
    check(flag_pre_build, True)
    check(flag_post_build, True)


# Initialize a crate and add as dependency the crate that contains the triggers
init_local_crate("root", binary=False)  # Lib so all contents are compiled
alr_with("hello_world")
# Test all triggers
do_checks(glob("./alire/cache/dependencies/hello*")[0].replace('\\', '/'))

# Repeat tests, for a crate that has been added as a linked dependency
os.chdir("..")
rmtree("root")
run_alr("get", "hello_world")
hello = glob("hello*")[0].replace('\\', '/')
init_local_crate("root", binary=False)
os.rename(f"../{hello}", f"./{hello}")
alr_with(path=f"{hello}", manual=False)
do_checks(f"./{hello}")

print('SUCCESS')
Пример #13
0
"""

import subprocess
import os

from drivers.alr import run_alr, init_local_crate, alr_with
from drivers.asserts import assert_eq, assert_match, match_solution
from re import escape as e

# This test relies on two crates in the toolchain_index:
# crate_subst both provides and forbids crate_real
# crate_real is a regular crate only provided by itself and crate_subst

# The following has only one possible solution, which is for crate_subst
# providing both dependencies.
init_local_crate("test")
alr_with("crate_real")

# Check that this is initially solved with the regular crate. This is currently
# guaranteed by the solver attempting crates in alphabetical order. We will
# need eventually a way to disable equivalences (via pins, or solver config).
match_solution("crate_real=1.0.0 (origin: filesystem)", escape=True)

# Let's add the drop-in equivalent crate that provides+forbids crate_lone
alr_with("crate_subst")
match_solution("crate_real=1.0.0 (crate_subst) (origin: filesystem)",
               escape=True)  # This is the substituted release
match_solution("crate_subst=1.0.0 (origin: filesystem)", escape=True)

print('SUCCESS')
Пример #14
0
Test that a tool built by a dependency is available to a dependent crate
"""

from drivers.alr import run_alr, init_local_crate, alr_with, alr_manifest
from drivers.alr import add_action
from os import chdir
from os.path import join
from shutil import rmtree, which

# We test with a locally pinned dependency, which should make no difference as
# it is a regular release in the eyes of the build process

init_local_crate("root")
init_local_crate("depended", binary=True, enter=False)

alr_with("depended", path="depended")

# Add a pre-build action to the root crate that attempts to run bin/depended
add_action("pre-build", ["depended/bin/depended"])

run_alr("build")

# Now, add the executable to the path in the depended crate, and an action that
# uses only the executable name

# First, ensure that a same-name executable isn't in the environment by some
# bizarre chance
assert which("depended") is None, "Unexpected 'depended' command in PATH"

chdir("depended")
with open(alr_manifest(), "a") as manifest:
Пример #15
0
comes first alphabetically), and verify the environment contains the compiler.
"""

import os
import re
import subprocess

from drivers.alr import run_alr, init_local_crate, alr_with
from drivers.asserts import assert_eq, assert_match
from drivers.helpers import dir_separator

# Install a binary compiler for later use
run_alr("toolchain", "--select", "gnat_native")

init_local_crate("another_crate")  # This enters the crate
alr_with("gnat")  # Make it depend on gnat (in the original bug, the dependency
# was also indirect, although it would have been a problem with a direct
# dependency as well).
os.chdir("..")  # Back to root folder

init_local_crate()
alr_with(path="../another_crate", manual=False)  # Autodetect the linked crate

p = run_alr("printenv")

s = re.escape(dir_separator())

# Ensure the compiler-set flag is in there:
assert_match(
    ".*export TEST_PATH=.*"
    f"printenv__compiler-indirect{s}alr-config{s}cache{s}"
Пример #16
0
p = run_alr("pin", complain_on_error=False)
s = re.escape(dir_separator())
assert_match(
    ".*"
    "ERROR: Pin circularity detected when adding pin zzz --> xxx:\n"
    f"ERROR:    Last manifest in the cycle is .*{s}zzz{s}alire.toml\n",
    p.out)

# Verify that the buggy case that was reported does not happen again
# In this case, we have
# dep1 -> dep2 -> dep3 -> dep4; dep1 -> dep3; dep1 -> dep4; dep2 -> dep4

init_local_crate("dep4", enter=False)

init_local_crate("dep3")
alr_with("dep4", path="../dep4")

os.chdir("..")
init_local_crate("dep2")
alr_with("dep3", path="../dep3")
alr_with("dep4", path="../dep4")

os.chdir("..")
init_local_crate("dep1")
alr_with("dep2", path="../dep2")
alr_with("dep3", path="../dep3")
alr_with("dep4", path="../dep4")

p = run_alr("with", "--solve")
assert_eq("""\
Dependencies (direct):
Пример #17
0
from glob import glob

expected_output = "POST-FETCH MAIN\n"

# Test trigger action in a root crate
run_alr("get", "main")
os.chdir(glob("main*")[0])
p = run_alr("action", "post-fetch")
assert_eq(expected_output, p.out)

# Test trigger of undefined action
p = run_alr("action", "post-build")
assert_eq("No actions to run.\n", p.out)

# Test trigger of non-existent action
p = run_alr("action", "made-up", complain_on_error=False)
assert_eq("ERROR: Invalid action: made-up\n", p.out)

# Test that action in dependency is not triggered by default
os.chdir("..")
init_local_crate()
alr_with("main")
p = run_alr("action", "post-fetch")
assert_eq("No actions to run.\n", p.out)

# Third test, check that action in dependency is listed with --recursive, -r
p = run_alr("action", "post-fetch", "--recursive")
assert_eq(expected_output, p.out)

print('SUCCESS')
Пример #18
0
# We create a second crate at another commit
os.chdir(os.path.join(start_dir, "monoproject.upstream"))
init_local_crate("crate2", enter=False)
os.chdir(start_dir)
commit2 = commit_all("monoproject.upstream")

# Check out changes and publish crate2
os.chdir("monoproject")
run(["git", "pull"]).check_returncode()
os.chdir("crate2")
alr_publish("crate2", "0.0.0", index_path=os.path.join(start_dir, "my_index"))

# Verify that the crates are usable as a dependency, and expected binary
# locations
init_local_crate("top")
alr_with("crate1")
alr_with("crate2")
run_alr("build")

assert os.path.isfile(os.path.join(
    "alire", "cache", "dependencies",
    f"monoproject_{commit1[:8]}", "crate1", "bin",
    f"crate1{'.exe' if on_windows() else ''}")), \
    "Expected binary does not exist"
assert os.path.isfile(os.path.join(
    "alire", "cache", "dependencies",
    f"monoproject_{commit2[:8]}", "crate2", "bin",
    f"crate2{'.exe' if on_windows() else ''}")), \
    "Expected binary does not exist"

# Also that the info files are there
Пример #19
0
"""
Test that two crates providing the same third crate are compatible
"""

import subprocess
import os

from drivers.alr import run_alr, init_local_crate, alr_with
from drivers.asserts import assert_eq, assert_match, match_solution
from re import escape as e

# This test relies on two crates in the index:
# crate_virt_1=2.0 also provides crate_virtual=1.0
# crate_virt_2=1.0 also provides crate_virtual=1.0

# Verify that these crates provide the same virtual release
p = run_alr("show", "crate_virt_1")
assert_match(".*Provides: crate_virtual=1.0.0.*", p.out)
p = run_alr("show", "crate_virt_2")
assert_match(".*Provides: crate_virtual=1.0.0.*", p.out)

init_local_crate("xxx")
alr_with("crate_virt_1")
alr_with("crate_virt_2")

# Both crates must appear in the solution
match_solution("crate_virt_1=2.0.0 (origin: filesystem)", escape=True)
match_solution("crate_virt_2=1.0.0 (origin: filesystem)", escape=True)

print('SUCCESS')
Пример #20
0
# pre/post-build expected for successful build
check_not_expected('./test_post_fetch')
check_expected('./test_pre_build')
check_expected('./test_post_build')

# updating dependencies causes the post-fetch action on the root crate to run:
run_alr('update')
check_expected('./test_post_fetch')
check_expected('./test_pre_build')
check_expected('./test_post_build')

# Add a linked dependency. Since these are never "fetched", in order to
# complete their action cycle, post-fetch is also run on updates

init_local_crate("depended", binary=False, enter=True)
# Add a similar action
if on_windows():
    add_action("post-fetch", ["cmd", "/C", "copy NUL test_post_fetch_dep"])
else:
    add_action("post-fetch", ["touch", "test_post_fetch_dep"])

check_not_expected('./test_post_fetch_dep')
os.chdir("..")  # Back to parent crate
alr_with("depended", path="depended", update=False)
run_alr("update")
check_not_expected('./test_post_fetch_dep')
check_expected('./depended/test_post_fetch_dep')

print('SUCCESS')
Пример #21
0
"""

import os

from drivers.alr import run_alr, init_local_crate, alr_lockfile, alr_with
# from drivers.asserts import assert_eq, assert_match
from drivers.helpers import content_of
from os.path import isfile


old_lockfile = "alire.lock"

init_local_crate()
# Add a dependency so the lockfile is not the same as the default one
default_content = content_of(alr_lockfile())
alr_with("libhello")
proper_content = content_of(alr_lockfile())
assert default_content != proper_content, \
    "error setting up the test (contents should differ)"


def verify():
    """
    Check that the lockfile is only in the new location, with proper contents
    """
    assert isfile(alr_lockfile()) and not isfile(old_lockfile), \
        "Unexpected lockfile placement"
    assert content_of(alr_lockfile()) == proper_content, "bad contents"


# Case 1: lockfile is only in the old location, and it is moved to new location
Пример #22
0
check_config(bin_config, 'development')

# Check that the project builds
run_alr('build')

# Build in validation mode
run_alr('build', '--validation')
check_config_changed()
check_config(bin_config, 'validation')

# Build in validation mode
run_alr('build', '--development')
check_config_changed()
check_config(bin_config, 'development')

# Build in release mode
run_alr('build', '--release')
check_config_changed()
check_config(bin_config, 'release')

# Alr with will re-generate the crate config and default to DEVELOPMENT
alr_with('lib_1', path='../lib_1')
check_config_changed()
check_config(bin_config, 'development')

# Build with default profile, the config should not change
run_alr('build')
check_config_not_changed()

print('SUCCESS')
Пример #23
0
    ".*\n"  # Headers
    "gnat_external.*Available.*Detected.*\n",
    p.out)

# Capture version
version = re.search("gnat_external ([0-9.]+)", p.out, re.MULTILINE).group(1)

print(version)
# When no compiler is selected, since the external one is available, it should
# be used before offering to download a new compiler.

# Create a crate for our experiments
init_local_crate("xxx")

# Check that a generic dependency results in the external being used
alr_with("gnat")
match_solution(f"gnat={version} (gnat_external) (installed)", escape=True)

# Check that requesting a version different to the one externally available
# results in missing compiler, as Alire won't try to install one.
alr_with("gnat", delete=True, manual=False)
alr_with(f"gnat/={version}")
match_solution(f"gnat/={version} (direct,hinted)", escape=True)
# Hinted because we know the crate exists as external

# Now, if the user installs a cross compiler, it will be used

run_alr("toolchain", "--install", "gnat_cross_2")
run_alr("update")
match_solution("gnat=1.0.0 (gnat_cross_2) (installed)", escape=True)