274 lines
9.0 KiB
Python
274 lines
9.0 KiB
Python
# Copyright 2020 Oliver Smith
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
import logging
|
|
import os
|
|
import pytest
|
|
import sys
|
|
|
|
import pmb_test
|
|
import pmb_test.const
|
|
import pmb.aportgen.device
|
|
import pmb.config
|
|
import pmb.config.init
|
|
import pmb.helpers.logging
|
|
|
|
|
|
@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(args.logfd.close)
|
|
return args
|
|
|
|
|
|
def fake_answers(monkeypatch, answers):
|
|
"""
|
|
Patch pmb.helpers.cli.ask() function to return defined answers instead of
|
|
asking the user for an answer.
|
|
|
|
:param answers: list of answer strings, e.g. ["y", "n", "invalid-device"].
|
|
In this example, the first question is answered with "y",
|
|
the second question with "n" and so on.
|
|
"""
|
|
def fake_ask(args, question="Continue?", choices=["y", "n"], default="n",
|
|
lowercase_answer=True, validation_regex=None, complete=None):
|
|
answer = answers.pop(0)
|
|
logging.info("pmb.helpers.cli.ask() fake answer: " + answer)
|
|
return answer
|
|
monkeypatch.setattr(pmb.helpers.cli, "ask", fake_ask)
|
|
|
|
|
|
def test_fake_answers_selftest(monkeypatch):
|
|
fake_answers(monkeypatch, ["first", "second"])
|
|
assert pmb.helpers.cli.ask(args) == "first"
|
|
assert pmb.helpers.cli.ask(args) == "second"
|
|
|
|
|
|
def test_questions_booleans(args, monkeypatch):
|
|
functions = [pmb.aportgen.device.ask_for_keyboard,
|
|
pmb.aportgen.device.ask_for_external_storage]
|
|
for func in functions:
|
|
fake_answers(monkeypatch, ["y", "n"])
|
|
assert func(args) is True
|
|
assert func(args) is False
|
|
|
|
|
|
def test_questions_strings(args, monkeypatch):
|
|
functions = [pmb.aportgen.device.ask_for_manufacturer]
|
|
for func in functions:
|
|
fake_answers(monkeypatch, ["Simple string answer"])
|
|
assert func(args) == "Simple string answer"
|
|
|
|
|
|
def test_questions_name(args, monkeypatch):
|
|
func = pmb.aportgen.device.ask_for_name
|
|
|
|
# Manufacturer should get added automatically, but not twice
|
|
fake_answers(monkeypatch, ["Amazon Thor"])
|
|
assert func(args, "Amazon") == "Amazon Thor"
|
|
fake_answers(monkeypatch, ["Thor"])
|
|
assert func(args, "Amazon") == "Amazon Thor"
|
|
|
|
# Don't add the manufacturer when it starts with "Google"
|
|
fake_answers(monkeypatch, ["Google Nexus 12345"])
|
|
assert func(args, "Amazon") == "Google Nexus 12345"
|
|
|
|
|
|
def test_questions_arch(args, monkeypatch):
|
|
fake_answers(monkeypatch, ["invalid_arch", "aarch64"])
|
|
assert pmb.aportgen.device.ask_for_architecture(args) == "aarch64"
|
|
|
|
|
|
def test_questions_bootimg(args, monkeypatch):
|
|
func = pmb.aportgen.device.ask_for_bootimg
|
|
fake_answers(monkeypatch, ["invalid_path", ""])
|
|
assert func(args) is None
|
|
|
|
bootimg_path = pmb_test.const.testdata + "/bootimg/normal-boot.img"
|
|
fake_answers(monkeypatch, [bootimg_path])
|
|
output = {"base": "0x80000000",
|
|
"kernel_offset": "0x00008000",
|
|
"ramdisk_offset": "0x04000000",
|
|
"second_offset": "0x00f00000",
|
|
"tags_offset": "0x0e000000",
|
|
"pagesize": "2048",
|
|
"cmdline": "bootopt=64S3,32S1,32S1",
|
|
"qcdt": "false",
|
|
"dtb_second": "false"}
|
|
assert func(args) == output
|
|
|
|
|
|
def test_questions_device(args, monkeypatch):
|
|
# Prepare args
|
|
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
|
|
args.device = "lg-mako"
|
|
args.nonfree_firmware = True
|
|
args.nonfree_userland = False
|
|
args.kernel = "downstream"
|
|
|
|
# Do not generate aports
|
|
def fake_generate(args, pkgname):
|
|
return
|
|
monkeypatch.setattr(pmb.aportgen, "generate", fake_generate)
|
|
|
|
# Existing device (without non-free components so we have defaults there)
|
|
func = pmb.config.init.ask_for_device
|
|
nonfree = {"firmware": True, "userland": False}
|
|
fake_answers(monkeypatch, ["lg", "mako"])
|
|
kernel = args.kernel
|
|
assert func(args) == ("lg-mako", True, kernel, nonfree)
|
|
|
|
# Non-existing vendor, go back, existing vendor+device
|
|
fake_answers(monkeypatch, ["whoops", "n", "lg", "mako"])
|
|
assert func(args) == ("lg-mako", True, kernel, nonfree)
|
|
|
|
# Existing vendor, new device, go back, existing vendor+device
|
|
fake_answers(monkeypatch, ["lg", "nonexistent", "n", "lg", "mako"])
|
|
assert func(args) == ("lg-mako", True, kernel, nonfree)
|
|
|
|
# New vendor and new device (new port)
|
|
fake_answers(monkeypatch, ["new", "y", "device", "y"])
|
|
assert func(args) == ("new-device", False, kernel, nonfree)
|
|
|
|
# Existing vendor, new device (new port)
|
|
fake_answers(monkeypatch, ["lg", "nonexistent", "y"])
|
|
assert func(args) == ("lg-nonexistent", False, kernel, nonfree)
|
|
|
|
|
|
def test_questions_device_kernel(args, monkeypatch):
|
|
# Prepare args
|
|
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
|
|
args.kernel = "downstream"
|
|
|
|
# Kernel hardcoded in depends
|
|
func = pmb.config.init.ask_for_device_kernel
|
|
device = "lg-mako"
|
|
assert func(args, device) == args.kernel
|
|
|
|
# Choose "mainline"
|
|
device = "sony-amami"
|
|
fake_answers(monkeypatch, ["mainline"])
|
|
assert func(args, device) == "mainline"
|
|
|
|
# Choose "downstream"
|
|
fake_answers(monkeypatch, ["downstream"])
|
|
assert func(args, device) == "downstream"
|
|
|
|
|
|
def test_questions_device_nonfree(args, monkeypatch):
|
|
# Prepare args
|
|
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
|
|
args.nonfree_firmware = False
|
|
args.nonfree_userland = False
|
|
|
|
# APKBUILD with firmware and userland (all yes)
|
|
func = pmb.config.init.ask_for_device_nonfree
|
|
device = "nonfree-firmware-and-userland"
|
|
fake_answers(monkeypatch, ["y", "y"])
|
|
nonfree = {"firmware": True, "userland": True}
|
|
assert func(args, device) == nonfree
|
|
|
|
# APKBUILD with firmware and userland (all no)
|
|
fake_answers(monkeypatch, ["n", "n"])
|
|
nonfree = {"firmware": False, "userland": False}
|
|
assert func(args, device) == nonfree
|
|
|
|
# APKBUILD with firmware only
|
|
func = pmb.config.init.ask_for_device_nonfree
|
|
device = "nonfree-firmware"
|
|
fake_answers(monkeypatch, ["y"])
|
|
nonfree = {"firmware": True, "userland": False}
|
|
assert func(args, device) == nonfree
|
|
|
|
# APKBUILD with userland only
|
|
func = pmb.config.init.ask_for_device_nonfree
|
|
device = "nonfree-userland"
|
|
fake_answers(monkeypatch, ["y"])
|
|
nonfree = {"firmware": False, "userland": True}
|
|
assert func(args, device) == nonfree
|
|
|
|
|
|
def test_questions_flash_methods(args, monkeypatch):
|
|
func = pmb.aportgen.device.ask_for_flash_method
|
|
fake_answers(monkeypatch, ["invalid_flash_method", "fastboot"])
|
|
assert func(args) == "fastboot"
|
|
|
|
fake_answers(monkeypatch, ["0xffff"])
|
|
assert func(args) == "0xffff"
|
|
|
|
fake_answers(monkeypatch, ["heimdall", "invalid_type", "isorec"])
|
|
assert func(args) == "heimdall-isorec"
|
|
|
|
fake_answers(monkeypatch, ["heimdall", "bootimg"])
|
|
assert func(args) == "heimdall-bootimg"
|
|
|
|
|
|
def test_questions_keymaps(args, monkeypatch):
|
|
func = pmb.config.init.ask_for_keymaps
|
|
fake_answers(monkeypatch, ["invalid_keymap", "us/rx51_us"])
|
|
assert func(args, "nokia-n900") == "us/rx51_us"
|
|
assert func(args, "lg-mako") == ""
|
|
|
|
|
|
def test_questions_ui(args, monkeypatch):
|
|
fake_answers(monkeypatch, ["invalid_UI", "weston"])
|
|
assert pmb.config.init.ask_for_ui(args) == "weston"
|
|
|
|
|
|
def test_questions_work_path(args, monkeypatch, tmpdir):
|
|
# Existing paths (triggering various errors)
|
|
func = pmb.config.init.ask_for_work_path
|
|
tmpdir = str(tmpdir)
|
|
fake_answers(monkeypatch, ["/dev/null", os.path.dirname(__file__),
|
|
pmb.config.pmb_src, tmpdir])
|
|
assert func(args) == (tmpdir, True)
|
|
|
|
# Non-existing path
|
|
work = tmpdir + "/non_existing_subfolder"
|
|
fake_answers(monkeypatch, [work])
|
|
assert func(args) == (work, False)
|
|
|
|
|
|
def test_questions_build_options(args, monkeypatch):
|
|
func = pmb.config.init.ask_for_build_options
|
|
cfg = {"pmbootstrap": {}}
|
|
|
|
# Skip changing anything
|
|
fake_answers(monkeypatch, ["n"])
|
|
func(args, cfg)
|
|
assert cfg == {"pmbootstrap": {}}
|
|
|
|
# Answer everything
|
|
fake_answers(monkeypatch, ["y", "5", "2G", "n"])
|
|
func(args, cfg)
|
|
assert cfg == {"pmbootstrap": {"jobs": "5",
|
|
"ccache_size": "2G"}}
|
|
|
|
|
|
def test_questions_hostname(args, monkeypatch):
|
|
func = pmb.config.init.ask_for_hostname
|
|
device = "test-device"
|
|
|
|
# Valid hostname
|
|
fake_answers(monkeypatch, ["valid"])
|
|
assert func(args, device) == "valid"
|
|
|
|
# Hostname too long ("aaaaa...")
|
|
fake_answers(monkeypatch, ["a" * 64, "a" * 63])
|
|
assert func(args, device) == "a" * 63
|
|
|
|
# Fail the regex
|
|
fake_answers(monkeypatch, ["$invalid", "valid"])
|
|
assert func(args, device) == "valid"
|
|
|
|
# Begins or ends with minus
|
|
fake_answers(monkeypatch, ["-invalid", "invalid-", "valid"])
|
|
assert func(args, device) == "valid"
|
|
|
|
# Device name: empty string
|
|
fake_answers(monkeypatch, [device])
|
|
assert func(args, device) == ""
|