From patchwork Mon Feb 26 09:19:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alexis_Lothor=C3=A9?= X-Patchwork-Id: 40075 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAEF7C54E56 for ; Mon, 26 Feb 2024 09:19:38 +0000 (UTC) Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by mx.groups.io with SMTP id smtpd.web11.16677.1708939174531800098 for ; Mon, 26 Feb 2024 01:19:35 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=ftx+Iobu; spf=pass (domain: bootlin.com, ip: 217.70.183.197, mailfrom: alexis.lothore@bootlin.com) Received: by mail.gandi.net (Postfix) with ESMTPSA id C52291C0008; Mon, 26 Feb 2024 09:19:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1708939173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nlKC1Y4YQ0d74xo32fD1eWVIGdKj0SmcVaahgs5G2Us=; b=ftx+IobuwT7bAAWxMoICsOvoVyXX3dqjVX3L91AiGSbMAzTBoxqGQS4KU5D9XF/DlDCUk/ ZBAFcHqVTWMJ2TiNDML0nn37SoZZywUIQmZkqP+RN2tJZEHzLRurCPxB07bBvb27eYriSn FfQVaZGO+fT95Lt16tvseRADMfubV9l4prFqWHKf0Hzwdz+fpSyrvA6Cq0kcWxdp9LVvnE /9WXtr0/Jvgg33+X2LOVubyP6vKXgINQc7LCWYuJtQNgbhASnJEn3gbITCRmZU0FSaHTvb VnQAgNIpMY3n9vpzsie9AeyZSXaL2rZNpcNtjbFfItuOhVUR9aXAdgwB4tOY9Q== From: =?utf-8?q?Alexis_Lothor=C3=A9?= To: Cc: Thomas Petazzoni , Alexandre Belloni Subject: [OE-Core][PATCH v4 1/5] lib/oeqa: share get_json_result_dir helper Date: Mon, 26 Feb 2024 10:19:18 +0100 Message-ID: <20240226091922.41801-2-alexis.lothore@bootlin.com> X-Mailer: git-send-email 2.43.1 In-Reply-To: <20240226091922.41801-1-alexis.lothore@bootlin.com> References: <20240226091922.41801-1-alexis.lothore@bootlin.com> MIME-Version: 1.0 X-GND-Sasl: alexis.lothore@bootlin.com List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 26 Feb 2024 09:19:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/196192 From: Alexis Lothoré Multiple places in oeqa need to get the log output path, and redefine a small helper to accomplish this Define this helper in lib/oeqa/utils/__init__.py and import it wherever needed to allow using it. Signed-off-by: Alexis Lothoré --- There is one additional place re-definining (slightly) differently this helper, which is in selftest/context.py. This one does not check OEQA_JSON_RESULT_DIR from the datastore but through test data embedded in the test context. Based on Richard's feedback in v2, the datastore functions may be correctly simulated even in this case, so I may do some tests and come up with a patch after this series Changes in v4: - fix missed function name update in TestSDKExt Changes in v3: - None Changes in v2: - patch introduced --- meta/classes-recipe/testimage.bbclass | 12 +++--------- meta/lib/oeqa/sdk/testsdk.py | 11 ++--------- meta/lib/oeqa/sdkext/testsdk.py | 3 ++- meta/lib/oeqa/utils/__init__.py | 7 +++++++ 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/meta/classes-recipe/testimage.bbclass b/meta/classes-recipe/testimage.bbclass index d076102f9691..959c226072aa 100644 --- a/meta/classes-recipe/testimage.bbclass +++ b/meta/classes-recipe/testimage.bbclass @@ -149,13 +149,6 @@ def get_testimage_configuration(d, test_type, machine): return configuration get_testimage_configuration[vardepsexclude] = "DATETIME" -def get_testimage_json_result_dir(d): - json_result_dir = os.path.join(d.getVar("LOG_DIR"), 'oeqa') - custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR") - if custom_json_result_dir: - json_result_dir = custom_json_result_dir - return json_result_dir - def get_testimage_result_id(configuration): return '%s_%s_%s_%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], configuration['MACHINE'], configuration['STARTTIME']) @@ -224,6 +217,7 @@ def testimage_main(d): from oeqa.core.target.qemu import supported_fstypes from oeqa.core.utils.test import getSuiteCases from oeqa.utils import make_logger_bitbake_compatible + from oeqa.utils import get_json_result_dir def sigterm_exception(signum, stackframe): """ @@ -426,14 +420,14 @@ def testimage_main(d): # Show results (if we have them) if results: configuration = get_testimage_configuration(d, 'runtime', machine) - results.logDetails(get_testimage_json_result_dir(d), + results.logDetails(get_json_result_dir(d), configuration, get_testimage_result_id(configuration), dump_streams=d.getVar('TESTREPORT_FULLLOGS')) results.logSummary(pn) # Copy additional logs to tmp/log/oeqa so it's easier to find them - targetdir = os.path.join(get_testimage_json_result_dir(d), d.getVar("PN")) + targetdir = os.path.join(get_json_result_dir(d), d.getVar("PN")) os.makedirs(targetdir, exist_ok=True) os.symlink(bootlog, os.path.join(targetdir, os.path.basename(bootlog))) os.symlink(d.getVar("BB_LOGFILE"), os.path.join(targetdir, os.path.basename(d.getVar("BB_LOGFILE") + "." + d.getVar('DATETIME')))) diff --git a/meta/lib/oeqa/sdk/testsdk.py b/meta/lib/oeqa/sdk/testsdk.py index b4719110edbc..518b09febb61 100644 --- a/meta/lib/oeqa/sdk/testsdk.py +++ b/meta/lib/oeqa/sdk/testsdk.py @@ -22,14 +22,6 @@ class TestSDKBase(object): 'LAYERS': get_layers(d.getVar("BBLAYERS"))} return configuration - @staticmethod - def get_sdk_json_result_dir(d): - json_result_dir = os.path.join(d.getVar("LOG_DIR"), 'oeqa') - custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR") - if custom_json_result_dir: - json_result_dir = custom_json_result_dir - return json_result_dir - @staticmethod def get_sdk_result_id(configuration): return '%s_%s_%s_%s_%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], configuration['SDKMACHINE'], configuration['MACHINE'], configuration['STARTTIME']) @@ -72,6 +64,7 @@ class TestSDK(TestSDKBase): from bb.utils import export_proxies from oeqa.utils import make_logger_bitbake_compatible + from oeqa.utils import get_json_result_dir pn = d.getVar("PN") logger = make_logger_bitbake_compatible(logging.getLogger("BitBake")) @@ -134,7 +127,7 @@ class TestSDK(TestSDKBase): component = "%s %s" % (pn, self.context_executor_class.name) context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env)) configuration = self.get_sdk_configuration(d, self.test_type) - result.logDetails(self.get_sdk_json_result_dir(d), + result.logDetails(get_json_result_dir(d), configuration, self.get_sdk_result_id(configuration)) result.logSummary(component, context_msg) diff --git a/meta/lib/oeqa/sdkext/testsdk.py b/meta/lib/oeqa/sdkext/testsdk.py index 159f0d135b9a..9d5a99d900fd 100644 --- a/meta/lib/oeqa/sdkext/testsdk.py +++ b/meta/lib/oeqa/sdkext/testsdk.py @@ -16,6 +16,7 @@ class TestSDKExt(TestSDKBase): from bb.utils import export_proxies from oeqa.utils import avoid_paths_in_environ, make_logger_bitbake_compatible, subprocesstweak from oeqa.sdkext.context import OESDKExtTestContext, OESDKExtTestContextExecutor + from oeqa.utils import get_json_result_dir pn = d.getVar("PN") logger = make_logger_bitbake_compatible(logging.getLogger("BitBake")) @@ -91,7 +92,7 @@ class TestSDKExt(TestSDKBase): component = "%s %s" % (pn, OESDKExtTestContextExecutor.name) context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env)) configuration = self.get_sdk_configuration(d, 'sdkext') - result.logDetails(self.get_sdk_json_result_dir(d), + result.logDetails(get_json_result_dir(d), configuration, self.get_sdk_result_id(configuration)) result.logSummary(component, context_msg) diff --git a/meta/lib/oeqa/utils/__init__.py b/meta/lib/oeqa/utils/__init__.py index fbc7f7d525d8..53bdcbf26618 100644 --- a/meta/lib/oeqa/utils/__init__.py +++ b/meta/lib/oeqa/utils/__init__.py @@ -90,3 +90,10 @@ def load_test_components(logger, executor): "_executor_class defined." % (comp_name, comp_context)) return components + +def get_json_result_dir(d): + json_result_dir = os.path.join(d.getVar("LOG_DIR"), 'oeqa') + custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR") + if custom_json_result_dir: + json_result_dir = custom_json_result_dir + return json_result_dir \ No newline at end of file From patchwork Mon Feb 26 09:19:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alexis_Lothor=C3=A9?= X-Patchwork-Id: 40072 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71F40C54E49 for ; Mon, 26 Feb 2024 09:19:38 +0000 (UTC) Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by mx.groups.io with SMTP id smtpd.web11.16678.1708939174549404777 for ; Mon, 26 Feb 2024 01:19:35 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=Ddozx4cl; spf=pass (domain: bootlin.com, ip: 217.70.183.197, mailfrom: alexis.lothore@bootlin.com) Received: by mail.gandi.net (Postfix) with ESMTPSA id 1425A1C0009; Mon, 26 Feb 2024 09:19:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1708939173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zerYml7HI3cI7My8zk1hkLYlvZraYCwMGnu812fhPZU=; b=Ddozx4clzx0ai3genE5grUaG3QPdz1wVcEO9hmdWngbb5ElBfJ+Eb1ryYMRQfWNFlY2a4E pbvZBfu7mywH4XG2P6LWb1iWr2a/Pby0DvyTLnRQ15N3qRsg6CGFjasQUj8OMkzHLVMnMy RKIFD0iqq/cnErjBK+2BtIhSrNDCTE71fUdAp9hLLeMOKptAcN+IE3BeNKBXxMF1IEzLqT 3xb8v6Mj6Y9jAKCGejFLNxNPO1EWirYn8NOyLM/rDzGYJ/I+3pyO5R/ks/Jy7JULd5TK2G PKAd/3IiOEiczVGZ50TbAxSn8u5X0RjGrx2oLKhxTwphTHAozaZc7G/fAP5jCw== From: =?utf-8?q?Alexis_Lothor=C3=A9?= To: Cc: Thomas Petazzoni , Alexandre Belloni Subject: [OE-Core][PATCH v4 2/5] testimage: create a list of failed test post actions Date: Mon, 26 Feb 2024 10:19:19 +0100 Message-ID: <20240226091922.41801-3-alexis.lothore@bootlin.com> X-Mailer: git-send-email 2.43.1 In-Reply-To: <20240226091922.41801-1-alexis.lothore@bootlin.com> References: <20240226091922.41801-1-alexis.lothore@bootlin.com> MIME-Version: 1.0 X-GND-Sasl: alexis.lothore@bootlin.com List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 26 Feb 2024 09:19:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/196191 From: Alexis Lothoré testimage is able to detect whenever a test run leads to some tests failing, and execute some actions in this case. The only action currently defined in such case is to retrieve artifacts from the target under test, as listed in TESTIMAGE_FAILED_QA_ARTIFACTS In order to be able to add multiple actions, define a central function to gather all "post actions" to run whenever a test has failed (run_failed_tests_post_actions). This function contains a table listing all functions to be called whenever a test fails. Any function in this table will be provided with bitbake internal data dictionary ("d") and the current runtime testing context ("tc"). Isolate all this feature in a dedicated postactions.py file inherited by testimage. This patch does not bring any functional change. Signed-off-by: Alexis Lothoré --- Changes in v2: - move functions in a lib in oeqa instead of a bbclass - use new shared helper get_json_result_dir() --- meta/classes-recipe/testimage.bbclass | 41 +--------------- meta/lib/oeqa/utils/postactions.py | 68 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 meta/lib/oeqa/utils/postactions.py diff --git a/meta/classes-recipe/testimage.bbclass b/meta/classes-recipe/testimage.bbclass index 959c226072aa..ad040ee8f071 100644 --- a/meta/classes-recipe/testimage.bbclass +++ b/meta/classes-recipe/testimage.bbclass @@ -170,40 +170,6 @@ def get_testimage_boot_patterns(d): boot_patterns[flag] = flagval.encode().decode('unicode-escape') return boot_patterns -def get_artifacts_list(target, raw_list): - result = [] - # Passed list may contains patterns in paths, expand them directly on target - for raw_path in raw_list.split(): - cmd = f"for p in {raw_path}; do if [ -e $p ]; then echo $p; fi; done" - try: - status, output = target.run(cmd) - if status != 0 or not output: - raise Exception() - result += output.split() - except: - bb.note(f"No file/directory matching path {raw_path}") - - return result - -def retrieve_test_artifacts(target, artifacts_list, target_dir): - import shutil - - local_artifacts_dir = os.path.join(target_dir, "artifacts") - if os.path.isdir(local_artifacts_dir): - shutil.rmtree(local_artifacts_dir) - - os.makedirs(local_artifacts_dir) - for artifact_path in artifacts_list: - if not os.path.isabs(artifact_path): - bb.warn(f"{artifact_path} is not an absolute path") - continue - try: - dest_dir = os.path.join(local_artifacts_dir, os.path.dirname(artifact_path[1:])) - os.makedirs(dest_dir, exist_ok=True) - target.copyFrom(artifact_path, dest_dir) - except Exception as e: - bb.warn(f"Can not retrieve {artifact_path} from test target: {e}") - def testimage_main(d): import os import json @@ -218,6 +184,7 @@ def testimage_main(d): from oeqa.core.utils.test import getSuiteCases from oeqa.utils import make_logger_bitbake_compatible from oeqa.utils import get_json_result_dir + from oeqa.utils.postactions import run_failed_tests_post_actions def sigterm_exception(signum, stackframe): """ @@ -400,11 +367,7 @@ def testimage_main(d): results = tc.runTests() complete = True if results.hasAnyFailingTest(): - artifacts_list = get_artifacts_list(tc.target, d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS")) - if not artifacts_list: - bb.warn("Could not load artifacts list, skip artifacts retrieval") - else: - retrieve_test_artifacts(tc.target, artifacts_list, get_testimage_json_result_dir(d)) + run_failed_tests_post_actions(d, tc) except (KeyboardInterrupt, BlockingIOError) as err: if isinstance(err, KeyboardInterrupt): bb.error('testimage interrupted, shutting down...') diff --git a/meta/lib/oeqa/utils/postactions.py b/meta/lib/oeqa/utils/postactions.py new file mode 100644 index 000000000000..09c338ef6886 --- /dev/null +++ b/meta/lib/oeqa/utils/postactions.py @@ -0,0 +1,68 @@ +# +# Copyright OpenEmbedded Contributors +# +# SPDX-License-Identifier: MIT +# + +# Run a set of actions after tests. The runner provides internal data +# dictionary as well as test context to any action to run. + +from oeqa.utils import get_json_result_dir + +################################################################## +# Artifacts retrieval +################################################################## + +def get_artifacts_list(target, raw_list): + result = [] + # Passed list may contains patterns in paths, expand them directly on target + for raw_path in raw_list.split(): + cmd = f"for p in {raw_path}; do if [ -e $p ]; then echo $p; fi; done" + try: + status, output = target.run(cmd) + if status != 0 or not output: + raise Exception() + result += output.split() + except: + bb.note(f"No file/directory matching path {raw_path}") + + return result + +def retrieve_test_artifacts(target, artifacts_list, target_dir): + import shutil + + local_artifacts_dir = os.path.join(target_dir, "artifacts") + if os.path.isdir(local_artifacts_dir): + shutil.rmtree(local_artifacts_dir) + + os.makedirs(local_artifacts_dir) + for artifact_path in artifacts_list: + if not os.path.isabs(artifact_path): + bb.warn(f"{artifact_path} is not an absolute path") + continue + try: + dest_dir = os.path.join(local_artifacts_dir, os.path.dirname(artifact_path[1:])) + os.makedirs(dest_dir, exist_ok=True) + target.copyFrom(artifact_path, dest_dir) + except Exception as e: + bb.warn(f"Can not retrieve {artifact_path} from test target: {e}") + +def list_and_fetch_failed_tests_artifacts(d, tc): + artifacts_list = get_artifacts_list(tc.target, d.getVar("TESTIMAGE_FAILED_QA_ARTIFACTS")) + if not artifacts_list: + bb.warn("Could not load artifacts list, skip artifacts retrieval") + else: + retrieve_test_artifacts(tc.target, artifacts_list, get_json_result_dir(d)) + + +################################################################## +# General post actions runner +################################################################## + +def run_failed_tests_post_actions(d, tc): + post_actions=[ + list_and_fetch_failed_tests_artifacts + ] + + for action in post_actions: + action(d, tc) From patchwork Mon Feb 26 09:19:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alexis_Lothor=C3=A9?= X-Patchwork-Id: 40071 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C636C54E51 for ; Mon, 26 Feb 2024 09:19:38 +0000 (UTC) Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by mx.groups.io with SMTP id smtpd.web10.16876.1708939174784555568 for ; Mon, 26 Feb 2024 01:19:35 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=UIczwLvY; spf=pass (domain: bootlin.com, ip: 217.70.183.197, mailfrom: alexis.lothore@bootlin.com) Received: by mail.gandi.net (Postfix) with ESMTPSA id 54B731C000C; Mon, 26 Feb 2024 09:19:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1708939173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oEgJ6pgDo3Pq0ewsLn/7kmErJddBHyBge+1pfyV16N0=; b=UIczwLvYXKHGngrUjdLfUbq9I9o2gX+m8PZCh+zYdz1+rEQRS1wYMA3DuZ5ja+OcD/a3Ka hNfZS4GNn5+kA2iF21ArSKzfJ6A8LWOTm+vS46ZvqkNDcqNYLN3xV+atwAY0DU6596dPxP W55fawIT6bsVx2qbs2+m+5M28sjOB1smXDsPqVDvYn0fgYqXhkXjPygcXNXOAKV3a3T1fy UZzHuAtpZnfs+Qk8op/BSxq2L+EiepWnCag/ANzYkjVd4vMb6VnGIFC/d1dOenk0AJp6IT xDWQJCeWwZixb/yinziv//xnYOoVU9LdhPyAqe/uT3UIlOc3YTwPAkBxUZ/BoA== From: =?utf-8?q?Alexis_Lothor=C3=A9?= To: Cc: Thomas Petazzoni , Alexandre Belloni Subject: [OE-Core][PATCH v4 3/5] oeqa/utils/postactions: isolate directory creation in dedicated action Date: Mon, 26 Feb 2024 10:19:20 +0100 Message-ID: <20240226091922.41801-4-alexis.lothore@bootlin.com> X-Mailer: git-send-email 2.43.1 In-Reply-To: <20240226091922.41801-1-alexis.lothore@bootlin.com> References: <20240226091922.41801-1-alexis.lothore@bootlin.com> MIME-Version: 1.0 X-GND-Sasl: alexis.lothore@bootlin.com List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 26 Feb 2024 09:19:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/196193 From: Alexis Lothoré In order to be able to create actions that could store new files during failed test post actions, we need to split artifacts directory creation from artifacts retrieval. Create a new dedicated action to create artifacts main directory so we can add actions creating files in this new directory, without worrying about actions order if at least this action is set first. Signed-off-by: Alexis Lothoré --- Changes in v2: - use new shared helper get_json_result_dir() --- meta/lib/oeqa/utils/postactions.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/meta/lib/oeqa/utils/postactions.py b/meta/lib/oeqa/utils/postactions.py index 09c338ef6886..7014b2830a9c 100644 --- a/meta/lib/oeqa/utils/postactions.py +++ b/meta/lib/oeqa/utils/postactions.py @@ -9,6 +9,15 @@ from oeqa.utils import get_json_result_dir +def create_artifacts_directory(d, tc): + import shutil + + local_artifacts_dir = os.path.join(get_json_result_dir(d), "artifacts") + if os.path.isdir(local_artifacts_dir): + shutil.rmtree(local_artifacts_dir) + + os.makedirs(local_artifacts_dir) + ################################################################## # Artifacts retrieval ################################################################## @@ -29,13 +38,7 @@ def get_artifacts_list(target, raw_list): return result def retrieve_test_artifacts(target, artifacts_list, target_dir): - import shutil - local_artifacts_dir = os.path.join(target_dir, "artifacts") - if os.path.isdir(local_artifacts_dir): - shutil.rmtree(local_artifacts_dir) - - os.makedirs(local_artifacts_dir) for artifact_path in artifacts_list: if not os.path.isabs(artifact_path): bb.warn(f"{artifact_path} is not an absolute path") @@ -61,6 +64,7 @@ def list_and_fetch_failed_tests_artifacts(d, tc): def run_failed_tests_post_actions(d, tc): post_actions=[ + create_artifacts_directory, list_and_fetch_failed_tests_artifacts ] From patchwork Mon Feb 26 09:19:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alexis_Lothor=C3=A9?= X-Patchwork-Id: 40073 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80AE8C48BF6 for ; Mon, 26 Feb 2024 09:19:38 +0000 (UTC) Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by mx.groups.io with SMTP id smtpd.web11.16679.1708939175028429530 for ; Mon, 26 Feb 2024 01:19:35 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=pZLPNdMK; spf=pass (domain: bootlin.com, ip: 217.70.183.197, mailfrom: alexis.lothore@bootlin.com) Received: by mail.gandi.net (Postfix) with ESMTPSA id 8CD901C000D; Mon, 26 Feb 2024 09:19:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1708939173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2gZl/CX2XdTl9L5zW6yK1ki4i4/oUog+WKw64t/cC68=; b=pZLPNdMKvc4p46a8+Kqu7GqXBaRh9gVRLeaP5ODifJmtY+TB+5y90cX04RfIAPYtqksq9W SbkzpSq8JxLo+ex47YI/8DMHn5q2BDWlMkChLlFIgOGh8pG29ijWD2HGL60vVGTv9h+zJq l8Hze03CHq6M0dRtBv4feBeGSl6m4WLE3em1j0RRuRjG+3cTg3i9NcmoaaMws+t2tejTRG Vbd+nL0KVFjHkVid95L3g84QrYHcnnpeTejTV1GADj5cWQxU5gpkwEn8y1mGozY1OhXyZt A34e0TBIu5KZ/faCyWSv2Mf8Z4auDhaC8ZMDVCQPt7Pgn5wBQ66z2fKOeWeTig== From: =?utf-8?q?Alexis_Lothor=C3=A9?= To: Cc: Thomas Petazzoni , Alexandre Belloni Subject: [OE-Core][PATCH v4 4/5] oeqa/utils/postactions: add target disk usage stat as post action Date: Mon, 26 Feb 2024 10:19:21 +0100 Message-ID: <20240226091922.41801-5-alexis.lothore@bootlin.com> X-Mailer: git-send-email 2.43.1 In-Reply-To: <20240226091922.41801-1-alexis.lothore@bootlin.com> References: <20240226091922.41801-1-alexis.lothore@bootlin.com> MIME-Version: 1.0 X-GND-Sasl: alexis.lothore@bootlin.com List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 26 Feb 2024 09:19:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/196195 From: Alexis Lothoré In order to debug issues related to disk space (see [1]), add a failed tests post action to retrieve disk usage on the target. Rely on the test context object to run the corresponding command onto the target [1] https://bugzilla.yoctoproject.org/show_bug.cgi?id=15220 Signed-off-by: Alexis Lothoré --- Changes in v2: - - use new shared helper get_json_result_dir() --- meta/lib/oeqa/utils/postactions.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/meta/lib/oeqa/utils/postactions.py b/meta/lib/oeqa/utils/postactions.py index 7014b2830a9c..008968b56a3f 100644 --- a/meta/lib/oeqa/utils/postactions.py +++ b/meta/lib/oeqa/utils/postactions.py @@ -18,6 +18,20 @@ def create_artifacts_directory(d, tc): os.makedirs(local_artifacts_dir) +################################################################## +# Host/target statistics +################################################################## + +def get_target_disk_usage(d, tc): + output_file = os.path.join(get_json_result_dir(d), "artifacts", "target_disk_usage.txt") + try: + (status, output) = tc.target.run('df -hl') + with open(output_file, 'w') as f: + f.write(output) + f.write("\n") + except Exception as e: + bb.warn(f"Can not get target disk usage: {e}") + ################################################################## # Artifacts retrieval ################################################################## @@ -65,7 +79,8 @@ def list_and_fetch_failed_tests_artifacts(d, tc): def run_failed_tests_post_actions(d, tc): post_actions=[ create_artifacts_directory, - list_and_fetch_failed_tests_artifacts + list_and_fetch_failed_tests_artifacts, + get_target_disk_usage ] for action in post_actions: From patchwork Mon Feb 26 09:19:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alexis_Lothor=C3=A9?= X-Patchwork-Id: 40074 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71F7AC54E4A for ; Mon, 26 Feb 2024 09:19:38 +0000 (UTC) Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by mx.groups.io with SMTP id smtpd.web11.16680.1708939175308044001 for ; Mon, 26 Feb 2024 01:19:35 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=CLwvAaju; spf=pass (domain: bootlin.com, ip: 217.70.183.197, mailfrom: alexis.lothore@bootlin.com) Received: by mail.gandi.net (Postfix) with ESMTPSA id C8B1F1C0016; Mon, 26 Feb 2024 09:19:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1708939173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5t1v6ah5B92Jt5MkGcmp5hSvI5wevVDMx3spVHHIIrE=; b=CLwvAajuyf6gdOEqJBZYVx7kVFdJ7EgFn5YqHRHtpMtRIUl/KaB7o1P8c6R2zkmCUm5nQy XewMYDxLAlYMQa4tixSNOA6Hu3IphH17mUKPHLoHLkEDjfPRm3f/ly3J4893Xgr7xHQj1n PjPgy/gUc75mAtn4MyWSJ61cWiJfxdEAEmFnGg82FE/DagNn8qzHQMAr7h85B8VHacnwe5 EvZg4pIlZlEuZtBmlrefiy8KtOKd6yw5EtllXh/KHkCAdKyX33xOVwDqOBwgAgEsWLrFj2 9TCdPN/YxylBk3rd3dSe6l25+6mEnPONcVcKnpZgdmEGSITMy+wu/iJq6FNdPQ== From: =?utf-8?q?Alexis_Lothor=C3=A9?= To: Cc: Thomas Petazzoni , Alexandre Belloni Subject: [OE-Core][PATCH v4 5/5] oeqa/utils/postactions: testimage: add host disk usage stat as post action Date: Mon, 26 Feb 2024 10:19:22 +0100 Message-ID: <20240226091922.41801-6-alexis.lothore@bootlin.com> X-Mailer: git-send-email 2.43.1 In-Reply-To: <20240226091922.41801-1-alexis.lothore@bootlin.com> References: <20240226091922.41801-1-alexis.lothore@bootlin.com> MIME-Version: 1.0 X-GND-Sasl: alexis.lothore@bootlin.com List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 26 Feb 2024 09:19:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/196196 From: Alexis Lothoré Since the target under test can be a virtualized guest, when some tests fail because of disk usage (see [1]), also fetch disk usage statistics from host to allow checking whether a host disk space saturation could affect running tests. [1] https://bugzilla.yoctoproject.org/show_bug.cgi?id=15220 Signed-off-by: Alexis Lothoré --- Changes in v2: - use new shared helper get_json_result_dir() --- meta/lib/oeqa/utils/postactions.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/meta/lib/oeqa/utils/postactions.py b/meta/lib/oeqa/utils/postactions.py index 008968b56a3f..03cecdc21578 100644 --- a/meta/lib/oeqa/utils/postactions.py +++ b/meta/lib/oeqa/utils/postactions.py @@ -32,6 +32,16 @@ def get_target_disk_usage(d, tc): except Exception as e: bb.warn(f"Can not get target disk usage: {e}") +def get_host_disk_usage(d, tc): + import subprocess + + output_file = os.path.join(get_json_result_dir(d), "artifacts", "host_disk_usage.txt") + try: + with open(output_file, 'w') as f: + output = subprocess.run(['/usr/bin/df', '-hl'], check=True, text=True, stdout=f) + except Exception as e: + bb.warn(f"Can not get host disk usage: {e}") + ################################################################## # Artifacts retrieval ################################################################## @@ -80,7 +90,8 @@ def run_failed_tests_post_actions(d, tc): post_actions=[ create_artifacts_directory, list_and_fetch_failed_tests_artifacts, - get_target_disk_usage + get_target_disk_usage, + get_host_disk_usage ] for action in post_actions: