From patchwork Fri Aug 18 14:17:10 2023 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: 29130 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 E1EB0C77B7A for ; Fri, 18 Aug 2023 14:16:52 +0000 (UTC) Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by mx.groups.io with SMTP id smtpd.web11.12488.1692368202317212836 for ; Fri, 18 Aug 2023 07:16:43 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=jAbvAS7L; spf=pass (domain: bootlin.com, ip: 217.70.183.199, mailfrom: alexis.lothore@bootlin.com) Received: by mail.gandi.net (Postfix) with ESMTPSA id E6592FF809; Fri, 18 Aug 2023 14:16:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1692368200; 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=SmT0u0TIrwCp/pxAQVCqaRQfsW0cJTexpNAiCHUL4io=; b=jAbvAS7LCvCjFANbys1tLU8+zzY6ScyfE0sQUt2X4UbmLyRNU21GQc+0lRXf9dHnGYYl/s kJzI5/2Nd/p5eANAR8I6d3BVaCxTmQuRetHhivgFKHlcwZXLurAYZIvnWfSV7kj26wUMg8 3q1x+B+JDHmbvSx3r1+8krg8BI3ev7vhfUU2FZisgZMu5oaR1jZMJWb12Jv1gVihtvXzDZ A5FB9ddTo1Oj248twXtvxJKtVilQZ/xXgSpsgIE16waEUgV165pjEbA+kWY3gqJWiz6Nzo 1SRUAaOE8ByCTfzVmbY/l1DhhvhF0RC7ArNeVGrzGpyFJutvmna1E005WDWTLg== From: =?utf-8?q?Alexis_Lothor=C3=A9?= To: Cc: Thomas Petazzoni , Alexandre Belloni Subject: [OE-Core][PATCH v2 1/3] oeqa/selftest: introduce gitarchive tests Date: Fri, 18 Aug 2023 16:17:10 +0200 Message-ID: <20230818141712.189294-2-alexis.lothore@bootlin.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230818141712.189294-1-alexis.lothore@bootlin.com> References: <20230818141712.189294-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 ; Fri, 18 Aug 2023 14:16:52 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/186372 From: Alexis Lothoré Add a test suite for gitarchive.py. For now, only introduce tests on methods which needs to read existing tags The tests rely on tmpdirs to create local, "fake" results repository in order to allow basic git commands Signed-off-by: Alexis Lothoré --- V2: no change --- .../oeqa/selftest/cases/gitarchivetests.py | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 meta/lib/oeqa/selftest/cases/gitarchivetests.py diff --git a/meta/lib/oeqa/selftest/cases/gitarchivetests.py b/meta/lib/oeqa/selftest/cases/gitarchivetests.py new file mode 100644 index 000000000000..4f7acd3311d5 --- /dev/null +++ b/meta/lib/oeqa/selftest/cases/gitarchivetests.py @@ -0,0 +1,96 @@ +# +# Copyright OpenEmbedded Contributors +# +# SPDX-License-Identifier: MIT +# + +import os +import sys +basepath = os.path.abspath(os.path.dirname(__file__) + '/../../../../../') +lib_path = basepath + '/scripts/lib' +sys.path = sys.path + [lib_path] +import oeqa.utils.gitarchive as ga +import tempfile +import shutil +import scriptutils +from oeqa.selftest.case import OESelftestTestCase + +logger = scriptutils.logger_create('resulttool') + +def create_fake_repository(commit, tag_list=[]): + """ Create a testing git directory + + Initialize a simple git repository with one initial commit, and as many + tags on this commit as listed in tag_list + Returns both git directory path and gitarchive git object + If commit is true, fake data will be commited, otherwise it will stay in staging area + If commit is true and tag_lsit is non empty, all tags in tag_list will be + created on the initial commit + Fake remote will also be added to make git ls-remote work + """ + fake_data_file = "fake_data.txt" + tempdir = tempfile.mkdtemp(prefix='fake_results.') + repo = ga.init_git_repo(tempdir, False, False, logger) + repo.run_cmd(["remote", "add", "origin", "."]) + with open(os.path.join(tempdir, fake_data_file), "w") as fake_data: + fake_data.write("Fake data") + if commit: + repo.run_cmd(["add", fake_data_file]) + repo.run_cmd(["commit", "-m", "\"Add fake data\""]) + for tag in tag_list: + repo.run_cmd(["tag", tag]) + + return tempdir, repo + +def delete_fake_repository(path): + shutil.rmtree(path) + +def tag_exists(git_obj, target_tag): + for tag in git_obj.run_cmd(["tag"]).splitlines(): + if target_tag == tag: + return True + return False + +class GitArchiveTests(OESelftestTestCase): + TEST_BRANCH="main" + TEST_COMMIT="0f7d5df" + TEST_COMMIT_COUNT="42" + + def test_create_first_test_tag(self): + path, git_obj = create_fake_repository(False) + keywords = {'commit': self.TEST_COMMIT, 'branch': self.TEST_BRANCH, "commit_count": self.TEST_COMMIT_COUNT} + target_tag = f"{self.TEST_BRANCH}/{self.TEST_COMMIT_COUNT}-g{self.TEST_COMMIT}/0" + + ga.gitarchive(path, path, True, False, + "Results of {branch}:{commit}", "branch: {branch}\ncommit: {commit}", "{branch}", + False, "{branch}/{commit_count}-g{commit}/{tag_number}", + 'Test run #{tag_number} of {branch}:{commit}', '', + [], [], False, keywords, logger) + self.assertTrue(tag_exists(git_obj, target_tag), msg=f"Tag {target_tag} has not been created") + delete_fake_repository(path) + + def test_create_second_test_tag(self): + first_tag = f"{self.TEST_BRANCH}/{self.TEST_COMMIT_COUNT}-g{self.TEST_COMMIT}/0" + second_tag = f"{self.TEST_BRANCH}/{self.TEST_COMMIT_COUNT}-g{self.TEST_COMMIT}/1" + keywords = {'commit': self.TEST_COMMIT, 'branch': self.TEST_BRANCH, "commit_count": self.TEST_COMMIT_COUNT} + + path, git_obj = create_fake_repository(True, [first_tag]) + ga.gitarchive(path, path, True, False, + "Results of {branch}:{commit}", "branch: {branch}\ncommit: {commit}", "{branch}", + False, "{branch}/{commit_count}-g{commit}/{tag_number}", + 'Test run #{tag_number} of {branch}:{commit}', '', + [], [], False, keywords, logger) + self.assertTrue(tag_exists(git_obj, second_tag), msg=f"Second tag {second_tag} has not been created") + delete_fake_repository(path) + + def test_get_revs_on_branch(self): + fake_tags_list=["main/10-g0f7d5df/0", "main/10-g0f7d5df/1", "foo/20-g2468f5d/0"] + tag_name = "{branch}/{commit_number}-g{commit}/{tag_number}" + + path, git_obj = create_fake_repository(True, fake_tags_list) + revs = ga.get_test_revs(logger, git_obj, tag_name, branch="main") + self.assertEqual(len(revs), 1) + self.assertEqual(revs[0].commit, "0f7d5df") + self.assertEqual(len(revs[0].tags), 2) + self.assertEqual(revs[0].tags, ['main/10-g0f7d5df/0', 'main/10-g0f7d5df/1']) + delete_fake_repository(path) From patchwork Fri Aug 18 14:17:11 2023 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: 29129 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 0C409C77B7F for ; Fri, 18 Aug 2023 14:16:53 +0000 (UTC) Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by mx.groups.io with SMTP id smtpd.web10.12270.1692368202532161835 for ; Fri, 18 Aug 2023 07:16:43 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=PJ3E0yA8; spf=pass (domain: bootlin.com, ip: 217.70.183.199, mailfrom: alexis.lothore@bootlin.com) Received: by mail.gandi.net (Postfix) with ESMTPSA id 4764DFF80D; Fri, 18 Aug 2023 14:16:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1692368200; 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=XaCvfGs+LCcg8cg4i4ih40vu2MKa8uohI3WdnS671S0=; b=PJ3E0yA8dJtJIz+hQaPtEce+zzWwbjODh5zr13TUEVtcv+6rwMZYBU/XE7lcPO3/Vjo7+r 03Zzl5SuR6JpgSHoGnO2Lf1akxfvRJ9pKjSNqpGr7TKB1i8R3x0fWVFDen+YpBFyknFEgS 4DTLihaMO0cx4fExcrjhJNyRgiTn0N3hxqwr6QQP5K8pZ9NKdC2oupQ+zGDqh8LYHo02Vo MyqYxwiSYAbj+oMczLo/03NPPzPSjU0RVdrQfpdQjrqOgbVZUXH5x78ZuRTUPHVD3/Bmy8 WmN3sMHhHx5HcZJvfDVND83/r2607lr9cteraWCVsgwkukU9duCUWiZwEYyufw== From: =?utf-8?q?Alexis_Lothor=C3=A9?= To: Cc: Thomas Petazzoni , Alexandre Belloni Subject: [OE-Core][PATCH v2 2/3] oeqa/utils/gitarchive: fix tag computation when creating archive Date: Fri, 18 Aug 2023 16:17:11 +0200 Message-ID: <20230818141712.189294-3-alexis.lothore@bootlin.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230818141712.189294-1-alexis.lothore@bootlin.com> References: <20230818141712.189294-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 ; Fri, 18 Aug 2023 14:16:53 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/186370 From: Alexis Lothoré Sporadic errors have been observed in autobuilder when trying to store new tests results: error: failed to push some refs to 'push.yoctoproject.org:yocto-testresults' hint: Updates were rejected because the tag already exists in the remote. The new tag name is generated by gitarchive based on known tags from the repository (learnt with git tag). In autobuilder case, this repository is a shallow clone, so git tag only returns most recent tags, which mean we could miss some older tags which exist in remote but not locally. In this case, gitarchive will likely create a tag which already exists in remote, and so will fail to push Fix this tag duplication by using git ls-remote to learn about existing tags instead of git tag. To do so, create a helper ("get_tags") which manages both nominal case (target directory is a git repository with a proper remote) and fallback case (target directory is not from a clone, no remote has been configured) Fixes [YOCTO #15140] Signed-off-by: Alexis Lothoré --- V2: - mutualize ls-remote usage in a single helper - add a fallback when no remote is properly configured: use push url if provided --- meta/lib/oeqa/utils/gitarchive.py | 36 +++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/meta/lib/oeqa/utils/gitarchive.py b/meta/lib/oeqa/utils/gitarchive.py index 6e8040eb5c96..1a28a09efef7 100644 --- a/meta/lib/oeqa/utils/gitarchive.py +++ b/meta/lib/oeqa/utils/gitarchive.py @@ -100,9 +100,36 @@ def git_commit_data(repo, data_dir, branch, message, exclude, notes, log): if os.path.exists(tmp_index): os.unlink(tmp_index) +def get_tags(repo, pattern=None, url=None): + """ Fetch remote tags from current repository + + A pattern can be provided to filter returned tags list + An URL can be provided if local repository has no valid remote configured + """ + + base_cmd = ['ls-remote', '--refs', '--tags', '-q'] + cmd = base_cmd.copy() + + # First try to fetch tags from repository configured remote + cmd.append('origin') + if pattern: + cmd.append(pattern) + try: + tags_refs = repo.run_cmd(cmd) + except GitError as e: + # If it fails, retry with repository url if one is provided + if not url: + raise(e) + cmd = base_cmd.copy() + cmd.append(url) + if pattern: + cmd.append(pattern) + tags_refs = repo.run_cmd(cmd) + + return ["".join(d.split()[1].split('/', 2)[2:]) for d in tags_refs.splitlines()] def expand_tag_strings(repo, name_pattern, msg_subj_pattern, msg_body_pattern, - keywords): + url, keywords): """Generate tag name and message, with support for running id number""" keyws = keywords.copy() # Tag number is handled specially: if not defined, we autoincrement it @@ -116,7 +143,7 @@ def expand_tag_strings(repo, name_pattern, msg_subj_pattern, msg_body_pattern, tag_re = tag_re.format(tag_number='(?P[0-9]{1,5})') keyws['tag_number'] = 0 - for existing_tag in repo.run_cmd('tag').splitlines(): + for existing_tag in get_tags(repo, url=url): match = re.match(tag_re, existing_tag) if match and int(match.group('tag_number')) >= keyws['tag_number']: @@ -143,7 +170,8 @@ def gitarchive(data_dir, git_dir, no_create, bare, commit_msg_subject, commit_ms if not no_tag and tagname: tag_name, tag_msg = expand_tag_strings(data_repo, tagname, tag_msg_subject, - tag_msg_body, keywords) + tag_msg_body, + push, keywords) # Commit data commit = git_commit_data(data_repo, data_dir, branch_name, @@ -181,7 +209,7 @@ def get_test_runs(log, repo, tag_name, **kwargs): # Get a list of all matching tags tag_pattern = tag_name.format(**str_fields) - tags = repo.run_cmd(['tag', '-l', tag_pattern]).splitlines() + tags = get_tags(repo, pattern=tag_pattern) log.debug("Found %d tags matching pattern '%s'", len(tags), tag_pattern) # Parse undefined fields from tag names From patchwork Fri Aug 18 14:17:12 2023 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: 29128 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 E0719C7113C for ; Fri, 18 Aug 2023 14:16:52 +0000 (UTC) Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by mx.groups.io with SMTP id smtpd.web10.12269.1692368202290937334 for ; Fri, 18 Aug 2023 07:16:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=DXux0MAN; spf=pass (domain: bootlin.com, ip: 217.70.183.199, mailfrom: alexis.lothore@bootlin.com) Received: by mail.gandi.net (Postfix) with ESMTPSA id 9F7DEFF80E; Fri, 18 Aug 2023 14:16:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1692368200; 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=nRwZosGbOu803OHlF6FaXH29ROXV8DNxsw6o62hX0O0=; b=DXux0MANbpy7n8Lyc4xOLEyVrR048vqh9XlmYeg8Gwi2u6RVJ5hDUj+X76rZ1TwdM4eVCi wnyKExf2nmT46hVq7HQoDgK/BwTm0fi9RUJSv74fJRJNASEB9lATUeUuBdRWhBaII3pber C4jSPsrXy7P727m1Ba1Eue+faOzAiizHb13DGHxJIXPH4T91VWYlRuALoooCgn8fA/xcwj 3mTCeQ4Km7arKJzzPX2agMMR/BjMZ9D2aatyYgqXzS/6QrYSu7Ui2AR4nr7P93bxObv7RK CnE3jyv6V6ei0eRQUeb/c2i0+t1vWL+uY7+k2Layw6WQFsT3MIkqJph3aVI8mw== From: =?utf-8?q?Alexis_Lothor=C3=A9?= To: Cc: Thomas Petazzoni , Alexandre Belloni Subject: [OE-Core][PATCH v2 3/3] oeqa/selftest/gitarchive: add tests about tags lisiting when no remote is configured Date: Fri, 18 Aug 2023 16:17:12 +0200 Message-ID: <20230818141712.189294-4-alexis.lothore@bootlin.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230818141712.189294-1-alexis.lothore@bootlin.com> References: <20230818141712.189294-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 ; Fri, 18 Aug 2023 14:16:52 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/186369 From: Alexis Lothoré Add specific tests on gitarchive for when tag listing is required but no remote is configured in target directory: it should either succeed if valid url is provided, or fail is url is not provided or wrong Signed-off-by: Alexis Lothoré --- .../oeqa/selftest/cases/gitarchivetests.py | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/gitarchivetests.py b/meta/lib/oeqa/selftest/cases/gitarchivetests.py index 4f7acd3311d5..11b88daab860 100644 --- a/meta/lib/oeqa/selftest/cases/gitarchivetests.py +++ b/meta/lib/oeqa/selftest/cases/gitarchivetests.py @@ -10,6 +10,7 @@ basepath = os.path.abspath(os.path.dirname(__file__) + '/../../../../../') lib_path = basepath + '/scripts/lib' sys.path = sys.path + [lib_path] import oeqa.utils.gitarchive as ga +from oeqa.utils.git import GitError import tempfile import shutil import scriptutils @@ -17,7 +18,7 @@ from oeqa.selftest.case import OESelftestTestCase logger = scriptutils.logger_create('resulttool') -def create_fake_repository(commit, tag_list=[]): +def create_fake_repository(commit, tag_list=[], add_remote=True): """ Create a testing git directory Initialize a simple git repository with one initial commit, and as many @@ -31,7 +32,8 @@ def create_fake_repository(commit, tag_list=[]): fake_data_file = "fake_data.txt" tempdir = tempfile.mkdtemp(prefix='fake_results.') repo = ga.init_git_repo(tempdir, False, False, logger) - repo.run_cmd(["remote", "add", "origin", "."]) + if add_remote: + repo.run_cmd(["remote", "add", "origin", "."]) with open(os.path.join(tempdir, fake_data_file), "w") as fake_data: fake_data.write("Fake data") if commit: @@ -94,3 +96,32 @@ class GitArchiveTests(OESelftestTestCase): self.assertEqual(len(revs[0].tags), 2) self.assertEqual(revs[0].tags, ['main/10-g0f7d5df/0', 'main/10-g0f7d5df/1']) delete_fake_repository(path) + + def test_get_tags_without_valid_remote(self): + url = 'git://git.yoctoproject.org/poky' + path, git_obj = create_fake_repository(False, None, False) + + tags = ga.get_tags(git_obj, pattern="yocto-*", url=url) + """Test for some well established tags (released tags)""" + self.assertIn("yocto-4.0", tags) + self.assertIn("yocto-4.1", tags) + self.assertIn("yocto-4.2", tags) + delete_fake_repository(path) + + def test_get_tags_without_valid_remote_neither_url(self): + url = 'git://git.yoctoproject.org/poky' + path, git_obj = create_fake_repository(False, None, False) + + """Test for some well established tags (released tags)""" + with self.assertRaises(GitError): + tags = ga.get_tags(git_obj, pattern="yocto-*") + delete_fake_repository(path) + + def test_get_tags_without_valid_remote_and_wrong_url(self): + url = 'git://git.foo.org/bar' + path, git_obj = create_fake_repository(False, None, False) + + """Test for some well established tags (released tags)""" + with self.assertRaises(GitError): + tags = ga.get_tags(git_obj, pattern="yocto-*", url=url) + delete_fake_repository(path)