Skip to content

Commit

Permalink
Tests for compiler in build hash input
Browse files Browse the repository at this point in the history
  • Loading branch information
mosteo committed Aug 25, 2023
1 parent eb735c6 commit fcf11d1
Show file tree
Hide file tree
Showing 17 changed files with 234 additions and 8 deletions.
30 changes: 25 additions & 5 deletions src/alire/alire-toolchains-solutions.adb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ with AAA.Strings;

with Alire.Index;
with Alire.Root;
with Alire.Solver;

package body Alire.Toolchains.Solutions is

Expand Down Expand Up @@ -75,6 +76,26 @@ package body Alire.Toolchains.Solutions is
function Compiler (Solution : Alire.Solutions.Solution)
return Releases.Release
is

--------------------------
-- Environment_Compiler --
--------------------------

function Environment_Compiler return Releases.Release is
begin
Index.Detect_Externals (GNAT_Crate, Root.Platform_Properties);
return Solver.Find (GNAT_External_Crate,
Policy => Solver.Default_Options.Age);
exception
when Query_Unsuccessful =>
Raise_Checked_Error
(Errors.New_Wrapper
.Wrap ("Unable to determine compiler version.")
.Wrap ("Check that the workspace solution is complete "
& "and a compiler is available.")
.Get);
end Environment_Compiler;

begin
if not Solution.Depends_On (GNAT_Crate) then
declare
Expand All @@ -83,11 +104,10 @@ package body Alire.Toolchains.Solutions is
Deploy => False);
begin
if not With_GNAT.Depends_On (GNAT_Crate) then
Raise_Checked_Error
(Errors.New_Wrapper
.Wrap ("Unable to determine compiler version.")
.Wrap ("Check that the workspace solution is complete.")
.Get);
-- This means that no compiler (or None) has been selected
-- with `alr toolchain`, so we return whichever one is in
-- the environment.
return Environment_Compiler;
else
return Compiler (With_GNAT);
end if;
Expand Down
8 changes: 8 additions & 0 deletions testsuite/drivers/builds.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@

from glob import glob
import os
from shutil import rmtree
from drivers.alr import alr_builds_dir


def clear_builds_dir() -> None:
"""
Clear the shared build directory
"""
rmtree(path())


def find_dir(crate_name: str) -> str:
"""
Find the build dir of a crate in the shared build directory
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
description = "GNAT is a compiler for the Ada programming language"
name = "gnat_external"

maintainers = ["[email protected]"]
maintainers-logins = ["mosteo"]

[[external]]
kind = "version-output"
# We look for make instead that should be always installed.
version-command = ["make", "--version"]
version-regexp = ".*Make ([\\d\\.]+).*"
provides = "gnat"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
description = "Fake GNAT native crate"
name = "gnat_native"
version = "7777.0.0"
maintainers = ["[email protected]"]
maintainers-logins = ["mylogin"]
provides = ["gnat=7777.0"]

# Test dynamic expression, but for all OSes
[origin."case(os)"."..."]
url = "file:../../../crates/libhello_1.0.0.tgz"
hashes = ["sha512:99fa3a55540d0655c87605b54af732f76a8a363015f183b06e98aa91e54c0e69397872718c5c16f436dd6de0fba506dc50c66d34a0e5c61fb63cb01fa22f35ac"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
description = "Fake GNAT native crate"
name = "gnat_native"
version = "8888.0.0"
maintainers = ["[email protected]"]
maintainers-logins = ["mylogin"]
provides = ["gnat=8888.0"]

# Although the compiler is fake, we use this path in some tests
environment.'case(os)'.'windows'.TEST_PATH.append = '${CRATE_ROOT}\bin'
environment.'case(os)'.'...'.TEST_PATH.append = '${CRATE_ROOT}/bin'

# Test dynamic expression, but for all OSes
[origin."case(os)"."..."]
url = "file:../../../crates/libhello_1.0.0.tgz"
hashes = ["sha512:99fa3a55540d0655c87605b54af732f76a8a363015f183b06e98aa91e54c0e69397872718c5c16f436dd6de0fba506dc50c66d34a0e5c61fb63cb01fa22f35ac"]
16 changes: 16 additions & 0 deletions testsuite/fixtures/build_hash_index/he/hello/hello-1.0.0.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
description = "\"Hello, world!\" demonstration project"
long-description = "This is an example of long description in a multi-line string.\n\nMarkdown formating `can` be used to have \"nice\" display on the website.\n"
name = "hello"
version = "1.0.0"
website = "example.com"
authors = ["Bob", "Alice"]
licenses = "GPL-3.0-only OR MIT"
maintainers = ["[email protected]", "[email protected]"]
maintainers-logins = ["mylogin"]
tags = ["tag1", "other-tag"]

[[depends-on]]
libhello = "^1.0"

[origin]
url = "file:../../../crates/hello_1.0.0"
29 changes: 29 additions & 0 deletions testsuite/fixtures/build_hash_index/he/hello/hello-1.0.1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
description = "\"Hello, world!\" demonstration project"
long-description = "This is an example of long description in a multi-line string.\n\nMarkdown formating `can` be used to have \"nice\" display on the website.\n"
name = "hello"
version = "1.0.1"
website = "example.com"
authors = ["Bob", "Alice"]
licenses = "GPL-3.0-only OR MIT"
maintainers = ["[email protected]", "[email protected]"]
maintainers-logins = ["mylogin"]
tags = ["tag1", "other-tag"]

[[depends-on]]
libhello = "^1.0"

[configuration.variables]
Var1={type="Boolean"}
Var2={type="String", default="str"}
Var3={type="Enum", values=["A", "B"], default="A"}
Var4={type="Integer", default=0}
Var5={type="Integer", first=-1, last=1, default=0}
Var7={type="Real", default=0.0}
Var6={type="Real", first=-1.0, last=1.0, default=0.0}

[configuration.values]
hello.Var1=true # So far it is possible for a crate to set its own var
libhello.Var1=false

[origin]
url = "file:../../../crates/hello_1.0.1"
1 change: 1 addition & 0 deletions testsuite/fixtures/build_hash_index/index.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = "1.1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
description = "\"Hello, world!\" demonstration project support library"
name = "libhello"
version = "1.0.0"
maintainers = ["[email protected]"]
maintainers-logins = ["mylogin"]
tags = ["libhello-tag1"]

[configuration.variables]
Var1={type="Boolean", default=true}

[gpr-externals]
TEST_GPR_EXTERNAL = ["gpr_ext_A", "gpr_ext_B", "gpr_ext_C"]
TEST_FREEFORM_UNSET = "" # to test build hashing with an unset var

[gpr-set-externals]
TEST_GPR_EXTERNAL = "gpr_ext_B"
TEST_UNDECLARED = "used_by_another_crate"

[environment]
TEST_ENV.set = "myenv"

[origin]
url = "file:../../../crates/libhello_1.0.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
description = "Utility for directing compilation"
name = "make"
maintainers = ["[email protected]"]
maintainers-logins = ["mylogin"]

[[external]]
kind = "system"
origin = [] # Empty on purpose to ensure unavailable in tests
56 changes: 56 additions & 0 deletions testsuite/tests/build/hashes/compiler-input/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
Check compiler version in hashing input
"""

import sys

from drivers.alr import run_alr, init_local_crate, alr_with
from drivers.asserts import assert_match, match_solution
from drivers.builds import clear_builds_dir, hash_input


def check_hash(signature: str) -> None:
"""
Check that the given signature is present in the hash inputs
"""
assert_match(f".*{signature}.*", hash_input("crate_real"))


run_alr("config", "--set", "--global", "dependencies.shared", "true")

# Select the default preferred compiler, in this index is gnat_native=8888
run_alr("toolchain", "--select")

# Init a crate without explicit compiler dependency
init_local_crate("xxx")
alr_with("crate_real") # A regular crate in the index
run_alr("update") # Ensure the hash inputs are written to disk

# Check the expected compiler is in the hash inputs
check_hash("version:gnat_native=8888.0.0")


# Next, check with an explicit compiler in the dependencies. Note that we give
# the virtual dependency, but the actual native one is used for the hash.

# Clear the build cache so we are able to locate the new hash
clear_builds_dir()
alr_with("gnat=7777") # Downgrade the compiler with an explicit dependency
run_alr("update")

# Check the expected compiler is in the hash inputs
check_hash("version:gnat_native=7777.0.0")


# Finally, check that having two explicit dependencies on the compiler (one
# virtual and another real) does not cause a conflict in compiler detection.
# The same compiler as in the previous step should be used for the hash.

clear_builds_dir()
alr_with("gnat_native")
run_alr("update")
check_hash("version:gnat_native=7777.0.0")


print('SUCCESS')
sys.exit(0)
4 changes: 4 additions & 0 deletions testsuite/tests/build/hashes/compiler-input/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
driver: python-script
indexes:
toolchain_index:
in_fixtures: true
19 changes: 19 additions & 0 deletions testsuite/tests/build/hashes/compiler-missing/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
Check that when no compiler is available we cannot compute the build hash
"""


from drivers.alr import run_alr, init_local_crate
from drivers.asserts import assert_match

# The index in this test has no compilers configured; hence we cannot locate
# even the default external compiler.

run_alr("config", "--set", "--global", "dependencies.shared", "true")

# Init a crate without explicit compiler dependency
init_local_crate("xxx")
p = run_alr("with", "libhello", complain_on_error=False) # This should fail
assert_match(".*Unable to determine compiler version", p.out)

print("SUCCESS")
4 changes: 4 additions & 0 deletions testsuite/tests/build/hashes/compiler-missing/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
driver: python-script
indexes:
basic_index:
in_fixtures: true
2 changes: 1 addition & 1 deletion testsuite/tests/build/hashes/hashing-inputs/test.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
driver: python-script
indexes:
basic_index: {}
build_hash_index: {}
2 changes: 1 addition & 1 deletion testsuite/tests/config/shared-deps/test.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
driver: python-script
indexes:
basic_index: {}
build_hash_index: {}
2 changes: 1 addition & 1 deletion testsuite/tests/dockerized/misc/default-cache/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

# Shared builds
# We hardcode this hash so we detect unwilling changes to our hashing scheme
hash = "e66592c9a181de97dc3a342cf76378f6ffa6667d7c1864c74d98bec8ffaf4f3d"
hash = "7b5ad18029d4984b4076f4910c699700e7a325ab0c3dc786ccf89c3c6035212f"
assert \
os.path.isdir(f"{base}/builds/crate_real_1.0.0_filesystem_{hash}"), \
f"Shared build not found at the expected location: f{contents(base)}"
Expand Down

0 comments on commit fcf11d1

Please sign in to comment.