def verify(head=""): # Either head or branch /= "" # Check that the linked dir exists at the expected location pin_path = (f"alire/cache/pins/upstream" + ("" if head == "" else f"_{head[:8]}")) assert os.path.isdir(pin_path) # Verify info reported by alr p = run_alr("pin") assert_eq(f"upstream file:{pin_path} ../upstream.git" + ("" if head == "" else f"#{head[0:8]}") + "\n", p.out) # Verify building with pinned dependency run_alr("build") # Verify removal of cached download run_alr("clean", "--cache") assert not os.path.isdir(pin_path) # Verify automatic redownload when needed run_alr("build") # Prepare for next test run_alr("with", "--del", "upstream") # Remove dependency p = run_alr("pin") assert_eq(f"There are no pins\n", p.out) # Ensure pin is gone shutil.rmtree("alire") # Total cleanup outside of alr
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")
def check_equivalent(crate, 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_pin(crate=crate, path=path, url=url, commit=commit, branch=branch, manual=manual[i]) # get pins output p[i] = run_alr("pin").out if i == 1: assert_eq(p[0], p[1]) # Cleanup os.chdir("..") shutil.rmtree("xxx")
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): dep2* dep3* dep4* Pins (direct): dep2 = { path='../dep2' } dep3 = { path='../dep3' } dep4 = { path='../dep4' } Dependencies (solution): dep2=0.0.0 (pinned) (origin: ../dep2) dep3=0.0.0 (pinned) (origin: ../dep3) dep4=0.0.0 (pinned) (origin: ../dep4) Dependencies (graph): dep1=0.0.0 --> dep2=0.0.0 (*) dep1=0.0.0 --> dep3=0.0.0 (*) dep1=0.0.0 --> dep4=0.0.0 (*) dep2=0.0.0 --> dep3=0.0.0 (*) dep2=0.0.0 --> dep4=0.0.0 (*) dep3=0.0.0 --> dep4=0.0.0 (*) """, p.out) print('SUCCESS')
assert_eq("Ada -> Crate_Version: 1.0.0\n" "Ada -> Crate_Name: libcrate_config\n" f"Ada -> Alire_Host_OS: {expected_host_os}\n" f"Ada -> Alire_Host_Arch: {expected_host_arch}\n" f"Ada -> Alire_Host_Distro: {expected_host_distro}\n" "Ada -> Var_Bool: TRUE\n" "Ada -> Var_String: 'Test string.'\n" "Ada -> Var_Int'First: -42\n" "Ada -> Var_Int'Last: 42\n" "Ada -> Var_Int: -1\n" "Ada -> Var_Real'First: -4.20000000000000E+01\n" "Ada -> Var_Real'Last: 4.20000000000000E+01\n" "Ada -> Var_Real: -1.000000000E+00\n" "Ada -> Var_Enum_Kind'First: A\n" "Ada -> Var_Enum_Kind'Last: C\n" "Ada -> Var_Enum: B\n" f"Host_Specific -> {expected_host_os} specific\n" "C -> Crate_Version: 1.0.0\n" "C -> Crate_Name: libcrate_config\n" f"C -> Alire_Host_OS: {expected_host_os}\n" f"C -> Alire_Host_Arch: {expected_host_arch}\n" f"C -> Alire_Host_Distro: {expected_host_distro}\n" "C -> VAR_BOOL: 1\n" "C -> VAR_STRING: 'Test string.'\n" "C -> VAR_INT_FIRST: -42\n" "C -> VAR_INT_LAST: 42\n" "C -> VAR_INT: -1\n" "C -> VAR_REAL_FIRST: -42.000000\n" "C -> VAR_REAL_LAST: 42.000000\n" "C -> VAR_REAL: -1.000000\n" "C -> VAR_ENUM_A: 1\n" "C -> VAR_ENUM_B: 2\n" "C -> VAR_ENUM_C: 3\n" "C -> VAR_ENUM: 2\n", p.out)
""" Test that external tool dependencies work as expected. """ import re from drivers.alr import run_alr from drivers.asserts import assert_eq from drivers.helpers import compare, contents from subprocess import check_output # Should silently retrieve everything p = run_alr('get', 'main') assert_eq('', p.out) dir_content = contents('main_1.0.0_filesystem/') # The directrory for the external dependencies 'make' contains a version number # that can be different depending on the platform or version of the # distribution. We search through the content to find that directory and use it # in the expected output. make_dep_dir = "__MAKE_DEPENDENCY_DIR_NOT_FOUND_" for elt in dir_content: if re.match('^.*/alire/cache/dependencies/make_.*_external$', elt): make_dep_dir = elt # Check folder contents compare(dir_content, [ 'main_1.0.0_filesystem/alire', 'main_1.0.0_filesystem/alire.toml', 'main_1.0.0_filesystem/alire/alire.lock',
""" Test the behavior of "alr get" to get a crate that does not exist. """ from glob import glob from drivers.alr import run_alr from drivers.asserts import assert_eq, assert_match p = run_alr('get', 'does_not_exist', complain_on_error=False) assert_eq(1, p.status) assert_match('.*Crate \[does_not_exist\] does not exist in the catalog\.\n', p.out) assert_eq([], glob('does_not_exist*')) print('SUCCESS')
""" Test the output of `alr show` for an abstract crate """ import subprocess import os from drivers.alr import run_alr from drivers.asserts import assert_eq # gnat does not contain releases but several other crates provide it assert_eq( """Crate gnat is abstract and provided by: gnat_cross_1 gnat_cross_2 gnat_external gnat_native """, run_alr("show", "gnat", quiet=False).out) print('SUCCESS')
""" Test a basic get-build-run workflow. """ from glob import glob import os from drivers.alr import run_alr from drivers.asserts import assert_eq # Get the "hello" project and enter its directory run_alr('get', 'hello') os.chdir(glob('hello*')[0]) # Build it run_alr('build') # Run it p = run_alr('run') assert_eq('Hello, world!\n', p.out) # Clean it assert os.listdir('obj') run_alr('clean') assert not os.listdir('obj') print('SUCCESS')
""" Verify prevention of double-add of dependencies """ import os from drivers.alr import run_alr from drivers.asserts import assert_eq # Initialize a project, enter it and double-add a dependency p = run_alr('init', '--bin', 'xxx') os.chdir('xxx') p = run_alr('with', 'libhello') p = run_alr('with', 'libhello', quiet=False, complain_on_error=False) assert_eq('ERROR: libhello is already a direct dependency.\n', p.out) print('SUCCESS')
from drivers.alr import run_alr from drivers.asserts import assert_eq from drivers.helpers import contents import os # Get and check post fetch action run_alr('get', 'hello_world', quiet=False, debug=True) os.chdir("hello_world_0.1.0_filesystem/") run_alr('build', quiet=False, debug=True) p = run_alr('run') assert_eq( "Ada -> Var_Bool: TRUE\n" "Ada -> Var_String: 'Test string.'\n" "Ada -> Var_Int: -1\n" "Ada -> Var_Real: -1.000000000E+00\n" "Ada -> Var_Enum: B\n", p.out) assert not os.path.isdir( 'config'), "config should not be created for root project" for top, dirs, files in os.walk('./'): for nm in files: path = os.path.join(top, nm) if 'plop_config' in path: assert not path.endswith('.h'), "C header should not be generated" assert not path.endswith('.gpr'), "GPR should not be generated" print(p.out)
""" Verify that pins when there is no lockfile are correctly applied on first run """ from drivers.alr import run_alr, alr_pin, init_local_crate, alr_lockfile from drivers.asserts import assert_eq import os fake_dep = "unobtainium" # Create a crate init_local_crate() # Add a dependency run_alr("with", fake_dep, force=True) # Pin to a local folder os.mkdir(fake_dep) alr_pin(fake_dep, path=fake_dep) # Remove the lockfile os.remove(alr_lockfile()) # Check that the pin is applied on next command run p = run_alr("pin") assert_eq(f"{fake_dep} file:{fake_dep} \n", p.out) print('SUCCESS')
""" Verify that recursive pins work for local paths """ from drivers.alr import run_alr, alr_pin, init_local_crate from drivers.asserts import assert_eq, assert_match import os # We are going to setup xxx --> yyy --> zzz, where xxx and zzz live at the # same level, and yyy is at ./nest/yyy init_local_crate(name="zzz", enter=False) os.mkdir("nest") os.chdir("nest") init_local_crate(name="yyy") alr_pin("zzz", path="../../zzz") os.chdir("..") os.chdir("..") init_local_crate() alr_pin("yyy", path="../nest/yyy") # Should work properly p = run_alr("pin") assert_eq('yyy file:../nest/yyy \n' 'zzz file:../zzz \n', p.out) print('SUCCESS')
""" Validate the output of alr --version """ import re from drivers.alr import run_alr from drivers.asserts import assert_eq, assert_match # Extract version from alr version version = re.search("alr version:\s*?([^\s$]+)", run_alr("version").out, flags=re.M)[1] # Match against the output we want assert_eq(run_alr("--version").out, f"alr {version}\n") print('SUCCESS')
""" Test Jekyll static website framework output. """ from drivers.alr import run_alr from drivers.asserts import assert_eq p = run_alr('show', '--jekyll', 'hello', complain_on_error=True, quiet=False) assert_eq( '---\n' 'layout: crate\n' 'crate: "hello"\n' 'authors: ["Bob", "Alice"]\n' 'maintainers: ["*****@*****.**", "*****@*****.**"]\n' 'licenses: ["GPL-3.0-only OR MIT"]\n' 'websites: ["example.com"]\n' 'tags: ["tag1", "other-tag"]\n' 'version: "1.0.1"\n' 'short_description: "\\"Hello, world!\\" demonstration project"\n' 'dependencies: [{crate: "libhello", version: "^1.0"}]\n' '---\n' 'This is an example of long description in a multi-line string.\n' '\n' 'Markdown formating `can` be used to have "nice" display on the website.\n' '\n' '\n', p.out) print('SUCCESS')
run_alr('init', '--bin', 'xxx') os.chdir('xxx') # Make it depend on a couple of crates (simplifies checking the solution later) # libparent depends on libchild run_alr('with', 'libparent') # Pin the child run_alr('pin', 'libchild') # Remove parent run_alr('with', '--del', 'libparent') # Check pin is there p = run_alr('pin') assert_eq('libchild 0.2.0\n', p.out) # Check that there are no dependencies p = run_alr('with') assert_eq('Dependencies (direct):\n' ' (empty)\n', p.out) # But the pinned release is still in the solution p = run_alr('with', '--solve') assert_match( '.*' 'Dependencies \(solution\):\n' ' libchild=0\.2\.0 \(pinned\) \(origin: filesystem\)\n' 'Dependencies \(graph\):.*', p.out, flags=re.S)
from glob import glob from drivers.alr import run_alr from drivers.asserts import assert_eq # Test vectors from https://www.di-mgt.com.au/sha_testvectors.html filenames = ["empty.tgz", "abc.tgz", "bits448.tgz"] contents = [ "", "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ] hashes = [ "sha512:cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47" "d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "sha512:ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a21" "92992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", "sha512:204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596" "fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445" ] # Generate a test "crate" in the current folder with known contents and hash: for i in range(len(filenames)): with open(filenames[i], "w") as file: file.write(contents[i]) # Hash and check p = run_alr('publish', '--hash', 'file://' + filenames[i], quiet=False) assert_eq(hashes[i] + '\n', p.out) print('SUCCESS')
import e3 import os os.mkdir("test") os.chdir("test") # We create a temp file above us, one at the current dir, and one below. # The one above us should not be cleaned. Also, a file not conforming to # "alr-????.tmp" should not be cleaned either. e3.os.fs.touch("../alr-0001.tmp") e3.os.fs.touch("alr-0002.tmp") os.mkdir("nested") e3.os.fs.touch("nested/alr-0003.tmp") e3.os.fs.touch("alien.tmp") p = run_alr("clean", "--temp") assert os.path.exists("../alr-0001.tmp"), "unexpected deletion" assert os.path.exists("alien.tmp"), "unexpected deletion" assert not os.path.exists("alr-0002.tmp"), "unexpected file" assert not os.path.exists("nested/alr-0003.tmp"), "unexpected file" # Finally verify that running again in a clean environment does nothing p = run_alr("clean", "--temp", quiet=False) assert_eq("No temporaries found.\n", p.out) print('SUCCESS')
from drivers.asserts import assert_eq, assert_match import re import platform # 1st test: directly attempting to retrieve an external (this is doable for # system externals in supported platforms -- never in this test). Depending on # whether the distro has a supported package manager we get two outcomes: p = run_alr('get', 'crate', quiet=False, complain_on_error=False) if distro_is_known(): assert_match(".*Hint: This is a custom hint.*", p.out, flags=re.S) else: assert_eq( 'ERROR: No source release indexed for the requested crate, and ' 'cannot use system packages in unknown distribution\n', p.out) # 2nd test: hint is displayed when the hint belongs to a dependency, on get p = run_alr('get', 'crate_master', '--force', quiet=False) assert_match ( ".*" # Skip previous user interaction and warning about incomplete solution "Warning: The following native dependencies are unavailable within Alire:\n" "Warning: crate\*\n" "Warning: Hint: This is a custom hint\n" "Warning: They should be made available in the environment by the user.\n", p.out)
run_alr('with', 'libhello') check_line_in(session_file, 'libhello = "^1.0.0"') # Add the corresponding "with" line in xxx.gpr. # # TODO: maybe "alr with" should do that automatically? with open('xxx.gpr', 'r') as f: content = f.read() with open('xxx.gpr', 'w') as f: f.write('with "libhello";\n') f.write(content) # Pin the version of libhello and verify pin is there alr_pin('libhello', version='1.0') p = run_alr('pin') assert_eq('libhello 1.0.0\n', p.out) # Build and run "xxx" with open(os.path.join('src', 'xxx.adb'), 'w') as f: f.write(""" with Ada.Text_IO; with libhello; procedure XXX is begin Ada.Text_IO.Put_Line ("This is XXX..."); libhello.Hello_World; end XXX; """) p = run_alr('run') assert_eq('This is XXX...\nHello, world!\n', p.out)
import os from drivers.alr import prepare_env, prepare_indexes, run_alr from drivers.asserts import assert_eq, assert_match def check_output(dump): assert_match( '''stderr: PROGRAM_ERROR stderr: Raising forcibly stderr: raised PROGRAM_ERROR : Raising forcibly.* ''', dump) # Check debug dump (we intentionally disable debug flag in run_alr) check_output( run_alr('-d', 'dev', '--raise', debug=False, complain_on_error=False).out) # Long flag version check_output( run_alr('--debug', 'dev', '--raise', debug=False, complain_on_error=False).out) # Check ordinary non-debug output: assert_eq( run_alr('dev', '--raise', debug=False, complain_on_error=False).out, "ERROR: Raising forcibly\n" "ERROR: alr encountered an unexpected error, re-run with -d for details.\n" ) print('SUCCESS')
from glob import glob import os import re from drivers.alr import run_alr from drivers.asserts import assert_eq, assert_match # Get the "hello" project and enter its directory, without solving dependencies run_alr('get', 'hello', '--only') os.chdir(glob('hello*')[0]) # Verify that it has no solution p = run_alr('with', '--solve') assert_eq( 'Dependencies (direct):\n' ' libhello^1.0\n' 'Dependencies (solution):\n' ' No solving attempted\n', p.out) # Verify that it has no pins p = run_alr('pin') assert_eq('There are no pins\n', p.out) # Verify that updating it fixes the solution run_alr('update') p = run_alr('with', '--solve') assert_match( '.*\n' # Skip dependencies 'Dependencies \(solution\):\n' ' libhello=1\.0\.0.*\n' '.*', # Skip graph
""" 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")
import os from drivers.alr import run_alr from drivers.asserts import assert_eq, assert_match import re import platform # Get the "hello" project and enter its directory run_alr('get', 'hello') os.chdir(glob('hello*')[0]) # Run it not quietly to ensure that at normal level # the output is not broken by some log message p = run_alr('printenv', quiet=False) assert_eq(0, p.status) def make_path(list): if platform.system() == 'Windows': return "\\\\".join(list) else: return "/".join(list) expected_hello_path = make_path(['.*', 'hello_1.0.1_filesystem']) expected_libhello_path = make_path( ['.*', 'alire', 'cache', 'dependencies', 'libhello_1\.0\.0_filesystem']) expected_gpr_path = os.pathsep.join( [expected_hello_path, expected_libhello_path])
""" Verify that using a relative path for Alire config dir is ok """ import os from glob import glob from drivers.alr import run_alr from drivers.asserts import assert_eq from drivers.helpers import lines_of run_alr("--config", ".", "config", "--global", "--set", "some_config_key", "true") assert_eq("some_config_key = true\n", lines_of("config.toml")[0]) print('SUCCESS')
return '{: <9} {: <7} {: <8} {: <54} {: <5}\n'.format( name, status, version, description, notes) def format_table(*args): lines = [format_line('NAME', 'STATUS', 'VERSION', 'DESCRIPTION', 'NOTES')] for arg in args: lines.append(format_line(*arg)) return ''.join(lines) # List latest releases crates p = run_alr('search', '--list') assert_eq( format_table( ('hello', '', '1.0.1', '"Hello, world!" demonstration project', ''), ('libhello', '', '1.0.0', '"Hello, world!" demonstration project support library', ''), ), p.out) # List all releases crates p = run_alr('search', '--list', '--full') assert_eq( format_table( ('hello', '', '1.0.1', '"Hello, world!" demonstration project', ''), ('hello', '', '1.0.0', '"Hello, world!" demonstration project', ''), ('libhello', '', '1.0.0', '"Hello, world!" demonstration project support library', ''), ), p.out) # Actually search in the index. First, on crate names p = run_alr('search', 'lib')
""" Test unpinning """ import os from drivers.alr import run_alr from drivers.asserts import assert_eq from drivers.helpers import check_line_in # Create a new "xxx" program project run_alr('init', '--bin', 'xxx') os.chdir('xxx') # Make it depend on libhello run_alr('with', 'libhello') # Pin the version of libhello and verify pin is there run_alr('pin', 'libhello') p = run_alr('pin') assert_eq('libhello 1.0.0\n', p.out) # Unpin and verify pin is not there run_alr('pin', '--unpin', 'libhello') p = run_alr('pin') assert_eq('There are no pins\n', p.out) print('SUCCESS')
import os from drivers.alr import run_alr from drivers.asserts import assert_eq, assert_match aliases_file = os.path.join(os.environ['ALR_CONFIG'], "indexes", "providers.toml") # This is the file where crate aliases are stored # Initially, the file mustn't exist assert not os.path.isfile(aliases_file), f"Unexpected file: {aliases_file}" # Force reading of the full index run_alr("search", "--crates") # Now, the file must exist assert os.path.isfile(aliases_file), f"Missing file: {aliases_file}" # Let's verify its contents with open(aliases_file, "rt") as file: contents = file.readlines() contents = "".join(contents).replace("\n", "") assert_eq('aliased = ["crate",]', contents) # This means that "crate" provides "aliased", so when solving "aliased" we also # need to load "crate" print('SUCCESS')
newlines = [] origin = "" for line in lines: if line.startswith("Origin:"): origin = line else: newlines.append(line) return '\n'.join(newlines), origin # Outside run run1 = run_alr('show', 'libhello') run_alr('get', 'libhello') os.chdir(glob('libhello*')[0]) # Inside run run2 = run_alr('show') # The origin will change from inside the index to the deployment folder, # so we have to compare that separately out1, origin1 = detach_origin(run1.out) out2, origin2 = detach_origin(run2.out) assert_eq(out1, out2) assert origin1.endswith("libhello_1.0.0") # Original source folder assert origin2.endswith("libhello_1.0.0_filesystem") # Created by `alr get` print('SUCCESS')
""" Verify prevention of double-add of dependencies """ import os from drivers.alr import run_alr from drivers.asserts import assert_eq # Initialize a project, enter it and double-add a dependency p = run_alr('init', '--bin', 'xxx') os.chdir('xxx') p = run_alr('with', 'libhello') p = run_alr('with', 'libhello', quiet=False) assert_eq( 'Not adding libhello because libhello^1.0.0 is already a dependency\n', p.out) print('SUCCESS')