diff --git a/pmb/challenge/__init__.py b/pmb/challenge/__init__.py deleted file mode 100644 index 55b82018..00000000 --- a/pmb/challenge/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -# Exported functions -from pmb.challenge.apk_file import apk -from pmb.challenge.apkindex import apkindex -from pmb.challenge.build import build -from pmb.challenge.frontend import frontend diff --git a/pmb/challenge/apk.py b/pmb/challenge/apk.py deleted file mode 100644 index f759e84f..00000000 --- a/pmb/challenge/apk.py +++ /dev/null @@ -1,124 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -import logging -import os -import tarfile -import tempfile -import filecmp -import shutil - - -def contents_diff(tar_a, tar_b, member_a, member_b, name): - # Extract both files - tars = [tar_a, tar_b] - members = [member_a, member_b] - temp_files = [] - for i in range(2): - handle, path = tempfile.mkstemp("pmbootstrap") - handle = open(handle, "wb") - shutil.copyfileobj(tars[i].extractfile(members[i]), handle) - handle.close() - temp_files.append(path) - - # Compare and delete - equal = filecmp.cmp(temp_files[0], temp_files[1], shallow=False) - for temp_file in temp_files: - os.remove(temp_file) - if equal: - logging.verbose("=> OK!") - else: - raise RuntimeError("File '" + name + "' is different!") - - -def contents_without_signature(tar, tar_name): - """ - The signature file name is always different. - This function raises an exception, when the number of signature - files in the archive is not 1. - :returns: a sorted list of all filenames inside the tar archive, - except for the signature file. - """ - names = tar.getnames() - found = False - ret = [] - for name in names: - if name.startswith(".SIGN.RSA."): - if found: - raise RuntimeError("More than one signature file found" - " inside " + tar_name + ": " + - str(names)) - else: - found = True - else: - ret.append(name) - - if not found: - raise RuntimeError("No signature file found inside " + - tar_name + ": " + str(names)) - return sorted(ret) - - -def apk(args, apk_a, apk_b): - with tarfile.open(apk_a, "r:gz") as tar_a: - with tarfile.open(apk_b, "r:gz") as tar_b: - # List of files must be the same - list_a = contents_without_signature(tar_a, apk_a) - list_b = contents_without_signature(tar_b, apk_b) - if list_a != list_b: - logging.info("Files in " + apk_a + ":" + str(list_a)) - logging.info("Files in " + apk_b + ":" + str(list_b)) - raise RuntimeError( - "Both APKs do not contain the same file names!") - - # Iterate through the list - success = True - for name in list_a: - try: - logging.verbose("Compare: " + name) - if name == ".PKGINFO": - logging.verbose( - "=> Skipping: expected to be different") - continue - - # Get members - member_a = tar_a.getmember(name) - member_b = tar_b.getmember(name) - if member_a.type != member_b.type: - raise RuntimeError( - "Entry '" + name + "' has a different type!") - - if member_a.isdir(): - logging.verbose("=> Skipping: directory") - elif member_a.isfile(): - contents_diff(tar_a, tar_b, member_a, member_b, name) - elif member_a.issym() or member_a.islnk(): - if member_a.linkname == member_b.linkname: - logging.verbose( - "=> Both link to " + member_a.linkname) - else: - raise RuntimeError( - "Link " + name + " has a different target!") - else: - raise RuntimeError( - "Can't diff '" + name + "', unsupported type!") - except Exception as e: - logging.info("CHALLENGE FAILED for " + name + ":" + str(e)) - success = False - if not success: - raise RuntimeError("Challenge failed (see errors above)") diff --git a/pmb/challenge/apk_file.py b/pmb/challenge/apk_file.py deleted file mode 100644 index e30facfd..00000000 --- a/pmb/challenge/apk_file.py +++ /dev/null @@ -1,130 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -import logging -import os -import tarfile -import tempfile -import filecmp -import shutil - - -def contents_diff(tar_a, tar_b, member_a, member_b, name): - # Extract both files - tars = [tar_a, tar_b] - members = [member_a, member_b] - temp_files = [] - for i in range(2): - handle, path = tempfile.mkstemp("pmbootstrap") - handle = open(handle, "wb") - shutil.copyfileobj(tars[i].extractfile(members[i]), handle) - handle.close() - temp_files.append(path) - - # Compare and delete - equal = filecmp.cmp(temp_files[0], temp_files[1], shallow=False) - for temp_file in temp_files: - os.remove(temp_file) - if equal: - logging.debug("=> OK!") - else: - raise RuntimeError("File '" + name + "' is different!") - - -def contents_without_signature(tar, tar_name): - """ - The signature file name is always different. - This function raises an exception, when the number of signature - files in the archive is not 1. - :returns: a sorted list of all filenames inside the tar archive, - except for the signature file. - """ - names = tar.getnames() - found = False - ret = [] - for name in names: - if name.startswith(".SIGN.RSA."): - if found: - raise RuntimeError("More than one signature file found" - " inside " + tar_name + ": " + - str(names)) - else: - found = True - else: - ret.append(name) - - if not found: - raise RuntimeError("No signature file found inside " + - tar_name + ": " + str(names)) - return sorted(ret) - - -def apk(args, apk_a, apk_b, stop_after_first_error=False): - with tarfile.open(apk_a, "r:gz") as tar_a: - with tarfile.open(apk_b, "r:gz") as tar_b: - # List of files must be the same - list_a = contents_without_signature(tar_a, apk_a) - list_b = contents_without_signature(tar_b, apk_b) - if list_a != list_b: - logging.info("Files in " + apk_a + ":" + str(list_a)) - logging.info("Files in " + apk_b + ":" + str(list_b)) - raise RuntimeError( - "Both APKs do not contain the same file names!") - - # Iterate through the list - success = True - for name in list_a: - try: - logging.debug("Compare: " + name) - if name == ".PKGINFO": - logging.debug( - "=> Skipping: expected to be different") - continue - - # Get members - member_a = tar_a.getmember(name) - member_b = tar_b.getmember(name) - if member_a.type != member_b.type: - logging.info("NOTE: " + name + " in " + apk_a + ":") - tar_a.list(members=[member_a]) - logging.info("NOTE: " + name + " in " + apk_b + ":") - tar_b.list(members=[member_b]) - raise RuntimeError( - "Entry '" + name + "' has a different type!") - - if member_a.isdir(): - logging.debug("=> Skipping: directory") - elif member_a.isfile(): - contents_diff(tar_a, tar_b, member_a, member_b, name) - elif member_a.issym() or member_a.islnk(): - if member_a.linkname == member_b.linkname: - logging.debug( - "=> Both link to " + member_a.linkname) - else: - raise RuntimeError( - "Link " + name + " has a different target!") - else: - raise RuntimeError( - "Can't diff '" + name + "', unsupported type!") - except Exception as e: - logging.info("CHALLENGE FAILED for " + name + ":" + str(e)) - success = False - if stop_after_first_error: - raise - if not success: - raise RuntimeError("Challenge failed (see errors above)") diff --git a/pmb/challenge/apkindex.py b/pmb/challenge/apkindex.py deleted file mode 100644 index 2c6de44c..00000000 --- a/pmb/challenge/apkindex.py +++ /dev/null @@ -1,68 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -import os -import glob -import logging -import pmb.parse.apkindex - - -def apkindex(args, path_apkindex, apk_suffix=""): - """ - Verify an APKINDEX.tar.gz file, and its repository folder: - - Each apk must be defined inside the APKINDEX (once!) - - There must be no extra files - - :param path_apkindex: full path to the APKINDEX.tar.gz - :param apk_suffix: set this to ".unverified", if all apk files in - the repository have such a suffix appended. - """ - # Parse the apkindex file - content = pmb.parse.apkindex.parse(args, path_apkindex, True) - folder = os.path.dirname(path_apkindex) - - # All listed packages must exist - found = [] - count = str(len(content.items())) - logging.info("Check for existence of all listed packages (" + count + ")") - for pkgname_alias, block in content.items(): - apk = (block["pkgname"] + "-" + block["version"] + ".apk" + - apk_suffix) - if not os.path.exists(folder + "/" + apk): - raise RuntimeError("Could not find file '" + apk + - "' mentioned in " + path_apkindex) - # Mark the apk and its buildinfo (if it exists) as found - if apk not in found: - found.append(apk) - buildinfo = (block["pkgname"] + "-" + block["version"] + - ".apk.buildinfo.json") - if os.path.exists(folder + "/" + buildinfo): - found.append(buildinfo) - # Add diff files, if they exist - for name in [apk + ".diff.md", buildinfo + ".diff.md"]: - if os.path.exists(folder + "/" + name): - found.append(name) - - # There must be no extra files - logging.info("Check for extra files") - for path in glob.glob(folder + "/*"): - name = os.path.basename(path) - if name == "APKINDEX.tar.gz" or name in found: - continue - raise RuntimeError("Unexpected file '" + name + "' inside the" - " repository folder: " + folder) diff --git a/pmb/challenge/build.py b/pmb/challenge/build.py deleted file mode 100644 index 7171a27e..00000000 --- a/pmb/challenge/build.py +++ /dev/null @@ -1,78 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -import logging -import json -import os -import pmb.build -import pmb.parse.apkbuild -import pmb.helpers.repo -import pmb.challenge - - -def build(args, apk_path): - # Parse buildinfo - buildinfo_path = apk_path + ".buildinfo.json" - if not os.path.exists(buildinfo_path): - logging.info("NOTE: To create a .buildinfo.json file, use the" - " --buildinfo command while building: 'pmbootstrap build" - " --buildinfo '") - raise RuntimeError("Missing file: " + buildinfo_path) - with open(buildinfo_path) as handle: - buildinfo = json.load(handle) - - # Install all listed packages - pmb.chroot.apk.install(args, buildinfo["versions"].keys()) - - # Verify the installed versions - installed = pmb.chroot.apk.installed(args) - for pkgname, version in buildinfo["versions"].items(): - version_installed = installed[pkgname]["version"] - if version_installed != version: - raise RuntimeError("Dependency " + pkgname + " version is different" - " (installed: " + version_installed + "," - " buildinfo: " + version + ")!") - # Build the package - repo_before = pmb.helpers.repo.files(args) - pmb.build.package(args, buildinfo["pkgname"], buildinfo["arch"], - force=True, buildinfo=True) - repo_diff = pmb.helpers.repo.diff(args, repo_before) - - # Diff the apk contents - staging_path = os.path.realpath(os.path.dirname(apk_path) + "/../") - for file in repo_diff: - file_staging = staging_path + "/" + file - file_work = args.work + "/packages/" + file - - if file.endswith(".apk"): - logging.info("Verify " + file) - pmb.challenge.apk(args, file_staging, file_work) - elif (file.endswith("/APKINDEX.tar.gz") or - file.endswith(".apk.buildinfo.json")): - # We only verify the apk file (see above). The APKINDEX can - # be verified separately. - continue - else: - raise RuntimeError("Unknown file type changed in the" - " package repository folder: " + file) - - # Output the changed files from the repository - if args.output_repo_changes: - with open(args.output_repo_changes, "w") as handler: - for file in repo_diff: - handler.write(file + "\n") diff --git a/pmb/challenge/frontend.py b/pmb/challenge/frontend.py deleted file mode 100644 index 2288b469..00000000 --- a/pmb/challenge/frontend.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -import os -import logging -import pmb.challenge - - -def frontend(args): - path = args.challenge_file - logging.info("Challenge " + path) - if path.endswith(".apk"): - pmb.challenge.build(args, path) - elif os.path.basename(path) == "APKINDEX.tar.gz": - pmb.challenge.apkindex(args, path) - else: - raise ValueError("It is only possible to challenge files ending" - " in .apk or files named APKINDEX.tar.gz.") diff --git a/pmb/helpers/frontend.py b/pmb/helpers/frontend.py index 1c431e4d..c2294980 100644 --- a/pmb/helpers/frontend.py +++ b/pmb/helpers/frontend.py @@ -29,7 +29,6 @@ import pmb.aportgen import pmb.build import pmb.build.autodetect import pmb.config -import pmb.challenge import pmb.chroot import pmb.chroot.initfs import pmb.chroot.other @@ -153,10 +152,6 @@ def build_init(args): pmb.build.init(args, suffix) -def challenge(args): - pmb.challenge.frontend(args) - - def checksum(args): for package in args.packages: pmb.build.checksum(args, package) diff --git a/pmb/parse/apkindex.py b/pmb/parse/apkindex.py index 4208e7a8..b8338ec0 100644 --- a/pmb/parse/apkindex.py +++ b/pmb/parse/apkindex.py @@ -107,15 +107,11 @@ def parse_next_block(args, path, lines, start): return None -def parse_add_block(path, strict, ret, block, pkgname=None): +def parse_add_block(path, ret, block, pkgname=None): """ Add one block to the return dictionary of parse(). :param path: to the APKINDEX.tar.gz - :param strict: When set to True, only allow one entry per pkgname. - In case there are two, raise an exception. - When set to False, and there are multiple entries - for one pkgname, it uses the latest one. :param ret: dictionary of all packages in the APKINDEX, that is getting built right now. This function will extend it. :param block: return value from parse_next_block(). @@ -131,9 +127,6 @@ def parse_add_block(path, strict, ret, block, pkgname=None): # Handle duplicate entries if pkgname in ret: - if strict: - raise RuntimeError("Multiple blocks for " + pkgname + - " in " + path) # Ignore the block, if the block we already have has a higher # version version_old = ret[pkgname]["version"] @@ -145,14 +138,10 @@ def parse_add_block(path, strict, ret, block, pkgname=None): ret[pkgname] = block -def parse(args, path, strict=False): +def parse(args, path): """ Parse an APKINDEX.tar.gz file, and return its content as dictionary. - :param strict: When set to True, only allow one entry per pkgname. - In case there are two, raise an exception. - When set to False, and there are multiple entries - for one pkgname, it uses the latest one. :returns: a dictionary with the following structure: { "postmarketos-mkinitfs": { @@ -189,10 +178,10 @@ def parse(args, path, strict=False): break # Add the next package and all aliases - parse_add_block(path, strict, ret, block) + parse_add_block(path, ret, block) if "provides" in block: for alias in block["provides"]: - parse_add_block(path, strict, ret, block, alias) + parse_add_block(path, ret, block, alias) # Update the cache args.cache["apkindex"][path] = {"lastmod": lastmod, "ret": ret} diff --git a/pmb/parse/arguments.py b/pmb/parse/arguments.py index 2301a302..af643935 100644 --- a/pmb/parse/arguments.py +++ b/pmb/parse/arguments.py @@ -328,21 +328,6 @@ def arguments(): for action in [kconfig_check, apkbuild_parse]: action.add_argument("packages", nargs="*") - # Action: challenge - challenge = sub.add_parser("challenge", - help="verify, that all files in an apk can be" - " reproduced from the same sources /" - " verify, that an APKINDEX.tar.gz properly" - " lists all apks in a repository folder") - challenge.add_argument("--output-repo-changes", dest="output_repo_changes", - help="pass the path to a file here, to store a list" - " of apk- and APKINDEX-files that have been" - " changed during the build", default=None) - challenge.add_argument("challenge_file", - help="the file to be verified. must end in" - " .apk, or must be named" - " APKINDEX.tar.gz.") - # Action: apkindex_parse apkindex_parse = sub.add_parser("apkindex_parse") apkindex_parse.add_argument("apkindex_path") diff --git a/test/test_challenge_apk.py b/test/test_challenge_apk.py deleted file mode 100644 index 73792c94..00000000 --- a/test/test_challenge_apk.py +++ /dev/null @@ -1,272 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -import os -import sys -import pytest -import tarfile - -# Import from parent directory -sys.path.append(os.path.realpath( - os.path.join(os.path.dirname(__file__) + "/.."))) -import pmb.challenge.apk_file -import pmb.config -import pmb.chroot.other -import pmb.helpers.logging - - -@pytest.fixture -def args(request): - import pmb.parse - sys.argv = ["pmbootstrap.py", "chroot"] - args = pmb.parse.arguments() - args.log = args.work + "/log_testsuite.txt" - pmb.helpers.logging.init(args) - request.addfinalizer(args.logfd.close) - return args - - -def test_apk_challenge_contents_diff(args): - """ - Create two tar files, which contain a file with the same name. - The content of that file is different. - """ - # Tempfolder inside chroot for fake apk files - temp_path = pmb.chroot.other.tempfolder( - args, "/tmp/test_apk_challenge_contents_diff") - temp_path_outside = args.work + "/chroot_native" + temp_path - - # First file - name = "testfile" - apk_a = temp_path_outside + "/a.apk" - pmb.chroot.user(args, ["cp", "/etc/inittab", temp_path + "/" + name]) - pmb.chroot.user(args, ["tar", "-czf", "a.apk", name], - working_dir=temp_path) - - # Second file - apk_b = temp_path_outside + "/b.apk" - pmb.chroot.user(args, ["cp", "/etc/motd", temp_path + "/" + name]) - pmb.chroot.user(args, ["tar", "-czf", "b.apk", name], - working_dir=temp_path) - - # Compare OK - with tarfile.open(apk_a, "r:gz") as tar_a: - member_a = tar_a.getmember(name) - pmb.challenge.apk_file.contents_diff( - tar_a, tar_a, member_a, member_a, name) - - # Compare NOK - with tarfile.open(apk_b, "r:gz") as tar_b: - member_b = tar_b.getmember(name) - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk_file.contents_diff(tar_a, tar_b, member_a, - member_b, name) - assert str(e.value).endswith(" is different!") - - -def test_apk_challenge_contents_without_signature(args): - # Tempfolder inside chroot for fake apk files - temp_path = pmb.chroot.other.tempfolder( - args, "/tmp/test_apk_challenge_nosig") - temp_path_outside = args.work + "/chroot_native" + temp_path - - # Create three archives - contents = { - "no_sig.apk": ["other_file"], - "one_sig.apk": [".SIGN.RSA.first", "other_file"], - "two_sig.apk": [".SIGN.RSA.first", ".SIGN.RSA.second"], - } - for apk, files in contents.items(): - for file in files: - pmb.chroot.user(args, ["touch", temp_path + "/" + file]) - pmb.chroot.user(args, ["tar", "-czf", apk] + - files, working_dir=temp_path) - - # No signature - with tarfile.open(temp_path_outside + "/no_sig.apk", "r:gz") as tar: - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk_file.contents_without_signature(tar, "a.apk") - assert str(e.value).startswith("No signature file found") - - # One signature - with tarfile.open(temp_path_outside + "/one_sig.apk", "r:gz") as tar: - contents = pmb.challenge.apk_file.contents_without_signature( - tar, "a.apk") - assert contents == ["other_file"] - - # More than one signature - with tarfile.open(temp_path_outside + "/two_sig.apk", "r:gz") as tar: - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk_file.contents_without_signature(tar, "a.apk") - assert str(e.value).startswith("More than one signature") - - -def test_apk_challenge_different_files_inside_archive(args): - # Tempfolder inside chroot for fake apk files - temp_path = pmb.chroot.other.tempfolder(args, "/tmp/test_apk_challenge") - temp_path_outside = args.work + "/chroot_native" + temp_path - - # Create fake apks - contents = { - "a.apk": [".SIGN.RSA.first", "first_file", "second_file"], - "b.apk": [".SIGN.RSA.second", "first_file"], - } - for apk, files in contents.items(): - for file in files: - pmb.chroot.user(args, ["touch", temp_path + "/" + file]) - pmb.chroot.user(args, ["tar", "-czf", apk] + - files, working_dir=temp_path) - - # Challenge both files - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/a.apk", - temp_path_outside + "/b.apk") - assert "do not contain the same file names" in str(e.value) - - -def test_apk_challenge_entry_has_a_different_type(args): - # Tempfolder inside chroot for fake apk files - temp_path = pmb.chroot.other.tempfolder(args, "/tmp/test_apk_challenge") - temp_path_outside = args.work + "/chroot_native" + temp_path - - # Create fake apks - contents = { - "a.apk": [".SIGN.RSA.first", ".APKINDEX", "different_type"], - "b.apk": [".SIGN.RSA.second", ".APKINDEX", "different_type"], - } - for apk, files in contents.items(): - for file in files: - if file == "different_type" and apk == "b.apk": - pmb.chroot.user(args, ["rm", temp_path + "/" + file]) - pmb.chroot.user(args, ["mkdir", temp_path + "/" + file]) - else: - pmb.chroot.user(args, ["touch", temp_path + "/" + file]) - pmb.chroot.user(args, ["tar", "-czf", apk] + - files, working_dir=temp_path) - - # Exact error (with stop_after_first_error) - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/a.apk", - temp_path_outside + "/b.apk", stop_after_first_error=True) - assert "has a different type!" in str(e.value) - - # Generic error - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/a.apk", - temp_path_outside + "/b.apk") - assert "Challenge failed" - - -def test_apk_challenge_file_has_different_content(args): - # Tempfolder inside chroot for fake apk files - temp_path = pmb.chroot.other.tempfolder(args, "/tmp/test_apk_challenge") - temp_path_outside = args.work + "/chroot_native" + temp_path - - # Create fake apks - contents = { - "a.apk": [".SIGN.RSA.first", ".APKINDEX", "different_content"], - "b.apk": [".SIGN.RSA.second", ".APKINDEX", "different_content"], - } - for apk, files in contents.items(): - for file in files: - if file == "different_content" and apk == "b.apk": - pmb.chroot.user( - args, [ - "cp", "/etc/hostname", temp_path + "/" + file]) - else: - pmb.chroot.user(args, ["touch", temp_path + "/" + file]) - pmb.chroot.user(args, ["tar", "-czf", apk] + - files, working_dir=temp_path) - - # Exact error (with stop_after_first_error) - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/a.apk", - temp_path_outside + "/b.apk", stop_after_first_error=True) - assert str(e.value).endswith("is different!") - - # Generic error - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/a.apk", - temp_path_outside + "/b.apk") - assert "Challenge failed" - - -def test_apk_challenge_different_link_target(args): - # Tempfolder inside chroot for fake apk files - temp_path = pmb.chroot.other.tempfolder(args, "/tmp/test_apk_challenge") - temp_path_outside = args.work + "/chroot_native" + temp_path - - # Create fake apks - contents = { - "a.apk": [".SIGN.RSA.first", ".APKINDEX", "link_same", "link_different"], - "b.apk": [".SIGN.RSA.second", ".APKINDEX", "link_same", "link_different"], - } - for apk, files in contents.items(): - for file in files: - if file.startswith("link_"): - if file == "link_different" and apk == "b.apk": - pmb.chroot.user(args, ["ln", "-sf", "/different_target", - temp_path + "/" + file]) - else: - pmb.chroot.user(args, ["ln", "-sf", "/some_link_target", - temp_path + "/" + file]) - else: - pmb.chroot.user(args, ["touch", temp_path + "/" + file]) - pmb.chroot.user(args, ["tar", "-czf", apk] + - files, working_dir=temp_path) - - # Exact error (with stop_after_first_error) - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/a.apk", - temp_path_outside + "/b.apk", stop_after_first_error=True) - assert str(e.value).endswith("has a different target!") - - # Generic error - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/a.apk", - temp_path_outside + "/b.apk") - assert "Challenge failed" - - -def test_apk_challenge_unsupported_type(args): - # Tempfolder inside chroot for fake apk files - temp_path = pmb.chroot.other.tempfolder(args, "/tmp/test_apk_challenge") - temp_path_outside = args.work + "/chroot_native" + temp_path - - # Create fake apk with a FIFO (-> unsupported type) - apk = "test.apk" - content = [".SIGN.RSA.first", ".APKINDEX", "fifo"] - for file in content: - if file == "fifo": - pmb.chroot.user(args, ["mkfifo", temp_path + "/" + file]) - else: - pmb.chroot.user(args, ["touch", temp_path + "/" + file]) - pmb.chroot.user(args, ["tar", "-czf", apk] + - content, working_dir=temp_path) - - # Exact error (with stop_after_first_error) - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/test.apk", - temp_path_outside + "/test.apk", stop_after_first_error=True) - assert str(e.value).endswith("unsupported type!") - - # Generic error - with pytest.raises(RuntimeError) as e: - pmb.challenge.apk(args, temp_path_outside + "/test.apk", - temp_path_outside + "/test.apk") - assert "Challenge failed" diff --git a/test/test_challenge_apkindex.py b/test/test_challenge_apkindex.py deleted file mode 100644 index 14fa9da5..00000000 --- a/test/test_challenge_apkindex.py +++ /dev/null @@ -1,89 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -import os -import sys -import pytest - -# Import from parent directory -sys.path.append(os.path.realpath( - os.path.join(os.path.dirname(__file__) + "/.."))) -import pmb.challenge.apkindex -import pmb.config -import pmb.helpers.logging - - -@pytest.fixture -def args(request, tmpdir): - import pmb.parse - sys.argv = ["pmbootstrap.py", "chroot"] - args = pmb.parse.arguments() - args.log = args.work + "/log_testsuite.txt" - pmb.helpers.logging.init(args) - request.addfinalizer(args.logfd.close) - - # Create an empty APKINDEX.tar.gz file, so we can use its path and - # timestamp to put test information in the cache. - path_apkindex = str(tmpdir) + "/APKINDEX.tar.gz" - open(path_apkindex, "a").close() - lastmod = os.path.getmtime(path_apkindex) - args.cache["apkindex"][path_apkindex] = {"lastmod": lastmod, "ret": {}} - - return args - - -def test_challenge_apkindex_extra_file(args): - """ - Create an extra file, that is not mentioned in the APKINDEX cache. - """ - path_apkindex = list(args.cache["apkindex"].keys())[0] - tmpdir = os.path.dirname(path_apkindex) - open(tmpdir + "/invalid-extra-file.apk", "a").close() - - with pytest.raises(RuntimeError) as e: - pmb.challenge.apkindex(args, path_apkindex) - assert "Unexpected file" in str(e.value) - - -def test_challenge_apkindex_file_does_not_exist(args): - """ - Add an entry to the APKINDEX cache, that does not exist on disk. - """ - path_apkindex = list(args.cache["apkindex"].keys())[0] - args.cache["apkindex"][path_apkindex]["ret"] = { - "hello-world": {"pkgname": "hello-world", "version": "1-r2"} - } - - with pytest.raises(RuntimeError) as e: - pmb.challenge.apkindex(args, path_apkindex) - assert str(e.value).startswith("Could not find file 'hello-world") - - -def test_challenge_apkindex_ok(args): - """ - Metion one file in the APKINDEX cache, and create it on disk. The challenge - should go through without an exception. - """ - path_apkindex = list(args.cache["apkindex"].keys())[0] - args.cache["apkindex"][path_apkindex]["ret"] = { - "hello-world": {"pkgname": "hello-world", "version": "1-r2"} - } - tmpdir = os.path.dirname(path_apkindex) - open(tmpdir + "/hello-world-1-r2.apk", "a").close() - - pmb.challenge.apkindex(args, path_apkindex) diff --git a/test/test_challenge_build.py b/test/test_challenge_build.py deleted file mode 100644 index 6d1cf41c..00000000 --- a/test/test_challenge_build.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Copyright 2018 Oliver Smith - -This file is part of pmbootstrap. - -pmbootstrap is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -pmbootstrap is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pmbootstrap. If not, see . -""" -import os -import sys -import pytest - -# Import from parent directory -sys.path.append(os.path.realpath( - os.path.join(os.path.dirname(__file__) + "/.."))) -import pmb.build -import pmb.challenge.build -import pmb.config -import pmb.helpers.logging -import pmb.parse - - -@pytest.fixture -def args(request, tmpdir): - import pmb.parse - sys.argv = ["pmbootstrap.py", "chroot"] - args = pmb.parse.arguments() - args.log = args.work + "/log_testsuite.txt" - pmb.helpers.logging.init(args) - request.addfinalizer(args.logfd.close) - return args - - -def test_challenge_build(args): - # Build the "hello-world" package - pkgname = "hello-world" - pmb.build.package(args, pkgname, None, force=True, buildinfo=True) - - # Copy it to a temporary path - aport = pmb.build.other.find_aport(args, "hello-world") - apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD") - version = apkbuild["pkgver"] + "-r" + apkbuild["pkgrel"] - temp_path = pmb.chroot.other.tempfolder(args, "/tmp/test_challenge_build/" + - args.arch_native) - packages_path = "/home/pmos/packages/pmos/" + args.arch_native - apk_path = packages_path + "/" + pkgname + "-" + version + ".apk" - pmb.chroot.user(args, ["cp", apk_path, apk_path + ".buildinfo.json", - temp_path]) - - # Change the timestamps of all files, so the changes file gets written - # correctly, even if this testcase gets executed very fast - pmb.chroot.user(args, ["touch", "-d", "2017-01-01", - packages_path + "/APKINDEX.tar.gz", - apk_path, - apk_path + ".buildinfo.json"]) - - # Challenge, output changes into a file - args.cache["built"] = {} - setattr(args, "output_repo_changes", args.work + "/chroot_native/tmp/" - "test_challenge_build_output.txt") - pmb.challenge.build(args, args.work + "/chroot_native/" + temp_path + "/" + - os.path.basename(apk_path)) - - # Verify the output textfile - with open(args.output_repo_changes, "r") as handle: - lines = handle.readlines() - assert lines == [args.arch_native + "/APKINDEX.tar.gz\n", - args.arch_native + "/" + pkgname + "-" + version + ".apk\n", - args.arch_native + "/" + pkgname + "-" + version + ".apk.buildinfo.json\n"]