diff --git a/testsuite/tests/workflows/air-gapping/my_index/crates/hello.tgz b/testsuite/tests/workflows/air-gapping/my_index/crates/hello.tgz new file mode 100644 index 000000000..a39010d27 Binary files /dev/null and b/testsuite/tests/workflows/air-gapping/my_index/crates/hello.tgz differ diff --git a/testsuite/tests/workflows/air-gapping/my_index/crates/libhello.tgz b/testsuite/tests/workflows/air-gapping/my_index/crates/libhello.tgz new file mode 100644 index 000000000..c5882e61a Binary files /dev/null and b/testsuite/tests/workflows/air-gapping/my_index/crates/libhello.tgz differ diff --git a/testsuite/tests/workflows/air-gapping/my_index/index/he/hello/hello-1.0.1.toml b/testsuite/tests/workflows/air-gapping/my_index/index/he/hello/hello-1.0.1.toml new file mode 100644 index 000000000..05221fc60 --- /dev/null +++ b/testsuite/tests/workflows/air-gapping/my_index/index/he/hello/hello-1.0.1.toml @@ -0,0 +1,11 @@ +description = "\"Hello, world!\" demonstration project" +name = "hello" +version = "1.0.1" +maintainers = ["alejandro@mosteo.com", "bob@example.com"] +maintainers-logins = ["mylogin"] + +[[depends-on]] +libhello = "^1.0" + +[origin] +url = "file:../../../crates/hello.tgz" diff --git a/testsuite/tests/workflows/air-gapping/my_index/index/index.toml b/testsuite/tests/workflows/air-gapping/my_index/index/index.toml new file mode 100644 index 000000000..bad265e4f --- /dev/null +++ b/testsuite/tests/workflows/air-gapping/my_index/index/index.toml @@ -0,0 +1 @@ +version = "1.1" diff --git a/testsuite/tests/workflows/air-gapping/my_index/index/li/libhello/libhello-1.0.0.toml b/testsuite/tests/workflows/air-gapping/my_index/index/li/libhello/libhello-1.0.0.toml new file mode 100644 index 000000000..b1d856d2a --- /dev/null +++ b/testsuite/tests/workflows/air-gapping/my_index/index/li/libhello/libhello-1.0.0.toml @@ -0,0 +1,8 @@ +description = "\"Hello, world!\" demonstration project support library" +name = "libhello" +version = "1.0.0" +maintainers = ["alejandro@mosteo.com"] +maintainers-logins = ["mylogin"] + +[origin] +url = "file:../../../crates/libhello.tgz" diff --git a/testsuite/tests/workflows/air-gapping/test.py b/testsuite/tests/workflows/air-gapping/test.py new file mode 100644 index 000000000..396688547 --- /dev/null +++ b/testsuite/tests/workflows/air-gapping/test.py @@ -0,0 +1,83 @@ +""" +Test fetching a crate online, and subsequently building offline. +""" + + +import os +import shutil +import subprocess + +from drivers.alr import run_alr +from drivers.asserts import assert_eq, assert_match + + +# Mock tar, git, curl, gprbuild etc. with dummy scripts +os.mkdir("path-dir") +os.chdir("path-dir") +for executable in ("tar", "git", "hg", "svn", "curl", "gprbuild"): + with open(executable, "w") as f: + f.write("\n".join([ + "#!/usr/bin/env python", + "import sys", + "print('Mocked command called')", + "sys.exit(1)" + ])) + os.chmod(executable, 0o764) +os.environ["PATH"] = f'{os.getcwd()}{os.pathsep}{os.environ["PATH"]}' +os.chdir("..") + + +# Run `alr get hello`. This will fail because tar is unavailable. +p = run_alr("get", "hello", quiet=False, complain_on_error=False) +assert_match(".*Mocked command called", p.out) +assert_match(".*Deployment of path .* to .* failed", p.out) + +# Disable tar mocking and run `alr get hello` to 'download' the crate and its +# dependencies. +os.remove(os.path.join("path-dir", "tar")) +p = run_alr("get", "hello", quiet=False) +assert_match(r".*hello=1\.0\.1 successfully retrieved", p.out) +assert_match(r".*\+ libhello 1\.0\.0 \(new\)", p.out) + +# Re-enable tar mocking and make the index unavailable to simulate disconnection +# from the network +shutil.copy(os.path.join("path-dir", "curl"), os.path.join("path-dir", "tar")) +shutil.move("my_index", "somewhere_else") + +# Simulate transferring to a different system by clearing the alr-config +# directory (we keep settings.toml, since it just does various things to isolate +# the test environment) and changing the absolute path of the crate directory. +for f in os.listdir("alr-config"): + if f != "settings.toml": + shutil.rmtree(os.path.join("alr-config", f)) +shutil.move(f"hello_1.0.1_filesystem", "hello") + +# Run `alr build`. This will fail because gprbuild is unavailable. +os.chdir(f"hello") +p = run_alr("build", quiet=False, complain_on_error=False) +assert_match(".*Mocked command called", p.out) +assert_match(r'.*Command \["gprbuild", .*\] exited with code 1', p.out) + +# Disable gprbuild mocking and run `alr build` to build the crate (with tar +# mocking still enabled to check it doesn't try to fetch anything else) +os.remove(os.path.join("..", "path-dir", "gprbuild")) +p = run_alr("build", quiet=False) + +# Check the built binary works as expected +assert_eq( + b"Hello, world!\n", + subprocess.run([os.path.join("obj", "hello")], capture_output=True).stdout +) + +# Clear out the downloaded dependencies, and verify that `alr build` then +# attempts (and fails) to re-fetch them +shutil.rmtree(os.path.join("alire", "cache", "dependencies")) +p = run_alr("build", quiet=False, complain_on_error=False) +assert_match( + ".*Filesystem crate is neither a folder nor a source archive: ", + p.out +) +assert_match(".*Deployment of path .* to .* failed", p.out) + + +print("SUCCESS") diff --git a/testsuite/tests/workflows/air-gapping/test.yaml b/testsuite/tests/workflows/air-gapping/test.yaml new file mode 100644 index 000000000..ec0413f72 --- /dev/null +++ b/testsuite/tests/workflows/air-gapping/test.yaml @@ -0,0 +1,10 @@ +driver: python-script +# We need 'dependencies.shared=false' anyway for dependencies to be packaged +# inside the workspace, so we only run in sandboxed mode. +build_mode: sandboxed +control: + # Mocking commands this way doesn't work on Windows + - [SKIP, "skip_unix", "Test is Unix-only"] +indexes: + my_index: + in_fixtures: false