def test_bootloader_embed(self, prepared_test_build, bitbake_image): """Test that MENDER_IMAGE_BOOTLOADER_FILE causes the bootloader to be embedded correctly in the resulting sdimg.""" loader_file = "bootloader.bin" loader_offset = 4 init_env_cmd = "cd %s && . oe-init-build-env %s" % ( prepared_test_build["bitbake_corebase"], prepared_test_build["build_dir"], ) new_bb_vars = get_bitbake_variables( "core-image-minimal", env_setup=init_env_cmd ) loader_dir = new_bb_vars["DEPLOY_DIR_IMAGE"] loader_path = os.path.join(loader_dir, loader_file) run_verbose("mkdir -p %s" % os.path.dirname(loader_path)) run_verbose("cp /etc/os-release %s" % loader_path) build_image( prepared_test_build["build_dir"], prepared_test_build["bitbake_corebase"], bitbake_image, [ 'MENDER_IMAGE_BOOTLOADER_FILE = "%s"' % loader_file, 'MENDER_IMAGE_BOOTLOADER_BOOTSECTOR_OFFSET = "%d"' % loader_offset, ], ) built_sdimg = latest_build_artifact( prepared_test_build["build_dir"], "core-image*.sdimg" ) original = os.open(loader_path, os.O_RDONLY) embedded = os.open(built_sdimg, os.O_RDONLY) os.lseek(embedded, loader_offset * 512, 0) block_size = 4096 while True: org_read = os.read(original, block_size) org_read_size = len(org_read) emb_read = os.read(embedded, org_read_size) assert ( org_read == emb_read ), "Embedded bootloader is not identical to the file specified in MENDER_IMAGE_BOOTLOADER_FILE" if org_read_size < block_size: break os.close(original) os.close(embedded)
def test_multiple_device_types_compatible(self, prepared_test_build, bitbake_path, bitbake_variables, bitbake_image): """Tests that we can include multiple device_types in the artifact.""" build_image( prepared_test_build["build_dir"], prepared_test_build["bitbake_corebase"], bitbake_image, ['MENDER_DEVICE_TYPES_COMPATIBLE = "machine1 machine2"'], ) image = latest_build_artifact(prepared_test_build["build_dir"], "core-image*.mender") output = run_verbose("mender-artifact read %s" % image, capture=True) assert b"Compatible devices: '[machine1 machine2]'" in output output = subprocess.check_output( "tar xOf %s header.tar.gz | tar xOz header-info" % image, shell=True).decode() data = json.loads(output) if version_is_minimum(bitbake_variables, "mender-artifact", "3.0.0"): assert data["artifact_depends"]["device_type"] == [ "machine1", "machine2" ] else: assert data["device_types_compatible"] == ["machine1", "machine2"]
def test_preferred_versions(self, prepared_test_build, recipe, version): """Most Jenkins builds build with PREFERRED_VERSION set, because we want to build from a specific SHA. This test tests that we can change that or turn it off and the build still works.""" old_file = get_local_conf_orig_path(prepared_test_build["build_dir"]) new_file = get_local_conf_path(prepared_test_build["build_dir"]) if recipe.endswith("-native"): base_recipe = recipe[: -len("-native")] else: base_recipe = recipe for pn_style in ["", "pn-"]: with open(old_file) as old_fd, open(new_file, "w") as new_fd: for line in old_fd.readlines(): if ( re.match("^EXTERNALSRC_pn-%s(-native)? *=" % base_recipe, line) is not None ): continue elif ( re.match( "^PREFERRED_VERSION_(pn-)?%s(-native)? *=" % base_recipe, line, ) is not None ): continue else: new_fd.write(line) if version is not None: new_fd.write( 'PREFERRED_VERSION_%s%s = "%s"\n' % (pn_style, base_recipe, version) ) new_fd.write( 'PREFERRED_VERSION_%s%s-native = "%s"\n' % (pn_style, base_recipe, version) ) init_env_cmd = "cd %s && . oe-init-build-env %s" % ( prepared_test_build["bitbake_corebase"], prepared_test_build["build_dir"], ) run_verbose("%s && bitbake %s" % (init_env_cmd, recipe))
def bitbake_path(request, conversion): """Fixture that enables the PATH we need for our testing tools.""" old_path = os.environ["PATH"] if not conversion: run_verbose( "bitbake -c prepare_recipe_sysroot mender-test-dependencies") bb_testing_variables = get_bitbake_variables( "mender-test-dependencies") os.environ[ "PATH"] = bb_testing_variables["PATH"] + ":" + os.environ["PATH"] def path_restore(): os.environ["PATH"] = old_path request.addfinalizer(path_restore) return os.environ["PATH"]
def prepared_test_build_base(request, conversion, bitbake_variables, no_tmp_build_dir): if conversion: return {"build_dir": None, "bitbake_corebase": None} if no_tmp_build_dir: build_dir = os.environ["BUILDDIR"] else: build_dir = tempfile.mkdtemp(prefix="test-build-", dir=os.environ["BUILDDIR"]) local_conf = get_local_conf_path(build_dir) local_conf_orig = get_local_conf_orig_path(build_dir) bblayers_conf = get_bblayers_conf_path(build_dir) bblayers_conf_orig = get_bblayers_conf_orig_path(build_dir) def cleanup_test_build(): if not no_tmp_build_dir: run_verbose("rm -rf %s" % build_dir) else: reset_build_conf(build_dir, full_cleanup=True) cleanup_test_build() request.addfinalizer(cleanup_test_build) env_setup = "cd %s && . oe-init-build-env %s" % ( bitbake_variables["COREBASE"], build_dir, ) run_verbose(env_setup) if not no_tmp_build_dir: run_verbose("cp %s/conf/* %s/conf" % (os.environ["BUILDDIR"], build_dir)) with open(local_conf, "a") as fd: fd.write('SSTATE_MIRRORS = " file://.* file://%s/PATH"\n' % bitbake_variables["SSTATE_DIR"]) fd.write('DL_DIR = "%s"\n' % bitbake_variables["DL_DIR"]) run_verbose("cp %s %s" % (local_conf, local_conf_orig)) run_verbose("cp %s %s" % (bblayers_conf, bblayers_conf_orig)) return { "build_dir": build_dir, "bitbake_corebase": bitbake_variables["COREBASE"] }
def test_build_artifact_depends_and_provides(self, prepared_test_build, bitbake_image, bitbake_path, dependsprovides): """Test whether a build with enabled Artifact Provides and Depends does indeed add the parameters to the built Artifact""" build_image( prepared_test_build["build_dir"], prepared_test_build["bitbake_corebase"], bitbake_image, [param for param in str(dependsprovides).splitlines()], ) image = latest_build_artifact(prepared_test_build["build_dir"], "core-image*.mender") output = run_verbose("mender-artifact read %s" % image, capture=True).decode() other = TestBuild.BuildDependsProvides.parse(output) # MEN-2956: Mender-Artifact now writes rootfs-image-checksum by default. # MEN-3482: The new key for the rootfs image checksum is rootfs-image.checksum assert ( "rootfs-image.checksum" in other.provides or "rootfs_image_checksum" in other.provides ), "Empty rootfs_image_checksum in the built rootfs-image artifact, this should be added by default by `mender-artifact write rootfs-image`" # Then remove it, not to mess up the expected test output if "rootfs-image.checksum" in other.provides.keys(): del other.provides["rootfs-image.checksum"] if "rootfs_image_checksum" in other.provides.keys(): del other.provides["rootfs_image_checksum"] # MEN-3076: Mender-Artifacts writes software version by default # older versions did not, thus we remove the key before asserting the content if "rootfs-image.version" in other.provides.keys(): del other.provides["rootfs-image.version"] assert dependsprovides.__dict__ == other.__dict__
def cleanup_test_build(): if not no_tmp_build_dir: run_verbose("rm -rf %s" % build_dir) else: reset_build_conf(build_dir, full_cleanup=True)
def test_boot_partition_population(self, prepared_test_build, bitbake_path, bitbake_image): # Notice in particular a mix of tabs, newlines and spaces. All there to # check that whitespace it treated correctly. build_image( prepared_test_build["build_dir"], prepared_test_build["bitbake_corebase"], bitbake_image, [ """ IMAGE_INSTALL_append = " test-boot-files" IMAGE_BOOT_FILES_append = " deployed-test1 deployed-test-dir2/deployed-test2 \ deployed-test3;renamed-deployed-test3 \ deployed-test-dir4/deployed-test4;renamed-deployed-test4 deployed-test5;renamed-deployed-test-dir5/renamed-deployed-test5 \ deployed-test-dir6/deployed-test6;renamed-deployed-test-dir6/renamed-deployed-test6 \ deployed-test-dir7/* \ deployed-test-dir8/*;./ \ deployed-test-dir9/*;renamed-deployed-test-dir9/ \ " """ ], ) image = latest_build_artifact(prepared_test_build["build_dir"], "core-image*.*img") extract_partition(image, 1) try: listing = (run_verbose("mdir -i img1.fs -b -/", capture=True).decode().split()) expected = [ "::/deployed-test1", "::/deployed-test2", "::/renamed-deployed-test3", "::/renamed-deployed-test4", "::/renamed-deployed-test-dir5/renamed-deployed-test5", "::/renamed-deployed-test-dir6/renamed-deployed-test6", "::/deployed-test7", "::/deployed-test8", "::/renamed-deployed-test-dir9/deployed-test9", ] assert all([item in listing for item in expected]) # Conflicting file with the same content should pass. build_image( prepared_test_build["build_dir"], prepared_test_build["bitbake_corebase"], bitbake_image, ['IMAGE_BOOT_FILES_append = " conflict-test1"'], ) # Conflicting file with different content should fail. try: build_image( prepared_test_build["build_dir"], prepared_test_build["bitbake_corebase"], bitbake_image, ['IMAGE_BOOT_FILES_append = " conflict-test2"'], ) pytest.fail( "Bitbake succeeded, but should have failed with a file conflict" ) except subprocess.CalledProcessError: pass finally: os.remove("img1.fs")