pmbootstrap/test/test_install.py

183 lines
6.2 KiB
Python
Raw Normal View History

2022-01-02 21:38:21 +00:00
# Copyright 2022 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
Make proprietary drivers optional (1/2): pmbootstrap changes (#1254) Here are the changes necessary in pmbootstrap to make proprietary software installed onto the device (firmware and userspace drivers) optional (#756). To full close the issue, we need to apply this concept to all device packages we already have in a follow-up PR. Changes: * New config file options nonfree_firmware and nonfree_userland, which we ask for during "pmbootstrap init" if there are non-free components for the selected device. * We find that out by checking the APKBUILD's subpakages: The non-free packages are called $pkgname-nonfree-firmware and $pkgname-nonfree-userland. * During "pmbootstrap init" we also show the pkgdesc of these subpackages. Parsing that is implemented in pmb.parse._apkbuild.subpkgdesc(). It was not implemented as part of the regular APKBUILD parsing, as this would need a change in the output format, and it is a lot *less* code if done like in this commit. * pmb/parse/apkbuild.py was renamed to _apkbuild.py, and pmb/install/install.py to _install.py: needed to call the function in the usual way (e.g. pmb.parse.apkbuild()) but still being able to test the individual functions from these files in the test suite. We did the same thing for pmb/build/_package.py already. * Install: New function get_nonfree_packages() returns the non-free packages that will be installed, based on the user's choice in "pmbootstrap init" and on the subpackages the device has. * Added test cases and test data (APKBUILDs) for all new code, refactored test/test_questions.py to have multiple functions for testing the various questions / question types from "pmbootstrap init" instead of having it all in one big function. This allows to use another aport folder for testing the new non-free related questions in init.
2018-02-24 21:49:10 +00:00
import pytest
import sys
import os
import shutil
Make proprietary drivers optional (1/2): pmbootstrap changes (#1254) Here are the changes necessary in pmbootstrap to make proprietary software installed onto the device (firmware and userspace drivers) optional (#756). To full close the issue, we need to apply this concept to all device packages we already have in a follow-up PR. Changes: * New config file options nonfree_firmware and nonfree_userland, which we ask for during "pmbootstrap init" if there are non-free components for the selected device. * We find that out by checking the APKBUILD's subpakages: The non-free packages are called $pkgname-nonfree-firmware and $pkgname-nonfree-userland. * During "pmbootstrap init" we also show the pkgdesc of these subpackages. Parsing that is implemented in pmb.parse._apkbuild.subpkgdesc(). It was not implemented as part of the regular APKBUILD parsing, as this would need a change in the output format, and it is a lot *less* code if done like in this commit. * pmb/parse/apkbuild.py was renamed to _apkbuild.py, and pmb/install/install.py to _install.py: needed to call the function in the usual way (e.g. pmb.parse.apkbuild()) but still being able to test the individual functions from these files in the test suite. We did the same thing for pmb/build/_package.py already. * Install: New function get_nonfree_packages() returns the non-free packages that will be installed, based on the user's choice in "pmbootstrap init" and on the subpackages the device has. * Added test cases and test data (APKBUILDs) for all new code, refactored test/test_questions.py to have multiple functions for testing the various questions / question types from "pmbootstrap init" instead of having it all in one big function. This allows to use another aport folder for testing the new non-free related questions in init.
2018-02-24 21:49:10 +00:00
import pmb_test
import pmb_test.const
Make proprietary drivers optional (1/2): pmbootstrap changes (#1254) Here are the changes necessary in pmbootstrap to make proprietary software installed onto the device (firmware and userspace drivers) optional (#756). To full close the issue, we need to apply this concept to all device packages we already have in a follow-up PR. Changes: * New config file options nonfree_firmware and nonfree_userland, which we ask for during "pmbootstrap init" if there are non-free components for the selected device. * We find that out by checking the APKBUILD's subpakages: The non-free packages are called $pkgname-nonfree-firmware and $pkgname-nonfree-userland. * During "pmbootstrap init" we also show the pkgdesc of these subpackages. Parsing that is implemented in pmb.parse._apkbuild.subpkgdesc(). It was not implemented as part of the regular APKBUILD parsing, as this would need a change in the output format, and it is a lot *less* code if done like in this commit. * pmb/parse/apkbuild.py was renamed to _apkbuild.py, and pmb/install/install.py to _install.py: needed to call the function in the usual way (e.g. pmb.parse.apkbuild()) but still being able to test the individual functions from these files in the test suite. We did the same thing for pmb/build/_package.py already. * Install: New function get_nonfree_packages() returns the non-free packages that will be installed, based on the user's choice in "pmbootstrap init" and on the subpackages the device has. * Added test cases and test data (APKBUILDs) for all new code, refactored test/test_questions.py to have multiple functions for testing the various questions / question types from "pmbootstrap init" instead of having it all in one big function. This allows to use another aport folder for testing the new non-free related questions in init.
2018-02-24 21:49:10 +00:00
import pmb.aportgen.device
import pmb.config
import pmb.config.init
import pmb.helpers.logging
import pmb.install._install
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "init"]
args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
Make proprietary drivers optional (1/2): pmbootstrap changes (#1254) Here are the changes necessary in pmbootstrap to make proprietary software installed onto the device (firmware and userspace drivers) optional (#756). To full close the issue, we need to apply this concept to all device packages we already have in a follow-up PR. Changes: * New config file options nonfree_firmware and nonfree_userland, which we ask for during "pmbootstrap init" if there are non-free components for the selected device. * We find that out by checking the APKBUILD's subpakages: The non-free packages are called $pkgname-nonfree-firmware and $pkgname-nonfree-userland. * During "pmbootstrap init" we also show the pkgdesc of these subpackages. Parsing that is implemented in pmb.parse._apkbuild.subpkgdesc(). It was not implemented as part of the regular APKBUILD parsing, as this would need a change in the output format, and it is a lot *less* code if done like in this commit. * pmb/parse/apkbuild.py was renamed to _apkbuild.py, and pmb/install/install.py to _install.py: needed to call the function in the usual way (e.g. pmb.parse.apkbuild()) but still being able to test the individual functions from these files in the test suite. We did the same thing for pmb/build/_package.py already. * Install: New function get_nonfree_packages() returns the non-free packages that will be installed, based on the user's choice in "pmbootstrap init" and on the subpackages the device has. * Added test cases and test data (APKBUILDs) for all new code, refactored test/test_questions.py to have multiple functions for testing the various questions / question types from "pmbootstrap init" instead of having it all in one big function. This allows to use another aport folder for testing the new non-free related questions in init.
2018-02-24 21:49:10 +00:00
return args
def test_get_nonfree_packages(args):
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
Make proprietary drivers optional (1/2): pmbootstrap changes (#1254) Here are the changes necessary in pmbootstrap to make proprietary software installed onto the device (firmware and userspace drivers) optional (#756). To full close the issue, we need to apply this concept to all device packages we already have in a follow-up PR. Changes: * New config file options nonfree_firmware and nonfree_userland, which we ask for during "pmbootstrap init" if there are non-free components for the selected device. * We find that out by checking the APKBUILD's subpakages: The non-free packages are called $pkgname-nonfree-firmware and $pkgname-nonfree-userland. * During "pmbootstrap init" we also show the pkgdesc of these subpackages. Parsing that is implemented in pmb.parse._apkbuild.subpkgdesc(). It was not implemented as part of the regular APKBUILD parsing, as this would need a change in the output format, and it is a lot *less* code if done like in this commit. * pmb/parse/apkbuild.py was renamed to _apkbuild.py, and pmb/install/install.py to _install.py: needed to call the function in the usual way (e.g. pmb.parse.apkbuild()) but still being able to test the individual functions from these files in the test suite. We did the same thing for pmb/build/_package.py already. * Install: New function get_nonfree_packages() returns the non-free packages that will be installed, based on the user's choice in "pmbootstrap init" and on the subpackages the device has. * Added test cases and test data (APKBUILDs) for all new code, refactored test/test_questions.py to have multiple functions for testing the various questions / question types from "pmbootstrap init" instead of having it all in one big function. This allows to use another aport folder for testing the new non-free related questions in init.
2018-02-24 21:49:10 +00:00
func = pmb.install._install.get_nonfree_packages
# Device without any non-free subpackages
args.nonfree_firmware = True
args.nonfree_userland = True
assert func(args, "lg-mako") == []
# Device with non-free firmware and userland
device = "nonfree-firmware-and-userland"
assert func(args, device) == ["device-" + device + "-nonfree-firmware",
"device-" + device + "-nonfree-userland"]
# Device with non-free userland
device = "nonfree-userland"
assert func(args, device) == ["device-" + device + "-nonfree-userland"]
# Device with non-free userland (but user disabled it init)
args.nonfree_userland = False
assert func(args, device) == []
def test_get_recommends(args):
args.aports = pmb_test.const.testdata + "/pmb_recommends"
func = pmb.install.ui.get_recommends
# UI: none
args.install_recommends = True
args.ui = "none"
assert func(args) == []
# UI: test, --no-recommends
args.install_recommends = False
args.ui = "test"
assert func(args) == []
# UI: test, without -extras
args.install_recommends = True
args.ui = "test"
args.ui_extras = False
assert func(args) == ["plasma-camera", "plasma-angelfish"]
# UI: test, with -extras
args.install_recommends = True
args.ui = "test"
args.ui_extras = True
assert func(args) == ["plasma-camera", "plasma-angelfish", "buho",
"kaidan"]
# UI: invalid
args.install_recommends = True
args.ui = "invalid"
with pytest.raises(RuntimeError) as e:
func(args)
assert str(e.value).startswith("Could not find aport for package")
def test_get_groups(args):
args.aports = f"{pmb_test.const.testdata}/pmb_groups"
func = pmb.install.ui.get_groups
# UI: none:
args.ui = "none"
assert func(args) == []
# UI: test, without -extras
args.ui = "test"
args.ui_extras = False
assert func(args) == ["feedbackd"]
# UI: test, with -extras
args.ui = "test"
args.ui_extras = True
assert func(args) == ["feedbackd", "extra"]
# UI: invalid
args.ui = "invalid"
with pytest.raises(RuntimeError) as e:
func(args)
assert str(e.value).startswith("Could not find aport for package")
def test_generate_binary_list(args):
suffix = "mysuffix"
args.work = "/tmp"
func = pmb.install._install.generate_binary_list
binary_dir = os.path.join(args.work, f"chroot_{suffix}", "usr/share")
os.makedirs(binary_dir, exist_ok=True)
step = 1024
binaries = [f"{pmb_test.const.testdata}/pmb_install/small.bin",
f"{pmb_test.const.testdata}/pmb_install/full.bin",
f"{pmb_test.const.testdata}/pmb_install/big.bin",
f"{pmb_test.const.testdata}/pmb_install/overrun.bin",
f"{pmb_test.const.testdata}/pmb_install/binary2.bin"]
for b in binaries:
shutil.copy(b, binary_dir)
# Binary that is small enough to fit the partition of 10 blocks
# of 512 bytes each
binaries = "small.bin:1,binary2.bin:11"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "128"}
assert func(args, suffix, step) == [('small.bin', 1), ('binary2.bin', 11)]
# Binary that is fully filling the partition of 10 blocks of 512 bytes each
binaries = "full.bin:1,binary2.bin:11"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "128"}
assert func(args, suffix, step) == [('full.bin', 1), ('binary2.bin', 11)]
# Binary that is too big to fit the partition of 10 blocks
# of 512 bytes each
binaries = "big.bin:1,binary2.bin:2"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "128"}
with pytest.raises(RuntimeError) as e:
func(args, suffix, step)
assert str(e.value).startswith("The firmware overlaps with at least one")
# Binary that overruns the first partition
binaries = "overrun.bin:1"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "1"}
with pytest.raises(RuntimeError) as e:
func(args, suffix, step)
assert str(e.value).startswith("The firmware is too big to embed in")
# Binary does not exist
binaries = "does-not-exist.bin:1,binary2.bin:11"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "128"}
with pytest.raises(RuntimeError) as e:
func(args, suffix, step)
assert str(e.value).startswith("The following firmware binary does not")
# Binaries are touching but not overlapping
# boot_part_start is at 2 sectors (1024 b)
# |-----|---------------------|-------------------|-------------------
# | … | binary2.bin (100 b) | small.bin (600 b) | /boot part start …
# |-----|---------------------|-------------------|-------------------
# 0 324 424 1024
step = 1
binaries = "binary2.bin:324,small.bin:424"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "2"}
assert func(args, suffix, step) == [('binary2.bin', 324),
('small.bin', 424)]
# Same layout written with different order in sd_embed_firmware
binaries = "small.bin:424,binary2.bin:324"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "2"}
assert func(args, suffix, step) == [('small.bin', 424),
('binary2.bin', 324)]