Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug & fix failed jobs in CI #3468

Merged
merged 1 commit into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/source/modules/tcms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ Submodules
tcms.handlers
tcms.signals
tcms.wsgi
tcms.xmlrpc_wrapper
7 changes: 7 additions & 0 deletions docs/source/modules/tcms.xmlrpc_wrapper.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
tcms.xmlrpc\_wrapper module
===========================

.. automodule:: tcms.xmlrpc_wrapper
:members:
:undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
allpairspy==2.5.1
bleach==6.1.0
bleach-allowlist==1.0.3
defusedxml==0.7.1
Django==4.2.8
django-attachments==1.11
django-colorfield==0.11.0
Expand Down
3 changes: 2 additions & 1 deletion tcms/bugs/tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# pylint: disable=attribute-defined-outside-init
# pylint: disable=wrong-import-position
import unittest
from xmlrpc.client import Fault as XmlRPCFault

from django.conf import settings

from tcms.xmlrpc_wrapper import XmlRPCFault

if "tcms.bugs.apps.AppConfig" not in settings.INSTALLED_APPS:
raise unittest.SkipTest("tcms.bugs is disabled")

Expand Down
4 changes: 2 additions & 2 deletions tcms/issuetracker/bugzilla_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
import os
import tempfile
from urllib.parse import urlencode
from xmlrpc.client import Fault

import bugzilla
from django.conf import settings

from tcms.core.contrib.linkreference.models import LinkReference
from tcms.issuetracker import base
from tcms.xmlrpc_wrapper import XmlRPCFault


class Bugzilla(base.IssueTrackerType):
Expand Down Expand Up @@ -94,7 +94,7 @@ def _report_issue(self, execution, user):
is_defect=True,
)
return (new_bug, new_bug.weburl)
except Fault:
except XmlRPCFault:
pass

url = self.bug_system.base_url
Expand Down
1 change: 0 additions & 1 deletion tcms/issuetracker/tests/test_gitlab_ce.py

This file was deleted.

192 changes: 192 additions & 0 deletions tcms/issuetracker/tests/test_gitlab_ce.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# pylint: disable=attribute-defined-outside-init

import os
import time
import unittest

from tcms.core.contrib.linkreference.models import LinkReference
from tcms.issuetracker.types import Gitlab
from tcms.rpc.tests.utils import APITestCase
from tcms.testcases.models import BugSystem
from tcms.tests.factories import ComponentFactory, TestExecutionFactory


@unittest.skipUnless(
os.getenv("TEST_BUGTRACKER_INTEGRATION"),
"Bug tracker integration testing not enabled",
)
class TestGitlabIntegration(APITestCase):
existing_bug_id = 1
existing_bug_url = "http://bugtracker.kiwitcms.org/root/kiwitcms/issues/1"
existing_bug_url_in_group = (
"http://bugtracker.kiwitcms.org/group/sub_group/kiwitcms_in_group/issues/1"
)

def _fixture_setup(self):
super()._fixture_setup()

self.execution_1 = TestExecutionFactory()
self.execution_1.case.text = "Given-When-Then"
self.execution_1.case.save() # will generate history object

self.component = ComponentFactory(
name="Gitlab integration", product=self.execution_1.run.plan.product
)
self.execution_1.case.add_component(self.component)

bug_system = BugSystem.objects.create( # nosec:B106:hardcoded_password_funcarg
name="GitLab-EE for root/kiwitcms",
tracker_type="tcms.issuetracker.types.Gitlab",
base_url="http://bugtracker.kiwitcms.org/root/kiwitcms/",
api_url="http://bugtracker.kiwitcms.org",
api_password="ypCa3Dzb23o5nvsixwPA",
)
self.integration = Gitlab(bug_system, None)

def test_bug_id_from_url(self):
result = self.integration.bug_id_from_url(self.existing_bug_url)
self.assertEqual(self.existing_bug_id, result)

# this is an alternative URL, with a dash
result = self.integration.bug_id_from_url(
"http://bugtracker.kiwitcms.org/root/kiwitcms/-/issues/1"
)
self.assertEqual(self.existing_bug_id, result)

def test_bug_id_from_url_in_group(self):
bug_system = BugSystem.objects.create( # nosec:B106:hardcoded_password_funcarg
name="GitLab-EE for group/sub_group/kiwitcms_in_group",
tracker_type="tcms.issuetracker.types.Gitlab",
base_url="http://bugtracker.kiwitcms.org/group/sub_group/kiwitcms_in_group/",
api_url="http://bugtracker.kiwitcms.org",
api_password="ypCa3Dzb23o5nvsixwPA",
)
integration = Gitlab(bug_system, None)

result = integration.bug_id_from_url(self.existing_bug_url_in_group)
self.assertEqual(self.existing_bug_id, result)

# this is an alternative URL, with a dash
result = integration.bug_id_from_url(
"http://bugtracker.kiwitcms.org/group/sub_group/kiwitcms_in_group/-/issues/1"
)
self.assertEqual(self.existing_bug_id, result)

def test_details_for_public_url(self):
result = self.integration.details(self.existing_bug_url)

self.assertEqual("Hello GitLab", result["title"])
self.assertEqual("Created via CLI", result["description"])

def test_details_for_public_url_in_group(self):
bug_system = BugSystem.objects.create( # nosec:B106:hardcoded_password_funcarg
name="GitLab-EE for group/sub_group/kiwitcms_in_group",
tracker_type="tcms.issuetracker.types.Gitlab",
base_url="http://bugtracker.kiwitcms.org/group/sub_group/kiwitcms_in_group/",
api_url="http://bugtracker.kiwitcms.org",
api_password="ypCa3Dzb23o5nvsixwPA",
)
integration = Gitlab(bug_system, None)

result = integration.details(self.existing_bug_url_in_group)

self.assertEqual("Hello GitLab Group", result["title"])
self.assertEqual("Created via CLI", result["description"])

def test_details_for_private_url(self):
bug_system = BugSystem.objects.create( # nosec:B106:hardcoded_password_funcarg
name="Private GitLab for root/katinar",
tracker_type="tcms.issuetracker.types.Gitlab",
base_url="http://bugtracker.kiwitcms.org/root/katinar/",
api_url="http://bugtracker.kiwitcms.org",
api_password="ypCa3Dzb23o5nvsixwPA",
)
integration = Gitlab(bug_system, None)

result = integration.details(
"http://bugtracker.kiwitcms.org/root/katinar/-/issues/1"
)

self.assertEqual("Hello Private Issue", result["title"])
self.assertEqual("Created in secret via CLI", result["description"])

def test_auto_update_bugtracker(self):
repo_id = self.integration.repo_id
gl_project = self.integration.rpc.projects.get(repo_id)
gl_issue = gl_project.issues.get(self.existing_bug_id)

# make sure there are no comments to confuse the test
initial_comment_count = 0
for comment in gl_issue.notes.list():
initial_comment_count += 1
self.assertNotIn("Confirmed via test execution", comment.body)

# simulate user adding a new bug URL to a TE and clicking
# 'Automatically update bug tracker'
result = self.rpc_client.TestExecution.add_link(
{
"execution_id": self.execution_1.pk,
"is_defect": True,
"url": self.existing_bug_url,
},
True,
)

# making sure RPC above returned the same URL
self.assertEqual(self.existing_bug_url, result["url"])

# wait until comments have been refreshed b/c this seem to happen async
retries = 0
while len(gl_issue.notes.list()) <= initial_comment_count:
time.sleep(1)
retries += 1
self.assertLess(retries, 20)

# sort by id b/c the gitlab library returns newest comments first but
# that may be depending on configuration !
last_comment = sorted(gl_issue.notes.list(), key=lambda x: x.id)[-1]

# assert that a comment has been added as the last one
# and also verify its text
for expected_string in [
"Confirmed via test execution",
f"TR-{self.execution_1.run_id}: {self.execution_1.run.summary}",
self.execution_1.run.get_full_url(),
f"TE-{self.execution_1.pk}: {self.execution_1.case.summary}",
]:
self.assertIn(expected_string, last_comment.body)

def test_report_issue_from_test_execution_1click_works(self):
# simulate user clicking the 'Report bug' button in TE widget, TR page
result = self.rpc_client.Bug.report(
self.execution_1.pk, self.integration.bug_system.pk
)
self.assertEqual(result["rc"], 0)
self.assertIn(self.integration.bug_system.base_url, result["response"])
self.assertIn("/-/issues/", result["response"])

# assert that the result looks like valid URL parameters
new_issue_id = self.integration.bug_id_from_url(result["response"])
repo_id = self.integration.repo_id
gl_project = self.integration.rpc.projects.get(repo_id)
issue = gl_project.issues.get(new_issue_id)

self.assertEqual(f"Failed test: {self.execution_1.case.summary}", issue.title)
for expected_string in [
f"Filed from execution {self.execution_1.get_full_url()}",
"Reporter",
self.execution_1.build.version.product.name,
self.component.name,
"Steps to reproduce",
self.execution_1.case.text,
]:
self.assertIn(expected_string, issue.description)

# verify that LR has been added to TE
self.assertTrue(
LinkReference.objects.filter(
execution=self.execution_1,
url=result["response"],
is_defect=True,
).exists()
)
10 changes: 5 additions & 5 deletions tcms/kiwi_attachments/tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
# pylint: disable=attribute-defined-outside-init, invalid-name, objects-update-used

import base64
from xmlrpc.client import Fault

from django.utils.translation import gettext_lazy as _
from parameterized import parameterized

from tcms.rpc.tests.utils import APITestCase
from tcms.xmlrpc_wrapper import XmlRPCFault


class TestValidators(APITestCase):
Expand All @@ -23,7 +23,7 @@ def test_uploading_svg_with_inline_script_should_fail(self, file_name):

tag_name = "script"
message = str(_(f"File contains forbidden tag: <{tag_name}>"))
with self.assertRaisesRegex(Fault, message):
with self.assertRaisesRegex(XmlRPCFault, message):
self.rpc_client.User.add_attachment("inline_javascript.svg", b64)

@parameterized.expand(
Expand All @@ -37,18 +37,18 @@ def test_uploading_svg_with_forbidden_attributes_should_fail(self, file_name):

attr_name = "onload"
message = str(_(f"File contains forbidden attribute: `{attr_name}`"))
with self.assertRaisesRegex(Fault, message):
with self.assertRaisesRegex(XmlRPCFault, message):
self.rpc_client.User.add_attachment("image.svg", b64)

def test_uploading_filename_ending_in_dot_exe_should_fail(self):
message = str(_("Uploading executable files is forbidden"))
with self.assertRaisesRegex(Fault, message):
with self.assertRaisesRegex(XmlRPCFault, message):
self.rpc_client.User.add_attachment("hello.exe", "a2l3aXRjbXM=")

def test_uploading_real_exe_file_should_fail(self):
with open("tests/ui/data/reactos_csrss.exe", "rb") as exe_file:
b64 = base64.b64encode(exe_file.read()).decode()

message = str(_("Uploading executable files is forbidden"))
with self.assertRaisesRegex(Fault, message):
with self.assertRaisesRegex(XmlRPCFault, message):
self.rpc_client.User.add_attachment("csrss.exe_from_reactos", b64)
2 changes: 1 addition & 1 deletion tcms/rpc/tests/test_attachment.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
# pylint: disable=attribute-defined-outside-init, invalid-name, objects-update-used

from xmlrpc.client import Fault as XmlRPCFault

from tcms.rpc.tests.utils import APIPermissionsTestCase, APITestCase
from tcms.tests import user_should_have_perm
from tcms.tests.factories import TestPlanFactory
from tcms.xmlrpc_wrapper import XmlRPCFault


class TestRemoveAttachment(APITestCase):
Expand Down
2 changes: 1 addition & 1 deletion tcms/rpc/tests/test_auth.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
# pylint: disable=attribute-defined-outside-init

from xmlrpc.client import Fault as XmlRPCFault

from tcms.rpc.tests.utils import APITestCase
from tcms.xmlrpc_wrapper import XmlRPCFault


class TestAuthLogin(APITestCase):
Expand Down
2 changes: 1 addition & 1 deletion tcms/rpc/tests/test_build.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name, attribute-defined-outside-init, objects-update-used

from xmlrpc.client import Fault as XmlRPCFault

from django.test import override_settings

from tcms.rpc.tests.utils import APITestCase
from tcms.tests.factories import BuildFactory, VersionFactory
from tcms.xmlrpc_wrapper import XmlRPCFault


@override_settings(LANGUAGE_CODE="en")
Expand Down
2 changes: 1 addition & 1 deletion tcms/rpc/tests/test_category.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
# pylint: disable=attribute-defined-outside-init, invalid-name, objects-update-used

from xmlrpc.client import Fault as XmlRPCFault

from tcms.rpc.tests.utils import APIPermissionsTestCase, APITestCase
from tcms.testcases.models import Category
from tcms.tests.factories import CategoryFactory, ProductFactory
from tcms.xmlrpc_wrapper import XmlRPCFault


class TestCategory(APITestCase):
Expand Down
2 changes: 1 addition & 1 deletion tcms/rpc/tests/test_classification.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
# pylint: disable=attribute-defined-outside-init

from xmlrpc.client import Fault as XmlRPCFault

from tcms.management.models import Classification
from tcms.rpc.tests.utils import APIPermissionsTestCase, APITestCase
from tcms.tests.factories import ClassificationFactory
from tcms.xmlrpc_wrapper import XmlRPCFault


class TestClassificationFilter(APITestCase):
Expand Down
2 changes: 1 addition & 1 deletion tcms/rpc/tests/test_component.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
# pylint: disable=attribute-defined-outside-init, invalid-name

from xmlrpc.client import Fault as XmlRPCFault

from tcms.rpc.tests.utils import APITestCase
from tcms.tests.factories import ComponentFactory, ProductFactory
from tcms.xmlrpc_wrapper import XmlRPCFault


class TestFilterComponents(APITestCase):
Expand Down
2 changes: 1 addition & 1 deletion tcms/rpc/tests/test_environment.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
from xmlrpc.client import Fault as XmlRPCFault

from django.test import override_settings

from tcms.rpc.tests.utils import APIPermissionsTestCase, APITestCase
from tcms.testruns.models import Environment
from tcms.xmlrpc_wrapper import XmlRPCFault


class TestFilterPermission(APIPermissionsTestCase):
Expand Down
2 changes: 1 addition & 1 deletion tcms/rpc/tests/test_plantype.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
# pylint: disable=attribute-defined-outside-init

from xmlrpc.client import Fault as XmlRPCFault

from tcms.rpc.tests.utils import APIPermissionsTestCase
from tcms.testplans.models import PlanType
from tcms.tests.factories import PlanTypeFactory
from tcms.xmlrpc_wrapper import XmlRPCFault


class TestPlanTypeFilter(APIPermissionsTestCase):
Expand Down
Loading
Loading