initial buildroot for linux 5.15
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# Needed for binfmt_misc service: "Arbitrary Executable File Formats File System"
|
||||
CONFIG_BINFMT_MISC=y
|
||||
@@ -0,0 +1,77 @@
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
# CONFIG_X86_EXTENDED_PLATFORM is not set
|
||||
CONFIG_IOSF_MBI=y
|
||||
CONFIG_MCORE2=y
|
||||
# CONFIG_X86_MCE is not set
|
||||
# CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS is not set
|
||||
CONFIG_LEGACY_VSYSCALL_NONE=y
|
||||
# CONFIG_SUSPEND is not set
|
||||
# CONFIG_ACPI is not set
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_PCI_MSI=y
|
||||
# CONFIG_VIRTUALIZATION is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
# CONFIG_MQ_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_MQ_IOSCHED_KYBER is not set
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
|
||||
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
|
||||
# CONFIG_INET_XFRM_MODE_BEET is not set
|
||||
# CONFIG_IPV6 is not set
|
||||
# CONFIG_NF_CONNTRACK_PROCFS is not set
|
||||
# CONFIG_NF_CT_PROTO_DCCP is not set
|
||||
# CONFIG_NF_CT_PROTO_SCTP is not set
|
||||
# CONFIG_NF_CT_PROTO_UDPLITE is not set
|
||||
CONFIG_IP_VS=y
|
||||
CONFIG_IP_VS_RR=y
|
||||
CONFIG_IP_VS_NFCT=y
|
||||
# CONFIG_BRIDGE_IGMP_SNOOPING is not set
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_VIRTIO_NET=y
|
||||
# CONFIG_ETHERNET is not set
|
||||
# CONFIG_WLAN is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_DEVMEM is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
# CONFIG_SERIAL_8250_LPSS is not set
|
||||
# CONFIG_SERIAL_8250_MID is not set
|
||||
# CONFIG_HW_RANDOM_INTEL is not set
|
||||
# CONFIG_HW_RANDOM_AMD is not set
|
||||
# CONFIG_HW_RANDOM_VIA is not set
|
||||
CONFIG_HW_RANDOM_VIRTIO=y
|
||||
# CONFIG_DEVPORT is not set
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_VIRTIO_PCI=y
|
||||
# CONFIG_VIRTIO_PCI_LEGACY is not set
|
||||
# CONFIG_X86_PLATFORM_DEVICES is not set
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_SECURITYFS=y
|
||||
# CONFIG_CRYPTO_ECHAINIV is not set
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
# CONFIG_UNUSED_SYMBOLS is not set
|
||||
CONFIG_UNWINDER_FRAME_POINTER=y
|
||||
@@ -0,0 +1,9 @@
|
||||
version: '3'
|
||||
services:
|
||||
busybox:
|
||||
image: "busybox:latest"
|
||||
command: httpd -f -h /www/
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- "/bin:/www"
|
||||
@@ -0,0 +1,5 @@
|
||||
CONFIG_F2FS_FS=y
|
||||
CONFIG_F2FS_STAT_FS=y
|
||||
CONFIG_F2FS_FS_XATTR=y
|
||||
CONFIG_F2FS_FS_POSIX_ACL=y
|
||||
CONFIG_F2FS_FS_SECURITY=y
|
||||
@@ -0,0 +1,2 @@
|
||||
set root=(cd0)
|
||||
set prefix=/boot/grub
|
||||
@@ -0,0 +1,7 @@
|
||||
set default="0"
|
||||
set timeout="1"
|
||||
|
||||
menuentry "Buildroot" {
|
||||
linux __KERNEL_PATH__ root=/dev/sr0 console=ttyS0,115200
|
||||
initrd __INITRD_PATH__
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
default 1
|
||||
label 1
|
||||
kernel __KERNEL_PATH__
|
||||
initrd __INITRD_PATH__
|
||||
append root=/dev/sr0 console=ttyS0,115200
|
||||
@@ -0,0 +1,50 @@
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_RETPOLINE is not set
|
||||
CONFIG_HYPERVISOR_GUEST=y
|
||||
CONFIG_PARAVIRT=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_SCSI_VIRTIO=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_ATA_PIIX=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_NE2K_PCI=y
|
||||
CONFIG_8139CP=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
CONFIG_HW_RANDOM_VIRTIO=m
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_BOCHS=y
|
||||
CONFIG_DRM_QXL=y
|
||||
CONFIG_DRM_VIRTIO_GPU=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_HDA_INTEL=y
|
||||
CONFIG_SND_HDA_GENERIC=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_UHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_VIRTIO_PCI=y
|
||||
CONFIG_VIRTIO_BALLOON=y
|
||||
CONFIG_VIRTIO_INPUT=y
|
||||
CONFIG_VIRTIO_MMIO=y
|
||||
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_ZISOFS=y
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
@@ -0,0 +1,5 @@
|
||||
[unittest]
|
||||
plugins = nose2.plugins.mp
|
||||
|
||||
[multiprocess]
|
||||
always-on = True
|
||||
@@ -0,0 +1,127 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import subprocess
|
||||
from urllib.request import urlopen
|
||||
from urllib.error import HTTPError, URLError
|
||||
|
||||
ARTIFACTS_URL = "http://autobuild.buildroot.net/artefacts/"
|
||||
BASE_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), "../../.."))
|
||||
|
||||
|
||||
def log_file_path(builddir, stage, logtofile=True):
|
||||
"""Return path to log file"""
|
||||
return "{}-{}.log".format(builddir, stage) if logtofile else None
|
||||
|
||||
|
||||
def open_log_file(builddir, stage, logtofile=True):
|
||||
"""
|
||||
Open a file for logging and return its handler.
|
||||
If logtofile is True, returns sys.stdout. Otherwise opens a file
|
||||
with a suitable name in the build directory.
|
||||
"""
|
||||
return open(log_file_path(builddir, stage, logtofile), 'a+') if logtofile else sys.stdout
|
||||
|
||||
|
||||
def basepath(relpath=""):
|
||||
"""Return the absolute path for a file or directory relative to the Buildroot top directory."""
|
||||
return os.path.join(BASE_DIR, relpath)
|
||||
|
||||
|
||||
def filepath(relpath):
|
||||
return os.path.join(BASE_DIR, "support/testing", relpath)
|
||||
|
||||
|
||||
def download(dldir, filename):
|
||||
finalpath = os.path.join(dldir, filename)
|
||||
if os.path.exists(finalpath):
|
||||
return finalpath
|
||||
|
||||
if not os.path.exists(dldir):
|
||||
os.makedirs(dldir)
|
||||
|
||||
tmpfile = tempfile.mktemp(dir=dldir)
|
||||
print("Downloading to {}".format(tmpfile))
|
||||
|
||||
try:
|
||||
url_fh = urlopen(os.path.join(ARTIFACTS_URL, filename))
|
||||
with open(tmpfile, "w+b") as tmpfile_fh:
|
||||
tmpfile_fh.write(url_fh.read())
|
||||
except (HTTPError, URLError) as err:
|
||||
os.unlink(tmpfile)
|
||||
raise err
|
||||
|
||||
print("Renaming from {} to {}".format(tmpfile, finalpath))
|
||||
os.rename(tmpfile, finalpath)
|
||||
return finalpath
|
||||
|
||||
|
||||
def run_cmd_on_host(builddir, cmd):
|
||||
"""Call subprocess.check_output and return the text output."""
|
||||
out = subprocess.check_output(cmd,
|
||||
stderr=open(os.devnull, "w"),
|
||||
cwd=builddir,
|
||||
env={"LANG": "C"},
|
||||
universal_newlines=True)
|
||||
return out
|
||||
|
||||
|
||||
def get_elf_arch_tag(builddir, prefix, fpath, tag):
|
||||
"""
|
||||
Runs the cross readelf on 'fpath', then extracts the value of tag 'tag'.
|
||||
Example:
|
||||
>>> get_elf_arch_tag('output', 'arm-none-linux-gnueabi-',
|
||||
'bin/busybox', 'Tag_CPU_arch')
|
||||
v5TEJ
|
||||
>>>
|
||||
"""
|
||||
cmd = ["host/bin/{}-readelf".format(prefix),
|
||||
"-A", os.path.join("target", fpath)]
|
||||
out = run_cmd_on_host(builddir, cmd)
|
||||
regexp = re.compile(r"^ {}: (.*)$".format(tag))
|
||||
for line in out.splitlines():
|
||||
m = regexp.match(line)
|
||||
if not m:
|
||||
continue
|
||||
return m.group(1)
|
||||
return None
|
||||
|
||||
|
||||
def get_file_arch(builddir, prefix, fpath):
|
||||
return get_elf_arch_tag(builddir, prefix, fpath, "Tag_CPU_arch")
|
||||
|
||||
|
||||
def get_elf_prog_interpreter(builddir, prefix, fpath):
|
||||
"""
|
||||
Runs the cross readelf on 'fpath' to extract the program interpreter
|
||||
name and returns it.
|
||||
Example:
|
||||
>>> get_elf_prog_interpreter('br-tests/TestExternalToolchainLinaroArm',
|
||||
'arm-linux-gnueabihf',
|
||||
'bin/busybox')
|
||||
/lib/ld-linux-armhf.so.3
|
||||
>>>
|
||||
"""
|
||||
cmd = ["host/bin/{}-readelf".format(prefix),
|
||||
"-l", os.path.join("target", fpath)]
|
||||
out = run_cmd_on_host(builddir, cmd)
|
||||
regexp = re.compile(r"^ *\[Requesting program interpreter: (.*)\]$")
|
||||
for line in out.splitlines():
|
||||
m = regexp.match(line)
|
||||
if not m:
|
||||
continue
|
||||
return m.group(1)
|
||||
return None
|
||||
|
||||
|
||||
def img_round_power2(img):
|
||||
"""
|
||||
Rounds up the size of an image file to the next power of 2
|
||||
"""
|
||||
sz = os.stat(img).st_size
|
||||
pow2 = 1
|
||||
while pow2 < sz:
|
||||
pow2 = pow2 << 1
|
||||
with open(img, 'ab') as f:
|
||||
f.truncate(pow2)
|
||||
@@ -0,0 +1,92 @@
|
||||
import unittest
|
||||
import os
|
||||
import datetime
|
||||
|
||||
from infra.builder import Builder
|
||||
from infra.emulator import Emulator
|
||||
|
||||
BASIC_TOOLCHAIN_CONFIG = \
|
||||
"""
|
||||
BR2_arm=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/armv5-eabi/tarballs/armv5-eabi--uclibc--bleeding-edge-2018.11-1.tar.bz2"
|
||||
BR2_TOOLCHAIN_EXTERNAL_GCC_8=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_14=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_LOCALE=y
|
||||
BR2_TOOLCHAIN_HAS_THREADS_DEBUG=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CXX=y
|
||||
"""
|
||||
|
||||
MINIMAL_CONFIG = \
|
||||
"""
|
||||
BR2_INIT_NONE=y
|
||||
BR2_SYSTEM_BIN_SH_NONE=y
|
||||
# BR2_PACKAGE_BUSYBOX is not set
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
"""
|
||||
|
||||
|
||||
class BRConfigTest(unittest.TestCase):
|
||||
config = None
|
||||
br2_external = list()
|
||||
downloaddir = None
|
||||
outputdir = None
|
||||
logtofile = True
|
||||
keepbuilds = False
|
||||
jlevel = 0
|
||||
timeout_multiplier = 1
|
||||
|
||||
def __init__(self, names):
|
||||
super(BRConfigTest, self).__init__(names)
|
||||
self.testname = self.__class__.__name__
|
||||
self.builddir = self.outputdir and os.path.join(self.outputdir, self.testname)
|
||||
self.config += '\nBR2_DL_DIR="{}"\n'.format(self.downloaddir)
|
||||
self.config += "\nBR2_JLEVEL={}\n".format(self.jlevel)
|
||||
|
||||
def show_msg(self, msg):
|
||||
print("{} {:40s} {}".format(datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
self.testname, msg))
|
||||
|
||||
def setUp(self):
|
||||
self.show_msg("Starting")
|
||||
self.b = Builder(self.config, self.builddir, self.logtofile)
|
||||
|
||||
if not self.keepbuilds:
|
||||
self.b.delete()
|
||||
|
||||
if not self.b.is_finished():
|
||||
self.b.configure(make_extra_opts=["BR2_EXTERNAL={}".format(":".join(self.br2_external))])
|
||||
|
||||
def tearDown(self):
|
||||
self.show_msg("Cleaning up")
|
||||
if self.b and not self.keepbuilds:
|
||||
self.b.delete()
|
||||
|
||||
|
||||
class BRTest(BRConfigTest):
|
||||
def __init__(self, names):
|
||||
super(BRTest, self).__init__(names)
|
||||
self.emulator = None
|
||||
|
||||
def setUp(self):
|
||||
super(BRTest, self).setUp()
|
||||
if not self.b.is_finished():
|
||||
self.show_msg("Building")
|
||||
self.b.build()
|
||||
self.show_msg("Building done")
|
||||
|
||||
self.emulator = Emulator(self.builddir, self.downloaddir,
|
||||
self.logtofile, self.timeout_multiplier)
|
||||
|
||||
def tearDown(self):
|
||||
if self.emulator:
|
||||
self.emulator.stop()
|
||||
super(BRTest, self).tearDown()
|
||||
|
||||
# Run the given 'cmd' with a 'timeout' on the target and
|
||||
# assert that the command succeeded
|
||||
def assertRunOk(self, cmd, timeout=-1):
|
||||
_, exit_code = self.emulator.run(cmd, timeout)
|
||||
self.assertEqual(exit_code, 0)
|
||||
@@ -0,0 +1,107 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
import infra
|
||||
|
||||
|
||||
class Builder(object):
|
||||
def __init__(self, config, builddir, logtofile):
|
||||
self.config = '\n'.join([line.lstrip() for line in
|
||||
config.splitlines()]) + '\n'
|
||||
self.builddir = builddir
|
||||
self.logfile = infra.open_log_file(builddir, "build", logtofile)
|
||||
|
||||
def is_defconfig_valid(self, configfile, defconfig):
|
||||
"""Check if the .config is contains all lines present in the defconfig."""
|
||||
with open(configfile) as configf:
|
||||
configlines = configf.readlines()
|
||||
|
||||
defconfiglines = defconfig.split("\n")
|
||||
|
||||
# Check that all the defconfig lines are still present
|
||||
for defconfigline in defconfiglines:
|
||||
if defconfigline + "\n" not in configlines:
|
||||
self.logfile.write("WARN: defconfig can't be used\n")
|
||||
self.logfile.write(" Missing: %s\n" % defconfigline.strip())
|
||||
self.logfile.flush()
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def configure(self, make_extra_opts=[], make_extra_env={}):
|
||||
"""Configure the build.
|
||||
|
||||
make_extra_opts: a list of arguments to be passed to the make
|
||||
command.
|
||||
e.g. make_extra_opts=["BR2_EXTERNAL=/path"]
|
||||
|
||||
make_extra_env: a dict of variables to be appended (or replaced)
|
||||
in the environment that calls make.
|
||||
e.g. make_extra_env={"BR2_DL_DIR": "/path"}
|
||||
"""
|
||||
if not os.path.isdir(self.builddir):
|
||||
os.makedirs(self.builddir)
|
||||
|
||||
config_file = os.path.join(self.builddir, ".config")
|
||||
with open(config_file, "w+") as cf:
|
||||
cf.write(self.config)
|
||||
# dump the defconfig to the logfile for easy debugging
|
||||
self.logfile.write("> start defconfig\n" + self.config +
|
||||
"> end defconfig\n")
|
||||
self.logfile.flush()
|
||||
|
||||
env = {"PATH": os.environ["PATH"]}
|
||||
env.update(make_extra_env)
|
||||
|
||||
cmd = ["make",
|
||||
"O={}".format(self.builddir)]
|
||||
cmd += make_extra_opts
|
||||
cmd += ["olddefconfig"]
|
||||
|
||||
ret = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile,
|
||||
cwd=infra.basepath(), env=env)
|
||||
if ret != 0:
|
||||
raise SystemError("Cannot olddefconfig")
|
||||
|
||||
if not self.is_defconfig_valid(config_file, self.config):
|
||||
raise SystemError("The defconfig is not valid")
|
||||
|
||||
def build(self, make_extra_opts=[], make_extra_env={}):
|
||||
"""Perform the build.
|
||||
|
||||
make_extra_opts: a list of arguments to be passed to the make
|
||||
command. It can include a make target.
|
||||
e.g. make_extra_opts=["foo-source"]
|
||||
|
||||
make_extra_env: a dict of variables to be appended (or replaced)
|
||||
in the environment that calls make.
|
||||
e.g. make_extra_env={"BR2_DL_DIR": "/path"}
|
||||
"""
|
||||
env = {"PATH": os.environ["PATH"]}
|
||||
if "http_proxy" in os.environ:
|
||||
self.logfile.write("Using system proxy: " +
|
||||
os.environ["http_proxy"] + "\n")
|
||||
env['http_proxy'] = os.environ["http_proxy"]
|
||||
env['https_proxy'] = os.environ["http_proxy"]
|
||||
env.update(make_extra_env)
|
||||
|
||||
cmd = ["make", "-C", self.builddir]
|
||||
cmd += make_extra_opts
|
||||
|
||||
ret = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile,
|
||||
env=env)
|
||||
if ret != 0:
|
||||
raise SystemError("Build failed")
|
||||
|
||||
open(self.stamp_path(), 'a').close()
|
||||
|
||||
def stamp_path(self):
|
||||
return os.path.join(self.builddir, "build-done")
|
||||
|
||||
def is_finished(self):
|
||||
return os.path.exists(self.stamp_path())
|
||||
|
||||
def delete(self):
|
||||
if os.path.exists(self.builddir):
|
||||
shutil.rmtree(self.builddir)
|
||||
@@ -0,0 +1,128 @@
|
||||
import pexpect
|
||||
|
||||
import infra
|
||||
|
||||
|
||||
class Emulator(object):
|
||||
|
||||
def __init__(self, builddir, downloaddir, logtofile, timeout_multiplier):
|
||||
self.qemu = None
|
||||
self.downloaddir = downloaddir
|
||||
self.logfile = infra.open_log_file(builddir, "run", logtofile)
|
||||
# We use elastic runners on the cloud to runs our tests. Those runners
|
||||
# can take a long time to run the emulator. Use a timeout multiplier
|
||||
# when running the tests to avoid sporadic failures.
|
||||
self.timeout_multiplier = timeout_multiplier
|
||||
|
||||
# Start Qemu to boot the system
|
||||
#
|
||||
# arch: Qemu architecture to use
|
||||
#
|
||||
# kernel: path to the kernel image, or the special string
|
||||
# 'builtin'. 'builtin' means a pre-built kernel image will be
|
||||
# downloaded from ARTEFACTS_URL and suitable options are
|
||||
# automatically passed to qemu and added to the kernel cmdline. So
|
||||
# far only armv5, armv7 and i386 builtin kernels are available.
|
||||
# If None, then no kernel is used, and we assume a bootable device
|
||||
# will be specified.
|
||||
#
|
||||
# kernel_cmdline: array of kernel arguments to pass to Qemu -append option
|
||||
#
|
||||
# options: array of command line options to pass to Qemu
|
||||
#
|
||||
def boot(self, arch, kernel=None, kernel_cmdline=None, options=None):
|
||||
if arch in ["armv7", "armv5"]:
|
||||
qemu_arch = "arm"
|
||||
else:
|
||||
qemu_arch = arch
|
||||
|
||||
qemu_cmd = ["qemu-system-{}".format(qemu_arch),
|
||||
"-serial", "stdio",
|
||||
"-display", "none",
|
||||
"-m", "256"]
|
||||
|
||||
if options:
|
||||
qemu_cmd += options
|
||||
|
||||
if kernel_cmdline is None:
|
||||
kernel_cmdline = []
|
||||
|
||||
if kernel:
|
||||
if kernel == "builtin":
|
||||
if arch in ["armv7", "armv5"]:
|
||||
kernel_cmdline.append("console=ttyAMA0")
|
||||
|
||||
if arch == "armv7":
|
||||
kernel = infra.download(self.downloaddir,
|
||||
"kernel-vexpress-5.10.7")
|
||||
dtb = infra.download(self.downloaddir,
|
||||
"vexpress-v2p-ca9-5.10.7.dtb")
|
||||
qemu_cmd += ["-dtb", dtb]
|
||||
qemu_cmd += ["-M", "vexpress-a9"]
|
||||
elif arch == "armv5":
|
||||
kernel = infra.download(self.downloaddir,
|
||||
"kernel-versatile-5.10.7")
|
||||
dtb = infra.download(self.downloaddir,
|
||||
"versatile-pb-5.10.7.dtb")
|
||||
qemu_cmd += ["-dtb", dtb]
|
||||
qemu_cmd += ["-M", "versatilepb"]
|
||||
qemu_cmd += ["-device", "virtio-rng-pci"]
|
||||
|
||||
qemu_cmd += ["-kernel", kernel]
|
||||
|
||||
if kernel_cmdline:
|
||||
qemu_cmd += ["-append", " ".join(kernel_cmdline)]
|
||||
|
||||
self.logfile.write("> starting qemu with '%s'\n" % " ".join(qemu_cmd))
|
||||
self.qemu = pexpect.spawn(qemu_cmd[0], qemu_cmd[1:],
|
||||
timeout=5 * self.timeout_multiplier,
|
||||
encoding='utf-8',
|
||||
codec_errors='replace',
|
||||
env={"QEMU_AUDIO_DRV": "none"})
|
||||
# We want only stdout into the log to avoid double echo
|
||||
self.qemu.logfile_read = self.logfile
|
||||
|
||||
# Wait for the login prompt to appear, and then login as root with
|
||||
# the provided password, or no password if not specified.
|
||||
def login(self, password=None):
|
||||
# The login prompt can take some time to appear when running multiple
|
||||
# instances in parallel, so set the timeout to a large value
|
||||
index = self.qemu.expect(["buildroot login:", pexpect.TIMEOUT],
|
||||
timeout=60 * self.timeout_multiplier)
|
||||
if index != 0:
|
||||
self.logfile.write("==> System does not boot")
|
||||
raise SystemError("System does not boot")
|
||||
|
||||
self.qemu.sendline("root")
|
||||
if password:
|
||||
self.qemu.expect("Password:")
|
||||
self.qemu.sendline(password)
|
||||
index = self.qemu.expect(["# ", pexpect.TIMEOUT])
|
||||
if index != 0:
|
||||
raise SystemError("Cannot login")
|
||||
self.run("dmesg -n 1")
|
||||
# Prevent the shell from wrapping the commands at 80 columns.
|
||||
self.run("stty columns 29999")
|
||||
|
||||
# Run the given 'cmd' with a 'timeout' on the target
|
||||
# return a tuple (output, exit_code)
|
||||
def run(self, cmd, timeout=-1):
|
||||
self.qemu.sendline(cmd)
|
||||
if timeout != -1:
|
||||
timeout *= self.timeout_multiplier
|
||||
self.qemu.expect("# ", timeout=timeout)
|
||||
# Remove double carriage return from qemu stdout so str.splitlines()
|
||||
# works as expected.
|
||||
output = self.qemu.before.replace("\r\r", "\r").splitlines()[1:]
|
||||
|
||||
self.qemu.sendline("echo $?")
|
||||
self.qemu.expect("# ")
|
||||
exit_code = self.qemu.before.splitlines()[2]
|
||||
exit_code = int(exit_code)
|
||||
|
||||
return output, exit_code
|
||||
|
||||
def stop(self):
|
||||
if self.qemu is None:
|
||||
return
|
||||
self.qemu.terminate(force=True)
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import multiprocessing
|
||||
import os
|
||||
import sys
|
||||
|
||||
import nose2
|
||||
|
||||
from infra.basetest import BRConfigTest
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Run Buildroot tests')
|
||||
parser.add_argument('testname', nargs='*',
|
||||
help='list of test cases to execute')
|
||||
parser.add_argument('-l', '--list', action='store_true',
|
||||
help='list of available test cases')
|
||||
parser.add_argument('-a', '--all', action='store_true',
|
||||
help='execute all test cases')
|
||||
parser.add_argument('-s', '--stdout', action='store_true',
|
||||
help='log everything to stdout')
|
||||
parser.add_argument('-o', '--output',
|
||||
help='output directory')
|
||||
parser.add_argument('-d', '--download',
|
||||
help='download directory')
|
||||
parser.add_argument('-k', '--keep',
|
||||
help='keep build directories',
|
||||
action='store_true')
|
||||
parser.add_argument('-t', '--testcases', type=int, default=1,
|
||||
help='number of testcases to run simultaneously')
|
||||
parser.add_argument('-j', '--jlevel', type=int,
|
||||
help='BR2_JLEVEL to use for each testcase')
|
||||
parser.add_argument('--timeout-multiplier', type=int, default=1,
|
||||
help='increase timeouts (useful for slow machines)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
script_path = os.path.realpath(__file__)
|
||||
test_dir = os.path.dirname(script_path)
|
||||
|
||||
if args.stdout:
|
||||
BRConfigTest.logtofile = False
|
||||
|
||||
if args.list:
|
||||
print("List of tests")
|
||||
nose2.discover(argv=[script_path,
|
||||
"-s", test_dir,
|
||||
"-v",
|
||||
"--collect-only"],
|
||||
plugins=["nose2.plugins.collect"])
|
||||
return 0
|
||||
|
||||
if args.download is None:
|
||||
args.download = os.getenv("BR2_DL_DIR")
|
||||
if args.download is None:
|
||||
print("Missing download directory, please use -d/--download")
|
||||
print("")
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
BRConfigTest.downloaddir = os.path.abspath(args.download)
|
||||
|
||||
if args.output is None:
|
||||
print("Missing output directory, please use -o/--output")
|
||||
print("")
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
if not os.path.exists(args.output):
|
||||
os.mkdir(args.output)
|
||||
|
||||
BRConfigTest.outputdir = os.path.abspath(args.output)
|
||||
|
||||
if args.all is False and not args.testname:
|
||||
print("No test selected")
|
||||
print("")
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
BRConfigTest.keepbuilds = args.keep
|
||||
|
||||
if args.testcases != 1:
|
||||
if args.testcases < 1:
|
||||
print("Invalid number of testcases to run simultaneously")
|
||||
print("")
|
||||
parser.print_help()
|
||||
return 1
|
||||
# same default BR2_JLEVEL as package/Makefile.in
|
||||
br2_jlevel = 1 + multiprocessing.cpu_count()
|
||||
each_testcase = br2_jlevel / args.testcases
|
||||
if each_testcase < 1:
|
||||
each_testcase = 1
|
||||
BRConfigTest.jlevel = each_testcase
|
||||
|
||||
if args.jlevel:
|
||||
if args.jlevel < 0:
|
||||
print("Invalid BR2_JLEVEL to use for each testcase")
|
||||
print("")
|
||||
parser.print_help()
|
||||
return 1
|
||||
# the user can override the auto calculated value
|
||||
BRConfigTest.jlevel = args.jlevel
|
||||
|
||||
if args.timeout_multiplier < 1:
|
||||
print("Invalid multiplier for timeout values")
|
||||
print("")
|
||||
parser.print_help()
|
||||
return 1
|
||||
BRConfigTest.timeout_multiplier = args.timeout_multiplier
|
||||
|
||||
nose2_args = ["-v",
|
||||
"-N", str(args.testcases),
|
||||
"-s", test_dir,
|
||||
"-c", os.path.join(test_dir, "conf/unittest.cfg")]
|
||||
|
||||
if args.testname:
|
||||
nose2_args += args.testname
|
||||
|
||||
nose2.discover(argv=nose2_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,56 @@
|
||||
import infra.basetest
|
||||
|
||||
|
||||
class TestATFVexpress(infra.basetest.BRTest):
|
||||
config = \
|
||||
"""
|
||||
BR2_aarch64=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_LINARO_AARCH64=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL="https://github.com/ARM-software/arm-trusted-firmware.git"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_VERSION="v2.5"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="juno"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_NEEDS_DTC=y
|
||||
BR2_TARGET_UBOOT=y
|
||||
BR2_TARGET_UBOOT_BOARDNAME="vexpress_aemv8a_juno"
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2020.07"
|
||||
BR2_TARGET_VEXPRESS_FIRMWARE=y
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestATFAllwinner(infra.basetest.BRTest):
|
||||
config = \
|
||||
"""
|
||||
BR2_aarch64=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_LINARO_AARCH64=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="v2.5"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="sun50i_a64"
|
||||
# BR2_TARGET_ARM_TRUSTED_FIRMWARE_SSP is not set
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_BL31=y
|
||||
BR2_TARGET_UBOOT=y
|
||||
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2021.04"
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="bananapi_m64"
|
||||
BR2_TARGET_UBOOT_NEEDS_DTC=y
|
||||
BR2_TARGET_UBOOT_NEEDS_PYTHON3=y
|
||||
BR2_TARGET_UBOOT_NEEDS_PYLIBFDT=y
|
||||
BR2_TARGET_UBOOT_NEEDS_ATF_BL31=y
|
||||
BR2_TARGET_UBOOT_SPL=y
|
||||
BR2_TARGET_UBOOT_SPL_NAME="u-boot-sunxi-with-spl.bin"
|
||||
BR2_TARGET_UBOOT_CUSTOM_MAKEOPTS="SCP=/dev/null"
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
pass
|
||||
@@ -0,0 +1,45 @@
|
||||
import os
|
||||
|
||||
import infra.basetest
|
||||
|
||||
|
||||
class TestEdk2(infra.basetest.BRTest):
|
||||
config = \
|
||||
"""
|
||||
BR2_aarch64=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0"
|
||||
BR2_TARGET_ROOTFS_EXT2=y
|
||||
BR2_TARGET_ROOTFS_EXT2_4=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="board/qemu/aarch64-sbsa/assemble-flash-images support/scripts/genimage.sh"
|
||||
BR2_ROOTFS_POST_SCRIPT_ARGS="-c board/qemu/aarch64-sbsa/genimage.cfg"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.10.34"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-sbsa/linux.config"
|
||||
BR2_TARGET_EDK2=y
|
||||
BR2_TARGET_EDK2_PLATFORM_QEMU_SBSA=y
|
||||
BR2_TARGET_GRUB2=y
|
||||
BR2_TARGET_GRUB2_ARM64_EFI=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="qemu_sbsa"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
|
||||
BR2_PACKAGE_HOST_GENIMAGE=y
|
||||
BR2_PACKAGE_HOST_DOSFSTOOLS=y
|
||||
BR2_PACKAGE_HOST_MTOOLS=y
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
hda = os.path.join(self.builddir, "images", "disk.img")
|
||||
flash0 = os.path.join(self.builddir, "images", "SBSA_FLASH0.fd")
|
||||
flash1 = os.path.join(self.builddir, "images", "SBSA_FLASH1.fd")
|
||||
self.emulator.boot(arch="aarch64",
|
||||
options=["-M", "sbsa-ref",
|
||||
"-cpu", "cortex-a57",
|
||||
"-m", "512M",
|
||||
"-pflash", flash0,
|
||||
"-pflash", flash1,
|
||||
"-hda", hda])
|
||||
self.emulator.login()
|
||||
@@ -0,0 +1,85 @@
|
||||
import infra.basetest
|
||||
|
||||
|
||||
class TestSysLinuxBase(infra.basetest.BRTest):
|
||||
x86_toolchain_config = \
|
||||
"""
|
||||
BR2_x86_i686=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_URL="http://toolchains.bootlin.com/downloads/releases/toolchains/x86-i686/tarballs/x86-i686--glibc--bleeding-edge-2018.11-1.tar.bz2"
|
||||
BR2_TOOLCHAIN_EXTERNAL_GCC_8=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_14=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CXX=y
|
||||
"""
|
||||
|
||||
x86_64_toolchain_config = \
|
||||
"""
|
||||
BR2_x86_64=y
|
||||
BR2_x86_corei7=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_URL="http://toolchains.bootlin.com/downloads/releases/toolchains/x86-64-core-i7/tarballs/x86-64-core-i7--glibc--stable-2018.11-1.tar.bz2"
|
||||
BR2_TOOLCHAIN_EXTERNAL_GCC_7=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_1=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CXX=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_HAS_SSP=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
|
||||
"""
|
||||
|
||||
syslinux_legacy_config = \
|
||||
"""
|
||||
BR2_TARGET_SYSLINUX=y
|
||||
BR2_TARGET_SYSLINUX_ISOLINUX=y
|
||||
BR2_TARGET_SYSLINUX_PXELINUX=y
|
||||
BR2_TARGET_SYSLINUX_MBR=y
|
||||
"""
|
||||
|
||||
syslinux_efi_config = \
|
||||
"""
|
||||
BR2_TARGET_SYSLINUX=y
|
||||
BR2_TARGET_SYSLINUX_EFI=y
|
||||
"""
|
||||
|
||||
|
||||
class TestSysLinuxX86LegacyBios(TestSysLinuxBase):
|
||||
config = \
|
||||
TestSysLinuxBase.x86_toolchain_config + \
|
||||
infra.basetest.MINIMAL_CONFIG + \
|
||||
TestSysLinuxBase.syslinux_legacy_config
|
||||
|
||||
def test_run(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestSysLinuxX86EFI(TestSysLinuxBase):
|
||||
config = \
|
||||
TestSysLinuxBase.x86_toolchain_config + \
|
||||
infra.basetest.MINIMAL_CONFIG + \
|
||||
TestSysLinuxBase.syslinux_efi_config
|
||||
|
||||
def test_run(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestSysLinuxX86_64LegacyBios(TestSysLinuxBase):
|
||||
config = \
|
||||
TestSysLinuxBase.x86_64_toolchain_config + \
|
||||
infra.basetest.MINIMAL_CONFIG + \
|
||||
TestSysLinuxBase.syslinux_legacy_config
|
||||
|
||||
def test_run(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestSysLinuxX86_64EFI(TestSysLinuxBase):
|
||||
config = \
|
||||
TestSysLinuxBase.x86_64_toolchain_config + \
|
||||
infra.basetest.MINIMAL_CONFIG + \
|
||||
TestSysLinuxBase.syslinux_efi_config
|
||||
|
||||
def test_run(self):
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
source "$BR2_EXTERNAL_DETECT_BAD_ARCH_PATH/package/detect-bad-arch/Config.in"
|
||||
@@ -0,0 +1 @@
|
||||
name: DETECT_BAD_ARCH
|
||||
@@ -0,0 +1 @@
|
||||
include $(sort $(wildcard $(BR2_EXTERNAL_DETECT_BAD_ARCH_PATH)/package/*/*.mk))
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
config BR2_PACKAGE_DETECT_BAD_ARCH
|
||||
bool
|
||||
default y
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
################################################################################
|
||||
#
|
||||
# detect-bad-arch
|
||||
#
|
||||
################################################################################
|
||||
|
||||
define DETECT_BAD_ARCH_BUILD_CMDS
|
||||
echo "int main(void) { return 0; }" | $(HOSTCC) -x c -o $(@D)/foo -
|
||||
endef
|
||||
|
||||
define DETECT_BAD_ARCH_INSTALL_TARGET_CMDS
|
||||
$(INSTALL) -D -m 0755 $(@D)/foo $(TARGET_DIR)/usr/bin/foo
|
||||
endef
|
||||
|
||||
$(eval $(generic-package))
|
||||
@@ -0,0 +1 @@
|
||||
name: CPE_ID
|
||||
@@ -0,0 +1 @@
|
||||
include $(sort $(wildcard $(BR2_EXTERNAL_CPE_ID_PATH)/package/*/*.mk))
|
||||
@@ -0,0 +1,4 @@
|
||||
CPE_ID_PKG1_VERSION = 42
|
||||
|
||||
$(eval $(generic-package))
|
||||
$(eval $(host-generic-package))
|
||||
@@ -0,0 +1,3 @@
|
||||
CPE_ID_PKG2_VERSION = 67
|
||||
|
||||
$(eval $(host-generic-package))
|
||||
@@ -0,0 +1,5 @@
|
||||
CPE_ID_PKG3_VERSION = 67
|
||||
CPE_ID_PKG3_CPE_ID_VENDOR = cpe-id-pkg3_project
|
||||
|
||||
$(eval $(generic-package))
|
||||
$(eval $(host-generic-package))
|
||||
@@ -0,0 +1,9 @@
|
||||
CPE_ID_PKG4_VERSION = 67
|
||||
CPE_ID_PKG4_CPE_ID_VENDOR = foo
|
||||
CPE_ID_PKG4_CPE_ID_PRODUCT = bar
|
||||
CPE_ID_PKG4_CPE_ID_VERSION = 42
|
||||
CPE_ID_PKG4_CPE_ID_UPDATE = b2
|
||||
CPE_ID_PKG4_CPE_ID_PREFIX = cpe:2.4:a
|
||||
|
||||
$(eval $(generic-package))
|
||||
$(eval $(host-generic-package))
|
||||
@@ -0,0 +1,16 @@
|
||||
CPE_ID_PKG5_VERSION = 57
|
||||
|
||||
CPE_ID_PKG5_CPE_ID_VENDOR = foo
|
||||
CPE_ID_PKG5_CPE_ID_PRODUCT = bar
|
||||
CPE_ID_PKG5_CPE_ID_VERSION = 42
|
||||
CPE_ID_PKG5_CPE_ID_UPDATE = b2
|
||||
CPE_ID_PKG5_CPE_ID_PREFIX = cpe:2.4:a
|
||||
|
||||
HOST_CPE_ID_PKG5_CPE_ID_VENDOR = baz
|
||||
HOST_CPE_ID_PKG5_CPE_ID_PRODUCT = fuz
|
||||
HOST_CPE_ID_PKG5_CPE_ID_VERSION = 43
|
||||
HOST_CPE_ID_PKG5_CPE_ID_UPDATE = b3
|
||||
HOST_CPE_ID_PKG5_CPE_ID_PREFIX = cpe:2.5:a
|
||||
|
||||
$(eval $(generic-package))
|
||||
$(eval $(host-generic-package))
|
||||
@@ -0,0 +1,7 @@
|
||||
# <name> <type> <mode> <uid> <gid> <major> <minor> <start> <inc> <count>
|
||||
/usr/sbin/getcap f 755 0 0 - - - - -
|
||||
|xattr cap_sys_nice+eip
|
||||
# leading spaces are ignored for xattr
|
||||
|xattr cap_kill+eip
|
||||
# leading tabs are ignored for xattr
|
||||
|xattr cap_sys_time+eip
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
(
|
||||
printf "arg1,%s\n" "${1}"
|
||||
printf "arg2,%s\n" "${2}"
|
||||
printf "arg3,%s\n" "${3}"
|
||||
printf "TARGET_DIR,%s\n" "${TARGET_DIR}"
|
||||
printf "BUILD_DIR,%s\n" "${BUILD_DIR}"
|
||||
printf "HOST_DIR,%s\n" "${HOST_DIR}"
|
||||
printf "STAGING_DIR,%s\n" "${STAGING_DIR}"
|
||||
printf "BINARIES_DIR,%s\n" "${BINARIES_DIR}"
|
||||
printf "BR2_CONFIG,%s\n" "${BR2_CONFIG}"
|
||||
) > ${BUILD_DIR}/$(basename "${0}" .sh).log
|
||||
@@ -0,0 +1 @@
|
||||
post-build.sh
|
||||
@@ -0,0 +1 @@
|
||||
post-build.sh
|
||||
@@ -0,0 +1 @@
|
||||
foobar
|
||||
@@ -0,0 +1 @@
|
||||
barfoo
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
@@ -0,0 +1,18 @@
|
||||
import infra
|
||||
import infra.basetest
|
||||
|
||||
|
||||
class DetectBadArchTest(infra.basetest.BRConfigTest):
|
||||
config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + infra.basetest.MINIMAL_CONFIG
|
||||
br2_external = [infra.filepath("tests/core/br2-external/detect-bad-arch")]
|
||||
|
||||
def test_run(self):
|
||||
with self.assertRaises(SystemError):
|
||||
self.b.build()
|
||||
logf_path = infra.log_file_path(self.b.builddir, "build",
|
||||
infra.basetest.BRConfigTest.logtofile)
|
||||
if logf_path:
|
||||
s = 'ERROR: architecture for "/usr/bin/foo" is'
|
||||
with open(logf_path, "r") as f:
|
||||
lines = [line for line in f.readlines() if line.startswith(s)]
|
||||
self.assertEqual(len(lines), 1)
|
||||
@@ -0,0 +1,110 @@
|
||||
import infra
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
|
||||
class CpeIdTest(infra.basetest.BRConfigTest):
|
||||
config = ""
|
||||
br2_external = [infra.filepath("tests/core/cpeid-br2-external")]
|
||||
|
||||
def get_vars(self, var):
|
||||
cmd = ["make", "--no-print-directory", "-C", self.b.builddir,
|
||||
"VARS=%s%%" % var, "printvars"]
|
||||
lines = subprocess.check_output(cmd).splitlines()
|
||||
return dict([str(x, "utf-8").split("=") for x in lines])
|
||||
|
||||
def get_json(self, pkg):
|
||||
cmd = ["make", "--no-print-directory", "-C", self.b.builddir,
|
||||
"%s-show-info" % pkg]
|
||||
return json.loads(subprocess.check_output(cmd))
|
||||
|
||||
def test_pkg1(self):
|
||||
# this package has no CPE ID information, it should not have
|
||||
# any CPE_ID variable defined.
|
||||
pkg_vars = self.get_vars("CPE_ID_PKG1_CPE_ID")
|
||||
cpe_vars = ["CPE_ID_VALID", "CPE_ID_PRODUCT", "CPE_ID_VERSION", "CPE_ID_UPDATE",
|
||||
"CPE_ID_PREFIX", "CPE_ID"]
|
||||
for v in cpe_vars:
|
||||
self.assertNotIn("CPE_ID_PKG1_%s" % v, pkg_vars)
|
||||
pkg_json = self.get_json("cpe-id-pkg1")
|
||||
self.assertNotIn("cpe-id", pkg_json['cpe-id-pkg1'])
|
||||
|
||||
pkg_vars = self.get_vars("HOST_CPE_ID_PKG1_CPE_ID")
|
||||
for v in cpe_vars:
|
||||
self.assertNotIn("HOST_CPE_ID_PKG1_%s" % v, pkg_vars)
|
||||
pkg_json = self.get_json("host-cpe-id-pkg1")
|
||||
self.assertNotIn("cpe-id", pkg_json['host-cpe-id-pkg1'])
|
||||
|
||||
def test_pkg2(self):
|
||||
# this package has no CPE ID information, it should not have
|
||||
# any CPE_ID variable defined.
|
||||
pkg_vars = self.get_vars("HOST_CPE_ID_PKG2_CPE_ID")
|
||||
cpe_vars = ["CPE_ID_VALID", "CPE_ID_PRODUCT", "CPE_ID_VERSION", "CPE_ID_UPDATE",
|
||||
"CPE_ID_PREFIX", "CPE_ID"]
|
||||
for v in cpe_vars:
|
||||
self.assertNotIn("HOST_CPE_ID_PKG2_%s" % v, pkg_vars)
|
||||
pkg_json = self.get_json("host-cpe-id-pkg2")
|
||||
self.assertNotIn("cpe-id", pkg_json['host-cpe-id-pkg2'])
|
||||
|
||||
def test_pkg3(self):
|
||||
# this package has just <pkg>_CPE_ID_VENDOR defined, so verify
|
||||
# it has the default CPE_ID value, and that inheritance of the
|
||||
# values for the host package is working
|
||||
pkg_vars = self.get_vars("CPE_ID_PKG3_CPE_ID")
|
||||
self.assertEqual(pkg_vars["CPE_ID_PKG3_CPE_ID"],
|
||||
"cpe:2.3:a:cpe-id-pkg3_project:cpe-id-pkg3:67:*:*:*:*:*:*:*")
|
||||
self.assertEqual(pkg_vars["CPE_ID_PKG3_CPE_ID_VALID"], "YES")
|
||||
pkg_json = self.get_json("cpe-id-pkg3")
|
||||
self.assertEqual(pkg_json['cpe-id-pkg3']['cpe-id'],
|
||||
"cpe:2.3:a:cpe-id-pkg3_project:cpe-id-pkg3:67:*:*:*:*:*:*:*")
|
||||
|
||||
pkg_vars = self.get_vars("HOST_CPE_ID_PKG3_CPE_ID")
|
||||
self.assertEqual(pkg_vars["HOST_CPE_ID_PKG3_CPE_ID"],
|
||||
"cpe:2.3:a:cpe-id-pkg3_project:cpe-id-pkg3:67:*:*:*:*:*:*:*")
|
||||
self.assertEqual(pkg_vars["HOST_CPE_ID_PKG3_CPE_ID_VALID"], "YES")
|
||||
pkg_json = self.get_json("host-cpe-id-pkg3")
|
||||
self.assertEqual(pkg_json['host-cpe-id-pkg3']['cpe-id'],
|
||||
"cpe:2.3:a:cpe-id-pkg3_project:cpe-id-pkg3:67:*:*:*:*:*:*:*")
|
||||
|
||||
def test_pkg4(self):
|
||||
# this package defines
|
||||
# <pkg>_CPE_ID_{VENDOR,PRODUCT,VERSION,UPDATE,PREFIX},
|
||||
# make sure we get the computed <pkg>_CPE_ID, and that it is
|
||||
# inherited by the host variant
|
||||
pkg_vars = self.get_vars("CPE_ID_PKG4_CPE_ID")
|
||||
self.assertEqual(pkg_vars["CPE_ID_PKG4_CPE_ID"],
|
||||
"cpe:2.4:a:foo:bar:42:b2:*:*:*:*:*:*")
|
||||
self.assertEqual(pkg_vars["CPE_ID_PKG4_CPE_ID_VALID"], "YES")
|
||||
pkg_json = self.get_json("cpe-id-pkg4")
|
||||
self.assertEqual(pkg_json['cpe-id-pkg4']['cpe-id'],
|
||||
"cpe:2.4:a:foo:bar:42:b2:*:*:*:*:*:*")
|
||||
|
||||
pkg_vars = self.get_vars("HOST_CPE_ID_PKG4_CPE_ID")
|
||||
self.assertEqual(pkg_vars["HOST_CPE_ID_PKG4_CPE_ID"],
|
||||
"cpe:2.4:a:foo:bar:42:b2:*:*:*:*:*:*")
|
||||
self.assertEqual(pkg_vars["HOST_CPE_ID_PKG4_CPE_ID_VALID"], "YES")
|
||||
pkg_json = self.get_json("host-cpe-id-pkg4")
|
||||
self.assertEqual(pkg_json['host-cpe-id-pkg4']['cpe-id'],
|
||||
"cpe:2.4:a:foo:bar:42:b2:*:*:*:*:*:*")
|
||||
|
||||
def test_pkg5(self):
|
||||
# this package defines
|
||||
# <pkg>_CPE_ID_{VENDOR,PRODUCT,VERSION,UPDATE,PREFIX} and
|
||||
# HOST_<pkg>_CPE_ID_{VENDOR,PRODUCT,VERSION,UPDATE,PREFIX}
|
||||
# separately, with different values. Make sure we get the
|
||||
# right <pkg>_CPE_ID and HOST_<pkg>_CPE_ID values.
|
||||
pkg_vars = self.get_vars("CPE_ID_PKG5_CPE_ID")
|
||||
self.assertEqual(pkg_vars["CPE_ID_PKG5_CPE_ID"],
|
||||
"cpe:2.4:a:foo:bar:42:b2:*:*:*:*:*:*")
|
||||
self.assertEqual(pkg_vars["CPE_ID_PKG5_CPE_ID_VALID"], "YES")
|
||||
pkg_json = self.get_json("cpe-id-pkg5")
|
||||
self.assertEqual(pkg_json['cpe-id-pkg5']['cpe-id'],
|
||||
"cpe:2.4:a:foo:bar:42:b2:*:*:*:*:*:*")
|
||||
|
||||
pkg_vars = self.get_vars("HOST_CPE_ID_PKG5_CPE_ID")
|
||||
self.assertEqual(pkg_vars["HOST_CPE_ID_PKG5_CPE_ID"],
|
||||
"cpe:2.5:a:baz:fuz:43:b3:*:*:*:*:*:*")
|
||||
self.assertEqual(pkg_vars["HOST_CPE_ID_PKG5_CPE_ID_VALID"], "YES")
|
||||
pkg_json = self.get_json("host-cpe-id-pkg5")
|
||||
self.assertEqual(pkg_json['host-cpe-id-pkg5']['cpe-id'],
|
||||
"cpe:2.5:a:baz:fuz:43:b3:*:*:*:*:*:*")
|
||||
@@ -0,0 +1,46 @@
|
||||
import os
|
||||
|
||||
import infra.basetest
|
||||
|
||||
|
||||
class TestFileCapabilities(infra.basetest.BRTest):
|
||||
config = \
|
||||
"""
|
||||
BR2_arm=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt {}"
|
||||
BR2_ROOTFS_DEVICE_TABLE_SUPPORTS_EXTENDED_ATTRIBUTES=y
|
||||
BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.19.204"
|
||||
BR2_LINUX_KERNEL_DEFCONFIG="vexpress"
|
||||
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{}"
|
||||
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
||||
BR2_LINUX_KERNEL_INTREE_DTS_NAME="vexpress-v2p-ca9"
|
||||
BR2_PACKAGE_LIBCAP=y
|
||||
BR2_PACKAGE_LIBCAP_TOOLS=y
|
||||
BR2_TARGET_ROOTFS_SQUASHFS=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
""".format(infra.filepath("tests/core/device_table2.txt"),
|
||||
infra.filepath("tests/core/squashfs-xattr-kernel.config"))
|
||||
|
||||
def test_run(self):
|
||||
img = os.path.join(self.builddir, "images", "rootfs.squashfs")
|
||||
infra.img_round_power2(img)
|
||||
|
||||
self.emulator.boot(arch="armv7",
|
||||
kernel=os.path.join(self.builddir, "images", "zImage"),
|
||||
kernel_cmdline=["root=/dev/mmcblk0",
|
||||
"rootfstype=squashfs"],
|
||||
options=["-drive", "file={},if=sd,format=raw".format(img),
|
||||
"-M", "vexpress-a9",
|
||||
"-dtb", os.path.join(self.builddir, "images", "vexpress-v2p-ca9.dtb")])
|
||||
self.emulator.login()
|
||||
|
||||
cmd = "getcap -v /usr/sbin/getcap"
|
||||
output, _ = self.emulator.run(cmd)
|
||||
self.assertIn("cap_kill", output[0])
|
||||
self.assertIn("cap_sys_nice", output[0])
|
||||
self.assertIn("cap_sys_time", output[0])
|
||||
self.assertIn("=eip", output[0])
|
||||
@@ -0,0 +1,115 @@
|
||||
import os
|
||||
import json
|
||||
|
||||
import infra.basetest
|
||||
|
||||
|
||||
class TestHardeningBase(infra.basetest.BRTest):
|
||||
config = \
|
||||
"""
|
||||
BR2_powerpc64=y
|
||||
BR2_powerpc_e5500=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc64-e5500/tarballs/powerpc64-e5500--glibc--stable-2018.02-2.tar.bz2"
|
||||
BR2_TOOLCHAIN_EXTERNAL_GCC_6=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_1=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_CXX=y
|
||||
BR2_PACKAGE_LIGHTTPD=y
|
||||
BR2_PACKAGE_HOST_CHECKSEC=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
"""
|
||||
|
||||
checksec_files = ["usr/sbin/lighttpd", "bin/busybox"]
|
||||
|
||||
def checksec_run(self, target_file):
|
||||
filepath = os.path.join(self.builddir, "target", target_file)
|
||||
cmd = ["host/bin/checksec", "--format=json",
|
||||
"--file={}".format(filepath)]
|
||||
# Checksec is being used for elf file analysis only. There are no
|
||||
# assumptions of target/run-time checks as part of this testing.
|
||||
ret = infra.run_cmd_on_host(self.builddir, cmd)
|
||||
return json.loads(ret)
|
||||
|
||||
|
||||
class TestRelro(TestHardeningBase):
|
||||
config = TestHardeningBase.config + \
|
||||
"""
|
||||
BR2_RELRO_FULL=y
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
for f in self.checksec_files:
|
||||
out = self.checksec_run(f)
|
||||
filepath = os.path.join(self.builddir, "target", f)
|
||||
self.assertEqual(out[filepath]["relro"], "full")
|
||||
self.assertEqual(out[filepath]["pie"], "yes")
|
||||
|
||||
|
||||
class TestRelroPartial(TestHardeningBase):
|
||||
config = TestHardeningBase.config + \
|
||||
"""
|
||||
BR2_RELRO_PARTIAL=y
|
||||
# BR2_PIC_PIE is not set
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
for f in self.checksec_files:
|
||||
out = self.checksec_run(f)
|
||||
filepath = os.path.join(self.builddir, "target", f)
|
||||
self.assertEqual(out[filepath]["relro"], "partial")
|
||||
self.assertEqual(out[filepath]["pie"], "no")
|
||||
|
||||
|
||||
class TestSspNone(TestHardeningBase):
|
||||
config = TestHardeningBase.config + \
|
||||
"""
|
||||
BR2_SSP_NONE=y
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
for f in self.checksec_files:
|
||||
out = self.checksec_run(f)
|
||||
filepath = os.path.join(self.builddir, "target", f)
|
||||
self.assertEqual(out[filepath]["canary"], "no")
|
||||
|
||||
|
||||
class TestSspStrong(TestHardeningBase):
|
||||
config = TestHardeningBase.config + \
|
||||
"""
|
||||
BR2_SSP_STRONG=y
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
for f in self.checksec_files:
|
||||
out = self.checksec_run(f)
|
||||
filepath = os.path.join(self.builddir, "target", f)
|
||||
self.assertEqual(out[filepath]["canary"], "yes")
|
||||
|
||||
|
||||
class TestFortifyNone(TestHardeningBase):
|
||||
config = TestHardeningBase.config + \
|
||||
"""
|
||||
BR2_FORTIFY_SOURCE_NONE=y
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
for f in self.checksec_files:
|
||||
out = self.checksec_run(f)
|
||||
filepath = os.path.join(self.builddir, "target", f)
|
||||
self.assertEqual(out[filepath]["fortified"], "0")
|
||||
|
||||
|
||||
class TestFortifyConserv(TestHardeningBase):
|
||||
config = TestHardeningBase.config + \
|
||||
"""
|
||||
BR2_FORTIFY_SOURCE_1=y
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
for f in self.checksec_files:
|
||||
out = self.checksec_run(f)
|
||||
filepath = os.path.join(self.builddir, "target", f)
|
||||
self.assertNotEqual(out[filepath]["fortified"], "0")
|
||||
@@ -0,0 +1,48 @@
|
||||
import os
|
||||
import csv
|
||||
|
||||
import infra.basetest
|
||||
|
||||
|
||||
class TestPostScripts(infra.basetest.BRTest):
|
||||
config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \
|
||||
"""
|
||||
BR2_INIT_NONE=y
|
||||
BR2_SYSTEM_BIN_SH_NONE=y
|
||||
# BR2_PACKAGE_BUSYBOX is not set
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="{}"
|
||||
BR2_ROOTFS_POST_FAKEROOT_SCRIPT="{}"
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="{}"
|
||||
BR2_ROOTFS_POST_SCRIPT_ARGS="foobar baz"
|
||||
""".format(infra.filepath("tests/core/post-build.sh"),
|
||||
infra.filepath("tests/core/post-fakeroot.sh"),
|
||||
infra.filepath("tests/core/post-image.sh"))
|
||||
|
||||
def check_post_log_file(self, f, what, target_dir):
|
||||
lines = {}
|
||||
with open(os.path.join(self.builddir, "build", f), newline='') as csvfile:
|
||||
r = csv.reader(csvfile, delimiter=',')
|
||||
for row in r:
|
||||
lines[row[0]] = row[1]
|
||||
|
||||
self.assertEqual(lines["arg1"], what)
|
||||
self.assertEqual(lines["arg2"], "foobar")
|
||||
self.assertEqual(lines["arg3"], "baz")
|
||||
self.assertEqual(lines["TARGET_DIR"], target_dir)
|
||||
self.assertEqual(lines["BUILD_DIR"], os.path.join(self.builddir, "build"))
|
||||
self.assertEqual(lines["HOST_DIR"], os.path.join(self.builddir, "host"))
|
||||
staging = os.readlink(os.path.join(self.builddir, "staging"))
|
||||
self.assertEqual(lines["STAGING_DIR"], staging)
|
||||
self.assertEqual(lines["BINARIES_DIR"], os.path.join(self.builddir, "images"))
|
||||
self.assertEqual(lines["BR2_CONFIG"], os.path.join(self.builddir, ".config"))
|
||||
|
||||
def test_run(self):
|
||||
self.check_post_log_file("post-build.log",
|
||||
os.path.join(self.builddir, "target"),
|
||||
os.path.join(self.builddir, "target"))
|
||||
self.check_post_log_file("post-fakeroot.log",
|
||||
os.path.join(self.builddir, "build/buildroot-fs/tar/target"),
|
||||
os.path.join(self.builddir, "build/buildroot-fs/tar/target"))
|
||||
self.check_post_log_file("post-image.log",
|
||||
os.path.join(self.builddir, "images"),
|
||||
os.path.join(self.builddir, "target"))
|
||||
@@ -0,0 +1,36 @@
|
||||
import os
|
||||
import infra.basetest
|
||||
from crypt import crypt
|
||||
|
||||
|
||||
class TestRootPassword(infra.basetest.BRTest):
|
||||
password = "foo"
|
||||
config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \
|
||||
"""
|
||||
BR2_TARGET_ROOTFS_CPIO=y
|
||||
BR2_TARGET_ENABLE_ROOT_LOGIN=y
|
||||
BR2_TARGET_GENERIC_ROOT_PASSWD="{}"
|
||||
""".format(password)
|
||||
|
||||
def test_run(self):
|
||||
# 1. Test by looking hash in the /etc/shadow
|
||||
shadow = os.path.join(self.builddir, "target", "etc", "shadow")
|
||||
with open(shadow, "r") as f:
|
||||
users = f.readlines()
|
||||
for user in users:
|
||||
s = user.split(":")
|
||||
n, h = s[0], s[1]
|
||||
if n == "root":
|
||||
# Fail if the account is disabled or no password is required
|
||||
self.assertTrue(h not in ["", "*"])
|
||||
# Fail if the hash isn't right
|
||||
self.assertEqual(crypt(self.password, h), h)
|
||||
|
||||
# 2. Test by attempting to login
|
||||
cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio")
|
||||
try:
|
||||
self.emulator.boot(arch="armv7", kernel="builtin",
|
||||
options=["-initrd", cpio_file])
|
||||
self.emulator.login(self.password)
|
||||
except SystemError:
|
||||
self.fail("Unable to login with the password")
|
||||
@@ -0,0 +1,30 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import infra.basetest
|
||||
|
||||
|
||||
def compare_file(file1, file2):
|
||||
return subprocess.call(["cmp", file1, file2])
|
||||
|
||||
|
||||
class TestRootfsOverlay(infra.basetest.BRTest):
|
||||
|
||||
rootfs_overlay_path = infra.filepath("tests/core/rootfs-overlay")
|
||||
|
||||
config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \
|
||||
infra.basetest.MINIMAL_CONFIG + \
|
||||
"""
|
||||
BR2_ROOTFS_OVERLAY="{0}1 {0}2"
|
||||
""".format(rootfs_overlay_path)
|
||||
|
||||
def test_run(self):
|
||||
target_file = os.path.join(self.builddir, "target", "test-file1")
|
||||
overlay_file = "{}1/test-file1".format(self.rootfs_overlay_path)
|
||||
ret = compare_file(overlay_file, target_file)
|
||||
self.assertEqual(ret, 0)
|
||||
|
||||
target_file = os.path.join(self.builddir, "target", "etc", "test-file2")
|
||||
overlay_file = "{}2/etc/test-file2".format(self.rootfs_overlay_path)
|
||||
ret = compare_file(overlay_file, target_file)
|
||||
self.assertEqual(ret, 0)
|
||||
@@ -0,0 +1,86 @@
|
||||
import os
|
||||
|
||||
import infra.basetest
|
||||
|
||||
|
||||
class TestSELinuxInfra(infra.basetest.BRTest):
|
||||
config = infra.basetest.BASIC_TOOLCHAIN_CONFIG +\
|
||||
"""
|
||||
BR2_PACKAGE_REFPOLICY=y
|
||||
BR2_PACKAGE_PYTHON3=y
|
||||
BR2_PACKAGE_SETOOLS=y
|
||||
BR2_TARGET_ROOTFS_CPIO=y
|
||||
"""
|
||||
|
||||
def base_test_run(self):
|
||||
cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio")
|
||||
self.emulator.boot(arch="armv5", kernel="builtin",
|
||||
options=["-initrd", cpio_file])
|
||||
self.emulator.login()
|
||||
|
||||
|
||||
class TestSELinuxExtraModules(TestSELinuxInfra):
|
||||
config = TestSELinuxInfra.config + \
|
||||
"""
|
||||
BR2_REFPOLICY_EXTRA_MODULES="ntp tor"
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
TestSELinuxInfra.base_test_run(self)
|
||||
|
||||
out, ret = self.emulator.run("seinfo -t ntpd_t", 15)
|
||||
self.assertEqual(ret, 0)
|
||||
self.assertEqual(out[2].strip(), "ntpd_t")
|
||||
|
||||
out, ret = self.emulator.run("seinfo -t tor_t", 15)
|
||||
self.assertEqual(ret, 0)
|
||||
self.assertEqual(out[2].strip(), "tor_t")
|
||||
|
||||
|
||||
class TestSELinuxExtraModulesDirs(TestSELinuxInfra):
|
||||
config = TestSELinuxInfra.config + \
|
||||
"""
|
||||
BR2_REFPOLICY_EXTRA_MODULES_DIRS="{}"
|
||||
""".format(infra.filepath("tests/core/test_selinux/extra_modules"))
|
||||
|
||||
def test_run(self):
|
||||
TestSELinuxInfra.base_test_run(self)
|
||||
|
||||
out, ret = self.emulator.run("seinfo -t buildroot_test_t", 15)
|
||||
self.assertEqual(ret, 0)
|
||||
self.assertEqual(out[2].strip(), "buildroot_test_t")
|
||||
|
||||
|
||||
class TestSELinuxCustomGit(TestSELinuxInfra):
|
||||
config = TestSELinuxInfra.config + \
|
||||
"""
|
||||
BR2_PACKAGE_REFPOLICY_CUSTOM_GIT=y
|
||||
BR2_PACKAGE_REFPOLICY_CUSTOM_REPO_URL="https://github.com/SELinuxProject/refpolicy.git"
|
||||
BR2_PACKAGE_REFPOLICY_CUSTOM_REPO_VERSION="RELEASE_2_20200818"
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestSELinuxPackage(TestSELinuxInfra):
|
||||
br2_external = [infra.filepath("tests/core/test_selinux/br2_external")]
|
||||
config = TestSELinuxInfra.config + \
|
||||
"""
|
||||
BR2_PACKAGE_SELINUX_TEST=y
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
TestSELinuxInfra.base_test_run(self)
|
||||
|
||||
out, ret = self.emulator.run("seinfo -t ntpd_t", 15)
|
||||
self.assertEqual(ret, 0)
|
||||
self.assertEqual(out[2].strip(), "ntpd_t")
|
||||
|
||||
out, ret = self.emulator.run("seinfo -t tor_t", 15)
|
||||
self.assertEqual(ret, 0)
|
||||
self.assertEqual(out[2].strip(), "tor_t")
|
||||
|
||||
out, ret = self.emulator.run("seinfo -t buildroot_test_t", 15)
|
||||
self.assertEqual(ret, 0)
|
||||
self.assertEqual(out[2].strip(), "buildroot_test_t")
|
||||
@@ -0,0 +1 @@
|
||||
source "$BR2_EXTERNAL_SELINUX_PATH/package/selinux-test/Config.in"
|
||||
@@ -0,0 +1 @@
|
||||
name: SELINUX
|
||||
@@ -0,0 +1 @@
|
||||
include $(sort $(wildcard $(BR2_EXTERNAL_SELINUX_PATH)/package/*/*.mk))
|
||||
@@ -0,0 +1,4 @@
|
||||
config BR2_PACKAGE_SELINUX_TEST
|
||||
bool "SELinux test package"
|
||||
help
|
||||
Test package for SELinux Buildroot helpers.
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
################################################################################
|
||||
#
|
||||
# SELinux test package
|
||||
#
|
||||
################################################################################
|
||||
|
||||
SELINUX_TEST_SELINUX_MODULES = ntp tor
|
||||
|
||||
$(eval $(generic-package))
|
||||
+1
@@ -0,0 +1 @@
|
||||
## <summary>Buildroot rules</summary>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
policy_module(buildroot, 1.0.0)
|
||||
|
||||
type buildroot_test_t;
|
||||
@@ -0,0 +1 @@
|
||||
## <summary>Buildroot rules</summary>
|
||||
@@ -0,0 +1,3 @@
|
||||
policy_module(buildroot, 1.0.0)
|
||||
|
||||
type buildroot_test_t;
|
||||
@@ -0,0 +1,72 @@
|
||||
import os
|
||||
|
||||
import infra.basetest
|
||||
|
||||
|
||||
def boot_armv5_cpio(emulator, builddir):
|
||||
img = os.path.join(builddir, "images", "rootfs.cpio")
|
||||
emulator.boot(arch="armv5", kernel="builtin",
|
||||
options=["-initrd", img])
|
||||
emulator.login()
|
||||
|
||||
|
||||
class TestNoTimezone(infra.basetest.BRTest):
|
||||
config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \
|
||||
"""
|
||||
# BR2_TARGET_TZ_INFO is not set
|
||||
BR2_TARGET_ROOTFS_CPIO=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
boot_armv5_cpio(self.emulator, self.builddir)
|
||||
tz, _ = self.emulator.run("TZ=UTC date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "UTC")
|
||||
tz, _ = self.emulator.run("TZ=America/Los_Angeles date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "UTC")
|
||||
|
||||
|
||||
class TestGlibcAllTimezone(infra.basetest.BRTest):
|
||||
config = \
|
||||
"""
|
||||
BR2_arm=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TARGET_TZ_INFO=y
|
||||
BR2_TARGET_ROOTFS_CPIO=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
boot_armv5_cpio(self.emulator, self.builddir)
|
||||
tz, _ = self.emulator.run("date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "UTC")
|
||||
tz, _ = self.emulator.run("TZ=UTC date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "UTC")
|
||||
tz, _ = self.emulator.run("TZ=America/Los_Angeles date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "PST")
|
||||
tz, _ = self.emulator.run("TZ=Europe/Paris date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "CET")
|
||||
|
||||
|
||||
class TestGlibcNonDefaultLimitedTimezone(infra.basetest.BRTest):
|
||||
config = \
|
||||
"""
|
||||
BR2_arm=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TARGET_TZ_INFO=y
|
||||
BR2_TARGET_TZ_ZONELIST="northamerica"
|
||||
BR2_TARGET_LOCALTIME="America/New_York"
|
||||
BR2_TARGET_ROOTFS_CPIO=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
"""
|
||||
|
||||
def test_run(self):
|
||||
boot_armv5_cpio(self.emulator, self.builddir)
|
||||
tz, _ = self.emulator.run("date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "EST")
|
||||
tz, _ = self.emulator.run("TZ=UTC date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "UTC")
|
||||
tz, _ = self.emulator.run("TZ=America/Los_Angeles date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "PST")
|
||||
tz, _ = self.emulator.run("TZ=Europe/Paris date +%Z")
|
||||
self.assertEqual(tz[0].strip(), "Europe")
|
||||
@@ -0,0 +1 @@
|
||||
name: GIT_HASH
|
||||
@@ -0,0 +1,4 @@
|
||||
include $(sort $(wildcard $(BR2_EXTERNAL_GIT_HASH_PATH)/package/*/*.mk))
|
||||
|
||||
# Get the git server port number from the test infra
|
||||
GITREMOTE_PORT_NUMBER ?= 9418
|
||||
@@ -0,0 +1 @@
|
||||
sha256 0000000000000000000000000000000000000000000000000000000000000000 bad-a238b1dfcd825d47d834af3c5223417c8411d90d-br1.tar.gz
|
||||
@@ -0,0 +1,10 @@
|
||||
################################################################################
|
||||
#
|
||||
# bad
|
||||
#
|
||||
################################################################################
|
||||
|
||||
BAD_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
|
||||
BAD_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
|
||||
$(eval $(generic-package))
|
||||
@@ -0,0 +1 @@
|
||||
sha256 682ad1f39f258bfb35e26f213f3798f44bb8105bb55fad47bdc003113765b650 good-a238b1dfcd825d47d834af3c5223417c8411d90d-br1.tar.gz
|
||||
@@ -0,0 +1,10 @@
|
||||
################################################################################
|
||||
#
|
||||
# good
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GOOD_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
|
||||
GOOD_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
|
||||
$(eval $(generic-package))
|
||||
@@ -0,0 +1,10 @@
|
||||
################################################################################
|
||||
#
|
||||
# nohash
|
||||
#
|
||||
################################################################################
|
||||
|
||||
NOHASH_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
|
||||
NOHASH_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
|
||||
$(eval $(generic-package))
|
||||
@@ -0,0 +1 @@
|
||||
name: GIT_REFS
|
||||
@@ -0,0 +1,4 @@
|
||||
include $(sort $(wildcard $(BR2_EXTERNAL_GIT_REFS_PATH)/package/*/*.mk))
|
||||
|
||||
# Get the git server port number from the test infra
|
||||
GITREMOTE_PORT_NUMBER ?= 9418
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 c27041b3e874beb0d0218158e7d6507ad1515b684de5eed5fabd0f7205e9718e git-partial-sha1-branch-head-68c197d0879d485f4f6c-br1.tar.gz
|
||||
sha256 2c1126513651b0d346a4e6d1bb75ac1c9999217e18026302d27bea47b06c7fb2 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-partial-sha1-branch-head
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_PARTIAL_SHA1_BRANCH_HEAD_VERSION = 68c197d0879d485f4f6c
|
||||
GIT_PARTIAL_SHA1_BRANCH_HEAD_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_PARTIAL_SHA1_BRANCH_HEAD_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 1bbba9bf2788bd789ed8da4e47cabbf3467b1f706875b3f6b62df38e08fb9aba git-partial-sha1-reachable-by-branch-317406308d9259e2231b-br1.tar.gz
|
||||
sha256 fabbc65c442bacb5e69b7adfea6d14fbbfc1327134322efd12771dc84387d507 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-partial-sha1-reachable-by-branch
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_PARTIAL_SHA1_REACHABLE_BY_BRANCH_VERSION = 317406308d9259e2231b
|
||||
GIT_PARTIAL_SHA1_REACHABLE_BY_BRANCH_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_PARTIAL_SHA1_REACHABLE_BY_BRANCH_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 52d223f3b2d625216c259e9ff949ca8818452a531ba61557dd91f3889c7919d7 git-partial-sha1-reachable-by-tag-46bae5b639e5a18e2cc4-br1.tar.gz
|
||||
sha256 2de87d77a2f226813f2d9bda906e970e4195605cdba6680443c0c04d89c532b6 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-partial-sha1-reachable-by-tag
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_PARTIAL_SHA1_REACHABLE_BY_TAG_VERSION = 46bae5b639e5a18e2cc4
|
||||
GIT_PARTIAL_SHA1_REACHABLE_BY_TAG_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_PARTIAL_SHA1_REACHABLE_BY_TAG_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 5cfc004b05f48b3fb419a5db4b7239223d670225fbbb91de2ae151c97910b36c git-partial-sha1-tag-itself-2b0e0d98a49c97da6a61-br1.tar.gz
|
||||
sha256 6de8772a0a58fa62e2b8c58d4dae55c9db7534ad3b3918ecc849a9008d58f081 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-partial-sha1-tag-itself
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_PARTIAL_SHA1_TAG_ITSELF_VERSION = 2b0e0d98a49c97da6a61
|
||||
GIT_PARTIAL_SHA1_TAG_ITSELF_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_PARTIAL_SHA1_TAG_ITSELF_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 0f40d7f39bf2e389cc2ce03c73cc0cc9ded1119378aaa68e2a2ef8597f6fd2f3 git-partial-sha1-tag-points-to-516c9c5f64ec66534d4d-br1.tar.gz
|
||||
sha256 6de8772a0a58fa62e2b8c58d4dae55c9db7534ad3b3918ecc849a9008d58f081 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-partial-sha1-tag-points-to
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_PARTIAL_SHA1_TAG_POINTS_TO_VERSION = 516c9c5f64ec66534d4d
|
||||
GIT_PARTIAL_SHA1_TAG_POINTS_TO_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_PARTIAL_SHA1_TAG_POINTS_TO_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 3ab67c485ce1825abbbf5db1d90d94dfadc89b30bb740041cfc75fc04021e218 git-sha1-branch-head-68c197d0879d485f4f6cee85544722b79e68e59f-br1.tar.gz
|
||||
sha256 2c1126513651b0d346a4e6d1bb75ac1c9999217e18026302d27bea47b06c7fb2 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-sha1-branch-head
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_SHA1_BRANCH_HEAD_VERSION = 68c197d0879d485f4f6cee85544722b79e68e59f
|
||||
GIT_SHA1_BRANCH_HEAD_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_SHA1_BRANCH_HEAD_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 a5936d6d6022ea101a6076864a2afa918ab2776764012c4be589027001044041 git-sha1-reachable-by-branch-317406308d9259e2231bd0d6ddad3de3832bce08-br1.tar.gz
|
||||
sha256 fabbc65c442bacb5e69b7adfea6d14fbbfc1327134322efd12771dc84387d507 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-sha1-reachable-by-branch
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_SHA1_REACHABLE_BY_BRANCH_VERSION = 317406308d9259e2231bd0d6ddad3de3832bce08
|
||||
GIT_SHA1_REACHABLE_BY_BRANCH_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_SHA1_REACHABLE_BY_BRANCH_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 c203f968e358ca478d4c5344b1e4ae9bf13f9fb1120f2ed96a12154dd64195a6 git-sha1-reachable-by-tag-46bae5b639e5a18e2cc4dc508f080d566baeff59-br1.tar.gz
|
||||
sha256 2de87d77a2f226813f2d9bda906e970e4195605cdba6680443c0c04d89c532b6 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-sha1-reachable-by-tag
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_SHA1_REACHABLE_BY_TAG_VERSION = 46bae5b639e5a18e2cc4dc508f080d566baeff59
|
||||
GIT_SHA1_REACHABLE_BY_TAG_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_SHA1_REACHABLE_BY_TAG_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 57f08e9f3914e79a10e7fb5d346b26fef2773dd22eed0d61fd755e79e62cee93 git-sha1-tag-itself-2b0e0d98a49c97da6a618ab36337e2058eb733a2-br1.tar.gz
|
||||
sha256 6de8772a0a58fa62e2b8c58d4dae55c9db7534ad3b3918ecc849a9008d58f081 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-sha1-tag-itself
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_SHA1_TAG_ITSELF_VERSION = 2b0e0d98a49c97da6a618ab36337e2058eb733a2
|
||||
GIT_SHA1_TAG_ITSELF_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_SHA1_TAG_ITSELF_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 1d8b565827137aa21ba37cde382aa291e33a135c697e38dcd31f14e195386327 git-sha1-tag-points-to-516c9c5f64ec66534d4d069c2e408d9ae4dce023-br1.tar.gz
|
||||
sha256 6de8772a0a58fa62e2b8c58d4dae55c9db7534ad3b3918ecc849a9008d58f081 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-sha1-tag-points-to
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_SHA1_TAG_POINTS_TO_VERSION = 516c9c5f64ec66534d4d069c2e408d9ae4dce023
|
||||
GIT_SHA1_TAG_POINTS_TO_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_SHA1_TAG_POINTS_TO_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 e8e0febc7f1408df22bce2d73d9a30081e03b45e152bc25effd14435ca8b3433 git-submodule-disabled-a9dbc1e23c45e8e1b88c0448763f54d714eb6f8f-br1.tar.gz
|
||||
sha256 ba8b6ddc4726bfb6a05045ebfd8c43263c968ad1bc601bd46a25bc055008eddc file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-submodule-disabled
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_SUBMODULE_DISABLED_VERSION = a9dbc1e23c45e8e1b88c0448763f54d714eb6f8f
|
||||
GIT_SUBMODULE_DISABLED_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_SUBMODULE_DISABLED_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+1
@@ -0,0 +1 @@
|
||||
sha256 176c32f10ad11f290b6251d701835450292ba281eb59c7fb57b244407a55ceab git-submodule-enabled-a9dbc1e23c45e8e1b88c0448763f54d714eb6f8f-br1.tar.gz
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-submodule-enabled
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_SUBMODULE_ENABLED_VERSION = a9dbc1e23c45e8e1b88c0448763f54d714eb6f8f
|
||||
GIT_SUBMODULE_ENABLED_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_SUBMODULE_ENABLED_GIT_SUBMODULES = YES
|
||||
|
||||
$(eval $(generic-package))
|
||||
@@ -0,0 +1,2 @@
|
||||
sha256 c66b2366d8ccb1670951012334fe8d48de3358aef39b3da2912b339448fefcde git-tag-mytag-br1.tar.gz
|
||||
sha256 6de8772a0a58fa62e2b8c58d4dae55c9db7534ad3b3918ecc849a9008d58f081 file
|
||||
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-tag
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_TAG_VERSION = mytag
|
||||
GIT_TAG_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_TAG_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
sha256 4a230e667227310289438cd7d899276a0d45ca8778abfd043dfc0a10ed2c9085 git-wrong-content-a238b1dfcd825d47d834af3c5223417c8411d90d-br1.tar.gz
|
||||
sha256 0000000000000000000000000000000000000000000000000000000000000000 file
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
#
|
||||
# git-wrong-content
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GIT_WRONG_CONTENT_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
|
||||
GIT_WRONG_CONTENT_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
|
||||
GIT_WRONG_CONTENT_LICENSE_FILES = file
|
||||
|
||||
$(eval $(generic-package))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user