summaryrefslogtreecommitdiffstats
path: root/import-layers/yocto-poky/meta/lib/oeqa/selftest
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@fuzziesquirrel.com>2018-02-01 10:27:11 -0500
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2018-03-12 22:51:39 -0400
commit6e60e8b2b2bab889379b380a28a167a0edd9d1d3 (patch)
treef12f54d5ba8e74e67e5fad3651a1e125bb8f4191 /import-layers/yocto-poky/meta/lib/oeqa/selftest
parent509842add85b53e13164c1569a1fd43d5b8d91c5 (diff)
downloadblackbird-openbmc-6e60e8b2b2bab889379b380a28a167a0edd9d1d3.tar.gz
blackbird-openbmc-6e60e8b2b2bab889379b380a28a167a0edd9d1d3.zip
Yocto 2.3
Move OpenBMC to Yocto 2.3(pyro). Tested: Built and verified Witherspoon and Palmetto images Change-Id: I50744030e771f4850afc2a93a10d3507e76d36bc Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com> Resolves: openbmc/openbmc#2461
Diffstat (limited to 'import-layers/yocto-poky/meta/lib/oeqa/selftest')
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/_toaster.py320
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/archiver.py101
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/base.py4
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/bblayers.py5
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py51
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/buildhistory.py5
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py27
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/containerimage.py83
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py440
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/eSDK.py64
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/image_typedep.py51
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/imagefeatures.py6
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/layerappend.py3
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/liboe.py22
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/manifest.py7
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/__init__.py0
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/buildhistory.py88
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/elf.py21
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/license.py68
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/path.py89
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/types.py50
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/utils.py51
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py28
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/pkgdata.py47
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py9
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py88
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/runqemu.py140
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/runtime-test.py176
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py37
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/sstate.py25
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py103
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/tinfoil.py190
-rw-r--r--import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py798
33 files changed, 2390 insertions, 807 deletions
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/_toaster.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/_toaster.py
deleted file mode 100644
index 15ea9df9e..000000000
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/_toaster.py
+++ /dev/null
@@ -1,320 +0,0 @@
-import unittest
-import os
-import sys
-import shlex, subprocess
-import urllib.request, urllib.parse, urllib.error, subprocess, time, getpass, re, json, shlex
-
-import oeqa.utils.ftools as ftools
-from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd
-
-sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../', 'bitbake/lib/toaster')))
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "toastermain.settings")
-
-import toastermain.settings
-from django.db.models import Q
-from orm.models import *
-from oeqa.utils.decorators import testcase
-
-class ToasterSetup(oeSelfTest):
-
- def recipe_parse(self, file_path, var):
- for line in open(file_path,'r'):
- if line.find(var) > -1:
- val = line.split(" = ")[1].replace("\"", "").strip()
- return val
-
- def fix_file_path(self, file_path):
- if ":" in file_path:
- file_path=file_path.split(":")[2]
- return file_path
-
-class Toaster_DB_Tests(ToasterSetup):
-
- # Check if build name is unique - tc_id=795
- @testcase(795)
- def test_Build_Unique_Name(self):
- all_builds = Build.objects.all().count()
- distinct_builds = Build.objects.values('id').distinct().count()
- self.assertEqual(distinct_builds, all_builds, msg = 'Build name is not unique')
-
- # Check if build coocker log path is unique - tc_id=819
- @testcase(819)
- def test_Build_Unique_Cooker_Log_Path(self):
- distinct_path = Build.objects.values('cooker_log_path').distinct().count()
- total_builds = Build.objects.values('id').count()
- self.assertEqual(distinct_path, total_builds, msg = 'Build coocker log path is not unique')
-
- # Check if task order is unique for one build - tc=824
- @testcase(824)
- def test_Task_Unique_Order(self):
- builds = Build.objects.values('id')
- cnt_err = []
- for build in builds:
- total_task_order = Task.objects.filter(build = build['id']).values('order').count()
- distinct_task_order = Task.objects.filter(build = build['id']).values('order').distinct().count()
- if (total_task_order != distinct_task_order):
- cnt_err.append(build['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for build id: %s' % cnt_err)
-
- # Check task order sequence for one build - tc=825
- @testcase(825)
- def test_Task_Order_Sequence(self):
- builds = builds = Build.objects.values('id')
- cnt_err = []
- for build in builds:
- tasks = Task.objects.filter(Q(build = build['id']), ~Q(order = None), ~Q(task_name__contains = '_setscene')).values('id', 'order').order_by("order")
- cnt_tasks = 0
- for task in tasks:
- cnt_tasks += 1
- if (task['order'] != cnt_tasks):
- cnt_err.append(task['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task id: %s' % cnt_err)
-
- # Check if disk_io matches the difference between EndTimeIO and StartTimeIO in build stats - tc=828
- ### this needs to be updated ###
- #def test_Task_Disk_IO_TC828(self):
-
- # Check if outcome = 2 (SSTATE) then sstate_result must be 3 (RESTORED) - tc=832
- @testcase(832)
- def test_Task_If_Outcome_2_Sstate_Result_Must_Be_3(self):
- tasks = Task.objects.filter(outcome = 2).values('id', 'sstate_result')
- cnt_err = []
- for task in tasks:
- if (row['sstate_result'] != 3):
- cnt_err.append(task['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task id: %s' % cnt_err)
-
- # Check if outcome = 1 (COVERED) or 3 (EXISTING) then sstate_result must be 0 (SSTATE_NA) - tc=833
- @testcase(833)
- def test_Task_If_Outcome_1_3_Sstate_Result_Must_Be_0(self):
- tasks = Task.objects.filter(outcome__in = (1, 3)).values('id', 'sstate_result')
- cnt_err = []
- for task in tasks:
- if (task['sstate_result'] != 0):
- cnt_err.append(task['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task id: %s' % cnt_err)
-
- # Check if outcome is 0 (SUCCESS) or 4 (FAILED) then sstate_result must be 0 (NA), 1 (MISS) or 2 (FAILED) - tc=834
- @testcase(834)
- def test_Task_If_Outcome_0_4_Sstate_Result_Must_Be_0_1_2(self):
- tasks = Task.objects.filter(outcome__in = (0, 4)).values('id', 'sstate_result')
- cnt_err = []
- for task in tasks:
- if (task['sstate_result'] not in [0, 1, 2]):
- cnt_err.append(task['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task id: %s' % cnt_err)
-
- # Check if task_executed = TRUE (1), script_type must be 0 (CODING_NA), 2 (CODING_PYTHON), 3 (CODING_SHELL) - tc=891
- @testcase(891)
- def test_Task_If_Task_Executed_True_Script_Type_0_2_3(self):
- tasks = Task.objects.filter(task_executed = 1).values('id', 'script_type')
- cnt_err = []
- for task in tasks:
- if (task['script_type'] not in [0, 2, 3]):
- cnt_err.append(task['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task id: %s' % cnt_err)
-
- # Check if task_executed = TRUE (1), outcome must be 0 (SUCCESS) or 4 (FAILED) - tc=836
- @testcase(836)
- def test_Task_If_Task_Executed_True_Outcome_0_4(self):
- tasks = Task.objects.filter(task_executed = 1).values('id', 'outcome')
- cnt_err = []
- for task in tasks:
- if (task['outcome'] not in [0, 4]):
- cnt_err.append(task['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task id: %s' % cnt_err)
-
- # Check if task_executed = FALSE (0), script_type must be 0 - tc=890
- @testcase(890)
- def test_Task_If_Task_Executed_False_Script_Type_0(self):
- tasks = Task.objects.filter(task_executed = 0).values('id', 'script_type')
- cnt_err = []
- for task in tasks:
- if (task['script_type'] != 0):
- cnt_err.append(task['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task id: %s' % cnt_err)
-
- # Check if task_executed = FALSE (0) and build outcome = SUCCEEDED (0), task outcome must be 1 (COVERED), 2 (CACHED), 3 (PREBUILT), 5 (EMPTY) - tc=837
- @testcase(837)
- def test_Task_If_Task_Executed_False_Outcome_1_2_3_5(self):
- builds = Build.objects.filter(outcome = 0).values('id')
- cnt_err = []
- for build in builds:
- tasks = Task.objects.filter(build = build['id'], task_executed = 0).values('id', 'outcome')
- for task in tasks:
- if (task['outcome'] not in [1, 2, 3, 5]):
- cnt_err.append(task['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task id: %s' % cnt_err)
-
- # Key verification - tc=888
- @testcase(888)
- def test_Target_Installed_Package(self):
- rows = Target_Installed_Package.objects.values('id', 'target_id', 'package_id')
- cnt_err = []
- for row in rows:
- target = Target.objects.filter(id = row['target_id']).values('id')
- package = Package.objects.filter(id = row['package_id']).values('id')
- if (not target or not package):
- cnt_err.append(row['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for target installed package id: %s' % cnt_err)
-
- # Key verification - tc=889
- @testcase(889)
- def test_Task_Dependency(self):
- rows = Task_Dependency.objects.values('id', 'task_id', 'depends_on_id')
- cnt_err = []
- for row in rows:
- task_id = Task.objects.filter(id = row['task_id']).values('id')
- depends_on_id = Task.objects.filter(id = row['depends_on_id']).values('id')
- if (not task_id or not depends_on_id):
- cnt_err.append(row['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for task dependency id: %s' % cnt_err)
-
- # Check if build target file_name is populated only if is_image=true AND orm_build.outcome=0 then if the file exists and its size matches the file_size value
- ### Need to add the tc in the test run
- @testcase(1037)
- def test_Target_File_Name_Populated(self):
- builds = Build.objects.filter(outcome = 0).values('id')
- for build in builds:
- targets = Target.objects.filter(build_id = build['id'], is_image = 1).values('id')
- for target in targets:
- target_files = Target_Image_File.objects.filter(target_id = target['id']).values('id', 'file_name', 'file_size')
- cnt_err = []
- for file_info in target_files:
- target_id = file_info['id']
- target_file_name = file_info['file_name']
- target_file_size = file_info['file_size']
- if (not target_file_name or not target_file_size):
- cnt_err.append(target_id)
- else:
- if (not os.path.exists(target_file_name)):
- cnt_err.append(target_id)
- else:
- if (os.path.getsize(target_file_name) != target_file_size):
- cnt_err.append(target_id)
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for target image file id: %s' % cnt_err)
-
- # Key verification - tc=884
- @testcase(884)
- def test_Package_Dependency(self):
- cnt_err = []
- deps = Package_Dependency.objects.values('id', 'package_id', 'depends_on_id')
- for dep in deps:
- if (dep['package_id'] == dep['depends_on_id']):
- cnt_err.append(dep['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for package dependency id: %s' % cnt_err)
-
- # Recipe key verification, recipe name does not depends on a recipe having the same name - tc=883
- @testcase(883)
- def test_Recipe_Dependency(self):
- deps = Recipe_Dependency.objects.values('id', 'recipe_id', 'depends_on_id')
- cnt_err = []
- for dep in deps:
- if (not dep['recipe_id'] or not dep['depends_on_id']):
- cnt_err.append(dep['id'])
- else:
- name = Recipe.objects.filter(id = dep['recipe_id']).values('name')
- dep_name = Recipe.objects.filter(id = dep['depends_on_id']).values('name')
- if (name == dep_name):
- cnt_err.append(dep['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for recipe dependency id: %s' % cnt_err)
-
- # Check if package name does not start with a number (0-9) - tc=846
- @testcase(846)
- def test_Package_Name_For_Number(self):
- packages = Package.objects.filter(~Q(size = -1)).values('id', 'name')
- cnt_err = []
- for package in packages:
- if (package['name'][0].isdigit() is True):
- cnt_err.append(package['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for package id: %s' % cnt_err)
-
- # Check if package version starts with a number (0-9) - tc=847
- @testcase(847)
- def test_Package_Version_Starts_With_Number(self):
- packages = Package.objects.filter(~Q(size = -1)).values('id', 'version')
- cnt_err = []
- for package in packages:
- if (package['version'][0].isdigit() is False):
- cnt_err.append(package['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for package id: %s' % cnt_err)
-
- # Check if package revision starts with 'r' - tc=848
- @testcase(848)
- def test_Package_Revision_Starts_With_r(self):
- packages = Package.objects.filter(~Q(size = -1)).values('id', 'revision')
- cnt_err = []
- for package in packages:
- if (package['revision'][0].startswith("r") is False):
- cnt_err.append(package['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for package id: %s' % cnt_err)
-
- # Check the validity of the package build_id
- ### TC must be added in test run
- @testcase(1038)
- def test_Package_Build_Id(self):
- packages = Package.objects.filter(~Q(size = -1)).values('id', 'build_id')
- cnt_err = []
- for package in packages:
- build_id = Build.objects.filter(id = package['build_id']).values('id')
- if (not build_id):
- cnt_err.append(package['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for package id: %s' % cnt_err)
-
- # Check the validity of package recipe_id
- ### TC must be added in test run
- @testcase(1039)
- def test_Package_Recipe_Id(self):
- packages = Package.objects.filter(~Q(size = -1)).values('id', 'recipe_id')
- cnt_err = []
- for package in packages:
- recipe_id = Recipe.objects.filter(id = package['recipe_id']).values('id')
- if (not recipe_id):
- cnt_err.append(package['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for package id: %s' % cnt_err)
-
- # Check if package installed_size field is not null
- ### TC must be aded in test run
- @testcase(1040)
- def test_Package_Installed_Size_Not_NULL(self):
- packages = Package.objects.filter(installed_size__isnull = True).values('id')
- cnt_err = []
- for package in packages:
- cnt_err.append(package['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for package id: %s' % cnt_err)
-
- # Check if all layers requests return exit code is 200 - tc=843
- @testcase(843)
- def test_Layers_Requests_Exit_Code(self):
- layers = Layer.objects.values('id', 'layer_index_url')
- cnt_err = []
- for layer in layers:
- resp = urllib.request.urlopen(layer['layer_index_url'])
- if (resp.getcode() != 200):
- cnt_err.append(layer['id'])
- self.assertEqual(len(cnt_err), 0, msg = 'Errors for layer id: %s' % cnt_err)
-
- # Check if django server starts regardless of the timezone set on the machine - tc=905
- @testcase(905)
- def test_Start_Django_Timezone(self):
- current_path = os.getcwd()
- zonefilelist = []
- ZONEINFOPATH = '/usr/share/zoneinfo/'
- os.chdir("../bitbake/lib/toaster/")
- cnt_err = 0
- for filename in os.listdir(ZONEINFOPATH):
- if os.path.isfile(os.path.join(ZONEINFOPATH, filename)):
- zonefilelist.append(filename)
- for k in range(len(zonefilelist)):
- if k <= 5:
- files = zonefilelist[k]
- os.system("export TZ="+str(files)+"; python manage.py runserver > /dev/null 2>&1 &")
- time.sleep(3)
- pid = subprocess.check_output("ps aux | grep '[/u]sr/bin/python manage.py runserver' | awk '{print $2}'", shell = True)
- if pid:
- os.system("kill -9 "+str(pid))
- else:
- cnt_err.append(zonefilelist[k])
- self.assertEqual(cnt_err, 0, msg = 'Errors django server does not start with timezone: %s' % cnt_err)
- os.chdir(current_path)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/archiver.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/archiver.py
index f2030c446..7f01c36d4 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/archiver.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/archiver.py
@@ -1,5 +1,5 @@
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import bitbake, get_bb_var
+from oeqa.utils.commands import bitbake, get_bb_vars
from oeqa.utils.decorators import testcase
import glob
import os
@@ -26,25 +26,94 @@ class Archiver(oeSelfTest):
features += 'ARCHIVER_MODE[src] = "original"\n'
features += 'COPYLEFT_PN_INCLUDE = "%s"\n' % include_recipe
features += 'COPYLEFT_PN_EXCLUDE = "%s"\n' % exclude_recipe
-
- # Update local.conf
self.write_config(features)
- tmp_dir = get_bb_var('TMPDIR')
- deploy_dir_src = get_bb_var('DEPLOY_DIR_SRC')
- target_sys = get_bb_var('TARGET_SYS')
- src_path = os.path.join(deploy_dir_src, target_sys)
-
- # Delete tmp directory
- shutil.rmtree(tmp_dir)
+ bitbake('-c clean %s %s' % (include_recipe, exclude_recipe))
+ bitbake("-c deploy_archives %s %s" % (include_recipe, exclude_recipe))
- # Build core-image-minimal
- bitbake('core-image-minimal')
+ bb_vars = get_bb_vars(['DEPLOY_DIR_SRC', 'TARGET_SYS'])
+ src_path = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['TARGET_SYS'])
# Check that include_recipe was included
- is_included = len(glob.glob(src_path + '/%s*' % include_recipe))
- self.assertEqual(1, is_included, 'Recipe %s was not included.' % include_recipe)
+ included_present = len(glob.glob(src_path + '/%s-*' % include_recipe))
+ self.assertTrue(included_present, 'Recipe %s was not included.' % include_recipe)
# Check that exclude_recipe was excluded
- is_excluded = len(glob.glob(src_path + '/%s*' % exclude_recipe))
- self.assertEqual(0, is_excluded, 'Recipe %s was not excluded.' % exclude_recipe)
+ excluded_present = len(glob.glob(src_path + '/%s-*' % exclude_recipe))
+ self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % exclude_recipe)
+
+
+ def test_archiver_filters_by_type(self):
+ """
+ Summary: The archiver is documented to filter on the recipe type.
+ Expected: 1. included recipe type (target) should be included
+ 2. other types should be excluded
+ Product: oe-core
+ Author: André Draszik <adraszik@tycoint.com>
+ """
+
+ target_recipe = 'initscripts'
+ native_recipe = 'zlib-native'
+
+ features = 'INHERIT += "archiver"\n'
+ features += 'ARCHIVER_MODE[src] = "original"\n'
+ features += 'COPYLEFT_RECIPE_TYPES = "target"\n'
+ self.write_config(features)
+
+ bitbake('-c clean %s %s' % (target_recipe, native_recipe))
+ bitbake("%s -c deploy_archives %s" % (target_recipe, native_recipe))
+
+ bb_vars = get_bb_vars(['DEPLOY_DIR_SRC', 'TARGET_SYS', 'BUILD_SYS'])
+ src_path_target = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['TARGET_SYS'])
+ src_path_native = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['BUILD_SYS'])
+
+ # Check that target_recipe was included
+ included_present = len(glob.glob(src_path_target + '/%s-*' % target_recipe))
+ self.assertTrue(included_present, 'Recipe %s was not included.' % target_recipe)
+
+ # Check that native_recipe was excluded
+ excluded_present = len(glob.glob(src_path_native + '/%s-*' % native_recipe))
+ self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % native_recipe)
+
+ def test_archiver_filters_by_type_and_name(self):
+ """
+ Summary: Test that the archiver archives by recipe type, taking the
+ recipe name into account.
+ Expected: 1. included recipe type (target) should be included
+ 2. other types should be excluded
+ 3. recipe by name should be included / excluded,
+ overriding previous decision by type
+ Product: oe-core
+ Author: André Draszik <adraszik@tycoint.com>
+ """
+
+ target_recipes = [ 'initscripts', 'zlib' ]
+ native_recipes = [ 'update-rc.d-native', 'zlib-native' ]
+
+ features = 'INHERIT += "archiver"\n'
+ features += 'ARCHIVER_MODE[src] = "original"\n'
+ features += 'COPYLEFT_RECIPE_TYPES = "target"\n'
+ features += 'COPYLEFT_PN_INCLUDE = "%s"\n' % native_recipes[1]
+ features += 'COPYLEFT_PN_EXCLUDE = "%s"\n' % target_recipes[1]
+ self.write_config(features)
+
+ bitbake('-c clean %s %s' % (' '.join(target_recipes), ' '.join(native_recipes)))
+ bitbake('-c deploy_archives %s %s' % (' '.join(target_recipes), ' '.join(native_recipes)))
+
+ bb_vars = get_bb_vars(['DEPLOY_DIR_SRC', 'TARGET_SYS', 'BUILD_SYS'])
+ src_path_target = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['TARGET_SYS'])
+ src_path_native = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['BUILD_SYS'])
+
+ # Check that target_recipe[0] and native_recipes[1] were included
+ included_present = len(glob.glob(src_path_target + '/%s-*' % target_recipes[0]))
+ self.assertTrue(included_present, 'Recipe %s was not included.' % target_recipes[0])
+
+ included_present = len(glob.glob(src_path_native + '/%s-*' % native_recipes[1]))
+ self.assertTrue(included_present, 'Recipe %s was not included.' % native_recipes[1])
+
+ # Check that native_recipes[0] and target_recipes[1] were excluded
+ excluded_present = len(glob.glob(src_path_native + '/%s-*' % native_recipes[0]))
+ self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % native_recipes[0])
+
+ excluded_present = len(glob.glob(src_path_target + '/%s-*' % target_recipes[1]))
+ self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % target_recipes[1])
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/base.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/base.py
index 26c93f905..47a8ea827 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/base.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/base.py
@@ -163,7 +163,7 @@ be re-executed from a clean environment to ensure accurate results.")
# remove data from <builddir>/conf/selftest.inc
def remove_config(self, data):
- self.log.debug("Removing from: %s\n\%s\n" % (self.testinc_path, data))
+ self.log.debug("Removing from: %s\n%s\n" % (self.testinc_path, data))
ftools.remove_from_file(self.testinc_path, data)
# write to meta-sefltest/recipes-test/<recipe>/test_recipe.inc
@@ -206,7 +206,7 @@ be re-executed from a clean environment to ensure accurate results.")
# remove data from <builddir>/conf/bblayers.inc
def remove_bblayers_config(self, data):
- self.log.debug("Removing from: %s\n\%s\n" % (self.testinc_bblayers_path, data))
+ self.log.debug("Removing from: %s\n%s\n" % (self.testinc_bblayers_path, data))
ftools.remove_from_file(self.testinc_bblayers_path, data)
# write to <builddir>/conf/machine.inc
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/bblayers.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/bblayers.py
index d23675e84..cd658c5d4 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/bblayers.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/bblayers.py
@@ -71,17 +71,12 @@ class BitbakeLayers(oeSelfTest):
result = runCmd('bitbake-layers show-recipes')
self.assertIn('aspell:', result.output)
self.assertIn('mtd-utils:', result.output)
- self.assertIn('linux-yocto:', result.output)
self.assertIn('core-image-minimal:', result.output)
result = runCmd('bitbake-layers show-recipes mtd-utils')
self.assertIn('mtd-utils:', result.output)
self.assertNotIn('aspell:', result.output)
- result = runCmd('bitbake-layers show-recipes -i kernel')
- self.assertIn('linux-yocto:', result.output)
- self.assertNotIn('mtd-utils:', result.output)
result = runCmd('bitbake-layers show-recipes -i image')
self.assertIn('core-image-minimal', result.output)
- self.assertNotIn('linux-yocto:', result.output)
self.assertNotIn('mtd-utils:', result.output)
result = runCmd('bitbake-layers show-recipes -i cmake,pkgconfig')
self.assertIn('libproxy:', result.output)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py
index 4ce935fc1..46e09f509 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py
@@ -3,7 +3,7 @@ import re
import oeqa.utils.ftools as ftools
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
from oeqa.utils.decorators import testcase
class BitbakeTests(oeSelfTest):
@@ -78,9 +78,10 @@ class BitbakeTests(oeSelfTest):
# test 1 from bug 5875
test_recipe = 'zlib'
test_data = "Microsoft Made No Profit From Anyone's Zunes Yo"
- image_dir = get_bb_var('D', test_recipe)
- pkgsplit_dir = get_bb_var('PKGDEST', test_recipe)
- man_dir = get_bb_var('mandir', test_recipe)
+ bb_vars = get_bb_vars(['D', 'PKGDEST', 'mandir'], test_recipe)
+ image_dir = bb_vars['D']
+ pkgsplit_dir = bb_vars['PKGDEST']
+ man_dir = bb_vars['mandir']
bitbake('-c clean %s' % test_recipe)
bitbake('-c package -f %s' % test_recipe)
@@ -112,17 +113,18 @@ class BitbakeTests(oeSelfTest):
@testcase(167)
def test_bitbake_g(self):
- result = bitbake('-g core-image-full-cmdline')
- for f in ['pn-buildlist', 'pn-depends.dot', 'package-depends.dot', 'task-depends.dot']:
+ result = bitbake('-g core-image-minimal')
+ for f in ['pn-buildlist', 'recipe-depends.dot', 'task-depends.dot']:
self.addCleanup(os.remove, f)
- self.assertTrue('NOTE: PN build list saved to \'pn-buildlist\'' in result.output, msg = "No dependency \"pn-buildlist\" file was generated for the given task target. bitbake output: %s" % result.output)
- self.assertTrue('openssh' in ftools.read_file(os.path.join(self.builddir, 'pn-buildlist')), msg = "No \"openssh\" dependency found in pn-buildlist file.")
+ self.assertTrue('Task dependencies saved to \'task-depends.dot\'' in result.output, msg = "No task dependency \"task-depends.dot\" file was generated for the given task target. bitbake output: %s" % result.output)
+ self.assertTrue('busybox' in ftools.read_file(os.path.join(self.builddir, 'task-depends.dot')), msg = "No \"busybox\" dependency found in task-depends.dot file.")
@testcase(899)
def test_image_manifest(self):
bitbake('core-image-minimal')
- deploydir = get_bb_var("DEPLOY_DIR_IMAGE", target="core-image-minimal")
- imagename = get_bb_var("IMAGE_LINK_NAME", target="core-image-minimal")
+ bb_vars = get_bb_vars(["DEPLOY_DIR_IMAGE", "IMAGE_LINK_NAME"], "core-image-minimal")
+ deploydir = bb_vars["DEPLOY_DIR_IMAGE"]
+ imagename = bb_vars["IMAGE_LINK_NAME"]
manifest = os.path.join(deploydir, imagename + ".manifest")
self.assertTrue(os.path.islink(manifest), msg="No manifest file created for image. It should have been created in %s" % manifest)
@@ -149,19 +151,21 @@ doesn't exist, yet fetcher didn't report any error. bitbake output: %s" % result
@testcase(171)
def test_rename_downloaded_file(self):
+ # TODO unique dldir instead of using cleanall
+ # TODO: need to set sstatedir?
self.write_config("""DL_DIR = \"${TOPDIR}/download-selftest\"
SSTATE_DIR = \"${TOPDIR}/download-selftest\"
""")
self.track_for_cleanup(os.path.join(self.builddir, "download-selftest"))
- data = 'SRC_URI_append = ";downloadfilename=test-aspell.tar.gz"'
+ data = 'SRC_URI = "${GNU_MIRROR}/aspell/aspell-${PV}.tar.gz;downloadfilename=test-aspell.tar.gz"'
self.write_recipeinc('aspell', data)
- bitbake('-ccleanall aspell')
- result = bitbake('-c fetch aspell', ignore_status=True)
+ result = bitbake('-f -c fetch aspell', ignore_status=True)
self.delete_recipeinc('aspell')
self.assertEqual(result.status, 0, msg = "Couldn't fetch aspell. %s" % result.output)
- self.assertTrue(os.path.isfile(os.path.join(get_bb_var("DL_DIR"), 'test-aspell.tar.gz')), msg = "File rename failed. No corresponding test-aspell.tar.gz file found under %s" % str(get_bb_var("DL_DIR")))
- self.assertTrue(os.path.isfile(os.path.join(get_bb_var("DL_DIR"), 'test-aspell.tar.gz.done')), "File rename failed. No corresponding test-aspell.tar.gz.done file found under %s" % str(get_bb_var("DL_DIR")))
+ dl_dir = get_bb_var("DL_DIR")
+ self.assertTrue(os.path.isfile(os.path.join(dl_dir, 'test-aspell.tar.gz')), msg = "File rename failed. No corresponding test-aspell.tar.gz file found under %s" % dl_dir)
+ self.assertTrue(os.path.isfile(os.path.join(dl_dir, 'test-aspell.tar.gz.done')), "File rename failed. No corresponding test-aspell.tar.gz.done file found under %s" % dl_dir)
@testcase(1028)
def test_environment(self):
@@ -227,14 +231,12 @@ INHERIT_remove = \"report-error\"
@testcase(1119)
def test_non_gplv3(self):
- data = 'INCOMPATIBLE_LICENSE = "GPLv3"'
- conf = os.path.join(self.builddir, 'conf/local.conf')
- ftools.append_file(conf ,data)
- self.addCleanup(ftools.remove_from_file, conf ,data)
- result = bitbake('readline', ignore_status=True)
+ self.write_config('INCOMPATIBLE_LICENSE = "GPLv3"')
+ result = bitbake('selftest-ed', ignore_status=True)
self.assertEqual(result.status, 0, "Bitbake failed, exit code %s, output %s" % (result.status, result.output))
- self.assertFalse(os.path.isfile(os.path.join(self.builddir, 'tmp/deploy/licenses/readline/generic_GPLv3')))
- self.assertTrue(os.path.isfile(os.path.join(self.builddir, 'tmp/deploy/licenses/readline/generic_GPLv2')))
+ lic_dir = get_bb_var('LICENSE_DIRECTORY')
+ self.assertFalse(os.path.isfile(os.path.join(lic_dir, 'selftest-ed/generic_GPLv3')))
+ self.assertTrue(os.path.isfile(os.path.join(lic_dir, 'selftest-ed/generic_GPLv2')))
@testcase(1422)
def test_setscene_only(self):
@@ -255,8 +257,9 @@ INHERIT_remove = \"report-error\"
def test_bbappend_order(self):
""" Bitbake should bbappend to recipe in a predictable order """
test_recipe = 'ed'
- test_recipe_summary_before = get_bb_var('SUMMARY', test_recipe)
- test_recipe_pv = get_bb_var('PV', test_recipe)
+ bb_vars = get_bb_vars(['SUMMARY', 'PV'], test_recipe)
+ test_recipe_summary_before = bb_vars['SUMMARY']
+ test_recipe_pv = bb_vars['PV']
recipe_append_file = test_recipe + '_' + test_recipe_pv + '.bbappend'
expected_recipe_summary = test_recipe_summary_before
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildhistory.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildhistory.py
index 674da6205..008c39c95 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildhistory.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildhistory.py
@@ -3,14 +3,15 @@ import re
import datetime
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import bitbake, get_bb_var
+from oeqa.utils.commands import bitbake, get_bb_vars
from oeqa.utils.decorators import testcase
class BuildhistoryBase(oeSelfTest):
def config_buildhistory(self, tmp_bh_location=False):
- if (not 'buildhistory' in get_bb_var('USER_CLASSES')) and (not 'buildhistory' in get_bb_var('INHERIT')):
+ bb_vars = get_bb_vars(['USER_CLASSES', 'INHERIT'])
+ if (not 'buildhistory' in bb_vars['USER_CLASSES']) and (not 'buildhistory' in bb_vars['INHERIT']):
add_buildhistory_config = 'INHERIT += "buildhistory"\nBUILDHISTORY_COMMIT = "1"'
self.append_config(add_buildhistory_config)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py
index 47549550c..a6e0203f5 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py
@@ -5,7 +5,7 @@ import shutil
import tempfile
from oeqa.selftest.base import oeSelfTest
from oeqa.selftest.buildhistory import BuildhistoryBase
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
import oeqa.utils.ftools as ftools
from oeqa.utils.decorators import testcase
@@ -16,32 +16,38 @@ class ImageOptionsTests(oeSelfTest):
image_pkgtype = get_bb_var("IMAGE_PKGTYPE")
if image_pkgtype != 'rpm':
self.skipTest('Not using RPM as main package format')
- bitbake("-c cleanall core-image-minimal")
+ bitbake("-c clean core-image-minimal")
self.write_config('INC_RPM_IMAGE_GEN = "1"')
self.append_config('IMAGE_FEATURES += "ssh-server-openssh"')
bitbake("core-image-minimal")
log_data_file = os.path.join(get_bb_var("WORKDIR", "core-image-minimal"), "temp/log.do_rootfs")
log_data_created = ftools.read_file(log_data_file)
- incremental_created = re.search("NOTE: load old install solution for incremental install\nNOTE: old install solution not exist\nNOTE: creating new install solution for incremental install(\n.*)*NOTE: Installing the following packages:.*packagegroup-core-ssh-openssh", log_data_created)
+ incremental_created = re.search("Installing : packagegroup-core-ssh-openssh", log_data_created)
self.remove_config('IMAGE_FEATURES += "ssh-server-openssh"')
self.assertTrue(incremental_created, msg = "Match failed in:\n%s" % log_data_created)
bitbake("core-image-minimal")
log_data_removed = ftools.read_file(log_data_file)
- incremental_removed = re.search("NOTE: load old install solution for incremental install\nNOTE: creating new install solution for incremental install(\n.*)*NOTE: incremental removed:.*openssh-sshd-.*", log_data_removed)
+ incremental_removed = re.search("Erasing : packagegroup-core-ssh-openssh", log_data_removed)
self.assertTrue(incremental_removed, msg = "Match failed in:\n%s" % log_data_removed)
@testcase(286)
def test_ccache_tool(self):
bitbake("ccache-native")
- self.assertTrue(os.path.isfile(os.path.join(get_bb_var('STAGING_BINDIR_NATIVE', 'ccache-native'), "ccache")), msg = "No ccache found under %s" % str(get_bb_var('STAGING_BINDIR_NATIVE', 'ccache-native')))
+ bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'ccache-native')
+ p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/" + "ccache"
+ self.assertTrue(os.path.isfile(p), msg = "No ccache found (%s)" % p)
self.write_config('INHERIT += "ccache"')
self.add_command_to_tearDown('bitbake -c clean m4')
bitbake("m4 -f -c compile")
- res = runCmd("grep ccache %s" % (os.path.join(get_bb_var("WORKDIR","m4"),"temp/log.do_compile")), ignore_status=True)
- self.assertEqual(0, res.status, msg="No match for ccache in m4 log.do_compile. For further details: %s" % os.path.join(get_bb_var("WORKDIR","m4"),"temp/log.do_compile"))
+ log_compile = os.path.join(get_bb_var("WORKDIR","m4"), "temp/log.do_compile")
+ res = runCmd("grep ccache %s" % log_compile, ignore_status=True)
+ self.assertEqual(0, res.status, msg="No match for ccache in m4 log.do_compile. For further details: %s" % log_compile)
@testcase(1435)
def test_read_only_image(self):
+ distro_features = get_bb_var('DISTRO_FEATURES')
+ if not ('x11' in distro_features and 'opengl' in distro_features):
+ self.skipTest('core-image-sato requires x11 and opengl in distro features')
self.write_config('IMAGE_FEATURES += "read-only-rootfs"')
bitbake("core-image-sato")
# do_image will fail if there are any pending postinsts
@@ -157,7 +163,6 @@ class BuildhistoryTests(BuildhistoryBase):
@testcase(294)
def test_buildhistory_buildtime_pr_backwards(self):
- self.add_command_to_tearDown('cleanup-workdir')
target = 'xcursor-transparent-theme'
error = "ERROR:.*QA Issue: Package version for package %s went backwards which would break package feeds from (.*-r1.* to .*-r0.*)" % target
self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True)
@@ -169,11 +174,11 @@ class ArchiverTest(oeSelfTest):
"""
Test for archiving the work directory and exporting the source files.
"""
- self.add_command_to_tearDown('cleanup-workdir')
self.write_config("INHERIT += \"archiver\"\nARCHIVER_MODE[src] = \"original\"\nARCHIVER_MODE[srpm] = \"1\"")
res = bitbake("xcursor-transparent-theme", ignore_status=True)
self.assertEqual(res.status, 0, "\nCouldn't build xcursortransparenttheme.\nbitbake output %s" % res.output)
- pkgs_path = g.glob(str(self.builddir) + "/tmp/deploy/sources/allarch*/xcurs*")
+ deploy_dir_src = get_bb_var('DEPLOY_DIR_SRC')
+ pkgs_path = g.glob(str(deploy_dir_src) + "/allarch*/xcurs*")
src_file_glob = str(pkgs_path[0]) + "/xcursor*.src.rpm"
tar_file_glob = str(pkgs_path[0]) + "/xcursor*.tar.gz"
- self.assertTrue((g.glob(src_file_glob) and g.glob(tar_file_glob)), "Couldn't find .src.rpm and .tar.gz files under tmp/deploy/sources/allarch*/xcursor*")
+ self.assertTrue((g.glob(src_file_glob) and g.glob(tar_file_glob)), "Couldn't find .src.rpm and .tar.gz files under %s/allarch*/xcursor*" % deploy_dir_src)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/containerimage.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/containerimage.py
new file mode 100644
index 000000000..def481f14
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/containerimage.py
@@ -0,0 +1,83 @@
+import os
+
+from oeqa.selftest.base import oeSelfTest
+from oeqa.utils.commands import bitbake, get_bb_vars, runCmd
+
+# This test builds an image with using the "container" IMAGE_FSTYPE, and
+# ensures that then files in the image are only the ones expected.
+#
+# The only package added to the image is container_image_testpkg, which
+# contains one file. However, due to some other things not cleaning up during
+# rootfs creation, there is some cruft. Ideally bugs will be filed and the
+# cruft removed, but for now we whitelist some known set.
+#
+# Also for performance reasons we're only checking the cruft when using ipk.
+# When using deb, and rpm it is a bit different and we could test all
+# of them, but this test is more to catch if other packages get added by
+# default other than what is in ROOTFS_BOOTSTRAP_INSTALL.
+#
+class ContainerImageTests(oeSelfTest):
+
+ # Verify that when specifying a IMAGE_TYPEDEP_ of the form "foo.bar" that
+ # the conversion type bar gets added as a dep as well
+ def test_expected_files(self):
+
+ def get_each_path_part(path):
+ if path:
+ part = [ '.' + path + '/' ]
+ result = get_each_path_part(path.rsplit('/', 1)[0])
+ if result:
+ return part + result
+ else:
+ return part
+ else:
+ return None
+
+ self.write_config("""PREFERRED_PROVIDER_virtual/kernel = "linux-dummy"
+IMAGE_FSTYPES = "container"
+PACKAGE_CLASSES = "package_ipk"
+IMAGE_FEATURES = ""
+""")
+
+ bbvars = get_bb_vars(['bindir', 'sysconfdir', 'localstatedir',
+ 'DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME'],
+ target='container-test-image')
+ expected_files = [
+ './',
+ '.{bindir}/theapp',
+ '.{sysconfdir}/default/',
+ '.{sysconfdir}/default/postinst',
+ '.{sysconfdir}/ld.so.cache',
+ '.{sysconfdir}/timestamp',
+ '.{sysconfdir}/version',
+ './run/',
+ '.{localstatedir}/cache/',
+ '.{localstatedir}/cache/ldconfig/',
+ '.{localstatedir}/cache/ldconfig/aux-cache',
+ '.{localstatedir}/cache/opkg/',
+ '.{localstatedir}/lib/',
+ '.{localstatedir}/lib/opkg/'
+ ]
+
+ expected_files = [ x.format(bindir=bbvars['bindir'],
+ sysconfdir=bbvars['sysconfdir'],
+ localstatedir=bbvars['localstatedir'])
+ for x in expected_files ]
+
+ # Since tar lists all directories individually, make sure each element
+ # from bindir, sysconfdir, etc is added
+ expected_files += get_each_path_part(bbvars['bindir'])
+ expected_files += get_each_path_part(bbvars['sysconfdir'])
+ expected_files += get_each_path_part(bbvars['localstatedir'])
+
+ expected_files = sorted(expected_files)
+
+ # Build the image of course
+ bitbake('container-test-image')
+
+ image = os.path.join(bbvars['DEPLOY_DIR_IMAGE'],
+ bbvars['IMAGE_LINK_NAME'] + '.tar.bz2')
+
+ # Ensure the files in the image are what we expect
+ result = runCmd("tar tf {} | sort".format(image), shell=True)
+ self.assertEqual(result.output.split('\n'), expected_files)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py
index 302ec5d42..57048665c 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py
@@ -45,9 +45,12 @@ class DevtoolBase(oeSelfTest):
if var and var in checkvars:
needvalue = checkvars.pop(var)
if needvalue is None:
- self.fail('Variable %s should not appear in recipe')
+ self.fail('Variable %s should not appear in recipe, but value is being set to "%s"' % (var, value))
if isinstance(needvalue, set):
- value = set(value.split())
+ if var == 'LICENSE':
+ value = set(value.split(' & '))
+ else:
+ value = set(value.split())
self.assertEqual(value, needvalue, 'values for %s do not match' % var)
@@ -210,9 +213,10 @@ class DevtoolTests(DevtoolBase):
bitbake('pv -c cleansstate')
# Test devtool build
result = runCmd('devtool build pv')
- installdir = get_bb_var('D', 'pv')
+ bb_vars = get_bb_vars(['D', 'bindir'], 'pv')
+ installdir = bb_vars['D']
self.assertTrue(installdir, 'Could not query installdir variable')
- bindir = get_bb_var('bindir', 'pv')
+ bindir = bb_vars['bindir']
self.assertTrue(bindir, 'Could not query bindir variable')
if bindir[0] == '/':
bindir = bindir[1:]
@@ -260,8 +264,6 @@ class DevtoolTests(DevtoolBase):
@testcase(1162)
def test_devtool_add_library(self):
- # We don't have the ability to pick up this dependency automatically yet...
- bitbake('libusb1')
# Fetch source
tempdir = tempfile.mkdtemp(prefix='devtoolqa')
self.track_for_cleanup(tempdir)
@@ -290,13 +292,17 @@ class DevtoolTests(DevtoolBase):
result = runCmd('recipetool setvar %s EXTRA_OECMAKE -- \'-DPYTHON_BINDINGS=OFF -DLIBFTDI_CMAKE_CONFIG_DIR=${datadir}/cmake/Modules\'' % recipefile)
with open(recipefile, 'a') as f:
f.write('\nFILES_${PN}-dev += "${datadir}/cmake/Modules"\n')
+ # We don't have the ability to pick up this dependency automatically yet...
+ f.write('\nDEPENDS += "libusb1"\n')
+ f.write('\nTESTLIBOUTPUT = "${COMPONENTS_DIR}/${TUNE_PKGARCH}/${PN}/${libdir}"\n')
# Test devtool build
result = runCmd('devtool build libftdi')
- staging_libdir = get_bb_var('STAGING_LIBDIR', 'libftdi')
- self.assertTrue(staging_libdir, 'Could not query STAGING_LIBDIR variable')
+ bb_vars = get_bb_vars(['TESTLIBOUTPUT', 'STAMP'], 'libftdi')
+ staging_libdir = bb_vars['TESTLIBOUTPUT']
+ self.assertTrue(staging_libdir, 'Could not query TESTLIBOUTPUT variable')
self.assertTrue(os.path.isfile(os.path.join(staging_libdir, 'libftdi1.so.2.1.0')), "libftdi binary not found in STAGING_LIBDIR. Output of devtool build libftdi %s" % result.output)
# Test devtool reset
- stampprefix = get_bb_var('STAMP', 'libftdi')
+ stampprefix = bb_vars['STAMP']
result = runCmd('devtool reset libftdi')
result = runCmd('devtool status')
self.assertNotIn('libftdi', result.output)
@@ -353,12 +359,11 @@ class DevtoolTests(DevtoolBase):
@testcase(1161)
def test_devtool_add_fetch_git(self):
- # Fetch source
tempdir = tempfile.mkdtemp(prefix='devtoolqa')
self.track_for_cleanup(tempdir)
- url = 'git://git.yoctoproject.org/libmatchbox'
- checkrev = '462f0652055d89c648ddd54fd7b03f175c2c6973'
- testrecipe = 'libmatchbox2'
+ url = 'gitsm://git.yoctoproject.org/mraa'
+ checkrev = 'ae127b19a50aa54255e4330ccfdd9a5d058e581d'
+ testrecipe = 'mraa'
srcdir = os.path.join(tempdir, testrecipe)
# Test devtool add
self.track_for_cleanup(self.workspacedir)
@@ -366,7 +371,7 @@ class DevtoolTests(DevtoolBase):
self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
result = runCmd('devtool add %s %s -a -f %s' % (testrecipe, srcdir, url))
self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created: %s' % result.output)
- self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure.ac in source directory')
+ self.assertTrue(os.path.isfile(os.path.join(srcdir, 'imraa', 'imraa.c')), 'Unable to find imraa/imraa.c in source directory')
# Test devtool status
result = runCmd('devtool status')
self.assertIn(testrecipe, result.output)
@@ -376,7 +381,7 @@ class DevtoolTests(DevtoolBase):
self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
checkvars = {}
checkvars['S'] = '${WORKDIR}/git'
- checkvars['PV'] = '1.12+git${SRCPV}'
+ checkvars['PV'] = '1.0+git${SRCPV}'
checkvars['SRC_URI'] = url
checkvars['SRCREV'] = '${AUTOREV}'
self._test_recipe_contents(recipefile, checkvars, [])
@@ -385,7 +390,7 @@ class DevtoolTests(DevtoolBase):
shutil.rmtree(srcdir)
url_rev = '%s;rev=%s' % (url, checkrev)
result = runCmd('devtool add %s %s -f "%s" -V 1.5' % (testrecipe, srcdir, url_rev))
- self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure.ac in source directory')
+ self.assertTrue(os.path.isfile(os.path.join(srcdir, 'imraa', 'imraa.c')), 'Unable to find imraa/imraa.c in source directory')
# Test devtool status
result = runCmd('devtool status')
self.assertIn(testrecipe, result.output)
@@ -430,9 +435,8 @@ class DevtoolTests(DevtoolBase):
@testcase(1164)
def test_devtool_modify(self):
- # Clean up anything in the workdir/sysroot/sstate cache
- bitbake('mdadm -c cleansstate')
- # Try modifying a recipe
+ import oe.path
+
tempdir = tempfile.mkdtemp(prefix='devtoolqa')
self.track_for_cleanup(tempdir)
self.track_for_cleanup(self.workspacedir)
@@ -443,35 +447,95 @@ class DevtoolTests(DevtoolBase):
self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mdadm_*.bbappend'))
self.assertTrue(matches, 'bbappend not created %s' % result.output)
+
# Test devtool status
result = runCmd('devtool status')
self.assertIn('mdadm', result.output)
self.assertIn(tempdir, result.output)
- # Check git repo
self._check_src_repo(tempdir)
- # Try building
- bitbake('mdadm')
- # Try making (minor) modifications to the source
- result = runCmd("sed -i 's!^\.TH.*!.TH MDADM 8 \"\" v9.999-custom!' %s" % os.path.join(tempdir, 'mdadm.8.in'))
- bitbake('mdadm -c package')
- pkgd = get_bb_var('PKGD', 'mdadm')
+
+ bitbake('mdadm -C unpack')
+
+ def check_line(checkfile, expected, message, present=True):
+ # Check for $expected, on a line on its own, in checkfile.
+ with open(checkfile, 'r') as f:
+ if present:
+ self.assertIn(expected + '\n', f, message)
+ else:
+ self.assertNotIn(expected + '\n', f, message)
+
+ modfile = os.path.join(tempdir, 'mdadm.8.in')
+ bb_vars = get_bb_vars(['PKGD', 'mandir'], 'mdadm')
+ pkgd = bb_vars['PKGD']
self.assertTrue(pkgd, 'Could not query PKGD variable')
- mandir = get_bb_var('mandir', 'mdadm')
+ mandir = bb_vars['mandir']
self.assertTrue(mandir, 'Could not query mandir variable')
- if mandir[0] == '/':
- mandir = mandir[1:]
- with open(os.path.join(pkgd, mandir, 'man8', 'mdadm.8'), 'r') as f:
- for line in f:
- if line.startswith('.TH'):
- self.assertEqual(line.rstrip(), '.TH MDADM 8 "" v9.999-custom', 'man file not modified. man searched file path: %s' % os.path.join(pkgd, mandir, 'man8', 'mdadm.8'))
- # Test devtool reset
- stampprefix = get_bb_var('STAMP', 'mdadm')
+ manfile = oe.path.join(pkgd, mandir, 'man8', 'mdadm.8')
+
+ check_line(modfile, 'Linux Software RAID', 'Could not find initial string')
+ check_line(modfile, 'antique pin sardine', 'Unexpectedly found replacement string', present=False)
+
+ result = runCmd("sed -i 's!^Linux Software RAID$!antique pin sardine!' %s" % modfile)
+ check_line(modfile, 'antique pin sardine', 'mdadm.8.in file not modified (sed failed)')
+
+ bitbake('mdadm -c package')
+ check_line(manfile, 'antique pin sardine', 'man file not modified. man searched file path: %s' % manfile)
+
+ result = runCmd('git checkout -- %s' % modfile, cwd=tempdir)
+ check_line(modfile, 'Linux Software RAID', 'man .in file not restored (git failed)')
+
+ bitbake('mdadm -c package')
+ check_line(manfile, 'Linux Software RAID', 'man file not updated. man searched file path: %s' % manfile)
+
result = runCmd('devtool reset mdadm')
result = runCmd('devtool status')
self.assertNotIn('mdadm', result.output)
- self.assertTrue(stampprefix, 'Unable to get STAMP value for recipe mdadm')
- matches = glob.glob(stampprefix + '*')
- self.assertFalse(matches, 'Stamp files exist for recipe mdadm that should have been cleaned')
+
+ def test_devtool_buildclean(self):
+ def assertFile(path, *paths):
+ f = os.path.join(path, *paths)
+ self.assertTrue(os.path.exists(f), "%r does not exist" % f)
+ def assertNoFile(path, *paths):
+ f = os.path.join(path, *paths)
+ self.assertFalse(os.path.exists(os.path.join(f)), "%r exists" % f)
+
+ # Clean up anything in the workdir/sysroot/sstate cache
+ bitbake('mdadm m4 -c cleansstate')
+ # Try modifying a recipe
+ tempdir_mdadm = tempfile.mkdtemp(prefix='devtoolqa')
+ tempdir_m4 = tempfile.mkdtemp(prefix='devtoolqa')
+ builddir_m4 = tempfile.mkdtemp(prefix='devtoolqa')
+ self.track_for_cleanup(tempdir_mdadm)
+ self.track_for_cleanup(tempdir_m4)
+ self.track_for_cleanup(builddir_m4)
+ self.track_for_cleanup(self.workspacedir)
+ self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
+ self.add_command_to_tearDown('bitbake -c clean mdadm m4')
+ self.write_recipeinc('m4', 'EXTERNALSRC_BUILD = "%s"\ndo_clean() {\n\t:\n}\n' % builddir_m4)
+ try:
+ runCmd('devtool modify mdadm -x %s' % tempdir_mdadm)
+ runCmd('devtool modify m4 -x %s' % tempdir_m4)
+ assertNoFile(tempdir_mdadm, 'mdadm')
+ assertNoFile(builddir_m4, 'src/m4')
+ result = bitbake('m4 -e')
+ result = bitbake('mdadm m4 -c compile')
+ self.assertEqual(result.status, 0)
+ assertFile(tempdir_mdadm, 'mdadm')
+ assertFile(builddir_m4, 'src/m4')
+ # Check that buildclean task exists and does call make clean
+ bitbake('mdadm m4 -c buildclean')
+ assertNoFile(tempdir_mdadm, 'mdadm')
+ assertNoFile(builddir_m4, 'src/m4')
+ bitbake('mdadm m4 -c compile')
+ assertFile(tempdir_mdadm, 'mdadm')
+ assertFile(builddir_m4, 'src/m4')
+ bitbake('mdadm m4 -c clean')
+ # Check that buildclean task is run before clean for B == S
+ assertNoFile(tempdir_mdadm, 'mdadm')
+ # Check that buildclean task is not run before clean for B != S
+ assertFile(builddir_m4, 'src/m4')
+ finally:
+ self.delete_recipeinc('m4')
@testcase(1166)
def test_devtool_modify_invalid(self):
@@ -594,8 +658,8 @@ class DevtoolTests(DevtoolBase):
@testcase(1378)
def test_devtool_modify_virtual(self):
# Try modifying a virtual recipe
- virtrecipe = 'virtual/libx11'
- realrecipe = 'libx11'
+ virtrecipe = 'virtual/make'
+ realrecipe = 'make'
tempdir = tempfile.mkdtemp(prefix='devtoolqa')
self.track_for_cleanup(tempdir)
self.track_for_cleanup(self.workspacedir)
@@ -618,8 +682,9 @@ class DevtoolTests(DevtoolBase):
def test_devtool_update_recipe(self):
# Check preconditions
testrecipe = 'minicom'
- recipefile = get_bb_var('FILE', testrecipe)
- src_uri = get_bb_var('SRC_URI', testrecipe)
+ bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
+ recipefile = bb_vars['FILE']
+ src_uri = bb_vars['SRC_URI']
self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
self._check_repo_status(os.path.dirname(recipefile), [])
# First, modify a recipe
@@ -650,8 +715,9 @@ class DevtoolTests(DevtoolBase):
def test_devtool_update_recipe_git(self):
# Check preconditions
testrecipe = 'mtd-utils'
- recipefile = get_bb_var('FILE', testrecipe)
- src_uri = get_bb_var('SRC_URI', testrecipe)
+ bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
+ recipefile = bb_vars['FILE']
+ src_uri = bb_vars['SRC_URI']
self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
patches = []
for entry in src_uri.split():
@@ -670,7 +736,7 @@ class DevtoolTests(DevtoolBase):
self._check_src_repo(tempdir)
# Add a couple of commits
# FIXME: this only tests adding, need to also test update and remove
- result = runCmd('echo "# Additional line" >> Makefile', cwd=tempdir)
+ result = runCmd('echo "# Additional line" >> Makefile.am', cwd=tempdir)
result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempdir)
result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
result = runCmd('git add devtool-new-file', cwd=tempdir)
@@ -719,8 +785,9 @@ class DevtoolTests(DevtoolBase):
def test_devtool_update_recipe_append(self):
# Check preconditions
testrecipe = 'mdadm'
- recipefile = get_bb_var('FILE', testrecipe)
- src_uri = get_bb_var('SRC_URI', testrecipe)
+ bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
+ recipefile = bb_vars['FILE']
+ src_uri = bb_vars['SRC_URI']
self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
self._check_repo_status(os.path.dirname(recipefile), [])
# First, modify a recipe
@@ -787,8 +854,9 @@ class DevtoolTests(DevtoolBase):
def test_devtool_update_recipe_append_git(self):
# Check preconditions
testrecipe = 'mtd-utils'
- recipefile = get_bb_var('FILE', testrecipe)
- src_uri = get_bb_var('SRC_URI', testrecipe)
+ bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
+ recipefile = bb_vars['FILE']
+ src_uri = bb_vars['SRC_URI']
self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
for entry in src_uri.split():
if entry.startswith('git://'):
@@ -807,7 +875,7 @@ class DevtoolTests(DevtoolBase):
# Check git repo
self._check_src_repo(tempsrcdir)
# Add a commit
- result = runCmd('echo "# Additional line" >> Makefile', cwd=tempsrcdir)
+ result = runCmd('echo "# Additional line" >> Makefile.am', cwd=tempsrcdir)
result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
# Create a temporary layer
@@ -887,6 +955,8 @@ class DevtoolTests(DevtoolBase):
result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
# Check git repo
self._check_src_repo(tempdir)
+ # Try building just to ensure we haven't broken that
+ bitbake("%s" % testrecipe)
# Edit / commit local source
runCmd('echo "/* Foobar */" >> oe-local-files/makedevs.c', cwd=tempdir)
runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
@@ -943,6 +1013,78 @@ class DevtoolTests(DevtoolBase):
('??', '.*/0001-Add-new-file.patch$')]
self._check_repo_status(os.path.dirname(recipefile), expected_status)
+ def test_devtool_update_recipe_local_files_3(self):
+ # First, modify the recipe
+ testrecipe = 'devtool-test-localonly'
+ bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
+ recipefile = bb_vars['FILE']
+ src_uri = bb_vars['SRC_URI']
+ tempdir = tempfile.mkdtemp(prefix='devtoolqa')
+ self.track_for_cleanup(tempdir)
+ self.track_for_cleanup(self.workspacedir)
+ self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
+ # (don't bother with cleaning the recipe on teardown, we won't be building it)
+ result = runCmd('devtool modify %s' % testrecipe)
+ # Modify one file
+ runCmd('echo "Another line" >> file2', cwd=os.path.join(self.workspacedir, 'sources', testrecipe, 'oe-local-files'))
+ self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
+ result = runCmd('devtool update-recipe %s' % testrecipe)
+ expected_status = [(' M', '.*/%s/file2$' % testrecipe)]
+ self._check_repo_status(os.path.dirname(recipefile), expected_status)
+
+ def test_devtool_update_recipe_local_patch_gz(self):
+ # First, modify the recipe
+ testrecipe = 'devtool-test-patch-gz'
+ if get_bb_var('DISTRO') == 'poky-tiny':
+ self.skipTest("The DISTRO 'poky-tiny' does not provide the dependencies needed by %s" % testrecipe)
+ bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
+ recipefile = bb_vars['FILE']
+ src_uri = bb_vars['SRC_URI']
+ tempdir = tempfile.mkdtemp(prefix='devtoolqa')
+ self.track_for_cleanup(tempdir)
+ self.track_for_cleanup(self.workspacedir)
+ self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
+ # (don't bother with cleaning the recipe on teardown, we won't be building it)
+ result = runCmd('devtool modify %s' % testrecipe)
+ # Modify one file
+ srctree = os.path.join(self.workspacedir, 'sources', testrecipe)
+ runCmd('echo "Another line" >> README', cwd=srctree)
+ runCmd('git commit -a --amend --no-edit', cwd=srctree)
+ self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
+ result = runCmd('devtool update-recipe %s' % testrecipe)
+ expected_status = [(' M', '.*/%s/readme.patch.gz$' % testrecipe)]
+ self._check_repo_status(os.path.dirname(recipefile), expected_status)
+ patch_gz = os.path.join(os.path.dirname(recipefile), testrecipe, 'readme.patch.gz')
+ result = runCmd('file %s' % patch_gz)
+ if 'gzip compressed data' not in result.output:
+ self.fail('New patch file is not gzipped - file reports:\n%s' % result.output)
+
+ def test_devtool_update_recipe_local_files_subdir(self):
+ # Try devtool extract on a recipe that has a file with subdir= set in
+ # SRC_URI such that it overwrites a file that was in an archive that
+ # was also in SRC_URI
+ # First, modify the recipe
+ testrecipe = 'devtool-test-subdir'
+ bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
+ recipefile = bb_vars['FILE']
+ src_uri = bb_vars['SRC_URI']
+ tempdir = tempfile.mkdtemp(prefix='devtoolqa')
+ self.track_for_cleanup(tempdir)
+ self.track_for_cleanup(self.workspacedir)
+ self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
+ # (don't bother with cleaning the recipe on teardown, we won't be building it)
+ result = runCmd('devtool modify %s' % testrecipe)
+ testfile = os.path.join(self.workspacedir, 'sources', testrecipe, 'testfile')
+ self.assertTrue(os.path.exists(testfile), 'Extracted source could not be found')
+ with open(testfile, 'r') as f:
+ contents = f.read().rstrip()
+ self.assertEqual(contents, 'Modified version', 'File has apparently not been overwritten as it should have been')
+ # Test devtool update-recipe without modifying any files
+ self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
+ result = runCmd('devtool update-recipe %s' % testrecipe)
+ expected_status = []
+ self._check_repo_status(os.path.dirname(recipefile), expected_status)
+
@testcase(1163)
def test_devtool_extract(self):
tempdir = tempfile.mkdtemp(prefix='devtoolqa')
@@ -960,7 +1102,7 @@ class DevtoolTests(DevtoolBase):
tempdir = tempfile.mkdtemp(prefix='devtoolqa')
# Try devtool extract
self.track_for_cleanup(tempdir)
- result = runCmd('devtool extract virtual/libx11 %s' % tempdir)
+ result = runCmd('devtool extract virtual/make %s' % tempdir)
self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found')
# devtool extract shouldn't create the workspace
self.assertFalse(os.path.exists(self.workspacedir))
@@ -1054,9 +1196,10 @@ class DevtoolTests(DevtoolBase):
result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand))
# Check if it deployed all of the files with the right ownership/perms
# First look on the host - need to do this under pseudo to get the correct ownership/perms
- installdir = get_bb_var('D', testrecipe)
- fakerootenv = get_bb_var('FAKEROOTENV', testrecipe)
- fakerootcmd = get_bb_var('FAKEROOTCMD', testrecipe)
+ bb_vars = get_bb_vars(['D', 'FAKEROOTENV', 'FAKEROOTCMD'], testrecipe)
+ installdir = bb_vars['D']
+ fakerootenv = bb_vars['FAKEROOTENV']
+ fakerootcmd = bb_vars['FAKEROOTCMD']
result = runCmd('%s %s find . -type f -exec ls -l {} \;' % (fakerootenv, fakerootcmd), cwd=installdir)
filelist1 = self._process_ls_output(result.output)
@@ -1207,6 +1350,49 @@ class DevtoolTests(DevtoolBase):
result = runCmd("devtool --quiet selftest-reverse \"%s\"" % s)
self.assertEqual(result.output, s[::-1])
+ def _copy_file_with_cleanup(self, srcfile, basedstdir, *paths):
+ dstdir = basedstdir
+ self.assertTrue(os.path.exists(dstdir))
+ for p in paths:
+ dstdir = os.path.join(dstdir, p)
+ if not os.path.exists(dstdir):
+ os.makedirs(dstdir)
+ self.track_for_cleanup(dstdir)
+ dstfile = os.path.join(dstdir, os.path.basename(srcfile))
+ if srcfile != dstfile:
+ shutil.copy(srcfile, dstfile)
+ self.track_for_cleanup(dstfile)
+
+ def test_devtool_load_plugin(self):
+ """Test that devtool loads only the first found plugin in BBPATH."""
+
+ self.track_for_cleanup(self.workspacedir)
+ self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
+
+ devtool = runCmd("which devtool")
+ fromname = runCmd("devtool --quiet pluginfile")
+ srcfile = fromname.output
+ bbpath = get_bb_var('BBPATH')
+ searchpath = bbpath.split(':') + [os.path.dirname(devtool.output)]
+ plugincontent = []
+ with open(srcfile) as fh:
+ plugincontent = fh.readlines()
+ try:
+ self.assertIn('meta-selftest', srcfile, 'wrong bbpath plugin found')
+ for path in searchpath:
+ self._copy_file_with_cleanup(srcfile, path, 'lib', 'devtool')
+ result = runCmd("devtool --quiet count")
+ self.assertEqual(result.output, '1')
+ result = runCmd("devtool --quiet multiloaded")
+ self.assertEqual(result.output, "no")
+ for path in searchpath:
+ result = runCmd("devtool --quiet bbdir")
+ self.assertEqual(result.output, path)
+ os.unlink(os.path.join(result.output, 'lib', 'devtool', 'bbpath.py'))
+ finally:
+ with open(srcfile, 'w') as fh:
+ fh.writelines(plugincontent)
+
def _setup_test_devtool_finish_upgrade(self):
# Check preconditions
self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
@@ -1362,3 +1548,149 @@ class DevtoolTests(DevtoolBase):
files.remove(foundpatch)
if files:
self.fail('Unexpected file(s) copied next to bbappend: %s' % ', '.join(files))
+
+ def test_devtool_rename(self):
+ # Check preconditions
+ self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
+ self.track_for_cleanup(self.workspacedir)
+ self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
+
+ # First run devtool add
+ # We already have this recipe in OE-Core, but that doesn't matter
+ recipename = 'i2c-tools'
+ recipever = '3.1.2'
+ recipefile = os.path.join(self.workspacedir, 'recipes', recipename, '%s_%s.bb' % (recipename, recipever))
+ url = 'http://downloads.yoctoproject.org/mirror/sources/i2c-tools-%s.tar.bz2' % recipever
+ def add_recipe():
+ result = runCmd('devtool add %s' % url)
+ self.assertTrue(os.path.exists(recipefile), 'Expected recipe file not created')
+ self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'sources', recipename)), 'Source directory not created')
+ checkvars = {}
+ checkvars['S'] = None
+ checkvars['SRC_URI'] = url.replace(recipever, '${PV}')
+ self._test_recipe_contents(recipefile, checkvars, [])
+ add_recipe()
+ # Now rename it - change both name and version
+ newrecipename = 'mynewrecipe'
+ newrecipever = '456'
+ newrecipefile = os.path.join(self.workspacedir, 'recipes', newrecipename, '%s_%s.bb' % (newrecipename, newrecipever))
+ result = runCmd('devtool rename %s %s -V %s' % (recipename, newrecipename, newrecipever))
+ self.assertTrue(os.path.exists(newrecipefile), 'Recipe file not renamed')
+ self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipename)), 'Old recipe directory still exists')
+ newsrctree = os.path.join(self.workspacedir, 'sources', newrecipename)
+ self.assertTrue(os.path.exists(newsrctree), 'Source directory not renamed')
+ checkvars = {}
+ checkvars['S'] = '${WORKDIR}/%s-%s' % (recipename, recipever)
+ checkvars['SRC_URI'] = url
+ self._test_recipe_contents(newrecipefile, checkvars, [])
+ # Try again - change just name this time
+ result = runCmd('devtool reset -n %s' % newrecipename)
+ shutil.rmtree(newsrctree)
+ add_recipe()
+ newrecipefile = os.path.join(self.workspacedir, 'recipes', newrecipename, '%s_%s.bb' % (newrecipename, recipever))
+ result = runCmd('devtool rename %s %s' % (recipename, newrecipename))
+ self.assertTrue(os.path.exists(newrecipefile), 'Recipe file not renamed')
+ self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipename)), 'Old recipe directory still exists')
+ self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'sources', newrecipename)), 'Source directory not renamed')
+ checkvars = {}
+ checkvars['S'] = '${WORKDIR}/%s-${PV}' % recipename
+ checkvars['SRC_URI'] = url.replace(recipever, '${PV}')
+ self._test_recipe_contents(newrecipefile, checkvars, [])
+ # Try again - change just version this time
+ result = runCmd('devtool reset -n %s' % newrecipename)
+ shutil.rmtree(newsrctree)
+ add_recipe()
+ newrecipefile = os.path.join(self.workspacedir, 'recipes', recipename, '%s_%s.bb' % (recipename, newrecipever))
+ result = runCmd('devtool rename %s -V %s' % (recipename, newrecipever))
+ self.assertTrue(os.path.exists(newrecipefile), 'Recipe file not renamed')
+ self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'sources', recipename)), 'Source directory no longer exists')
+ checkvars = {}
+ checkvars['S'] = '${WORKDIR}/${BPN}-%s' % recipever
+ checkvars['SRC_URI'] = url
+ self._test_recipe_contents(newrecipefile, checkvars, [])
+
+ @testcase(1577)
+ def test_devtool_virtual_kernel_modify(self):
+ """
+ Summary: The purpose of this test case is to verify that
+ devtool modify works correctly when building
+ the kernel.
+ Dependencies: NA
+ Steps: 1. Build kernel with bitbake.
+ 2. Save the config file generated.
+ 3. Clean the environment.
+ 4. Use `devtool modify virtual/kernel` to validate following:
+ 4.1 The source is checked out correctly.
+ 4.2 The resulting configuration is the same as
+ what was get on step 2.
+ 4.3 The Kernel can be build correctly.
+ 4.4 Changes made on the source are reflected on the
+ subsequent builds.
+ 4.5 Changes on the configuration are reflected on the
+ subsequent builds
+ Expected: devtool modify is able to checkout the source of the kernel
+ and modification to the source and configurations are reflected
+ when building the kernel.
+ """
+ #Set machine to qemxu86 to be able to modify the kernel and
+ #verify the modification.
+ features = 'MACHINE = "qemux86"\n'
+ self.write_config(features)
+ kernel_provider = get_bb_var('PREFERRED_PROVIDER_virtual/kernel')
+ # Clean up the enviroment
+ bitbake('%s -c clean' % kernel_provider)
+ tempdir = tempfile.mkdtemp(prefix='devtoolqa')
+ self.track_for_cleanup(tempdir)
+ self.track_for_cleanup(self.workspacedir)
+ self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
+ self.add_command_to_tearDown('bitbake -c clean %s' % kernel_provider)
+ #Step 1
+ #Here is just generated the config file instead of all the kernel to optimize the
+ #time of executing this test case.
+ bitbake('%s -c configure' % kernel_provider)
+ bbconfig = os.path.join(get_bb_var('B', kernel_provider),'.config')
+ buildir= get_bb_var('TOPDIR')
+ #Step 2
+ runCmd('cp %s %s' % (bbconfig, buildir))
+ self.assertTrue(os.path.exists(os.path.join(buildir, '.config')),
+ 'Could not copy .config file from kernel')
+
+ tmpconfig = os.path.join(buildir, '.config')
+ #Step 3
+ bitbake('%s -c clean' % kernel_provider)
+ #Step 4.1
+ runCmd('devtool modify virtual/kernel -x %s' % tempdir)
+ self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')),
+ 'Extracted source could not be found')
+ #Step 4.2
+ configfile = os.path.join(tempdir,'.config')
+ diff = runCmd('diff %s %s' % (tmpconfig, configfile))
+ self.assertEqual(0,diff.status,'Kernel .config file is not the same using bitbake and devtool')
+ #Step 4.3
+ #NOTE: virtual/kernel is mapped to kernel_provider
+ result = runCmd('devtool build %s' % kernel_provider)
+ self.assertEqual(0,result.status,'Cannot build kernel using `devtool build`')
+ kernelfile = os.path.join(get_bb_var('KBUILD_OUTPUT', kernel_provider), 'vmlinux')
+ self.assertTrue(os.path.exists(kernelfile),'Kernel was not build correctly')
+
+ #Modify the kernel source, this is specific for qemux86
+ modfile = os.path.join(tempdir,'arch/x86/boot/header.S')
+ modstring = "use a boot loader - Devtool kernel testing"
+ modapplied = runCmd("sed -i 's/boot loader/%s/' %s" % (modstring, modfile))
+ self.assertEqual(0,modapplied.status,'Modification to %s on kernel source failed' % modfile)
+ #Modify the configuration
+ codeconfigfile = os.path.join(tempdir,'.config.new')
+ modconfopt = "CONFIG_SG_POOL=n"
+ modconf = runCmd("sed -i 's/CONFIG_SG_POOL=y/%s/' %s" % (modconfopt, codeconfigfile))
+ self.assertEqual(0,modconf.status,'Modification to %s failed' % codeconfigfile)
+ #Build again kernel with devtool
+ rebuild = runCmd('devtool build %s' % kernel_provider)
+ self.assertEqual(0,rebuild.status,'Fail to build kernel after modification of source and config')
+ #Step 4.4
+ bzimagename = 'bzImage-' + get_bb_var('KERNEL_VERSION_NAME', kernel_provider)
+ bzimagefile = os.path.join(get_bb_var('D', kernel_provider),'boot', bzimagename)
+ checkmodcode = runCmd("grep '%s' %s" % (modstring, bzimagefile))
+ self.assertEqual(0,checkmodcode.status,'Modification on kernel source failed')
+ #Step 4.5
+ checkmodconfg = runCmd("grep %s %s" % (modconfopt, codeconfigfile))
+ self.assertEqual(0,checkmodconfg.status,'Modification to configuration file failed')
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/eSDK.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/eSDK.py
index 9d5c68094..1596c6e9d 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/eSDK.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/eSDK.py
@@ -6,16 +6,15 @@ import glob
import logging
import subprocess
import oeqa.utils.ftools as ftools
-from oeqa.utils.decorators import testcase
+from oeqa.utils.decorators import testcase
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var
-from oeqa.utils.httpserver import HTTPService
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
class oeSDKExtSelfTest(oeSelfTest):
"""
# Bugzilla Test Plan: 6033
# This code is planned to be part of the automation for eSDK containig
- # Install libraries and headers, image generation binary feeds.
+ # Install libraries and headers, image generation binary feeds, sdk-update.
"""
@staticmethod
@@ -24,7 +23,7 @@ class oeSDKExtSelfTest(oeSelfTest):
# what environment load oe-selftest, i586, x86_64
pattern = os.path.join(tmpdir_eSDKQA, 'environment-setup-*')
return glob.glob(pattern)[0]
-
+
@staticmethod
def run_esdk_cmd(env_eSDK, tmpdir_eSDKQA, cmd, postconfig=None, **options):
if postconfig:
@@ -47,53 +46,66 @@ class oeSDKExtSelfTest(oeSelfTest):
def get_eSDK_toolchain(image):
pn_task = '%s -c populate_sdk_ext' % image
- sdk_deploy = get_bb_var('SDK_DEPLOY', pn_task)
- toolchain_name = get_bb_var('TOOLCHAINEXT_OUTPUTNAME', pn_task)
+ bb_vars = get_bb_vars(['SDK_DEPLOY', 'TOOLCHAINEXT_OUTPUTNAME'], pn_task)
+ sdk_deploy = bb_vars['SDK_DEPLOY']
+ toolchain_name = bb_vars['TOOLCHAINEXT_OUTPUTNAME']
return os.path.join(sdk_deploy, toolchain_name + '.sh')
-
- @classmethod
- def setUpClass(cls):
- # Start to serve sstate dir
+ @staticmethod
+ def update_configuration(cls, image, tmpdir_eSDKQA, env_eSDK, ext_sdk_path):
sstate_dir = os.path.join(os.environ['BUILDDIR'], 'sstate-cache')
- cls.http_service = HTTPService(sstate_dir)
- cls.http_service.start()
- http_url = "127.0.0.1:%d" % cls.http_service.port
-
- image = 'core-image-minimal'
+ oeSDKExtSelfTest.generate_eSDK(cls.image)
+ cls.ext_sdk_path = oeSDKExtSelfTest.get_eSDK_toolchain(cls.image)
+ runCmd("%s -y -d \"%s\"" % (cls.ext_sdk_path, cls.tmpdir_eSDKQA))
+
+ cls.env_eSDK = oeSDKExtSelfTest.get_esdk_environment('', cls.tmpdir_eSDKQA)
+
+ sstate_config="""
+SDK_LOCAL_CONF_WHITELIST = "SSTATE_MIRRORS"
+SSTATE_MIRRORS = "file://.* file://%s/PATH"
+CORE_IMAGE_EXTRA_INSTALL = "perl"
+ """ % sstate_dir
+
+ with open(os.path.join(cls.tmpdir_eSDKQA, 'conf', 'local.conf'), 'a+') as f:
+ f.write(sstate_config)
+
+ @classmethod
+ def setUpClass(cls):
cls.tmpdir_eSDKQA = tempfile.mkdtemp(prefix='eSDKQA')
- oeSDKExtSelfTest.generate_eSDK(image)
+
+ sstate_dir = get_bb_var('SSTATE_DIR')
+
+ cls.image = 'core-image-minimal'
+ oeSDKExtSelfTest.generate_eSDK(cls.image)
# Install eSDK
- ext_sdk_path = oeSDKExtSelfTest.get_eSDK_toolchain(image)
- runCmd("%s -y -d \"%s\"" % (ext_sdk_path, cls.tmpdir_eSDKQA))
+ cls.ext_sdk_path = oeSDKExtSelfTest.get_eSDK_toolchain(cls.image)
+ runCmd("%s -y -d \"%s\"" % (cls.ext_sdk_path, cls.tmpdir_eSDKQA))
cls.env_eSDK = oeSDKExtSelfTest.get_esdk_environment('', cls.tmpdir_eSDKQA)
# Configure eSDK to use sstate mirror from poky
sstate_config="""
SDK_LOCAL_CONF_WHITELIST = "SSTATE_MIRRORS"
-SSTATE_MIRRORS = "file://.* http://%s/PATH"
- """ % http_url
+SSTATE_MIRRORS = "file://.* file://%s/PATH"
+ """ % sstate_dir
with open(os.path.join(cls.tmpdir_eSDKQA, 'conf', 'local.conf'), 'a+') as f:
f.write(sstate_config)
-
@classmethod
def tearDownClass(cls):
shutil.rmtree(cls.tmpdir_eSDKQA)
- cls.http_service.stop()
- @testcase (1471)
+ @testcase (1602)
def test_install_libraries_headers(self):
pn_sstate = 'bc'
bitbake(pn_sstate)
cmd = "devtool sdk-install %s " % pn_sstate
oeSDKExtSelfTest.run_esdk_cmd(self.env_eSDK, self.tmpdir_eSDKQA, cmd)
-
- @testcase(1472)
+
+ @testcase(1603)
def test_image_generation_binary_feeds(self):
image = 'core-image-minimal'
cmd = "devtool build-image %s" % image
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/image_typedep.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/image_typedep.py
new file mode 100644
index 000000000..256142d25
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/image_typedep.py
@@ -0,0 +1,51 @@
+import os
+
+from oeqa.selftest.base import oeSelfTest
+from oeqa.utils.commands import bitbake
+
+class ImageTypeDepTests(oeSelfTest):
+
+ # Verify that when specifying a IMAGE_TYPEDEP_ of the form "foo.bar" that
+ # the conversion type bar gets added as a dep as well
+ def test_conversion_typedep_added(self):
+
+ self.write_recipeinc('emptytest', """
+# Try to empty out the default dependency list
+PACKAGE_INSTALL = ""
+DISTRO_EXTRA_RDEPENDS=""
+
+LICENSE = "MIT"
+IMAGE_FSTYPES = "testfstype"
+
+IMAGE_TYPES_MASKED += "testfstype"
+IMAGE_TYPEDEP_testfstype = "tar.bz2"
+
+inherit image
+
+""")
+ # First get the dependency that should exist for bz2, it will look
+ # like CONVERSION_DEPENDS_bz2="somedep"
+ result = bitbake('-e emptytest')
+
+ for line in result.output.split('\n'):
+ if line.startswith('CONVERSION_DEPENDS_bz2'):
+ dep = line.split('=')[1].strip('"')
+ break
+
+ # Now get the dependency task list and check for the expected task
+ # dependency
+ bitbake('-g emptytest')
+
+ taskdependsfile = os.path.join(self.builddir, 'task-depends.dot')
+ dep = dep + ".do_populate_sysroot"
+ depfound = False
+ expectedline = '"emptytest.do_rootfs" -> "{}"'.format(dep)
+
+ with open(taskdependsfile, "r") as f:
+ for line in f:
+ if line.strip() == expectedline:
+ depfound = True
+ break
+
+ if not depfound:
+ raise AssertionError("\"{}\" not found".format(expectedline))
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/imagefeatures.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/imagefeatures.py
index d015c4908..76896c798 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/imagefeatures.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/imagefeatures.py
@@ -91,9 +91,9 @@ class ImageFeatures(oeSelfTest):
AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
"""
- features = 'DISTRO_FEATURES_append = " wayland"\n'
- features += 'CORE_IMAGE_EXTRA_INSTALL += "wayland weston"'
- self.write_config(features)
+ distro_features = get_bb_var('DISTRO_FEATURES')
+ if not ('opengl' in distro_features and 'wayland' in distro_features):
+ self.skipTest('neither opengl nor wayland present on DISTRO_FEATURES so core-image-weston cannot be built')
# Build a core-image-weston
bitbake('core-image-weston')
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/layerappend.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/layerappend.py
index 4de5034a9..37bb32cd1 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/layerappend.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/layerappend.py
@@ -55,7 +55,7 @@ SRC_URI_append += "file://appendtest.txt"
@testcase(1196)
def test_layer_appends(self):
corebase = get_bb_var("COREBASE")
- stagingdir = get_bb_var("STAGING_DIR_TARGET")
+
for l in ["0", "1", "2"]:
layer = os.path.join(corebase, "meta-layertest" + l)
self.assertFalse(os.path.exists(layer))
@@ -83,6 +83,7 @@ SRC_URI_append += "file://appendtest.txt"
self.layerappend = "BBLAYERS += \"{0}/meta-layertest0 {0}/meta-layertest1 {0}/meta-layertest2\"".format(corebase)
ftools.append_file(self.builddir + "/conf/bblayers.conf", self.layerappend)
+ stagingdir = get_bb_var("SYSROOT_DESTDIR", "layerappendtest")
bitbake("layerappendtest")
data = ftools.read_file(stagingdir + "/appendtest.txt")
self.assertEqual(data, "Layer 2 test")
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/liboe.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/liboe.py
index 35131eb24..0b0301def 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/liboe.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/liboe.py
@@ -1,11 +1,16 @@
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import get_bb_var, bitbake, runCmd
+from oeqa.utils.commands import get_bb_var, get_bb_vars, bitbake, runCmd
import oe.path
import glob
import os
import os.path
class LibOE(oeSelfTest):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.tmp_dir = get_bb_var('TMPDIR')
+
def test_copy_tree_special(self):
"""
Summary: oe.path.copytree() should copy files with special character
@@ -14,8 +19,7 @@ class LibOE(oeSelfTest):
Product: OE-Core
Author: Joshua Lock <joshua.g.lock@intel.com>
"""
- tmp_dir = get_bb_var('TMPDIR')
- testloc = oe.path.join(tmp_dir, 'liboetests')
+ testloc = oe.path.join(self.tmp_dir, 'liboetests')
src = oe.path.join(testloc, 'src')
dst = oe.path.join(testloc, 'dst')
bb.utils.mkdirhier(testloc)
@@ -40,8 +44,7 @@ class LibOE(oeSelfTest):
Product: OE-Core
Author: Joshua Lock <joshua.g.lock@intel.com>
"""
- tmp_dir = get_bb_var('TMPDIR')
- testloc = oe.path.join(tmp_dir, 'liboetests')
+ testloc = oe.path.join(self.tmp_dir, 'liboetests')
src = oe.path.join(testloc, 'src')
dst = oe.path.join(testloc, 'dst')
bb.utils.mkdirhier(testloc)
@@ -50,7 +53,11 @@ class LibOE(oeSelfTest):
# ensure we have setfattr available
bitbake("attr-native")
- bindir = get_bb_var('STAGING_BINDIR_NATIVE')
+
+ bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'attr-native')
+ destdir = bb_vars['SYSROOT_DESTDIR']
+ bindir = bb_vars['bindir']
+ bindir = destdir + bindir
# create a file with xattr and copy it
open(oe.path.join(src, testfilename), 'w+b').close()
@@ -70,8 +77,7 @@ class LibOE(oeSelfTest):
Product: OE-Core
Author: Joshua Lock <joshua.g.lock@intel.com>
"""
- tmp_dir = get_bb_var('TMPDIR')
- testloc = oe.path.join(tmp_dir, 'liboetests')
+ testloc = oe.path.join(self.tmp_dir, 'liboetests')
src = oe.path.join(testloc, 'src')
dst = oe.path.join(testloc, 'dst')
bb.utils.mkdirhier(testloc)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/manifest.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/manifest.py
index 44d0404c5..fe6f94964 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/manifest.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/manifest.py
@@ -2,7 +2,7 @@ import unittest
import os
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import get_bb_var, bitbake
+from oeqa.utils.commands import get_bb_var, get_bb_vars, bitbake
from oeqa.utils.decorators import testcase
class ManifestEntry:
@@ -84,9 +84,10 @@ class VerifyManifest(oeSelfTest):
try:
mdir = self.get_dir_from_bb_var('SDK_DEPLOY', self.buildtarget)
for k in d_target.keys():
+ bb_vars = get_bb_vars(['SDK_NAME', 'SDK_VERSION'], self.buildtarget)
mfilename[k] = "{}-toolchain-{}.{}.manifest".format(
- get_bb_var("SDK_NAME", self.buildtarget),
- get_bb_var("SDK_VERSION", self.buildtarget),
+ bb_vars['SDK_NAME'],
+ bb_vars['SDK_VERSION'],
k)
mpath[k] = os.path.join(mdir, mfilename[k])
if not os.path.isfile(mpath[k]):
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/__init__.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/__init__.py
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/buildhistory.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/buildhistory.py
new file mode 100644
index 000000000..5ed4b026f
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/buildhistory.py
@@ -0,0 +1,88 @@
+import os
+import unittest
+import tempfile
+from git import Repo
+from oeqa.utils.commands import get_bb_var
+from oe.buildhistory_analysis import blob_to_dict, compare_dict_blobs
+
+class TestBlobParsing(unittest.TestCase):
+
+ def setUp(self):
+ import time
+ self.repo_path = tempfile.mkdtemp(prefix='selftest-buildhistory',
+ dir=get_bb_var('TOPDIR'))
+
+ self.repo = Repo.init(self.repo_path)
+ self.test_file = "test"
+ self.var_map = {}
+
+ def tearDown(self):
+ import shutil
+ shutil.rmtree(self.repo_path)
+
+ def commit_vars(self, to_add={}, to_remove = [], msg="A commit message"):
+ if len(to_add) == 0 and len(to_remove) == 0:
+ return
+
+ for k in to_remove:
+ self.var_map.pop(x,None)
+ for k in to_add:
+ self.var_map[k] = to_add[k]
+
+ with open(os.path.join(self.repo_path, self.test_file), 'w') as repo_file:
+ for k in self.var_map:
+ repo_file.write("%s = %s\n" % (k, self.var_map[k]))
+
+ self.repo.git.add("--all")
+ self.repo.git.commit(message=msg)
+
+ def test_blob_to_dict(self):
+ """
+ Test convertion of git blobs to dictionary
+ """
+ valuesmap = { "foo" : "1", "bar" : "2" }
+ self.commit_vars(to_add = valuesmap)
+
+ blob = self.repo.head.commit.tree.blobs[0]
+ self.assertEqual(valuesmap, blob_to_dict(blob),
+ "commit was not translated correctly to dictionary")
+
+ def test_compare_dict_blobs(self):
+ """
+ Test comparisson of dictionaries extracted from git blobs
+ """
+ changesmap = { "foo-2" : ("2", "8"), "bar" : ("","4"), "bar-2" : ("","5")}
+
+ self.commit_vars(to_add = { "foo" : "1", "foo-2" : "2", "foo-3" : "3" })
+ blob1 = self.repo.heads.master.commit.tree.blobs[0]
+
+ self.commit_vars(to_add = { "foo-2" : "8", "bar" : "4", "bar-2" : "5" })
+ blob2 = self.repo.heads.master.commit.tree.blobs[0]
+
+ change_records = compare_dict_blobs(os.path.join(self.repo_path, self.test_file),
+ blob1, blob2, False, False)
+
+ var_changes = { x.fieldname : (x.oldvalue, x.newvalue) for x in change_records}
+ self.assertEqual(changesmap, var_changes, "Changes not reported correctly")
+
+ def test_compare_dict_blobs_default(self):
+ """
+ Test default values for comparisson of git blob dictionaries
+ """
+ defaultmap = { x : ("default", "1") for x in ["PKG", "PKGE", "PKGV", "PKGR"]}
+
+ self.commit_vars(to_add = { "foo" : "1" })
+ blob1 = self.repo.heads.master.commit.tree.blobs[0]
+
+ self.commit_vars(to_add = { "PKG" : "1", "PKGE" : "1", "PKGV" : "1", "PKGR" : "1" })
+ blob2 = self.repo.heads.master.commit.tree.blobs[0]
+
+ change_records = compare_dict_blobs(os.path.join(self.repo_path, self.test_file),
+ blob1, blob2, False, False)
+
+ var_changes = {}
+ for x in change_records:
+ oldvalue = "default" if ("default" in x.oldvalue) else x.oldvalue
+ var_changes[x.fieldname] = (oldvalue, x.newvalue)
+
+ self.assertEqual(defaultmap, var_changes, "Defaults not set properly")
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/elf.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/elf.py
new file mode 100644
index 000000000..1f59037ed
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/elf.py
@@ -0,0 +1,21 @@
+import unittest
+import oe.qa
+
+class TestElf(unittest.TestCase):
+ def test_machine_name(self):
+ """
+ Test elf_machine_to_string()
+ """
+ self.assertEqual(oe.qa.elf_machine_to_string(0x02), "SPARC")
+ self.assertEqual(oe.qa.elf_machine_to_string(0x03), "x86")
+ self.assertEqual(oe.qa.elf_machine_to_string(0x08), "MIPS")
+ self.assertEqual(oe.qa.elf_machine_to_string(0x14), "PowerPC")
+ self.assertEqual(oe.qa.elf_machine_to_string(0x28), "ARM")
+ self.assertEqual(oe.qa.elf_machine_to_string(0x2A), "SuperH")
+ self.assertEqual(oe.qa.elf_machine_to_string(0x32), "IA-64")
+ self.assertEqual(oe.qa.elf_machine_to_string(0x3E), "x86-64")
+ self.assertEqual(oe.qa.elf_machine_to_string(0xB7), "AArch64")
+
+ self.assertEqual(oe.qa.elf_machine_to_string(0x00), "Unknown (0)")
+ self.assertEqual(oe.qa.elf_machine_to_string(0xDEADBEEF), "Unknown (3735928559)")
+ self.assertEqual(oe.qa.elf_machine_to_string("foobar"), "Unknown ('foobar')")
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/license.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/license.py
new file mode 100644
index 000000000..c38888618
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/license.py
@@ -0,0 +1,68 @@
+import unittest
+import oe.license
+
+class SeenVisitor(oe.license.LicenseVisitor):
+ def __init__(self):
+ self.seen = []
+ oe.license.LicenseVisitor.__init__(self)
+
+ def visit_Str(self, node):
+ self.seen.append(node.s)
+
+class TestSingleLicense(unittest.TestCase):
+ licenses = [
+ "GPLv2",
+ "LGPL-2.0",
+ "Artistic",
+ "MIT",
+ "GPLv3+",
+ "FOO_BAR",
+ ]
+ invalid_licenses = ["GPL/BSD"]
+
+ @staticmethod
+ def parse(licensestr):
+ visitor = SeenVisitor()
+ visitor.visit_string(licensestr)
+ return visitor.seen
+
+ def test_single_licenses(self):
+ for license in self.licenses:
+ licenses = self.parse(license)
+ self.assertListEqual(licenses, [license])
+
+ def test_invalid_licenses(self):
+ for license in self.invalid_licenses:
+ with self.assertRaises(oe.license.InvalidLicense) as cm:
+ self.parse(license)
+ self.assertEqual(cm.exception.license, license)
+
+class TestSimpleCombinations(unittest.TestCase):
+ tests = {
+ "FOO&BAR": ["FOO", "BAR"],
+ "BAZ & MOO": ["BAZ", "MOO"],
+ "ALPHA|BETA": ["ALPHA"],
+ "BAZ&MOO|FOO": ["FOO"],
+ "FOO&BAR|BAZ": ["FOO", "BAR"],
+ }
+ preferred = ["ALPHA", "FOO", "BAR"]
+
+ def test_tests(self):
+ def choose(a, b):
+ if all(lic in self.preferred for lic in b):
+ return b
+ else:
+ return a
+
+ for license, expected in self.tests.items():
+ licenses = oe.license.flattened_licenses(license, choose)
+ self.assertListEqual(licenses, expected)
+
+class TestComplexCombinations(TestSimpleCombinations):
+ tests = {
+ "FOO & (BAR | BAZ)&MOO": ["FOO", "BAR", "MOO"],
+ "(ALPHA|(BETA&THETA)|OMEGA)&DELTA": ["OMEGA", "DELTA"],
+ "((ALPHA|BETA)&FOO)|BAZ": ["BETA", "FOO"],
+ "(GPL-2.0|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0", "BSD-4-clause", "MIT"],
+ }
+ preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0"]
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/path.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/path.py
new file mode 100644
index 000000000..44d068143
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/path.py
@@ -0,0 +1,89 @@
+import unittest
+import oe, oe.path
+import tempfile
+import os
+import errno
+import shutil
+
+class TestRealPath(unittest.TestCase):
+ DIRS = [ "a", "b", "etc", "sbin", "usr", "usr/bin", "usr/binX", "usr/sbin", "usr/include", "usr/include/gdbm" ]
+ FILES = [ "etc/passwd", "b/file" ]
+ LINKS = [
+ ( "bin", "/usr/bin", "/usr/bin" ),
+ ( "binX", "usr/binX", "/usr/binX" ),
+ ( "c", "broken", "/broken" ),
+ ( "etc/passwd-1", "passwd", "/etc/passwd" ),
+ ( "etc/passwd-2", "passwd-1", "/etc/passwd" ),
+ ( "etc/passwd-3", "/etc/passwd-1", "/etc/passwd" ),
+ ( "etc/shadow-1", "/etc/shadow", "/etc/shadow" ),
+ ( "etc/shadow-2", "/etc/shadow-1", "/etc/shadow" ),
+ ( "prog-A", "bin/prog-A", "/usr/bin/prog-A" ),
+ ( "prog-B", "/bin/prog-B", "/usr/bin/prog-B" ),
+ ( "usr/bin/prog-C", "../../sbin/prog-C", "/sbin/prog-C" ),
+ ( "usr/bin/prog-D", "/sbin/prog-D", "/sbin/prog-D" ),
+ ( "usr/binX/prog-E", "../sbin/prog-E", None ),
+ ( "usr/bin/prog-F", "../../../sbin/prog-F", "/sbin/prog-F" ),
+ ( "loop", "a/loop", None ),
+ ( "a/loop", "../loop", None ),
+ ( "b/test", "file/foo", "/b/file/foo" ),
+ ]
+
+ LINKS_PHYS = [
+ ( "./", "/", "" ),
+ ( "binX/prog-E", "/usr/sbin/prog-E", "/sbin/prog-E" ),
+ ]
+
+ EXCEPTIONS = [
+ ( "loop", errno.ELOOP ),
+ ( "b/test", errno.ENOENT ),
+ ]
+
+ def __del__(self):
+ try:
+ #os.system("tree -F %s" % self.tmpdir)
+ shutil.rmtree(self.tmpdir)
+ except:
+ pass
+
+ def setUp(self):
+ self.tmpdir = tempfile.mkdtemp(prefix = "oe-test_path")
+ self.root = os.path.join(self.tmpdir, "R")
+
+ os.mkdir(os.path.join(self.tmpdir, "_real"))
+ os.symlink("_real", self.root)
+
+ for d in self.DIRS:
+ os.mkdir(os.path.join(self.root, d))
+ for f in self.FILES:
+ open(os.path.join(self.root, f), "w")
+ for l in self.LINKS:
+ os.symlink(l[1], os.path.join(self.root, l[0]))
+
+ def __realpath(self, file, use_physdir, assume_dir = True):
+ return oe.path.realpath(os.path.join(self.root, file), self.root,
+ use_physdir, assume_dir = assume_dir)
+
+ def test_norm(self):
+ for l in self.LINKS:
+ if l[2] == None:
+ continue
+
+ target_p = self.__realpath(l[0], True)
+ target_l = self.__realpath(l[0], False)
+
+ if l[2] != False:
+ self.assertEqual(target_p, target_l)
+ self.assertEqual(l[2], target_p[len(self.root):])
+
+ def test_phys(self):
+ for l in self.LINKS_PHYS:
+ target_p = self.__realpath(l[0], True)
+ target_l = self.__realpath(l[0], False)
+
+ self.assertEqual(l[1], target_p[len(self.root):])
+ self.assertEqual(l[2], target_l[len(self.root):])
+
+ def test_loop(self):
+ for e in self.EXCEPTIONS:
+ self.assertRaisesRegex(OSError, r'\[Errno %u\]' % e[1],
+ self.__realpath, e[0], False, False)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/types.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/types.py
new file mode 100644
index 000000000..4fe2746a3
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/types.py
@@ -0,0 +1,50 @@
+import unittest
+from oe.maketype import create
+
+class TestBooleanType(unittest.TestCase):
+ def test_invalid(self):
+ self.assertRaises(ValueError, create, '', 'boolean')
+ self.assertRaises(ValueError, create, 'foo', 'boolean')
+ self.assertRaises(TypeError, create, object(), 'boolean')
+
+ def test_true(self):
+ self.assertTrue(create('y', 'boolean'))
+ self.assertTrue(create('yes', 'boolean'))
+ self.assertTrue(create('1', 'boolean'))
+ self.assertTrue(create('t', 'boolean'))
+ self.assertTrue(create('true', 'boolean'))
+ self.assertTrue(create('TRUE', 'boolean'))
+ self.assertTrue(create('truE', 'boolean'))
+
+ def test_false(self):
+ self.assertFalse(create('n', 'boolean'))
+ self.assertFalse(create('no', 'boolean'))
+ self.assertFalse(create('0', 'boolean'))
+ self.assertFalse(create('f', 'boolean'))
+ self.assertFalse(create('false', 'boolean'))
+ self.assertFalse(create('FALSE', 'boolean'))
+ self.assertFalse(create('faLse', 'boolean'))
+
+ def test_bool_equality(self):
+ self.assertEqual(create('n', 'boolean'), False)
+ self.assertNotEqual(create('n', 'boolean'), True)
+ self.assertEqual(create('y', 'boolean'), True)
+ self.assertNotEqual(create('y', 'boolean'), False)
+
+class TestList(unittest.TestCase):
+ def assertListEqual(self, value, valid, sep=None):
+ obj = create(value, 'list', separator=sep)
+ self.assertEqual(obj, valid)
+ if sep is not None:
+ self.assertEqual(obj.separator, sep)
+ self.assertEqual(str(obj), obj.separator.join(obj))
+
+ def test_list_nosep(self):
+ testlist = ['alpha', 'beta', 'theta']
+ self.assertListEqual('alpha beta theta', testlist)
+ self.assertListEqual('alpha beta\ttheta', testlist)
+ self.assertListEqual('alpha', ['alpha'])
+
+ def test_list_usersep(self):
+ self.assertListEqual('foo:bar', ['foo', 'bar'], ':')
+ self.assertListEqual('foo:bar:baz', ['foo', 'bar', 'baz'], ':')
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/utils.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/utils.py
new file mode 100644
index 000000000..7deb10f3c
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oelib/utils.py
@@ -0,0 +1,51 @@
+import unittest
+from oe.utils import packages_filter_out_system, trim_version
+
+class TestPackagesFilterOutSystem(unittest.TestCase):
+ def test_filter(self):
+ """
+ Test that oe.utils.packages_filter_out_system works.
+ """
+ try:
+ import bb
+ except ImportError:
+ self.skipTest("Cannot import bb")
+
+ d = bb.data_smart.DataSmart()
+ d.setVar("PN", "foo")
+
+ d.setVar("PACKAGES", "foo foo-doc foo-dev")
+ pkgs = packages_filter_out_system(d)
+ self.assertEqual(pkgs, [])
+
+ d.setVar("PACKAGES", "foo foo-doc foo-data foo-dev")
+ pkgs = packages_filter_out_system(d)
+ self.assertEqual(pkgs, ["foo-data"])
+
+ d.setVar("PACKAGES", "foo foo-locale-en-gb")
+ pkgs = packages_filter_out_system(d)
+ self.assertEqual(pkgs, [])
+
+ d.setVar("PACKAGES", "foo foo-data foo-locale-en-gb")
+ pkgs = packages_filter_out_system(d)
+ self.assertEqual(pkgs, ["foo-data"])
+
+
+class TestTrimVersion(unittest.TestCase):
+ def test_version_exception(self):
+ with self.assertRaises(TypeError):
+ trim_version(None, 2)
+ with self.assertRaises(TypeError):
+ trim_version((1, 2, 3), 2)
+
+ def test_num_exception(self):
+ with self.assertRaises(ValueError):
+ trim_version("1.2.3", 0)
+ with self.assertRaises(ValueError):
+ trim_version("1.2.3", -1)
+
+ def test_valid(self):
+ self.assertEqual(trim_version("1.2.3", 1), "1")
+ self.assertEqual(trim_version("1.2.3", 2), "1.2")
+ self.assertEqual(trim_version("1.2.3", 3), "1.2.3")
+ self.assertEqual(trim_version("1.2.3", 4), "1.2.3")
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py
index 28345dc6a..29547f56a 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py
@@ -10,38 +10,10 @@ from oeqa.selftest.buildhistory import BuildhistoryBase
from oeqa.utils.commands import Command, runCmd, bitbake, get_bb_var, get_test_layer
from oeqa.utils.decorators import testcase
-class TestScripts(oeSelfTest):
-
- @testcase(300)
- def test_cleanup_workdir(self):
- path = os.path.dirname(get_bb_var('WORKDIR', 'gzip'))
- old_version_recipe = os.path.join(get_bb_var('COREBASE'), 'meta/recipes-extended/gzip/gzip_1.3.12.bb')
- old_version = '1.3.12'
- bitbake("-c clean gzip")
- bitbake("-c clean -b %s" % old_version_recipe)
-
- if os.path.exists(path):
- initial_contents = os.listdir(path)
- else:
- initial_contents = []
-
- bitbake('gzip')
- intermediary_contents = os.listdir(path)
- bitbake("-b %s" % old_version_recipe)
- runCmd('cleanup-workdir')
- remaining_contents = os.listdir(path)
-
- expected_contents = [x for x in intermediary_contents if x not in initial_contents]
- remaining_not_expected = [x for x in remaining_contents if x not in expected_contents]
- self.assertFalse(remaining_not_expected, msg="Not all necessary content has been deleted from %s: %s" % (path, ', '.join(map(str, remaining_not_expected))))
- expected_not_remaining = [x for x in expected_contents if x not in remaining_contents]
- self.assertFalse(expected_not_remaining, msg="The script removed extra contents from %s: %s" % (path, ', '.join(map(str, expected_not_remaining))))
-
class BuildhistoryDiffTests(BuildhistoryBase):
@testcase(295)
def test_buildhistory_diff(self):
- self.add_command_to_tearDown('cleanup-workdir')
target = 'xcursor-transparent-theme'
self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True)
self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/pkgdata.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/pkgdata.py
index 5a63f89ff..d69c3c800 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/pkgdata.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/pkgdata.py
@@ -6,7 +6,7 @@ import fnmatch
import oeqa.utils.ftools as ftools
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
from oeqa.utils.decorators import testcase
class OePkgdataUtilTests(oeSelfTest):
@@ -16,21 +16,21 @@ class OePkgdataUtilTests(oeSelfTest):
# Ensure we have the right data in pkgdata
logger = logging.getLogger("selftest")
logger.info('Running bitbake to generate pkgdata')
- bitbake('glibc busybox zlib bash')
+ bitbake('busybox zlib m4')
@testcase(1203)
def test_lookup_pkg(self):
# Forward tests
- result = runCmd('oe-pkgdata-util lookup-pkg "glibc busybox"')
- self.assertEqual(result.output, 'libc6\nbusybox')
+ result = runCmd('oe-pkgdata-util lookup-pkg "zlib busybox"')
+ self.assertEqual(result.output, 'libz1\nbusybox')
result = runCmd('oe-pkgdata-util lookup-pkg zlib-dev')
self.assertEqual(result.output, 'libz-dev')
result = runCmd('oe-pkgdata-util lookup-pkg nonexistentpkg', ignore_status=True)
self.assertEqual(result.status, 1, "Status different than 1. output: %s" % result.output)
self.assertEqual(result.output, 'ERROR: The following packages could not be found: nonexistentpkg')
# Reverse tests
- result = runCmd('oe-pkgdata-util lookup-pkg -r "libc6 busybox"')
- self.assertEqual(result.output, 'glibc\nbusybox')
+ result = runCmd('oe-pkgdata-util lookup-pkg -r "libz1 busybox"')
+ self.assertEqual(result.output, 'zlib\nbusybox')
result = runCmd('oe-pkgdata-util lookup-pkg -r libz-dev')
self.assertEqual(result.output, 'zlib-dev')
result = runCmd('oe-pkgdata-util lookup-pkg -r nonexistentpkg', ignore_status=True)
@@ -41,24 +41,26 @@ class OePkgdataUtilTests(oeSelfTest):
def test_read_value(self):
result = runCmd('oe-pkgdata-util read-value PN libz1')
self.assertEqual(result.output, 'zlib')
- result = runCmd('oe-pkgdata-util read-value PKGSIZE bash')
+ result = runCmd('oe-pkgdata-util read-value PKG libz1')
+ self.assertEqual(result.output, 'libz1')
+ result = runCmd('oe-pkgdata-util read-value PKGSIZE m4')
pkgsize = int(result.output.strip())
self.assertGreater(pkgsize, 1, "Size should be greater than 1. %s" % result.output)
@testcase(1198)
def test_find_path(self):
- result = runCmd('oe-pkgdata-util find-path /lib/libc.so.6')
- self.assertEqual(result.output, 'glibc: /lib/libc.so.6')
- result = runCmd('oe-pkgdata-util find-path /bin/bash')
- self.assertEqual(result.output, 'bash: /bin/bash')
+ result = runCmd('oe-pkgdata-util find-path /lib/libz.so.1')
+ self.assertEqual(result.output, 'zlib: /lib/libz.so.1')
+ result = runCmd('oe-pkgdata-util find-path /usr/bin/m4')
+ self.assertEqual(result.output, 'm4: /usr/bin/m4')
result = runCmd('oe-pkgdata-util find-path /not/exist', ignore_status=True)
self.assertEqual(result.status, 1, "Status different than 1. output: %s" % result.output)
self.assertEqual(result.output, 'ERROR: Unable to find any package producing path /not/exist')
@testcase(1204)
def test_lookup_recipe(self):
- result = runCmd('oe-pkgdata-util lookup-recipe "libc6-staticdev busybox"')
- self.assertEqual(result.output, 'glibc\nbusybox')
+ result = runCmd('oe-pkgdata-util lookup-recipe "libz-staticdev busybox"')
+ self.assertEqual(result.output, 'zlib\nbusybox')
result = runCmd('oe-pkgdata-util lookup-recipe libz-dbg')
self.assertEqual(result.output, 'zlib')
result = runCmd('oe-pkgdata-util lookup-recipe nonexistentpkg', ignore_status=True)
@@ -70,12 +72,11 @@ class OePkgdataUtilTests(oeSelfTest):
# No arguments
result = runCmd('oe-pkgdata-util list-pkgs')
pkglist = result.output.split()
- self.assertIn('glibc-utils', pkglist, "Listed packages: %s" % result.output)
+ self.assertIn('zlib', pkglist, "Listed packages: %s" % result.output)
self.assertIn('zlib-dev', pkglist, "Listed packages: %s" % result.output)
# No pkgspec, runtime
result = runCmd('oe-pkgdata-util list-pkgs -r')
pkglist = result.output.split()
- self.assertIn('libc6-utils', pkglist, "Listed packages: %s" % result.output)
self.assertIn('libz-dev', pkglist, "Listed packages: %s" % result.output)
# With recipe specified
result = runCmd('oe-pkgdata-util list-pkgs -p zlib')
@@ -124,10 +125,11 @@ class OePkgdataUtilTests(oeSelfTest):
curpkg = line.split(':')[0]
files[curpkg] = []
return files
- base_libdir = get_bb_var('base_libdir')
- libdir = get_bb_var('libdir')
- includedir = get_bb_var('includedir')
- mandir = get_bb_var('mandir')
+ bb_vars = get_bb_vars(['base_libdir', 'libdir', 'includedir', 'mandir'])
+ base_libdir = bb_vars['base_libdir']
+ libdir = bb_vars['libdir']
+ includedir = bb_vars['includedir']
+ mandir = bb_vars['mandir']
# Test recipe-space package name
result = runCmd('oe-pkgdata-util list-pkg-files zlib-dev zlib-doc')
files = splitoutput(result.output)
@@ -205,11 +207,10 @@ class OePkgdataUtilTests(oeSelfTest):
self.track_for_cleanup(tempdir)
pkglistfile = os.path.join(tempdir, 'pkglist')
with open(pkglistfile, 'w') as f:
- f.write('libc6\n')
f.write('libz1\n')
f.write('busybox\n')
result = runCmd('oe-pkgdata-util glob %s "*-dev"' % pkglistfile)
- desiredresult = ['libc6-dev', 'libz-dev', 'busybox-dev']
+ desiredresult = ['libz-dev', 'busybox-dev']
self.assertEqual(sorted(result.output.split()), sorted(desiredresult))
# The following should not error (because when we use this during rootfs construction, sometimes the complementary package won't exist)
result = runCmd('oe-pkgdata-util glob %s "*-nonexistent"' % pkglistfile)
@@ -222,5 +223,5 @@ class OePkgdataUtilTests(oeSelfTest):
@testcase(1206)
def test_specify_pkgdatadir(self):
- result = runCmd('oe-pkgdata-util -p %s lookup-pkg glibc' % get_bb_var('PKGDATA_DIR'))
- self.assertEqual(result.output, 'libc6')
+ result = runCmd('oe-pkgdata-util -p %s lookup-pkg zlib' % get_bb_var('PKGDATA_DIR'))
+ self.assertEqual(result.output, 'libz1')
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py
index 0b2dfe649..34d419762 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py
@@ -12,10 +12,13 @@ from oeqa.utils.decorators import testcase
from oeqa.utils.network import get_free_port
class BitbakePrTests(oeSelfTest):
-
+
+ @classmethod
+ def setUpClass(cls):
+ cls.pkgdata_dir = get_bb_var('PKGDATA_DIR')
+
def get_pr_version(self, package_name):
- pkgdata_dir = get_bb_var('PKGDATA_DIR')
- package_data_file = os.path.join(pkgdata_dir, 'runtime', package_name)
+ package_data_file = os.path.join(self.pkgdata_dir, 'runtime', package_name)
package_data = ftools.read_file(package_data_file)
find_pr = re.search("PKGR: r[0-9]+\.([0-9]+)", package_data)
self.assertTrue(find_pr, "No PKG revision found in %s" % package_data_file)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py
index 9b669248f..dc55a5e49 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py
@@ -1,9 +1,11 @@
import os
import logging
+import shutil
import tempfile
import urllib.parse
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var
+from oeqa.utils.commands import get_bb_vars, create_temp_layer
from oeqa.utils.decorators import testcase
from oeqa.selftest import devtool
@@ -24,6 +26,7 @@ def tearDownModule():
class RecipetoolBase(devtool.DevtoolBase):
+
def setUpLocal(self):
self.templayerdir = templayerdir
self.tempdir = tempfile.mkdtemp(prefix='recipetoolqa')
@@ -64,12 +67,16 @@ class RecipetoolBase(devtool.DevtoolBase):
class RecipetoolTests(RecipetoolBase):
+
@classmethod
def setUpClass(cls):
# Ensure we have the right data in shlibs/pkgdata
logger = logging.getLogger("selftest")
logger.info('Running bitbake to generate pkgdata')
bitbake('-c packagedata base-files coreutils busybox selftest-recipetool-appendfile')
+ bb_vars = get_bb_vars(['COREBASE', 'BBPATH'])
+ cls.corebase = bb_vars['COREBASE']
+ cls.bbpath = bb_vars['BBPATH']
def _try_recipetool_appendfile(self, testrecipe, destfile, newfile, options, expectedlines, expectedfiles):
cmd = 'recipetool appendfile %s %s %s %s' % (self.templayerdir, destfile, newfile, options)
@@ -103,9 +110,8 @@ class RecipetoolTests(RecipetoolBase):
# Now try with a file we know should be an alternative
# (this is very much a fake example, but one we know is reliably an alternative)
self._try_recipetool_appendfile_fail('/bin/ls', self.testfile, ['ERROR: File /bin/ls is an alternative possibly provided by the following recipes:', 'coreutils', 'busybox'])
- corebase = get_bb_var('COREBASE')
# Need a test file - should be executable
- testfile2 = os.path.join(corebase, 'oe-init-build-env')
+ testfile2 = os.path.join(self.corebase, 'oe-init-build-env')
testfile2name = os.path.basename(testfile2)
expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
'\n',
@@ -134,7 +140,6 @@ class RecipetoolTests(RecipetoolBase):
@testcase(1173)
def test_recipetool_appendfile_add(self):
- corebase = get_bb_var('COREBASE')
# Try arbitrary file add to a recipe
expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
'\n',
@@ -147,7 +152,7 @@ class RecipetoolTests(RecipetoolBase):
self._try_recipetool_appendfile('netbase', '/usr/share/something', self.testfile, '-r netbase', expectedlines, ['testfile'])
# Try adding another file, this time where the source file is executable
# (so we're testing that, plus modifying an existing bbappend)
- testfile2 = os.path.join(corebase, 'oe-init-build-env')
+ testfile2 = os.path.join(self.corebase, 'oe-init-build-env')
testfile2name = os.path.basename(testfile2)
expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
'\n',
@@ -363,20 +368,22 @@ class RecipetoolTests(RecipetoolBase):
# Try adding a recipe
tempsrc = os.path.join(self.tempdir, 'srctree')
os.makedirs(tempsrc)
- recipefile = os.path.join(self.tempdir, 'logrotate_3.8.7.bb')
- srcuri = 'https://github.com/logrotate/logrotate/archive/r3-8-7.tar.gz'
+ recipefile = os.path.join(self.tempdir, 'logrotate_3.12.3.bb')
+ srcuri = 'https://github.com/logrotate/logrotate/releases/download/3.12.3/logrotate-3.12.3.tar.xz'
result = runCmd('recipetool create -o %s %s -x %s' % (recipefile, srcuri, tempsrc))
self.assertTrue(os.path.isfile(recipefile))
checkvars = {}
checkvars['LICENSE'] = 'GPLv2'
- checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=18810669f13b87348459e611d31ab760'
- checkvars['SRC_URI'] = 'https://github.com/logrotate/logrotate/archive/r3-8-7.tar.gz'
- checkvars['SRC_URI[md5sum]'] = '6b1aa0e0d07eda3c9a2526520850397a'
- checkvars['SRC_URI[sha256sum]'] = 'dece4bfeb9d8374a0ecafa34be139b5a697db5c926dcc69a9b8715431a22e733'
+ checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'
+ checkvars['SRC_URI'] = 'https://github.com/logrotate/logrotate/releases/download/${PV}/logrotate-${PV}.tar.xz'
+ checkvars['SRC_URI[md5sum]'] = 'a560c57fac87c45b2fc17406cdf79288'
+ checkvars['SRC_URI[sha256sum]'] = '2e6a401cac9024db2288297e3be1a8ab60e7401ba8e91225218aaf4a27e82a07'
self._test_recipe_contents(recipefile, checkvars, [])
@testcase(1194)
def test_recipetool_create_git(self):
+ if 'x11' not in get_bb_var('DISTRO_FEATURES'):
+ self.skipTest('Test requires x11 as distro feature')
# Ensure we have the right data in shlibs/pkgdata
bitbake('libpng pango libx11 libxext jpeg libcheck')
# Try adding a recipe
@@ -480,6 +487,46 @@ class RecipetoolTests(RecipetoolBase):
inherits = ['pkgconfig', 'autotools']
self._test_recipe_contents(recipefile, checkvars, inherits)
+ def _copy_file_with_cleanup(self, srcfile, basedstdir, *paths):
+ dstdir = basedstdir
+ self.assertTrue(os.path.exists(dstdir))
+ for p in paths:
+ dstdir = os.path.join(dstdir, p)
+ if not os.path.exists(dstdir):
+ os.makedirs(dstdir)
+ self.track_for_cleanup(dstdir)
+ dstfile = os.path.join(dstdir, os.path.basename(srcfile))
+ if srcfile != dstfile:
+ shutil.copy(srcfile, dstfile)
+ self.track_for_cleanup(dstfile)
+
+ def test_recipetool_load_plugin(self):
+ """Test that recipetool loads only the first found plugin in BBPATH."""
+
+ recipetool = runCmd("which recipetool")
+ fromname = runCmd("recipetool --quiet pluginfile")
+ srcfile = fromname.output
+ searchpath = self.bbpath.split(':') + [os.path.dirname(recipetool.output)]
+ plugincontent = []
+ with open(srcfile) as fh:
+ plugincontent = fh.readlines()
+ try:
+ self.assertIn('meta-selftest', srcfile, 'wrong bbpath plugin found')
+ for path in searchpath:
+ self._copy_file_with_cleanup(srcfile, path, 'lib', 'recipetool')
+ result = runCmd("recipetool --quiet count")
+ self.assertEqual(result.output, '1')
+ result = runCmd("recipetool --quiet multiloaded")
+ self.assertEqual(result.output, "no")
+ for path in searchpath:
+ result = runCmd("recipetool --quiet bbdir")
+ self.assertEqual(result.output, path)
+ os.unlink(os.path.join(result.output, 'lib', 'recipetool', 'bbpath.py'))
+ finally:
+ with open(srcfile, 'w') as fh:
+ fh.writelines(plugincontent)
+
+
class RecipetoolAppendsrcBase(RecipetoolBase):
def _try_recipetool_appendsrcfile(self, testrecipe, newfile, destfile, options, expectedlines, expectedfiles):
cmd = 'recipetool appendsrcfile %s %s %s %s %s' % (options, self.templayerdir, testrecipe, newfile, destfile)
@@ -555,20 +602,23 @@ class RecipetoolAppendsrcBase(RecipetoolBase):
self._try_recipetool_appendsrcfiles(testrecipe, newfiles, expectedfiles=expectedfiles, destdir=destdir, options=options)
- src_uri = get_bb_var('SRC_URI', testrecipe).split()
+ bb_vars = get_bb_vars(['SRC_URI', 'FILE', 'FILESEXTRAPATHS'], testrecipe)
+ src_uri = bb_vars['SRC_URI'].split()
for f in expectedfiles:
if destdir:
self.assertIn('file://%s;subdir=%s' % (f, destdir), src_uri)
else:
self.assertIn('file://%s' % f, src_uri)
- recipefile = get_bb_var('FILE', testrecipe)
+ recipefile = bb_vars['FILE']
bbappendfile = self._check_bbappend(testrecipe, recipefile, self.templayerdir)
filesdir = os.path.join(os.path.dirname(bbappendfile), testrecipe)
- filesextrapaths = get_bb_var('FILESEXTRAPATHS', testrecipe).split(':')
+ filesextrapaths = bb_vars['FILESEXTRAPATHS'].split(':')
self.assertIn(filesdir, filesextrapaths)
+
+
class RecipetoolAppendsrcTests(RecipetoolAppendsrcBase):
@testcase(1273)
@@ -594,8 +644,9 @@ class RecipetoolAppendsrcTests(RecipetoolAppendsrcBase):
@testcase(1280)
def test_recipetool_appendsrcfile_srcdir_basic(self):
testrecipe = 'bash'
- srcdir = get_bb_var('S', testrecipe)
- workdir = get_bb_var('WORKDIR', testrecipe)
+ bb_vars = get_bb_vars(['S', 'WORKDIR'], testrecipe)
+ srcdir = bb_vars['S']
+ workdir = bb_vars['WORKDIR']
subdir = os.path.relpath(srcdir, workdir)
self._test_appendsrcfile(testrecipe, 'a-file', srcdir=subdir)
@@ -620,8 +671,9 @@ class RecipetoolAppendsrcTests(RecipetoolAppendsrcBase):
def test_recipetool_appendsrcfile_replace_file_srcdir(self):
testrecipe = 'bash'
filepath = 'Makefile.in'
- srcdir = get_bb_var('S', testrecipe)
- workdir = get_bb_var('WORKDIR', testrecipe)
+ bb_vars = get_bb_vars(['S', 'WORKDIR'], testrecipe)
+ srcdir = bb_vars['S']
+ workdir = bb_vars['WORKDIR']
subdir = os.path.relpath(srcdir, workdir)
self._test_appendsrcfile(testrecipe, filepath, srcdir=subdir)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/runqemu.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/runqemu.py
new file mode 100644
index 000000000..58c6f96f9
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/runqemu.py
@@ -0,0 +1,140 @@
+#
+# Copyright (c) 2017 Wind River Systems, Inc.
+#
+
+import re
+import logging
+
+from oeqa.selftest.base import oeSelfTest
+from oeqa.utils.commands import bitbake, runqemu, get_bb_var
+from oeqa.utils.decorators import testcase
+
+class RunqemuTests(oeSelfTest):
+ """Runqemu test class"""
+
+ image_is_ready = False
+ deploy_dir_image = ''
+
+ def setUpLocal(self):
+ self.recipe = 'core-image-minimal'
+ self.machine = 'qemux86-64'
+ self.fstypes = "ext4 iso hddimg vmdk qcow2 vdi"
+ self.cmd_common = "runqemu nographic"
+
+ # Avoid emit the same record multiple times.
+ mainlogger = logging.getLogger("BitBake.Main")
+ mainlogger.propagate = False
+
+ self.write_config(
+"""
+MACHINE = "%s"
+IMAGE_FSTYPES = "%s"
+# 10 means 1 second
+SYSLINUX_TIMEOUT = "10"
+"""
+% (self.machine, self.fstypes)
+ )
+
+ if not RunqemuTests.image_is_ready:
+ RunqemuTests.deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
+ bitbake(self.recipe)
+ RunqemuTests.image_is_ready = True
+
+ @testcase(2001)
+ def test_boot_machine(self):
+ """Test runqemu machine"""
+ cmd = "%s %s" % (self.cmd_common, self.machine)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)
+
+ @testcase(2002)
+ def test_boot_machine_ext4(self):
+ """Test runqemu machine ext4"""
+ cmd = "%s %s ext4" % (self.cmd_common, self.machine)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ with open(qemu.qemurunnerlog) as f:
+ self.assertTrue('rootfs.ext4' in f.read(), "Failed: %s" % cmd)
+
+ @testcase(2003)
+ def test_boot_machine_iso(self):
+ """Test runqemu machine iso"""
+ cmd = "%s %s iso" % (self.cmd_common, self.machine)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ with open(qemu.qemurunnerlog) as f:
+ self.assertTrue(' -cdrom ' in f.read(), "Failed: %s" % cmd)
+
+ @testcase(2004)
+ def test_boot_recipe_image(self):
+ """Test runqemu recipe-image"""
+ cmd = "%s %s" % (self.cmd_common, self.recipe)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)
+
+ @testcase(2005)
+ def test_boot_recipe_image_vmdk(self):
+ """Test runqemu recipe-image vmdk"""
+ cmd = "%s %s vmdk" % (self.cmd_common, self.recipe)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ with open(qemu.qemurunnerlog) as f:
+ self.assertTrue('format=vmdk' in f.read(), "Failed: %s" % cmd)
+
+ @testcase(2006)
+ def test_boot_recipe_image_vdi(self):
+ """Test runqemu recipe-image vdi"""
+ cmd = "%s %s vdi" % (self.cmd_common, self.recipe)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ with open(qemu.qemurunnerlog) as f:
+ self.assertTrue('format=vdi' in f.read(), "Failed: %s" % cmd)
+
+ @testcase(2007)
+ def test_boot_deploy(self):
+ """Test runqemu deploy_dir_image"""
+ cmd = "%s %s" % (self.cmd_common, self.deploy_dir_image)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)
+
+ @testcase(2008)
+ def test_boot_deploy_hddimg(self):
+ """Test runqemu deploy_dir_image hddimg"""
+ cmd = "%s %s hddimg" % (self.cmd_common, self.deploy_dir_image)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ with open(qemu.qemurunnerlog) as f:
+ self.assertTrue(re.search('file=.*.hddimg', f.read()), "Failed: %s" % cmd)
+
+ @testcase(2009)
+ def test_boot_machine_slirp(self):
+ """Test runqemu machine slirp"""
+ cmd = "%s slirp %s" % (self.cmd_common, self.machine)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ with open(qemu.qemurunnerlog) as f:
+ self.assertTrue(' -netdev user' in f.read(), "Failed: %s" % cmd)
+
+ @testcase(2009)
+ def test_boot_machine_slirp_qcow2(self):
+ """Test runqemu machine slirp qcow2"""
+ cmd = "%s slirp qcow2 %s" % (self.cmd_common, self.machine)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ with open(qemu.qemurunnerlog) as f:
+ self.assertTrue('format=qcow2' in f.read(), "Failed: %s" % cmd)
+
+ @testcase(2010)
+ def test_boot_qemu_boot(self):
+ """Test runqemu /path/to/image.qemuboot.conf"""
+ qemuboot_conf = "%s-%s.qemuboot.conf" % (self.recipe, self.machine)
+ qemuboot_conf = os.path.join(self.deploy_dir_image, qemuboot_conf)
+ if not os.path.exists(qemuboot_conf):
+ self.skipTest("%s not found" % qemuboot_conf)
+ cmd = "%s %s" % (self.cmd_common, qemuboot_conf)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)
+
+ @testcase(2011)
+ def test_boot_rootfs(self):
+ """Test runqemu /path/to/rootfs.ext4"""
+ rootfs = "%s-%s.ext4" % (self.recipe, self.machine)
+ rootfs = os.path.join(self.deploy_dir_image, rootfs)
+ if not os.path.exists(rootfs):
+ self.skipTest("%s not found" % rootfs)
+ cmd = "%s %s" % (self.cmd_common, rootfs)
+ with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
+ self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/runtime-test.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/runtime-test.py
index c2d5b45a4..e498d046c 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/runtime-test.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/runtime-test.py
@@ -1,10 +1,15 @@
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars, runqemu
from oeqa.utils.decorators import testcase
import os
+import re
class TestExport(oeSelfTest):
+ @classmethod
+ def tearDownClass(cls):
+ runCmd("rm -rf /tmp/sdk")
+
def test_testexport_basic(self):
"""
Summary: Check basic testexport functionality with only ping test enabled.
@@ -26,22 +31,23 @@ class TestExport(oeSelfTest):
bitbake('core-image-minimal')
bitbake('-c testexport core-image-minimal')
- # Verify if TEST_EXPORT_DIR was created
testexport_dir = get_bb_var('TEST_EXPORT_DIR', 'core-image-minimal')
+
+ # Verify if TEST_EXPORT_DIR was created
isdir = os.path.isdir(testexport_dir)
self.assertEqual(True, isdir, 'Failed to create testexport dir: %s' % testexport_dir)
with runqemu('core-image-minimal') as qemu:
# Attempt to run runexported.py to perform ping test
- runexported_path = os.path.join(testexport_dir, "runexported.py")
- testdata_path = os.path.join(testexport_dir, "testdata.json")
- cmd = "%s -t %s -s %s %s" % (runexported_path, qemu.ip, qemu.server_ip, testdata_path)
+ test_path = os.path.join(testexport_dir, "oe-test")
+ data_file = os.path.join(testexport_dir, 'data', 'testdata.json')
+ manifest = os.path.join(testexport_dir, 'data', 'manifest')
+ cmd = ("%s runtime --test-data-file %s --packages-manifest %s "
+ "--target-ip %s --server-ip %s --quiet"
+ % (test_path, data_file, manifest, qemu.ip, qemu.server_ip))
result = runCmd(cmd)
- self.assertEqual(0, result.status, 'runexported.py returned a non 0 status')
-
# Verify ping test was succesful
- failure = True if 'FAIL' in result.output else False
- self.assertNotEqual(True, failure, 'ping test failed')
+ self.assertEqual(0, result.status, 'oe-test runtime returned a non 0 status')
def test_testexport_sdk(self):
"""
@@ -60,7 +66,6 @@ class TestExport(oeSelfTest):
features += 'TEST_SERVER_IP = "192.168.7.1"\n'
features += 'TEST_TARGET_IP = "192.168.7.1"\n'
features += 'TEST_SUITES = "ping"\n'
- features += 'TEST_SUITES_TAGS = "selftest_sdk"\n'
features += 'TEST_EXPORT_SDK_ENABLED = "1"\n'
features += 'TEST_EXPORT_SDK_PACKAGES = "nativesdk-tar"\n'
self.write_config(features)
@@ -69,19 +74,31 @@ class TestExport(oeSelfTest):
bitbake('core-image-minimal')
bitbake('-c testexport core-image-minimal')
+ needed_vars = ['TEST_EXPORT_DIR', 'TEST_EXPORT_SDK_DIR', 'TEST_EXPORT_SDK_NAME']
+ bb_vars = get_bb_vars(needed_vars, 'core-image-minimal')
+ testexport_dir = bb_vars['TEST_EXPORT_DIR']
+ sdk_dir = bb_vars['TEST_EXPORT_SDK_DIR']
+ sdk_name = bb_vars['TEST_EXPORT_SDK_NAME']
+
# Check for SDK
- testexport_dir = get_bb_var('TEST_EXPORT_DIR', 'core-image-minimal')
- sdk_dir = get_bb_var('TEST_EXPORT_SDK_DIR', 'core-image-minimal')
- tarball_name = "%s.sh" % get_bb_var('TEST_EXPORT_SDK_NAME', 'core-image-minimal')
+ tarball_name = "%s.sh" % sdk_name
tarball_path = os.path.join(testexport_dir, sdk_dir, tarball_name)
- self.assertEqual(os.path.isfile(tarball_path), True, "Couldn't find SDK tarball: %s" % tarball_path)
+ msg = "Couldn't find SDK tarball: %s" % tarball_path
+ self.assertEqual(os.path.isfile(tarball_path), True, msg)
+
+ # Extract SDK and run tar from SDK
+ result = runCmd("%s -y -d /tmp/sdk" % tarball_path)
+ self.assertEqual(0, result.status, "Couldn't extract SDK")
- # Run runexported.py
- runexported_path = os.path.join(testexport_dir, "runexported.py")
- testdata_path = os.path.join(testexport_dir, "testdata.json")
- cmd = "%s %s" % (runexported_path, testdata_path)
- result = runCmd(cmd)
- self.assertEqual(0, result.status, 'runexported.py returned a non 0 status')
+ env_script = result.output.split()[-1]
+ result = runCmd(". %s; which tar" % env_script, shell=True)
+ self.assertEqual(0, result.status, "Couldn't setup SDK environment")
+ is_sdk_tar = True if "/tmp/sdk" in result.output else False
+ self.assertTrue(is_sdk_tar, "Couldn't setup SDK environment")
+
+ tar_sdk = result.output
+ result = runCmd("%s --version" % tar_sdk)
+ self.assertEqual(0, result.status, "Couldn't run tar from SDK")
class TestImage(oeSelfTest):
@@ -90,16 +107,131 @@ class TestImage(oeSelfTest):
"""
Summary: Check install packages functionality for testimage/testexport.
Expected: 1. Import tests from a directory other than meta.
- 2. Check install/unistall of socat.
+ 2. Check install/uninstall of socat.
+ 3. Check that remote package feeds can be accessed
Product: oe-core
Author: Mariano Lopez <mariano.lopez@intel.com>
+ Author: Alexander Kanavin <alexander.kanavin@intel.com>
"""
+ if get_bb_var('DISTRO') == 'poky-tiny':
+ self.skipTest('core-image-full-cmdline not buildable for poky-tiny')
features = 'INHERIT += "testimage"\n'
features += 'TEST_SUITES = "ping ssh selftest"\n'
- features += 'TEST_SUITES_TAGS = "selftest_package_install"\n'
+ # We don't yet know what the server ip and port will be - they will be patched
+ # in at the start of the on-image test
+ features += 'PACKAGE_FEED_URIS = "http://bogus_ip:bogus_port"\n'
+ features += 'EXTRA_IMAGE_FEATURES += "package-management"\n'
+ features += 'PACKAGE_CLASSES = "package_rpm"'
self.write_config(features)
# Build core-image-sato and testimage
bitbake('core-image-full-cmdline socat')
bitbake('-c testimage core-image-full-cmdline')
+
+class Postinst(oeSelfTest):
+ @testcase(1540)
+ def test_verify_postinst(self):
+ """
+ Summary: The purpose of this test is to verify the execution order of postinst Bugzilla ID: [5319]
+ Expected :
+ 1. Compile a minimal image.
+ 2. The compiled image will add the created layer with the recipes postinst[ abdpt]
+ 3. Run qemux86
+ 4. Validate the task execution order
+ Author: Francisco Pedraza <francisco.j.pedraza.gonzalez@intel.com>
+ """
+ features = 'INHERIT += "testimage"\n'
+ features += 'CORE_IMAGE_EXTRA_INSTALL += "postinst-at-rootfs \
+postinst-delayed-a \
+postinst-delayed-b \
+postinst-delayed-d \
+postinst-delayed-p \
+postinst-delayed-t \
+"\n'
+ self.write_config(features)
+
+ bitbake('core-image-minimal -f ')
+
+ postinst_list = ['100-postinst-at-rootfs',
+ '101-postinst-delayed-a',
+ '102-postinst-delayed-b',
+ '103-postinst-delayed-d',
+ '104-postinst-delayed-p',
+ '105-postinst-delayed-t']
+ path_workdir = get_bb_var('WORKDIR','core-image-minimal')
+ workspacedir = 'testimage/qemu_boot_log'
+ workspacedir = os.path.join(path_workdir, workspacedir)
+ rexp = re.compile("^Running postinst .*/(?P<postinst>.*)\.\.\.$")
+ with runqemu('core-image-minimal') as qemu:
+ with open(workspacedir) as f:
+ found = False
+ idx = 0
+ for line in f.readlines():
+ line = line.strip().replace("^M","")
+ if not line: # To avoid empty lines
+ continue
+ m = rexp.search(line)
+ if m:
+ self.assertEqual(postinst_list[idx], m.group('postinst'), "Fail")
+ idx = idx+1
+ found = True
+ elif found:
+ self.assertEqual(idx, len(postinst_list), "Not found all postinsts")
+ break
+
+ @testcase(1545)
+ def test_postinst_rootfs_and_boot(self):
+ """
+ Summary: The purpose of this test case is to verify Post-installation
+ scripts are called when rootfs is created and also test
+ that script can be delayed to run at first boot.
+ Dependencies: NA
+ Steps: 1. Add proper configuration to local.conf file
+ 2. Build a "core-image-minimal" image
+ 3. Verify that file created by postinst_rootfs recipe is
+ present on rootfs dir.
+ 4. Boot the image created on qemu and verify that the file
+ created by postinst_boot recipe is present on image.
+ Expected: The files are successfully created during rootfs and boot
+ time for 3 different package managers: rpm,ipk,deb and
+ for initialization managers: sysvinit and systemd.
+
+ """
+ file_rootfs_name = "this-was-created-at-rootfstime"
+ fileboot_name = "this-was-created-at-first-boot"
+ rootfs_pkg = 'postinst-at-rootfs'
+ boot_pkg = 'postinst-delayed-a'
+ #Step 1
+ features = 'MACHINE = "qemux86"\n'
+ features += 'CORE_IMAGE_EXTRA_INSTALL += "%s %s "\n'% (rootfs_pkg, boot_pkg)
+ features += 'IMAGE_FEATURES += "ssh-server-openssh"\n'
+ for init_manager in ("sysvinit", "systemd"):
+ #for sysvinit no extra configuration is needed,
+ if (init_manager is "systemd"):
+ features += 'DISTRO_FEATURES_append = " systemd"\n'
+ features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n'
+ features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n'
+ features += 'VIRTUAL-RUNTIME_initscripts = ""\n'
+ for classes in ("package_rpm package_deb package_ipk",
+ "package_deb package_rpm package_ipk",
+ "package_ipk package_deb package_rpm"):
+ features += 'PACKAGE_CLASSES = "%s"\n' % classes
+ self.write_config(features)
+
+ #Step 2
+ bitbake('core-image-minimal')
+
+ #Step 3
+ file_rootfs_created = os.path.join(get_bb_var('IMAGE_ROOTFS',"core-image-minimal"),
+ file_rootfs_name)
+ found = os.path.isfile(file_rootfs_created)
+ self.assertTrue(found, "File %s was not created at rootfs time by %s" % \
+ (file_rootfs_name, rootfs_pkg))
+
+ #Step 4
+ testcommand = 'ls /etc/'+fileboot_name
+ with runqemu('core-image-minimal') as qemu:
+ sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
+ result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand))
+ self.assertEqual(result.status, 0, 'File %s was not created at firts boot'% fileboot_name)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py
index 606bfd3e9..0ac3d1fac 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py
@@ -1,5 +1,5 @@
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
import os
import glob
import re
@@ -27,15 +27,17 @@ class Signing(oeSelfTest):
cls.pub_key_path = os.path.join(cls.testlayer_path, 'files', 'signing', "key.pub")
cls.secret_key_path = os.path.join(cls.testlayer_path, 'files', 'signing', "key.secret")
- runCmd('gpg --homedir %s --import %s %s' % (cls.gpg_dir, cls.pub_key_path, cls.secret_key_path))
+ runCmd('gpg --batch --homedir %s --import %s %s' % (cls.gpg_dir, cls.pub_key_path, cls.secret_key_path))
@testcase(1362)
def test_signing_packages(self):
"""
Summary: Test that packages can be signed in the package feed
Expected: Package should be signed with the correct key
+ Expected: Images can be created from signed packages
Product: oe-core
Author: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
+ Author: Alexander Kanavin <alexander.kanavin@intel.com>
AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
"""
import oe.packagedata
@@ -49,7 +51,6 @@ class Signing(oeSelfTest):
feature = 'INHERIT += "sign_rpm"\n'
feature += 'RPM_GPG_PASSPHRASE = "test123"\n'
feature += 'RPM_GPG_NAME = "testuser"\n'
- feature += 'RPM_GPG_PUBKEY = "%s"\n' % self.pub_key_path
feature += 'GPG_PATH = "%s"\n' % self.gpg_dir
self.write_config(feature)
@@ -59,30 +60,38 @@ class Signing(oeSelfTest):
self.add_command_to_tearDown('bitbake -c clean %s' % test_recipe)
- pkgdatadir = get_bb_var('PKGDATA_DIR', test_recipe)
+ needed_vars = ['PKGDATA_DIR', 'DEPLOY_DIR_RPM', 'PACKAGE_ARCH', 'STAGING_BINDIR_NATIVE']
+ bb_vars = get_bb_vars(needed_vars, test_recipe)
+ pkgdatadir = bb_vars['PKGDATA_DIR']
pkgdata = oe.packagedata.read_pkgdatafile(pkgdatadir + "/runtime/ed")
if 'PKGE' in pkgdata:
pf = pkgdata['PN'] + "-" + pkgdata['PKGE'] + pkgdata['PKGV'] + '-' + pkgdata['PKGR']
else:
pf = pkgdata['PN'] + "-" + pkgdata['PKGV'] + '-' + pkgdata['PKGR']
- deploy_dir_rpm = get_bb_var('DEPLOY_DIR_RPM', test_recipe)
- package_arch = get_bb_var('PACKAGE_ARCH', test_recipe).replace('-', '_')
- staging_bindir_native = get_bb_var('STAGING_BINDIR_NATIVE')
+ deploy_dir_rpm = bb_vars['DEPLOY_DIR_RPM']
+ package_arch = bb_vars['PACKAGE_ARCH'].replace('-', '_')
+ staging_bindir_native = bb_vars['STAGING_BINDIR_NATIVE']
pkg_deploy = os.path.join(deploy_dir_rpm, package_arch, '.'.join((pf, package_arch, 'rpm')))
# Use a temporary rpmdb
rpmdb = tempfile.mkdtemp(prefix='oeqa-rpmdb')
- runCmd('%s/rpm --define "_dbpath %s" --import %s' %
+ runCmd('%s/rpmkeys --define "_dbpath %s" --import %s' %
(staging_bindir_native, rpmdb, self.pub_key_path))
- ret = runCmd('%s/rpm --define "_dbpath %s" --checksig %s' %
+ ret = runCmd('%s/rpmkeys --define "_dbpath %s" --checksig %s' %
(staging_bindir_native, rpmdb, pkg_deploy))
# tmp/deploy/rpm/i586/ed-1.9-r0.i586.rpm: rsa sha1 md5 OK
- self.assertIn('rsa sha1 md5 OK', ret.output, 'Package signed incorrectly.')
+ self.assertIn('rsa sha1 (md5) pgp md5 OK', ret.output, 'Package signed incorrectly.')
shutil.rmtree(rpmdb)
+ #Check that an image can be built from signed packages
+ self.add_command_to_tearDown('bitbake -c clean core-image-minimal')
+ bitbake('-c clean core-image-minimal')
+ bitbake('core-image-minimal')
+
+
@testcase(1382)
def test_signing_sstate_archive(self):
"""
@@ -101,13 +110,7 @@ class Signing(oeSelfTest):
self.add_command_to_tearDown('bitbake -c clean %s' % test_recipe)
self.add_command_to_tearDown('rm -rf %s' % sstatedir)
- # Determine the pub key signature
- ret = runCmd('gpg --homedir %s --list-keys' % self.gpg_dir)
- pub_key = re.search(r'^pub\s+\S+/(\S+)\s+', ret.output, re.M)
- self.assertIsNotNone(pub_key, 'Failed to determine the public key signature.')
- pub_key = pub_key.group(1)
-
- feature = 'SSTATE_SIG_KEY ?= "%s"\n' % pub_key
+ feature = 'SSTATE_SIG_KEY ?= "testuser"\n'
feature += 'SSTATE_SIG_PASSPHRASE ?= "test123"\n'
feature += 'SSTATE_VERIFY_SIG ?= "1"\n'
feature += 'GPG_PATH = "%s"\n' % self.gpg_dir
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstate.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstate.py
index 598972443..f54bc4146 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstate.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstate.py
@@ -6,16 +6,24 @@ import shutil
import oeqa.utils.ftools as ftools
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_test_layer
+from oeqa.utils.commands import runCmd, bitbake, get_bb_vars, get_test_layer
class SStateBase(oeSelfTest):
def setUpLocal(self):
self.temp_sstate_location = None
- self.sstate_path = get_bb_var('SSTATE_DIR')
- self.distro = get_bb_var('NATIVELSBSTRING')
- self.distro_specific_sstate = os.path.join(self.sstate_path, self.distro)
+ needed_vars = ['SSTATE_DIR', 'NATIVELSBSTRING', 'TCLIBC', 'TUNE_ARCH',
+ 'TOPDIR', 'TARGET_VENDOR', 'TARGET_OS']
+ bb_vars = get_bb_vars(needed_vars)
+ self.sstate_path = bb_vars['SSTATE_DIR']
+ self.hostdistro = bb_vars['NATIVELSBSTRING']
+ self.tclibc = bb_vars['TCLIBC']
+ self.tune_arch = bb_vars['TUNE_ARCH']
+ self.topdir = bb_vars['TOPDIR']
+ self.target_vendor = bb_vars['TARGET_VENDOR']
+ self.target_os = bb_vars['TARGET_OS']
+ self.distro_specific_sstate = os.path.join(self.sstate_path, self.hostdistro)
# Creates a special sstate configuration with the option to add sstate mirrors
def config_sstate(self, temp_sstate_location=False, add_local_mirrors=[]):
@@ -26,9 +34,10 @@ class SStateBase(oeSelfTest):
config_temp_sstate = "SSTATE_DIR = \"%s\"" % temp_sstate_path
self.append_config(config_temp_sstate)
self.track_for_cleanup(temp_sstate_path)
- self.sstate_path = get_bb_var('SSTATE_DIR')
- self.distro = get_bb_var('NATIVELSBSTRING')
- self.distro_specific_sstate = os.path.join(self.sstate_path, self.distro)
+ bb_vars = get_bb_vars(['SSTATE_DIR', 'NATIVELSBSTRING'])
+ self.sstate_path = bb_vars['SSTATE_DIR']
+ self.hostdistro = bb_vars['NATIVELSBSTRING']
+ self.distro_specific_sstate = os.path.join(self.sstate_path, self.hostdistro)
if add_local_mirrors:
config_set_sstate_if_not_set = 'SSTATE_MIRRORS ?= ""'
@@ -42,7 +51,7 @@ class SStateBase(oeSelfTest):
def search_sstate(self, filename_regex, distro_specific=True, distro_nonspecific=True):
result = []
for root, dirs, files in os.walk(self.sstate_path):
- if distro_specific and re.search("%s/[a-z0-9]{2}$" % self.distro, root):
+ if distro_specific and re.search("%s/[a-z0-9]{2}$" % self.hostdistro, root):
for f in files:
if re.search(filename_regex, f):
result.append(f)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py
index f99d74684..e35ddfff5 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py
@@ -41,22 +41,19 @@ class SStateTests(SStateBase):
@testcase(975)
def test_sstate_creation_distro_specific_pass(self):
- targetarch = get_bb_var('TUNE_ARCH')
- self.run_test_sstate_creation(['binutils-cross-'+ targetarch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
+ self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
@testcase(1374)
def test_sstate_creation_distro_specific_fail(self):
- targetarch = get_bb_var('TUNE_ARCH')
- self.run_test_sstate_creation(['binutils-cross-'+ targetarch, 'binutils-native'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True, should_pass=False)
+ self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True, should_pass=False)
@testcase(976)
def test_sstate_creation_distro_nonspecific_pass(self):
- self.run_test_sstate_creation(['glibc-initial'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
+ self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
@testcase(1375)
def test_sstate_creation_distro_nonspecific_fail(self):
- self.run_test_sstate_creation(['glibc-initial'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False)
-
+ self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False)
# Test the sstate files deletion part of the do_cleansstate task
def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True):
@@ -77,17 +74,19 @@ class SStateTests(SStateBase):
@testcase(977)
def test_cleansstate_task_distro_specific_nonspecific(self):
- targetarch = get_bb_var('TUNE_ARCH')
- self.run_test_cleansstate_task(['binutils-cross-' + targetarch, 'binutils-native', 'glibc-initial'], distro_specific=True, distro_nonspecific=True, temp_sstate_location=True)
+ targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
+ targets.append('linux-libc-headers')
+ self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True)
@testcase(1376)
def test_cleansstate_task_distro_nonspecific(self):
- self.run_test_cleansstate_task(['glibc-initial'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
+ self.run_test_cleansstate_task(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
@testcase(1377)
def test_cleansstate_task_distro_specific(self):
- targetarch = get_bb_var('TUNE_ARCH')
- self.run_test_cleansstate_task(['binutils-cross-'+ targetarch, 'binutils-native', 'glibc-initial'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
+ targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
+ targets.append('linux-libc-headers')
+ self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
# Test rebuilding of distro-specific sstate files
@@ -124,13 +123,11 @@ class SStateTests(SStateBase):
@testcase(175)
def test_rebuild_distro_specific_sstate_cross_native_targets(self):
- targetarch = get_bb_var('TUNE_ARCH')
- self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + targetarch, 'binutils-native'], temp_sstate_location=True)
+ self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True)
@testcase(1372)
def test_rebuild_distro_specific_sstate_cross_target(self):
- targetarch = get_bb_var('TUNE_ARCH')
- self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + targetarch], temp_sstate_location=True)
+ self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch], temp_sstate_location=True)
@testcase(1373)
def test_rebuild_distro_specific_sstate_native_target(self):
@@ -145,10 +142,9 @@ class SStateTests(SStateBase):
self.assertTrue(len(global_config) == len(target_config), msg='Lists global_config and target_config should have the same number of elements')
self.config_sstate(temp_sstate_location=True, add_local_mirrors=[self.sstate_path])
- # If buildhistory is enabled, we need to disable version-going-backwards QA checks for this test. It may report errors otherwise.
- if ('buildhistory' in get_bb_var('USER_CLASSES')) or ('buildhistory' in get_bb_var('INHERIT')):
- remove_errors_config = 'ERROR_QA_remove = "version-going-backwards"'
- self.append_config(remove_errors_config)
+ # If buildhistory is enabled, we need to disable version-going-backwards
+ # QA checks for this test. It may report errors otherwise.
+ self.append_config('ERROR_QA_remove = "version-going-backwards"')
# For not this only checks if random sstate tasks are handled correctly as a group.
# In the future we should add control over what tasks we check for.
@@ -229,8 +225,6 @@ class SStateTests(SStateBase):
manually and check using bitbake -S.
"""
- topdir = get_bb_var('TOPDIR')
- targetvendor = get_bb_var('TARGET_VENDOR')
self.write_config("""
MACHINE = "qemux86"
TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
@@ -239,7 +233,7 @@ BUILD_OS = "linux"
SDKMACHINE = "x86_64"
PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
""")
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
bitbake("core-image-sato -S none")
self.write_config("""
MACHINE = "qemux86"
@@ -249,7 +243,7 @@ BUILD_OS = "linux"
SDKMACHINE = "i686"
PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
""")
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
bitbake("core-image-sato -S none")
def get_files(d):
@@ -262,9 +256,9 @@ PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
continue
f.extend(os.path.join(root, name) for name in files)
return f
- files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/")
- files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/")
- files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash").replace("i686-linux", "x86_64-linux").replace("i686" + targetvendor + "-linux", "x86_64" + targetvendor + "-linux", ) for x in files2]
+ files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
+ files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
+ files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash").replace("i686-linux", "x86_64-linux").replace("i686" + self.target_vendor + "-linux", "x86_64" + self.target_vendor + "-linux", ) for x in files2]
self.maxDiff = None
self.assertCountEqual(files1, files2)
@@ -277,18 +271,17 @@ PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
builds, override the variables manually and check using bitbake -S.
"""
- topdir = get_bb_var('TOPDIR')
self.write_config("""
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
NATIVELSBSTRING = \"DistroA\"
""")
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
bitbake("core-image-sato -S none")
self.write_config("""
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
NATIVELSBSTRING = \"DistroB\"
""")
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
bitbake("core-image-sato -S none")
def get_files(d):
@@ -296,8 +289,8 @@ NATIVELSBSTRING = \"DistroB\"
for root, dirs, files in os.walk(d):
f.extend(os.path.join(root, name) for name in files)
return f
- files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/")
- files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/")
+ files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
+ files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
self.maxDiff = None
self.assertCountEqual(files1, files2)
@@ -346,14 +339,11 @@ MULTILIBS = \"\"
def sstate_allarch_samesigs(self, configA, configB):
- topdir = get_bb_var('TOPDIR')
- targetos = get_bb_var('TARGET_OS')
- targetvendor = get_bb_var('TARGET_VENDOR')
self.write_config(configA)
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
bitbake("world meta-toolchain -S none")
self.write_config(configB)
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
bitbake("world meta-toolchain -S none")
def get_files(d):
@@ -367,15 +357,15 @@ MULTILIBS = \"\"
(_, task, _, shash) = name.rsplit(".", 3)
f[os.path.join(os.path.basename(root), task)] = shash
return f
- files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/all" + targetvendor + "-" + targetos)
- files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/all" + targetvendor + "-" + targetos)
+ files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/all" + self.target_vendor + "-" + self.target_os)
+ files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/all" + self.target_vendor + "-" + self.target_os)
self.maxDiff = None
self.assertEqual(files1, files2)
- nativesdkdir = os.path.basename(glob.glob(topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])
+ nativesdkdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])
- files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
- files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
+ files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
+ files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
self.maxDiff = None
self.assertEqual(files1, files2)
@@ -387,9 +377,6 @@ MULTILIBS = \"\"
qemux86copy machine to test this. Also include multilibs in the test.
"""
- topdir = get_bb_var('TOPDIR')
- targetos = get_bb_var('TARGET_OS')
- targetvendor = get_bb_var('TARGET_VENDOR')
self.write_config("""
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
MACHINE = \"qemux86\"
@@ -397,7 +384,7 @@ require conf/multilib.conf
MULTILIBS = "multilib:lib32"
DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
""")
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
bitbake("world meta-toolchain -S none")
self.write_config("""
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
@@ -406,7 +393,7 @@ require conf/multilib.conf
MULTILIBS = "multilib:lib32"
DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
""")
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
bitbake("world meta-toolchain -S none")
def get_files(d):
@@ -420,8 +407,8 @@ DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
if "do_build" not in name and "do_populate_sdk" not in name:
f.append(os.path.join(root, name))
return f
- files1 = get_files(topdir + "/tmp-sstatesamehash/stamps")
- files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps")
+ files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
+ files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
self.maxDiff = None
self.assertCountEqual(files1, files2)
@@ -433,8 +420,6 @@ DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
classes inherits should be the same.
"""
- topdir = get_bb_var('TOPDIR')
- targetvendor = get_bb_var('TARGET_VENDOR')
self.write_config("""
TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
BB_NUMBER_THREADS = "1"
@@ -445,8 +430,8 @@ DATE = "20161111"
INHERIT_remove = "buildstats-summary buildhistory uninative"
http_proxy = ""
""")
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
- self.track_for_cleanup(topdir + "/download1")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
+ self.track_for_cleanup(self.topdir + "/download1")
bitbake("world meta-toolchain -S none")
self.write_config("""
TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
@@ -460,8 +445,8 @@ INHERIT_remove = "uninative"
INHERIT += "buildstats-summary buildhistory"
http_proxy = "http://example.com/"
""")
- self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
- self.track_for_cleanup(topdir + "/download2")
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
+ self.track_for_cleanup(self.topdir + "/download2")
bitbake("world meta-toolchain -S none")
def get_files(d):
@@ -473,8 +458,8 @@ http_proxy = "http://example.com/"
base = os.sep.join(root.rsplit(os.sep, 2)[-2:] + [name])
f[base] = shash
return f
- files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/")
- files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/")
+ files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
+ files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
# Remove items that are identical in both sets
for k,v in files1.items() & files2.items():
del files1[k]
@@ -487,8 +472,8 @@ http_proxy = "http://example.com/"
if k in files1 and k in files2:
print("%s differs:" % k)
print(subprocess.check_output(("bitbake-diffsigs",
- topdir + "/tmp-sstatesamehash/stamps/" + k + "." + files1[k],
- topdir + "/tmp-sstatesamehash2/stamps/" + k + "." + files2[k])))
+ self.topdir + "/tmp-sstatesamehash/stamps/" + k + "." + files1[k],
+ self.topdir + "/tmp-sstatesamehash2/stamps/" + k + "." + files2[k])))
elif k in files1 and k not in files2:
print("%s in files1" % k)
elif k not in files1 and k in files2:
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/tinfoil.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/tinfoil.py
new file mode 100644
index 000000000..73a0c3bac
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/tinfoil.py
@@ -0,0 +1,190 @@
+import unittest
+import os
+import re
+import bb.tinfoil
+
+from oeqa.selftest.base import oeSelfTest
+from oeqa.utils.commands import runCmd
+from oeqa.utils.decorators import testcase
+
+class TinfoilTests(oeSelfTest):
+ """ Basic tests for the tinfoil API """
+
+ @testcase(1568)
+ def test_getvar(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(True)
+ machine = tinfoil.config_data.getVar('MACHINE')
+ if not machine:
+ self.fail('Unable to get MACHINE value - returned %s' % machine)
+
+ @testcase(1569)
+ def test_expand(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(True)
+ expr = '${@os.getpid()}'
+ pid = tinfoil.config_data.expand(expr)
+ if not pid:
+ self.fail('Unable to expand "%s" - returned %s' % (expr, pid))
+
+ @testcase(1570)
+ def test_getvar_bb_origenv(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(True)
+ origenv = tinfoil.config_data.getVar('BB_ORIGENV', False)
+ if not origenv:
+ self.fail('Unable to get BB_ORIGENV value - returned %s' % origenv)
+ self.assertEqual(origenv.getVar('HOME', False), os.environ['HOME'])
+
+ @testcase(1571)
+ def test_parse_recipe(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=False, quiet=2)
+ testrecipe = 'mdadm'
+ best = tinfoil.find_best_provider(testrecipe)
+ if not best:
+ self.fail('Unable to find recipe providing %s' % testrecipe)
+ rd = tinfoil.parse_recipe_file(best[3])
+ self.assertEqual(testrecipe, rd.getVar('PN'))
+
+ @testcase(1572)
+ def test_parse_recipe_copy_expand(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=False, quiet=2)
+ testrecipe = 'mdadm'
+ best = tinfoil.find_best_provider(testrecipe)
+ if not best:
+ self.fail('Unable to find recipe providing %s' % testrecipe)
+ rd = tinfoil.parse_recipe_file(best[3])
+ # Check we can get variable values
+ self.assertEqual(testrecipe, rd.getVar('PN'))
+ # Check that expanding a value that includes a variable reference works
+ self.assertEqual(testrecipe, rd.getVar('BPN'))
+ # Now check that changing the referenced variable's value in a copy gives that
+ # value when expanding
+ localdata = bb.data.createCopy(rd)
+ localdata.setVar('PN', 'hello')
+ self.assertEqual('hello', localdata.getVar('BPN'))
+
+ @testcase(1573)
+ def test_parse_recipe_initial_datastore(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=False, quiet=2)
+ testrecipe = 'mdadm'
+ best = tinfoil.find_best_provider(testrecipe)
+ if not best:
+ self.fail('Unable to find recipe providing %s' % testrecipe)
+ dcopy = bb.data.createCopy(tinfoil.config_data)
+ dcopy.setVar('MYVARIABLE', 'somevalue')
+ rd = tinfoil.parse_recipe_file(best[3], config_data=dcopy)
+ # Check we can get variable values
+ self.assertEqual('somevalue', rd.getVar('MYVARIABLE'))
+
+ @testcase(1574)
+ def test_list_recipes(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=False, quiet=2)
+ # Check pkg_pn
+ checkpns = ['tar', 'automake', 'coreutils', 'm4-native', 'nativesdk-gcc']
+ pkg_pn = tinfoil.cooker.recipecaches[''].pkg_pn
+ for pn in checkpns:
+ self.assertIn(pn, pkg_pn)
+ # Check pkg_fn
+ checkfns = {'nativesdk-gcc': '^virtual:nativesdk:.*', 'coreutils': '.*/coreutils_.*.bb'}
+ for fn, pn in tinfoil.cooker.recipecaches[''].pkg_fn.items():
+ if pn in checkpns:
+ if pn in checkfns:
+ self.assertTrue(re.match(checkfns[pn], fn), 'Entry for %s: %s did not match %s' % (pn, fn, checkfns[pn]))
+ checkpns.remove(pn)
+ if checkpns:
+ self.fail('Unable to find pkg_fn entries for: %s' % ', '.join(checkpns))
+
+ @testcase(1575)
+ def test_wait_event(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=True)
+ # Need to drain events otherwise events that will be masked will still be in the queue
+ while tinfoil.wait_event(0.25):
+ pass
+ tinfoil.set_event_mask(['bb.event.FilesMatchingFound', 'bb.command.CommandCompleted'])
+ pattern = 'conf'
+ res = tinfoil.run_command('findFilesMatchingInDir', pattern, 'conf/machine')
+ self.assertTrue(res)
+
+ eventreceived = False
+ waitcount = 5
+ while waitcount > 0:
+ event = tinfoil.wait_event(1)
+ if event:
+ if isinstance(event, bb.command.CommandCompleted):
+ break
+ elif isinstance(event, bb.event.FilesMatchingFound):
+ self.assertEqual(pattern, event._pattern)
+ self.assertIn('qemuarm.conf', event._matches)
+ eventreceived = True
+ else:
+ self.fail('Unexpected event: %s' % event)
+
+ waitcount = waitcount - 1
+
+ self.assertNotEqual(waitcount, 0, 'Timed out waiting for CommandCompleted event from bitbake server')
+ self.assertTrue(eventreceived, 'Did not receive FilesMatchingFound event from bitbake server')
+
+ @testcase(1576)
+ def test_setvariable_clean(self):
+ # First check that setVariable affects the datastore
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=True)
+ tinfoil.run_command('setVariable', 'TESTVAR', 'specialvalue')
+ self.assertEqual(tinfoil.config_data.getVar('TESTVAR'), 'specialvalue', 'Value set using setVariable is not reflected in client-side getVar()')
+
+ # Now check that the setVariable's effects are no longer present
+ # (this may legitimately break in future if we stop reinitialising
+ # the datastore, in which case we'll have to reconsider use of
+ # setVariable entirely)
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=True)
+ self.assertNotEqual(tinfoil.config_data.getVar('TESTVAR'), 'specialvalue', 'Value set using setVariable is still present!')
+
+ # Now check that setVar on the main datastore works (uses setVariable internally)
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=True)
+ tinfoil.config_data.setVar('TESTVAR', 'specialvalue')
+ value = tinfoil.run_command('getVariable', 'TESTVAR')
+ self.assertEqual(value, 'specialvalue', 'Value set using config_data.setVar() is not reflected in config_data.getVar()')
+
+ def test_datastore_operations(self):
+ with bb.tinfoil.Tinfoil() as tinfoil:
+ tinfoil.prepare(config_only=True)
+ # Test setVarFlag() / getVarFlag()
+ tinfoil.config_data.setVarFlag('TESTVAR', 'flagname', 'flagval')
+ value = tinfoil.config_data.getVarFlag('TESTVAR', 'flagname')
+ self.assertEqual(value, 'flagval', 'Value set using config_data.setVarFlag() is not reflected in config_data.getVarFlag()')
+ # Test delVarFlag()
+ tinfoil.config_data.setVarFlag('TESTVAR', 'otherflag', 'othervalue')
+ tinfoil.config_data.delVarFlag('TESTVAR', 'flagname')
+ value = tinfoil.config_data.getVarFlag('TESTVAR', 'flagname')
+ self.assertEqual(value, None, 'Varflag deleted using config_data.delVarFlag() is not reflected in config_data.getVarFlag()')
+ value = tinfoil.config_data.getVarFlag('TESTVAR', 'otherflag')
+ self.assertEqual(value, 'othervalue', 'Varflag deleted using config_data.delVarFlag() caused unrelated flag to be removed')
+ # Test delVar()
+ tinfoil.config_data.setVar('TESTVAR', 'varvalue')
+ value = tinfoil.config_data.getVar('TESTVAR')
+ self.assertEqual(value, 'varvalue', 'Value set using config_data.setVar() is not reflected in config_data.getVar()')
+ tinfoil.config_data.delVar('TESTVAR')
+ value = tinfoil.config_data.getVar('TESTVAR')
+ self.assertEqual(value, None, 'Variable deleted using config_data.delVar() appears to still have a value')
+ # Test renameVar()
+ tinfoil.config_data.setVar('TESTVAROLD', 'origvalue')
+ tinfoil.config_data.renameVar('TESTVAROLD', 'TESTVARNEW')
+ value = tinfoil.config_data.getVar('TESTVAROLD')
+ self.assertEqual(value, None, 'Variable renamed using config_data.renameVar() still seems to exist')
+ value = tinfoil.config_data.getVar('TESTVARNEW')
+ self.assertEqual(value, 'origvalue', 'Variable renamed using config_data.renameVar() does not appear with new name')
+ # Test overrides
+ tinfoil.config_data.setVar('TESTVAR', 'original')
+ tinfoil.config_data.setVar('TESTVAR_overrideone', 'one')
+ tinfoil.config_data.setVar('TESTVAR_overridetwo', 'two')
+ tinfoil.config_data.appendVar('OVERRIDES', ':overrideone')
+ value = tinfoil.config_data.getVar('TESTVAR')
+ self.assertEqual(value, 'one', 'Variable overrides not functioning correctly')
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py
index e652fad24..726af19e9 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py
@@ -24,42 +24,84 @@
"""Test cases for wic."""
import os
+import sys
+import unittest
from glob import glob
from shutil import rmtree
+from functools import wraps, lru_cache
+from tempfile import NamedTemporaryFile
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars, runqemu
from oeqa.utils.decorators import testcase
+@lru_cache(maxsize=32)
+def get_host_arch(recipe):
+ """A cached call to get_bb_var('HOST_ARCH', <recipe>)"""
+ return get_bb_var('HOST_ARCH', recipe)
+
+
+def only_for_arch(archs, image='core-image-minimal'):
+ """Decorator for wrapping test cases that can be run only for specific target
+ architectures. A list of compatible architectures is passed in `archs`.
+ Current architecture will be determined by parsing bitbake output for
+ `image` recipe.
+ """
+ def wrapper(func):
+ @wraps(func)
+ def wrapped_f(*args, **kwargs):
+ arch = get_host_arch(image)
+ if archs and arch not in archs:
+ raise unittest.SkipTest("Testcase arch dependency not met: %s" % arch)
+ return func(*args, **kwargs)
+ wrapped_f.__name__ = func.__name__
+ return wrapped_f
+ return wrapper
+
+
class Wic(oeSelfTest):
"""Wic test class."""
- resultdir = "/var/tmp/wic/build/"
+ resultdir = "/var/tmp/wic.oe-selftest/"
image_is_ready = False
+ native_sysroot = None
+ wicenv_cache = {}
def setUpLocal(self):
"""This code is executed before each test method."""
- self.write_config('IMAGE_FSTYPES += " hddimg"\n'
- 'MACHINE_FEATURES_append = " efi"\n'
- 'WKS_FILE = "wic-image-minimal"\n')
+ if not self.native_sysroot:
+ Wic.native_sysroot = get_bb_var('STAGING_DIR_NATIVE', 'wic-tools')
# Do this here instead of in setUpClass as the base setUp does some
# clean up which can result in the native tools built earlier in
# setUpClass being unavailable.
if not Wic.image_is_ready:
- bitbake('syslinux syslinux-native parted-native gptfdisk-native '
- 'dosfstools-native mtools-native bmap-tools-native')
+ if get_bb_var('USE_NLS') == 'yes':
+ bitbake('wic-tools')
+ else:
+ self.skipTest('wic-tools cannot be built due its (intltool|gettext)-native dependency and NLS disable')
+
bitbake('core-image-minimal')
Wic.image_is_ready = True
rmtree(self.resultdir, ignore_errors=True)
+ def tearDownLocal(self):
+ """Remove resultdir as it may contain images."""
+ rmtree(self.resultdir, ignore_errors=True)
+
+ @testcase(1552)
+ def test_version(self):
+ """Test wic --version"""
+ self.assertEqual(0, runCmd('wic --version').status)
+
@testcase(1208)
def test_help(self):
- """Test wic --help"""
+ """Test wic --help and wic -h"""
self.assertEqual(0, runCmd('wic --help').status)
+ self.assertEqual(0, runCmd('wic -h').status)
@testcase(1209)
def test_createhelp(self):
@@ -71,44 +113,15 @@ class Wic(oeSelfTest):
"""Test wic list --help"""
self.assertEqual(0, runCmd('wic list --help').status)
- @testcase(1211)
- def test_build_image_name(self):
- """Test wic create directdisk --image-name core-image-minimal"""
- self.assertEqual(0, runCmd("wic create directdisk "
- "--image-name core-image-minimal").status)
- self.assertEqual(1, len(glob(self.resultdir + "directdisk-*.direct")))
-
- @testcase(1212)
- def test_build_artifacts(self):
- """Test wic create directdisk providing all artifacts."""
- bbvars = dict((var.lower(), get_bb_var(var, 'core-image-minimal')) \
- for var in ('STAGING_DATADIR', 'DEPLOY_DIR_IMAGE',
- 'STAGING_DIR_NATIVE', 'IMAGE_ROOTFS'))
- status = runCmd("wic create directdisk "
- "-b %(staging_datadir)s "
- "-k %(deploy_dir_image)s "
- "-n %(staging_dir_native)s "
- "-r %(image_rootfs)s" % bbvars).status
- self.assertEqual(0, status)
- self.assertEqual(1, len(glob(self.resultdir + "directdisk-*.direct")))
-
- @testcase(1157)
- def test_gpt_image(self):
- """Test creation of core-image-minimal with gpt table and UUID boot"""
- self.assertEqual(0, runCmd("wic create directdisk-gpt "
- "--image-name core-image-minimal").status)
- self.assertEqual(1, len(glob(self.resultdir + "directdisk-*.direct")))
-
- @testcase(1213)
- def test_unsupported_subcommand(self):
- """Test unsupported subcommand"""
- self.assertEqual(1, runCmd('wic unsupported',
- ignore_status=True).status)
+ @testcase(1553)
+ def test_help_create(self):
+ """Test wic help create"""
+ self.assertEqual(0, runCmd('wic help create').status)
- @testcase(1214)
- def test_no_command(self):
- """Test wic without command"""
- self.assertEqual(1, runCmd('wic', ignore_status=True).status)
+ @testcase(1554)
+ def test_help_list(self):
+ """Test wic help list"""
+ self.assertEqual(0, runCmd('wic help list').status)
@testcase(1215)
def test_help_overview(self):
@@ -125,94 +138,418 @@ class Wic(oeSelfTest):
"""Test wic help kickstart"""
self.assertEqual(0, runCmd('wic help kickstart').status)
+ @testcase(1555)
+ def test_list_images(self):
+ """Test wic list images"""
+ self.assertEqual(0, runCmd('wic list images').status)
+
+ @testcase(1556)
+ def test_list_source_plugins(self):
+ """Test wic list source-plugins"""
+ self.assertEqual(0, runCmd('wic list source-plugins').status)
+
+ @testcase(1557)
+ def test_listed_images_help(self):
+ """Test wic listed images help"""
+ output = runCmd('wic list images').output
+ imagelist = [line.split()[0] for line in output.splitlines()]
+ for image in imagelist:
+ self.assertEqual(0, runCmd('wic list %s help' % image).status)
+
+ @testcase(1213)
+ def test_unsupported_subcommand(self):
+ """Test unsupported subcommand"""
+ self.assertEqual(1, runCmd('wic unsupported',
+ ignore_status=True).status)
+
+ @testcase(1214)
+ def test_no_command(self):
+ """Test wic without command"""
+ self.assertEqual(1, runCmd('wic', ignore_status=True).status)
+
+ @testcase(1211)
+ def test_build_image_name(self):
+ """Test wic create wictestdisk --image-name=core-image-minimal"""
+ cmd = "wic create wictestdisk --image-name=core-image-minimal -o %s" % self.resultdir
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct")))
+
+ @testcase(1157)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_gpt_image(self):
+ """Test creation of core-image-minimal with gpt table and UUID boot"""
+ cmd = "wic create directdisk-gpt --image-name core-image-minimal -o %s" % self.resultdir
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob(self.resultdir + "directdisk-*.direct")))
+
+ @testcase(1346)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_iso_image(self):
+ """Test creation of hybrid iso image with legacy and EFI boot"""
+ config = 'INITRAMFS_IMAGE = "core-image-minimal-initramfs"\n'\
+ 'MACHINE_FEATURES_append = " efi"\n'
+ self.append_config(config)
+ bitbake('core-image-minimal')
+ self.remove_config(config)
+ cmd = "wic create mkhybridiso --image-name core-image-minimal -o %s" % self.resultdir
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob(self.resultdir + "HYBRID_ISO_IMG-*.direct")))
+ self.assertEqual(1, len(glob(self.resultdir + "HYBRID_ISO_IMG-*.iso")))
+
+ @testcase(1348)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_qemux86_directdisk(self):
+ """Test creation of qemux-86-directdisk image"""
+ cmd = "wic create qemux86-directdisk -e core-image-minimal -o %s" % self.resultdir
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob(self.resultdir + "qemux86-directdisk-*direct")))
+
+ @testcase(1350)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_mkefidisk(self):
+ """Test creation of mkefidisk image"""
+ cmd = "wic create mkefidisk -e core-image-minimal -o %s" % self.resultdir
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob(self.resultdir + "mkefidisk-*direct")))
+
+ @testcase(1385)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_bootloader_config(self):
+ """Test creation of directdisk-bootloader-config image"""
+ cmd = "wic create directdisk-bootloader-config -e core-image-minimal -o %s" % self.resultdir
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob(self.resultdir + "directdisk-bootloader-config-*direct")))
+
+ @testcase(1560)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_systemd_bootdisk(self):
+ """Test creation of systemd-bootdisk image"""
+ config = 'MACHINE_FEATURES_append = " efi"\n'
+ self.append_config(config)
+ bitbake('core-image-minimal')
+ self.remove_config(config)
+ cmd = "wic create systemd-bootdisk -e core-image-minimal -o %s" % self.resultdir
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob(self.resultdir + "systemd-bootdisk-*direct")))
+
+ @testcase(1561)
+ def test_sdimage_bootpart(self):
+ """Test creation of sdimage-bootpart image"""
+ cmd = "wic create sdimage-bootpart -e core-image-minimal -o %s" % self.resultdir
+ kimgtype = get_bb_var('KERNEL_IMAGETYPE', 'core-image-minimal')
+ self.write_config('IMAGE_BOOT_FILES = "%s"\n' % kimgtype)
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob(self.resultdir + "sdimage-bootpart-*direct")))
+
+ @testcase(1562)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_default_output_dir(self):
+ """Test default output location"""
+ for fname in glob("directdisk-*.direct"):
+ os.remove(fname)
+ cmd = "wic create directdisk -e core-image-minimal"
+ self.assertEqual(0, runCmd(cmd).status)
+ self.assertEqual(1, len(glob("directdisk-*.direct")))
+
+ @testcase(1212)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_build_artifacts(self):
+ """Test wic create directdisk providing all artifacts."""
+ bb_vars = get_bb_vars(['STAGING_DATADIR', 'RECIPE_SYSROOT_NATIVE'],
+ 'wic-tools')
+ bb_vars.update(get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_ROOTFS'],
+ 'core-image-minimal'))
+ bbvars = {key.lower(): value for key, value in bb_vars.items()}
+ bbvars['resultdir'] = self.resultdir
+ status = runCmd("wic create directdisk "
+ "-b %(staging_datadir)s "
+ "-k %(deploy_dir_image)s "
+ "-n %(recipe_sysroot_native)s "
+ "-r %(image_rootfs)s "
+ "-o %(resultdir)s" % bbvars).status
+ self.assertEqual(0, status)
+ self.assertEqual(1, len(glob(self.resultdir + "directdisk-*.direct")))
+
@testcase(1264)
def test_compress_gzip(self):
"""Test compressing an image with gzip"""
- self.assertEqual(0, runCmd("wic create directdisk "
+ self.assertEqual(0, runCmd("wic create wictestdisk "
"--image-name core-image-minimal "
- "-c gzip").status)
- self.assertEqual(1, len(glob(self.resultdir + \
- "directdisk-*.direct.gz")))
+ "-c gzip -o %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct.gz")))
@testcase(1265)
def test_compress_bzip2(self):
"""Test compressing an image with bzip2"""
- self.assertEqual(0, runCmd("wic create directdisk "
- "--image-name core-image-minimal "
- "-c bzip2").status)
- self.assertEqual(1, len(glob(self.resultdir + \
- "directdisk-*.direct.bz2")))
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "-c bzip2 -o %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct.bz2")))
@testcase(1266)
def test_compress_xz(self):
"""Test compressing an image with xz"""
- self.assertEqual(0, runCmd("wic create directdisk "
- "--image-name core-image-minimal "
- "-c xz").status)
- self.assertEqual(1, len(glob(self.resultdir + \
- "directdisk-*.direct.xz")))
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "--compress-with=xz -o %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct.xz")))
@testcase(1267)
def test_wrong_compressor(self):
"""Test how wic breaks if wrong compressor is provided"""
- self.assertEqual(2, runCmd("wic create directdisk "
- "--image-name core-image-minimal "
- "-c wrong", ignore_status=True).status)
+ self.assertEqual(2, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "-c wrong -o %s" % self.resultdir,
+ ignore_status=True).status)
+
+ @testcase(1558)
+ def test_debug_short(self):
+ """Test -D option"""
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "-D -o %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct")))
+
+ def test_debug_long(self):
+ """Test --debug option"""
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "--debug -o %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct")))
+
+ @testcase(1563)
+ def test_skip_build_check_short(self):
+ """Test -s option"""
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "-s -o %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct")))
+
+ def test_skip_build_check_long(self):
+ """Test --skip-build-check option"""
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "--skip-build-check "
+ "--outdir %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct")))
+
+ @testcase(1564)
+ def test_build_rootfs_short(self):
+ """Test -f option"""
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "-f -o %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct")))
+
+ def test_build_rootfs_long(self):
+ """Test --build-rootfs option"""
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=core-image-minimal "
+ "--build-rootfs "
+ "--outdir %s" % self.resultdir).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*.direct")))
@testcase(1268)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
def test_rootfs_indirect_recipes(self):
"""Test usage of rootfs plugin with rootfs recipes"""
- wks = "directdisk-multi-rootfs"
- self.assertEqual(0, runCmd("wic create %s "
- "--image-name core-image-minimal "
- "--rootfs rootfs1=core-image-minimal "
- "--rootfs rootfs2=core-image-minimal" \
- % wks).status)
- self.assertEqual(1, len(glob(self.resultdir + "%s*.direct" % wks)))
+ status = runCmd("wic create directdisk-multi-rootfs "
+ "--image-name=core-image-minimal "
+ "--rootfs rootfs1=core-image-minimal "
+ "--rootfs rootfs2=core-image-minimal "
+ "--outdir %s" % self.resultdir).status
+ self.assertEqual(0, status)
+ self.assertEqual(1, len(glob(self.resultdir + "directdisk-multi-rootfs*.direct")))
@testcase(1269)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
def test_rootfs_artifacts(self):
"""Test usage of rootfs plugin with rootfs paths"""
- bbvars = dict((var.lower(), get_bb_var(var, 'core-image-minimal')) \
- for var in ('STAGING_DATADIR', 'DEPLOY_DIR_IMAGE',
- 'STAGING_DIR_NATIVE', 'IMAGE_ROOTFS'))
+ bb_vars = get_bb_vars(['STAGING_DATADIR', 'RECIPE_SYSROOT_NATIVE'],
+ 'wic-tools')
+ bb_vars.update(get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_ROOTFS'],
+ 'core-image-minimal'))
+ bbvars = {key.lower(): value for key, value in bb_vars.items()}
bbvars['wks'] = "directdisk-multi-rootfs"
+ bbvars['resultdir'] = self.resultdir
status = runCmd("wic create %(wks)s "
- "-b %(staging_datadir)s "
- "-k %(deploy_dir_image)s "
- "-n %(staging_dir_native)s "
+ "--bootimg-dir=%(staging_datadir)s "
+ "--kernel-dir=%(deploy_dir_image)s "
+ "--native-sysroot=%(recipe_sysroot_native)s "
"--rootfs-dir rootfs1=%(image_rootfs)s "
- "--rootfs-dir rootfs2=%(image_rootfs)s" \
- % bbvars).status
+ "--rootfs-dir rootfs2=%(image_rootfs)s "
+ "--outdir %(resultdir)s" % bbvars).status
+ self.assertEqual(0, status)
+ self.assertEqual(1, len(glob(self.resultdir + "%(wks)s-*.direct" % bbvars)))
+
+ def test_exclude_path(self):
+ """Test --exclude-path wks option."""
+
+ oldpath = os.environ['PATH']
+ os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
+
+ try:
+ wks_file = 'temp.wks'
+ with open(wks_file, 'w') as wks:
+ rootfs_dir = get_bb_var('IMAGE_ROOTFS', 'core-image-minimal')
+ wks.write("""
+part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path usr
+part /usr --source rootfs --ondisk mmcblk0 --fstype=ext4 --rootfs-dir %s/usr
+part /etc --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path bin/ --rootfs-dir %s/usr"""
+ % (rootfs_dir, rootfs_dir))
+ self.assertEqual(0, runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir)).status)
+
+ os.remove(wks_file)
+ wicout = glob(self.resultdir + "%s-*direct" % 'temp')
+ self.assertEqual(1, len(wicout))
+
+ wicimg = wicout[0]
+
+ # verify partition size with wic
+ res = runCmd("parted -m %s unit b p 2>/dev/null" % wicimg)
+ self.assertEqual(0, res.status)
+
+ # parse parted output which looks like this:
+ # BYT;\n
+ # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
+ # 1:0.00MiB:200MiB:200MiB:ext4::;\n
+ partlns = res.output.splitlines()[2:]
+
+ self.assertEqual(3, len(partlns))
+
+ for part in [1, 2, 3]:
+ part_file = os.path.join(self.resultdir, "selftest_img.part%d" % part)
+ partln = partlns[part-1].split(":")
+ self.assertEqual(7, len(partln))
+ start = int(partln[1].rstrip("B")) / 512
+ length = int(partln[3].rstrip("B")) / 512
+ self.assertEqual(0, runCmd("dd if=%s of=%s skip=%d count=%d" %
+ (wicimg, part_file, start, length)).status)
+
+ def extract_files(debugfs_output):
+ """
+ extract file names from the output of debugfs -R 'ls -p',
+ which looks like this:
+
+ /2/040755/0/0/.//\n
+ /2/040755/0/0/..//\n
+ /11/040700/0/0/lost+found^M//\n
+ /12/040755/1002/1002/run//\n
+ /13/040755/1002/1002/sys//\n
+ /14/040755/1002/1002/bin//\n
+ /80/040755/1002/1002/var//\n
+ /92/040755/1002/1002/tmp//\n
+ """
+ # NOTE the occasional ^M in file names
+ return [line.split('/')[5].strip() for line in \
+ debugfs_output.strip().split('/\n')]
+
+ # Test partition 1, should contain the normal root directories, except
+ # /usr.
+ res = runCmd("debugfs -R 'ls -p' %s 2>/dev/null" % \
+ os.path.join(self.resultdir, "selftest_img.part1"))
+ self.assertEqual(0, res.status)
+ files = extract_files(res.output)
+ self.assertIn("etc", files)
+ self.assertNotIn("usr", files)
+
+ # Partition 2, should contain common directories for /usr, not root
+ # directories.
+ res = runCmd("debugfs -R 'ls -p' %s 2>/dev/null" % \
+ os.path.join(self.resultdir, "selftest_img.part2"))
+ self.assertEqual(0, res.status)
+ files = extract_files(res.output)
+ self.assertNotIn("etc", files)
+ self.assertNotIn("usr", files)
+ self.assertIn("share", files)
+
+ # Partition 3, should contain the same as partition 2, including the bin
+ # directory, but not the files inside it.
+ res = runCmd("debugfs -R 'ls -p' %s 2>/dev/null" % \
+ os.path.join(self.resultdir, "selftest_img.part3"))
+ self.assertEqual(0, res.status)
+ files = extract_files(res.output)
+ self.assertNotIn("etc", files)
+ self.assertNotIn("usr", files)
+ self.assertIn("share", files)
+ self.assertIn("bin", files)
+ res = runCmd("debugfs -R 'ls -p bin' %s 2>/dev/null" % \
+ os.path.join(self.resultdir, "selftest_img.part3"))
+ self.assertEqual(0, res.status)
+ files = extract_files(res.output)
+ self.assertIn(".", files)
+ self.assertIn("..", files)
+ self.assertEqual(2, len(files))
+
+ for part in [1, 2, 3]:
+ part_file = os.path.join(self.resultdir, "selftest_img.part%d" % part)
+ os.remove(part_file)
+
+ finally:
+ os.environ['PATH'] = oldpath
+
+ def test_exclude_path_errors(self):
+ """Test --exclude-path wks option error handling."""
+ wks_file = 'temp.wks'
+
+ # Absolute argument.
+ with open(wks_file, 'w') as wks:
+ wks.write("part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path /usr")
+ self.assertNotEqual(0, runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir), ignore_status=True).status)
+ os.remove(wks_file)
+
+ # Argument pointing to parent directory.
+ with open(wks_file, 'w') as wks:
+ wks.write("part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path ././..")
+ self.assertNotEqual(0, runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir), ignore_status=True).status)
+ os.remove(wks_file)
+
+ @testcase(1496)
+ def test_bmap_short(self):
+ """Test generation of .bmap file -m option"""
+ cmd = "wic create wictestdisk -e core-image-minimal -m -o %s" % self.resultdir
+ status = runCmd(cmd).status
self.assertEqual(0, status)
- self.assertEqual(1, len(glob(self.resultdir + \
- "%(wks)s-*.direct" % bbvars)))
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*direct")))
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*direct.bmap")))
- @testcase(1346)
- def test_iso_image(self):
- """Test creation of hybrid iso image with legacy and EFI boot"""
- self.assertEqual(0, runCmd("wic create mkhybridiso "
- "--image-name core-image-minimal").status)
- self.assertEqual(1, len(glob(self.resultdir + "HYBRID_ISO_IMG-*.direct")))
- self.assertEqual(1, len(glob(self.resultdir + "HYBRID_ISO_IMG-*.iso")))
+ def test_bmap_long(self):
+ """Test generation of .bmap file --bmap option"""
+ cmd = "wic create wictestdisk -e core-image-minimal --bmap -o %s" % self.resultdir
+ status = runCmd(cmd).status
+ self.assertEqual(0, status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*direct")))
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*direct.bmap")))
+
+ def _get_image_env_path(self, image):
+ """Generate and obtain the path to <image>.env"""
+ if image not in self.wicenv_cache:
+ self.assertEqual(0, bitbake('%s -c do_rootfs_wicenv' % image).status)
+ bb_vars = get_bb_vars(['STAGING_DIR', 'MACHINE'], image)
+ stdir = bb_vars['STAGING_DIR']
+ machine = bb_vars['MACHINE']
+ self.wicenv_cache[image] = os.path.join(stdir, machine, 'imgdata')
+ return self.wicenv_cache[image]
@testcase(1347)
def test_image_env(self):
"""Test generation of <image>.env files."""
image = 'core-image-minimal'
- self.assertEqual(0, bitbake('%s -c do_rootfs_wicenv' % image).status)
- stdir = get_bb_var('STAGING_DIR_TARGET', image)
- imgdatadir = os.path.join(stdir, 'imgdata')
+ imgdatadir = self._get_image_env_path(image)
- basename = get_bb_var('IMAGE_BASENAME', image)
+ bb_vars = get_bb_vars(['IMAGE_BASENAME', 'WICVARS'], image)
+ basename = bb_vars['IMAGE_BASENAME']
self.assertEqual(basename, image)
path = os.path.join(imgdatadir, basename) + '.env'
self.assertTrue(os.path.isfile(path))
- wicvars = set(get_bb_var('WICVARS', image).split())
+ wicvars = set(bb_vars['WICVARS'].split())
# filter out optional variables
- wicvars = wicvars.difference(('HDDDIR', 'IMAGE_BOOT_FILES',
- 'INITRD', 'ISODIR'))
+ wicvars = wicvars.difference(('DEPLOY_DIR_IMAGE', 'IMAGE_BOOT_FILES',
+ 'INITRD', 'INITRD_LIVE', 'ISODIR'))
with open(path) as envfile:
content = dict(line.split("=", 1) for line in envfile)
# test if variables used by wic present in the .env file
@@ -220,13 +557,41 @@ class Wic(oeSelfTest):
self.assertTrue(var in content, "%s is not in .env file" % var)
self.assertTrue(content[var])
+ @testcase(1559)
+ def test_image_vars_dir_short(self):
+ """Test image vars directory selection -v option"""
+ image = 'core-image-minimal'
+ imgenvdir = self._get_image_env_path(image)
+
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=%s -v %s -o %s"
+ % (image, imgenvdir, self.resultdir)).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*direct")))
+
+ def test_image_vars_dir_long(self):
+ """Test image vars directory selection --vars option"""
+ image = 'core-image-minimal'
+ imgenvdir = self._get_image_env_path(image)
+ self.assertEqual(0, runCmd("wic create wictestdisk "
+ "--image-name=%s "
+ "--vars %s "
+ "--outdir %s"
+ % (image, imgenvdir, self.resultdir)).status)
+ self.assertEqual(1, len(glob(self.resultdir + "wictestdisk-*direct")))
+
@testcase(1351)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
def test_wic_image_type(self):
"""Test building wic images by bitbake"""
+ config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\
+ 'MACHINE_FEATURES_append = " efi"\n'
+ self.append_config(config)
self.assertEqual(0, bitbake('wic-image-minimal').status)
+ self.remove_config(config)
- deploy_dir = get_bb_var('DEPLOY_DIR_IMAGE')
- machine = get_bb_var('MACHINE')
+ bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'MACHINE'])
+ deploy_dir = bb_vars['DEPLOY_DIR_IMAGE']
+ machine = bb_vars['MACHINE']
prefix = os.path.join(deploy_dir, 'wic-image-minimal-%s.' % machine)
# check if we have result image and manifests symlinks
# pointing to existing files
@@ -235,68 +600,193 @@ class Wic(oeSelfTest):
self.assertTrue(os.path.islink(path))
self.assertTrue(os.path.isfile(os.path.realpath(path)))
- @testcase(1348)
- def test_qemux86_directdisk(self):
- """Test creation of qemux-86-directdisk image"""
- image = "qemux86-directdisk"
- self.assertEqual(0, runCmd("wic create %s -e core-image-minimal" \
- % image).status)
- self.assertEqual(1, len(glob(self.resultdir + "%s-*direct" % image)))
-
- @testcase(1349)
- def test_mkgummidisk(self):
- """Test creation of mkgummidisk image"""
- image = "mkgummidisk"
- self.assertEqual(0, runCmd("wic create %s -e core-image-minimal" \
- % image).status)
- self.assertEqual(1, len(glob(self.resultdir + "%s-*direct" % image)))
-
- @testcase(1350)
- def test_mkefidisk(self):
- """Test creation of mkefidisk image"""
- image = "mkefidisk"
- self.assertEqual(0, runCmd("wic create %s -e core-image-minimal" \
- % image).status)
- self.assertEqual(1, len(glob(self.resultdir + "%s-*direct" % image)))
-
- @testcase(1385)
- def test_directdisk_bootloader_config(self):
- """Test creation of directdisk-bootloader-config image"""
- image = "directdisk-bootloader-config"
- self.assertEqual(0, runCmd("wic create %s -e core-image-minimal" \
- % image).status)
- self.assertEqual(1, len(glob(self.resultdir + "%s-*direct" % image)))
-
@testcase(1422)
+ @only_for_arch(['i586', 'i686', 'x86_64'])
def test_qemu(self):
"""Test wic-image-minimal under qemu"""
+ config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\
+ 'MACHINE_FEATURES_append = " efi"\n'
+ self.append_config(config)
self.assertEqual(0, bitbake('wic-image-minimal').status)
+ self.remove_config(config)
with runqemu('wic-image-minimal', ssh=False) as qemu:
- command = "mount |grep '^/dev/' | cut -f1,3 -d ' '"
- status, output = qemu.run_serial(command)
- self.assertEqual(1, status, 'Failed to run command "%s": %s' % (command, output))
- self.assertEqual(output, '/dev/root /\r\n/dev/vda3 /mnt')
-
- def test_bmap(self):
- """Test generation of .bmap file"""
- image = "directdisk"
- status = runCmd("wic create %s -e core-image-minimal --bmap" % image).status
- self.assertEqual(0, status)
- self.assertEqual(1, len(glob(self.resultdir + "%s-*direct" % image)))
- self.assertEqual(1, len(glob(self.resultdir + "%s-*direct.bmap" % image)))
-
- def test_systemd_bootdisk(self):
- """Test creation of systemd-bootdisk image"""
- image = "systemd-bootdisk"
- self.assertEqual(0, runCmd("wic create %s -e core-image-minimal" \
- % image).status)
- self.assertEqual(1, len(glob(self.resultdir + "%s-*direct" % image)))
-
- def test_sdimage_bootpart(self):
- """Test creation of sdimage-bootpart image"""
- image = "sdimage-bootpart"
- self.write_config('IMAGE_BOOT_FILES = "bzImage"\n')
- self.assertEqual(0, runCmd("wic create %s -e core-image-minimal" \
- % image).status)
- self.assertEqual(1, len(glob(self.resultdir + "%s-*direct" % image)))
+ cmd = "mount |grep '^/dev/' | cut -f1,3 -d ' '"
+ status, output = qemu.run_serial(cmd)
+ self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
+ self.assertEqual(output, '/dev/root /\r\n/dev/sda3 /mnt')
+
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_qemu_efi(self):
+ """Test core-image-minimal efi image under qemu"""
+ config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "mkefidisk.wks"\n'
+ self.append_config(config)
+ self.assertEqual(0, bitbake('core-image-minimal ovmf').status)
+ self.remove_config(config)
+
+ with runqemu('core-image-minimal', ssh=False,
+ runqemuparams='ovmf', image_fstype='wic') as qemu:
+ cmd = "grep sda. /proc/partitions |wc -l"
+ status, output = qemu.run_serial(cmd)
+ self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
+ self.assertEqual(output, '3')
+
+ @staticmethod
+ def _make_fixed_size_wks(size):
+ """
+ Create a wks of an image with a single partition. Size of the partition is set
+ using --fixed-size flag. Returns a tuple: (path to wks file, wks image name)
+ """
+ with NamedTemporaryFile("w", suffix=".wks", delete=False) as tempf:
+ wkspath = tempf.name
+ tempf.write("part " \
+ "--source rootfs --ondisk hda --align 4 --fixed-size %d "
+ "--fstype=ext4\n" % size)
+ wksname = os.path.splitext(os.path.basename(wkspath))[0]
+
+ return wkspath, wksname
+
+ def test_fixed_size(self):
+ """
+ Test creation of a simple image with partition size controlled through
+ --fixed-size flag
+ """
+ wkspath, wksname = Wic._make_fixed_size_wks(200)
+
+ self.assertEqual(0, runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wkspath, self.resultdir)).status)
+ os.remove(wkspath)
+ wicout = glob(self.resultdir + "%s-*direct" % wksname)
+ self.assertEqual(1, len(wicout))
+
+ wicimg = wicout[0]
+
+ # verify partition size with wic
+ res = runCmd("parted -m %s unit mib p 2>/dev/null" % wicimg,
+ ignore_status=True,
+ native_sysroot=self.native_sysroot)
+ self.assertEqual(0, res.status)
+
+ # parse parted output which looks like this:
+ # BYT;\n
+ # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
+ # 1:0.00MiB:200MiB:200MiB:ext4::;\n
+ partlns = res.output.splitlines()[2:]
+
+ self.assertEqual(1, len(partlns))
+ self.assertEqual("1:0.00MiB:200MiB:200MiB:ext4::;", partlns[0])
+
+ def test_fixed_size_error(self):
+ """
+ Test creation of a simple image with partition size controlled through
+ --fixed-size flag. The size of partition is intentionally set to 1MiB
+ in order to trigger an error in wic.
+ """
+ wkspath, wksname = Wic._make_fixed_size_wks(1)
+
+ self.assertEqual(1, runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wkspath, self.resultdir), ignore_status=True).status)
+ os.remove(wkspath)
+ wicout = glob(self.resultdir + "%s-*direct" % wksname)
+ self.assertEqual(0, len(wicout))
+
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_rawcopy_plugin_qemu(self):
+ """Test rawcopy plugin in qemu"""
+ # build ext4 and wic images
+ for fstype in ("ext4", "wic"):
+ config = 'IMAGE_FSTYPES = "%s"\nWKS_FILE = "test_rawcopy_plugin.wks.in"\n' % fstype
+ self.append_config(config)
+ self.assertEqual(0, bitbake('core-image-minimal').status)
+ self.remove_config(config)
+
+ with runqemu('core-image-minimal', ssh=False, image_fstype='wic') as qemu:
+ cmd = "grep sda. /proc/partitions |wc -l"
+ status, output = qemu.run_serial(cmd)
+ self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
+ self.assertEqual(output, '2')
+
+ def test_rawcopy_plugin(self):
+ """Test rawcopy plugin"""
+ img = 'core-image-minimal'
+ machine = get_bb_var('MACHINE', img)
+ with NamedTemporaryFile("w", suffix=".wks") as wks:
+ wks.writelines(['part /boot --active --source bootimg-pcbios\n',
+ 'part / --source rawcopy --sourceparams="file=%s-%s.ext4" --use-uuid\n'\
+ % (img, machine),
+ 'bootloader --timeout=0 --append="console=ttyS0,115200n8"\n'])
+ wks.flush()
+ cmd = "wic create %s -e %s -o %s" % (wks.name, img, self.resultdir)
+ self.assertEqual(0, runCmd(cmd).status)
+ wksname = os.path.splitext(os.path.basename(wks.name))[0]
+ out = glob(self.resultdir + "%s-*direct" % wksname)
+ self.assertEqual(1, len(out))
+
+ def test_fs_types(self):
+ """Test filesystem types for empty and not empty partitions"""
+ img = 'core-image-minimal'
+ with NamedTemporaryFile("w", suffix=".wks") as wks:
+ wks.writelines(['part ext2 --fstype ext2 --source rootfs\n',
+ 'part btrfs --fstype btrfs --source rootfs --size 40M\n',
+ 'part squash --fstype squashfs --source rootfs\n',
+ 'part swap --fstype swap --size 1M\n',
+ 'part emptyvfat --fstype vfat --size 1M\n',
+ 'part emptymsdos --fstype msdos --size 1M\n',
+ 'part emptyext2 --fstype ext2 --size 1M\n',
+ 'part emptybtrfs --fstype btrfs --size 100M\n'])
+ wks.flush()
+ cmd = "wic create %s -e %s -o %s" % (wks.name, img, self.resultdir)
+ self.assertEqual(0, runCmd(cmd).status)
+ wksname = os.path.splitext(os.path.basename(wks.name))[0]
+ out = glob(self.resultdir + "%s-*direct" % wksname)
+ self.assertEqual(1, len(out))
+
+ def test_kickstart_parser(self):
+ """Test wks parser options"""
+ with NamedTemporaryFile("w", suffix=".wks") as wks:
+ wks.writelines(['part / --fstype ext3 --source rootfs --system-id 0xFF '\
+ '--overhead-factor 1.2 --size 100k\n'])
+ wks.flush()
+ cmd = "wic create %s -e core-image-minimal -o %s" % (wks.name, self.resultdir)
+ self.assertEqual(0, runCmd(cmd).status)
+ wksname = os.path.splitext(os.path.basename(wks.name))[0]
+ out = glob(self.resultdir + "%s-*direct" % wksname)
+ self.assertEqual(1, len(out))
+
+ def test_image_bootpart_globbed(self):
+ """Test globbed sources with image-bootpart plugin"""
+ img = "core-image-minimal"
+ cmd = "wic create sdimage-bootpart -e %s -o %s" % (img, self.resultdir)
+ config = 'IMAGE_BOOT_FILES = "%s*"' % get_bb_var('KERNEL_IMAGETYPE', img)
+ self.append_config(config)
+ self.assertEqual(0, runCmd(cmd).status)
+ self.remove_config(config)
+ self.assertEqual(1, len(glob(self.resultdir + "sdimage-bootpart-*direct")))
+
+ def test_sparse_copy(self):
+ """Test sparse_copy with FIEMAP and SEEK_HOLE filemap APIs"""
+ libpath = os.path.join(get_bb_var('COREBASE'), 'scripts', 'lib', 'wic')
+ sys.path.insert(0, libpath)
+ from filemap import FilemapFiemap, FilemapSeek, sparse_copy, ErrorNotSupp
+ with NamedTemporaryFile("w", suffix=".wic-sparse") as sparse:
+ src_name = sparse.name
+ src_size = 1024 * 10
+ sparse.truncate(src_size)
+ # write one byte to the file
+ with open(src_name, 'r+b') as sfile:
+ sfile.seek(1024 * 4)
+ sfile.write(b'\x00')
+ dest = sparse.name + '.out'
+ # copy src file to dest using different filemap APIs
+ for api in (FilemapFiemap, FilemapSeek, None):
+ if os.path.exists(dest):
+ os.unlink(dest)
+ try:
+ sparse_copy(sparse.name, dest, api=api)
+ except ErrorNotSupp:
+ continue # skip unsupported API
+ dest_stat = os.stat(dest)
+ self.assertEqual(dest_stat.st_size, src_size)
+ # 8 blocks is 4K (physical sector size)
+ self.assertEqual(dest_stat.st_blocks, 8)
+ os.unlink(dest)
OpenPOWER on IntegriCloud