]> git-server-git.apps.pok.os.sepia.ceph.com Git - teuthology.git/commitdiff
orch/run: Add unit test XML scanner
authorVallari Agrawal <val.agl002@gmail.com>
Sat, 1 Oct 2022 11:16:52 +0000 (16:46 +0530)
committerVallari Agrawal <val.agl002@gmail.com>
Sun, 2 Oct 2022 04:05:05 +0000 (09:35 +0530)
Scan XML output files with find_unittest_error
and raise UnitTestError.

Signed-off-by: Vallari Agrawal <val.agl002@gmail.com>
setup.cfg
teuthology/exceptions.py
teuthology/orchestra/run.py
teuthology/orchestra/test/test_run.py
teuthology/orchestra/test/xml_files/test_scan_nose.xml [new file with mode: 0644]

index f5de27bf925e76f0d6e75483008fa2a01fe84a57..26483eb31bbc59da4511b327ab33c264aa70976e 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -44,6 +44,7 @@ install_requires =
     httplib2
     humanfriendly
     lupa
+    lxml
     ndg-httpsclient
     netaddr
     paramiko
index 3939ba53c6434202b266cc7f2a26f14358c67c8d..bd8c4a20eee2f7080d0f1cfccb3cd2c894fd9d0c 100644 (file)
@@ -205,3 +205,26 @@ class NoRemoteError(Exception):
 
     def __str__(self):
         return self.message
+
+
+class UnitTestError(Exception):
+    """
+    Exception thrown on unit test failure
+    """
+    def __init__(self, exitstatus=None, node=None, label=None, message=None):
+        self.exitstatus = exitstatus
+        self.node = node
+        self.label = label
+        self.message = message
+
+    def __str__(self):
+        prefix = "Unit test failed"
+        if self.label:
+            prefix += " ({label})".format(label=self.label)
+        if self.node:
+            prefix += " on {node}".format(node=self.node)
+        return "{prefix} with status {status}: '{message}'".format(
+            prefix=prefix,
+            status=self.exitstatus,
+            message=self.message,
+        )
index f31dfd0d7fc1db89feab1f67abdc95c809a9731d..085eea71515cff475bbc5c479beadc9eeb863013 100644 (file)
@@ -3,6 +3,7 @@ Paramiko run support
 """
 
 import io
+from pathlib import Path
 
 from paramiko import ChannelFile
 
@@ -12,10 +13,11 @@ import socket
 import pipes
 import logging
 import shutil
+from lxml import etree
 
 from teuthology.contextutil import safe_while
 from teuthology.exceptions import (CommandCrashedError, CommandFailedError,
-                                   ConnectionLostError)
+                                   ConnectionLostError, UnitTestError)
 
 log = logging.getLogger(__name__)
 
@@ -34,12 +36,13 @@ class RemoteProcess(object):
         # for orchestra.remote.Remote to place a backreference
         'remote',
         'label',
+        'unittest_xml',
         ]
 
     deadlock_warning = "Using PIPE for %s without wait=False would deadlock"
 
     def __init__(self, client, args, check_status=True, hostname=None,
-                 label=None, timeout=None, wait=True, logger=None, cwd=None):
+                 label=None, timeout=None, wait=True, logger=None, cwd=None, unittest_xml=None):
         """
         Create the object. Does not initiate command execution.
 
@@ -58,6 +61,8 @@ class RemoteProcess(object):
         :param logger:       Alternative logger to use (optional)
         :param cwd:          Directory in which the command will be executed
                              (optional)
+        :param unittest_xml: Absolute path to unit-tests output XML file  
+                             (optional)
         """
         self.client = client
         self.args = args
@@ -84,6 +89,7 @@ class RemoteProcess(object):
         self.returncode = self.exitstatus = None
         self._wait = wait
         self.logger = logger or log
+        self.unittest_xml = unittest_xml or ""
 
     def execute(self):
         """
@@ -178,6 +184,17 @@ class RemoteProcess(object):
                 # signal; sadly SSH does not tell us which signal
                 raise CommandCrashedError(command=self.command)
             if self.returncode != 0:
+                if self.unittest_xml:
+                    error_msg = None
+                    try:
+                        error_msg = find_unittest_error(self.unittest_xml)
+                    except Exception as exc:
+                        self.logger.error('Unable to scan logs, exception occurred: {exc}'.format(exc=repr(exc)))
+                    if error_msg:
+                        raise UnitTestError(
+                            exitstatus=self.returncode, node=self.hostname, 
+                            label=self.label, message=error_msg
+                        )
                 raise CommandFailedError(
                     command=self.command, exitstatus=self.returncode,
                     node=self.hostname, label=self.label
@@ -221,6 +238,43 @@ class RemoteProcess(object):
             name=self.hostname,
             )
 
+def find_unittest_error(xmlfile_path):
+    """ 
+    Load the unit test output XML file 
+    and parse for failures and errors.
+    """
+
+    if not xmlfile_path:
+        return "No XML file was passed to process!"
+    try:
+        xml_path = Path(xmlfile_path)
+        if xml_path.is_file():
+            tree = etree.parse(xmlfile_path)
+            failed_testcases = tree.xpath('.//failure/.. | .//error/..')
+            if len(failed_testcases) == 0:
+                log.debug("No failures or errors found in unit test's output xml file.")
+                return None
+
+            error_message = f'Total {len(failed_testcases)} testcase/s did not pass. '
+
+            # show details of first error/failure for quick inspection
+            testcase1 = failed_testcases[0]
+            testcase1_casename = testcase1.get("name", "test-name")
+            testcase1_suitename = testcase1.get("classname", "suite-name")
+            testcase1_msg = f'Test `{testcase1_casename}` of `{testcase1_suitename}` did not pass.'
+            for child in testcase1:
+                if child.tag in ['failure', 'error']:
+                    fault_kind = child.tag.upper()
+                    reason = child.get('message', 'NO MESSAGE FOUND IN XML FILE; CHECK LOGS.')
+                    reason = reason[:reason.find('begin captured')] # remove captured logs/stdout
+                    testcase1_msg = f'{fault_kind}: Test `{testcase1_casename}` of `{testcase1_suitename}` because {reason}'
+                    break
+
+            return (error_message + testcase1_msg).replace("\n", " ")
+        return f'XML output not found at `{xmlfile_path}`!'
+    except Exception as exc:
+        raise Exception("Somthing went wrong while searching for error in XML file: " + repr(exc))
 
 class Raw(object):
 
@@ -394,6 +448,7 @@ def run(
     quiet=False,
     timeout=None,
     cwd=None,
+    unittest_xml=None,
     # omit_sudo is used by vstart_runner.py
     omit_sudo=False
 ):
@@ -429,6 +484,7 @@ def run(
     :param timeout: timeout value for args to complete on remote channel of
                     paramiko
     :param cwd: Directory in which the command should be executed.
+    :param unittest_xml: Absolute path to unit-tests output XML file.  
     """
     try:
         transport = client.get_transport()
@@ -446,7 +502,7 @@ def run(
         log.info("Running command with timeout %d", timeout)
     r = RemoteProcess(client, args, check_status=check_status, hostname=name,
                       label=label, timeout=timeout, wait=wait, logger=logger,
-                      cwd=cwd)
+                      cwd=cwd, unittest_xml=unittest_xml)
     r.execute()
     r.setup_stdin(stdin)
     r.setup_output_stream(stderr, 'stderr', quiet)
index 074d90b05da7ed4ff2b152b2f22b09906e5f49a9..14b4b98f0a96f37713be8c8ef52d6247967ce4df 100644 (file)
@@ -263,6 +263,10 @@ class TestRun(object):
         run.copy_and_close('', MagicMock())
         run.copy_and_close(b'', MagicMock())
 
+    def test_find_unittest_error(self):
+        unittest_xml = "xml_files/test_scan_nose.xml"
+        error_msg = run.find_unittest_error(unittest_xml)
+        assert error_msg == "Total 1 testcase/s did not pass. FAILURE: Test `test_set_bucket_tagging` of `s3tests_boto3.functional.test_s3` because 'NoSuchTagSetError' != 'NoSuchTagSet' -------------------- >> "
 
 class TestQuote(object):
     def test_quote_simple(self):
diff --git a/teuthology/orchestra/test/xml_files/test_scan_nose.xml b/teuthology/orchestra/test/xml_files/test_scan_nose.xml
new file mode 100644 (file)
index 0000000..d0fab48
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="nosetests" tests="644" errors="0" failures="1" skip="79">
+<testcase classname="s3tests_boto3.functional.test_s3" name="test_cors_origin_response" time="3.205"></testcase>
+<testcase classname="s3tests_boto3.functional.test_s3" name="test_cors_origin_wildcard" time="3.081"></testcase>
+<testcase classname="s3tests_boto3.functional.test_s3" name="test_cors_header_option" time="3.119"></testcase>
+<testcase classname="s3tests_boto3.functional.test_s3" name="test_set_bucket_tagging" time="0.059"><failure type="builtins.AssertionError" message="'NoSuchTagSetError' != 'NoSuchTagSet'&#10;-------------------- &gt;&gt; begin captured logging &lt;&lt; --------------------&#10;botocore.hooks: DEBUG: Event choose-service-name: calling handler &lt;function handle_service_name_alias at 0x7fb6def62d30&gt;&#10;botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler &lt;function add_generate_presigned_post at 0x7fb6defdad30&gt;&#10;botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler &lt;function lazy_call.&lt;locals&gt;._handler at 0x7fb6debf5d30&gt;&#10;botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler &lt;function add_generate_presigned_url at 0x7fb6defdaaf0&gt;&#10;botocore.endpoint: DEBUG: Setting s3 timeout as (60, 60)&#10;botocore.client: DEBUG: Registering retry handlers for service: s3&#10;botocore.hooks: DEBUG: Event before-parameter-build.s3.CreateBucket: calling handler &lt;function validate_bucket_name at 0x7fb6def01430&gt;&#10;botocore.hooks: DEBUG: Event before-parameter-build.s3.CreateBucket: calling handler &lt;bound method S3RegionRedirector.redirect_from_cache of &lt;botocore.utils.S3RegionRedirector object at 0x7fb6de659d30&gt;&gt;&#10;botocore.hooks: DEBUG: Event before-parameter-build.s3.CreateBucket: calling handler &lt;bound method S3ArnParamHandler.handle_arn of &lt;botocore.utils.S3ArnParamHandler object at 0x7fb6de659580&gt;&gt;&#10;botocore.hooks: DEBUG: Event before-parameter-build.s3.CreateBucket: calling handler &lt;function generate_idempotent_uuid at 0x7fb6def01280&gt;&#10;botocore.hooks: DEBUG: Event before-call.s3.CreateBucket: calling handler &lt;function add_expect_header at 0x7fb6def01790&gt;&#10;botocore.hooks: DEBUG: Event before-call.s3.CreateBucket: calling handler &lt;bound method S3RegionRedirector.set_request_url of &lt;botocore.utils.S3RegionRedirector object at 0x7fb6de659d30&gt;&gt;&#10;botocore.hooks: DEBUG: Event before-call.s3.CreateBucket: calling handler &lt;function add_recursion_detection_header at 0x7fb6deef7ee0&gt;&#10;botocore.hooks: DEBUG: Event before-call.s3.CreateBucket: calling handler &lt;function inject_api_version_header_if_needed at 0x7fb6def02af0&gt;&#10;botocore.endpoint: DEBUG: Making request for OperationModel(name=CreateBucket) with params: {'url_path': '/test-client.0-2txq2dyjghs0vdf-335', 'query_string': {}, 'method': 'PUT', 'headers': {'User-Agent': 'Boto3/1.24.82 Python/3.8.10 Linux/5.4.0-126-generic Botocore/1.27.82'}, 'body': b'', 'url': 'http://smithi196.front.sepia.ceph.com:80/test-client.0-2txq2dyjghs0vdf-335', 'context': {'client_region': 'us-east-1', 'client_config': &lt;botocore.config.Config object at 0x7fb6de1298b0&gt;, 'has_streaming_input': False, 'auth_type': None, 'signing': {'bucket': 'test-client.0-2txq2dyjghs0vdf-335'}}}&#10;botocore.hooks: DEBUG: Event request-created.s3.CreateBucket: calling handler &lt;bound method RequestSigner.handler of &lt;botocore.signers.RequestSigner object at 0x7fb6de129e20&gt;&gt;&#10;botocore.hooks: DEBUG: Event choose-signer.s3.CreateBucket: calling handler &lt;bound method S3EndpointSetter.set_signer of &lt;botocore.utils.S3EndpointSetter object at 0x7fb6de6598b0&gt;&gt;&#10;botocore.hooks: DEBUG: Event choose-signer.s3.CreateBucket: calling handler &lt;function set_operation_specific_signer at 0x7fb6def01160&gt;&#10;botocore.hooks: DEBUG: Event before-sign.s3.CreateBucket: calling handler &lt;bound method S3EndpointSetter.set_endpoint of &lt;botocore.utils.S3EndpointSetter object at 0x7fb6de6598b0&gt;&gt;&#10;botocore.utils: DEBUG: Using S3 path style addressing.&#10;botocore.auth: DEBUG: Calculating signature using v4 auth.&#10;botocore.auth: DEBUG: CanonicalRequest:&#10;PUT&#10;/test-client.0-2txq2dyjghs0vdf-335&#10;&#10;host:smithi196.front.sepia.ceph.com&#10;x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&#10;x-amz-date:20220929T065029Z&#10;&#10;host;x-amz-content-sha256;x-amz-date&#10;e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&#10;botocore.auth: DEBUG: StringToSign:&#10;AWS4-HMAC-SHA256&#10;20220929T065029Z&#10;20220929/us-east-1/s3/aws4_request&#10;ddfd952c0ac842cff08711f6b1425bec213bd1f69ae5ae6f37afb7a2f66e7fcb&#10;botocore.auth: DEBUG: Signature:&#10;8b7f685e9b8a9a807437088da293390ac21ed9a10acf51903a8da2281bdc9c45&#10;botocore.hooks: DEBUG: Event request-created.s3.CreateBucket: calling handler &lt;function add_retry_headers at 0x7fb6def031f0&gt;&#10;botocore.endpoint: DEBUG: Sending http request: &lt;AWSPreparedRequest stream_output=False, method=PUT, url=http://smithi196.front.sepia.ceph.com:80/test-client.0-2txq2dyjghs0vdf-335, headers={'User-Agent': b'Boto3/1.24.82 Python/3.8.10 Linux/5.4.0-126-generic Botocore/1.27.82', 'X-Amz-Date': b'20220929T065029Z', 'X-Amz-Content-SHA256': b'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'Authorization': b'AWS4-HMAC-SHA256 Credential=EBIAVLDBAMGWPWFMDQHA/20220929/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=8b7f685e9b8a9a807437088da293390ac21ed9a10acf51903a8da2281bdc9c45', 'amz-sdk-invocation-id': b'1795d992-7f27-43c5-ae48-06ef5ea88c6c', 'amz-sdk-request': b'attempt=1', 'Content-Length': '0'}&gt;&#10;urllib3.connectionpool: DEBUG: Starting new HTTP connection (1): smithi196.front.sepia.ceph.com:80&#10;urllib3.connectionpool: DEBUG: http://smithi196.front.sepia.ceph.com:80 &quot;PUT /test-client.0-2txq2dyjghs0vdf-335 HTTP/1.1&quot; 200 0&#10;botocore.parsers: DEBUG: Response headers: {'x-amz-request-id': 'tx00000e29af2294ab8b56c-0063354035-1157-default', 'Content-Length': '0', 'Date': 'Thu, 29 Sep 2022 06:50:29 GMT', 'Connection': 'Keep-Alive'}&#10;botocore.parsers: DEBUG: Response body:&#10;b''&#10;botocore.hooks: DEBUG: Event needs-retry.s3.CreateBucket: calling handler &lt;botocore.retryhandler.RetryHandler object at 0x7fb6de6597c0&gt;&#10;botocore.retryhandler: DEBUG: No retry needed.&#10;botocore.hooks: DEBUG: Event needs-retry.s3.CreateBucket: calling handler &lt;bound method S3RegionRedirector.redirect_from_error of &lt;botocore.utils.S3RegionRedirector object at 0x7fb6de659d30&gt;&gt;&#10;botocore.hooks: DEBUG: Event choose-service-name: calling handler &lt;function handle_service_name_alias at 0x7fb6def62d30&gt;&#10;botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler &lt;function add_generate_presigned_post at 0x7fb6defdad30&gt;&#10;botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler &lt;function lazy_call.&lt;locals&gt;._handler at 0x7fb6debf5d30&gt;&#10;botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler &lt;function add_generate_presigned_url at 0x7fb6defdaaf0&gt;&#10;botocore.endpoint: DEBUG: Setting s3 timeout as (60, 60)&#10;botocore.client: DEBUG: Registering retry handlers for service: s3&#10;botocore.hooks: DEBUG: Event before-parameter-build.s3.GetBucketTagging: calling handler &lt;function validate_bucket_name at 0x7fb6def01430&gt;&#10;botocore.hooks: DEBUG: Event before-parameter-build.s3.GetBucketTagging: calling handler &lt;bound method S3RegionRedirector.redirect_from_cache of &lt;botocore.utils.S3RegionRedirector object at 0x7fb6dec1eaf0&gt;&gt;&#10;botocore.hooks: DEBUG: Event before-parameter-build.s3.GetBucketTagging: calling handler &lt;bound method S3ArnParamHandler.handle_arn of &lt;botocore.utils.S3ArnParamHandler object at 0x7fb6dec1ec10&gt;&gt;&#10;botocore.hooks: DEBUG: Event before-parameter-build.s3.GetBucketTagging: calling handler &lt;function generate_idempotent_uuid at 0x7fb6def01280&gt;&#10;botocore.hooks: DEBUG: Event before-call.s3.GetBucketTagging: calling handler &lt;function add_expect_header at 0x7fb6def01790&gt;&#10;botocore.hooks: DEBUG: Event before-call.s3.GetBucketTagging: calling handler &lt;bound method S3RegionRedirector.set_request_url of &lt;botocore.utils.S3RegionRedirector object at 0x7fb6dec1eaf0&gt;&gt;&#10;botocore.hooks: DEBUG: Event before-call.s3.GetBucketTagging: calling handler &lt;function add_recursion_detection_header at 0x7fb6deef7ee0&gt;&#10;botocore.hooks: DEBUG: Event before-call.s3.GetBucketTagging: calling handler &lt;function inject_api_version_header_if_needed at 0x7fb6def02af0&gt;&#10;botocore.endpoint: DEBUG: Making request for OperationModel(name=GetBucketTagging) with params: {'url_path': '/test-client.0-2txq2dyjghs0vdf-335?tagging', 'query_string': {}, 'method': 'GET', 'headers': {'User-Agent': 'Boto3/1.24.82 Python/3.8.10 Linux/5.4.0-126-generic Botocore/1.27.82'}, 'body': b'', 'url': 'http://smithi196.front.sepia.ceph.com:80/test-client.0-2txq2dyjghs0vdf-335?tagging', 'context': {'client_region': 'us-east-1', 'client_config': &lt;botocore.config.Config object at 0x7fb6de2c5220&gt;, 'has_streaming_input': False, 'auth_type': None, 'signing': {'bucket': 'test-client.0-2txq2dyjghs0vdf-335'}}}&#10;botocore.hooks: DEBUG: Event request-created.s3.GetBucketTagging: calling handler &lt;bound method RequestSigner.handler of &lt;botocore.signers.RequestSigner object at 0x7fb6de2c5dc0&gt;&gt;&#10;botocore.hooks: DEBUG: Event choose-signer.s3.GetBucketTagging: calling handler &lt;bound method S3EndpointSetter.set_signer of &lt;botocore.utils.S3EndpointSetter object at 0x7fb6dec1e760&gt;&gt;&#10;botocore.hooks: DEBUG: Event choose-signer.s3.GetBucketTagging: calling handler &lt;function set_operation_specific_signer at 0x7fb6def01160&gt;&#10;botocore.hooks: DEBUG: Event before-sign.s3.GetBucketTagging: calling handler &lt;bound method S3EndpointSetter.set_endpoint of &lt;botocore.utils.S3EndpointSetter object at 0x7fb6dec1e760&gt;&gt;&#10;botocore.utils: DEBUG: Using S3 path style addressing.&#10;botocore.auth: DEBUG: Calculating signature using v4 auth.&#10;botocore.auth: DEBUG: CanonicalRequest:&#10;GET&#10;/test-client.0-2txq2dyjghs0vdf-335&#10;tagging=&#10;host:smithi196.front.sepia.ceph.com&#10;x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&#10;x-amz-date:20220929T065029Z&#10;&#10;host;x-amz-content-sha256;x-amz-date&#10;e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&#10;botocore.auth: DEBUG: StringToSign:&#10;AWS4-HMAC-SHA256&#10;20220929T065029Z&#10;20220929/us-east-1/s3/aws4_request&#10;8a096d01796a8a6afca50c1bc3bc5c9098917c26a6dba7e752412ce31041c575&#10;botocore.auth: DEBUG: Signature:&#10;a58a94727b0c0d6d43e8783c91499ce9a9758260aa09a286524c0eb1bc4883d1&#10;botocore.hooks: DEBUG: Event request-created.s3.GetBucketTagging: calling handler &lt;function add_retry_headers at 0x7fb6def031f0&gt;&#10;botocore.endpoint: DEBUG: Sending http request: &lt;AWSPreparedRequest stream_output=False, method=GET, url=http://smithi196.front.sepia.ceph.com:80/test-client.0-2txq2dyjghs0vdf-335?tagging, headers={'User-Agent': b'Boto3/1.24.82 Python/3.8.10 Linux/5.4.0-126-generic Botocore/1.27.82', 'X-Amz-Date': b'20220929T065029Z', 'X-Amz-Content-SHA256': b'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'Authorization': b'AWS4-HMAC-SHA256 Credential=EBIAVLDBAMGWPWFMDQHA/20220929/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=a58a94727b0c0d6d43e8783c91499ce9a9758260aa09a286524c0eb1bc4883d1', 'amz-sdk-invocation-id': b'c4afeb5a-6a87-4e29-83ef-b96195038217', 'amz-sdk-request': b'attempt=1'}&gt;&#10;urllib3.connectionpool: DEBUG: Starting new HTTP connection (1): smithi196.front.sepia.ceph.com:80&#10;urllib3.connectionpool: DEBUG: http://smithi196.front.sepia.ceph.com:80 &quot;GET /test-client.0-2txq2dyjghs0vdf-335?tagging HTTP/1.1&quot; 404 248&#10;botocore.parsers: DEBUG: Response headers: {'Content-Length': '248', 'x-amz-request-id': 'tx00000ebc589e4bcad8d86-0063354035-1157-default', 'Accept-Ranges': 'bytes', 'Content-Type': 'application/xml', 'Date': 'Thu, 29 Sep 2022 06:50:29 GMT', 'Connection': 'Keep-Alive'}&#10;botocore.parsers: DEBUG: Response body:&#10;b'&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;Error&gt;&lt;Code&gt;NoSuchTagSetError&lt;/Code&gt;&lt;BucketName&gt;test-client.0-2txq2dyjghs0vdf-335&lt;/BucketName&gt;&lt;RequestId&gt;tx00000ebc589e4bcad8d86-0063354035-1157-default&lt;/RequestId&gt;&lt;HostId&gt;1157-default-default&lt;/HostId&gt;&lt;/Error&gt;'&#10;botocore.hooks: DEBUG: Event needs-retry.s3.GetBucketTagging: calling handler &lt;botocore.retryhandler.RetryHandler object at 0x7fb6dec1ebe0&gt;&#10;botocore.retryhandler: DEBUG: No retry needed.&#10;botocore.hooks: DEBUG: Event needs-retry.s3.GetBucketTagging: calling handler &lt;bound method S3RegionRedirector.redirect_from_error of &lt;botocore.utils.S3RegionRedirector object at 0x7fb6dec1eaf0&gt;&gt;&#10;--------------------- &gt;&gt; end captured logging &lt;&lt; ---------------------"><![CDATA[  File "/usr/lib/python3.8/unittest/case.py", line 60, in testPartExecutor
+    yield
+  File "/usr/lib/python3.8/unittest/case.py", line 676, in run
+    self._callTestMethod(testMethod)
+  File "/usr/lib/python3.8/unittest/case.py", line 633, in _callTestMethod
+    method()
+  File "/home/ubuntu/cephtest/s3-tests-client.0/virtualenv/lib/python3.8/site-packages/nose/case.py", line 198, in runTest
+    self.test(*self.arg)
+  File "/home/ubuntu/cephtest/s3-tests-client.0/s3tests_boto3/functional/test_s3.py", line 7692, in test_set_bucket_tagging
+    eq(error_code, 'NoSuchTagSet')
+  File "/home/ubuntu/cephtest/s3-tests-client.0/virtualenv/lib/python3.8/site-packages/nose/tools/trivial.py", line 29, in eq_
+    raise AssertionError(msg or "%r != %r" % (a, b))
+'NoSuchTagSetError' != 'NoSuchTagSet'
+-------------------- >> begin captured logging << --------------------
+botocore.hooks: DEBUG: Event choose-service-name: calling handler <function handle_service_name_alias at 0x7fb6def62d30>
+PUT
+/test-client.0-2txq2dyjghs0vdf-335
+
+host:smithi196.front.sepia.ceph.com
+x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+x-amz-date:20220929T065029Z
+
+host;x-amz-content-sha256;x-amz-date
+e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+botocore.auth: DEBUG: StringToSign:
+AWS4-HMAC-SHA256
+20220929T065029Z
+20220929/us-east-1/s3/aws4_request
+ddfd952c0ac842cff08711f6b1425bec213bd1f69ae5ae6f37afb7a2f66e7fcb
+botocore.auth: DEBUG: Signature:
+8b7f685e9b8a9a807437088da293390ac21ed9a10acf51903a8da2281bdc9c45
+botocore.hooks: DEBUG: Event request-created.s3.CreateBucket: calling handler <function add_retry_headers at 0x7fb6def031f0>
+botocore.endpoint: DEBUG: Sending http request: <AWSPreparedRequest stream_output=False, method=PUT, url=http://smithi196.front.sepia.ceph.com:80/test-client.0-2txq2dyjghs0vdf-335, headers={'User-Agent': b'Boto3/1.24.82 Python/3.8.10 Linux/5.4.0-126-generic Botocore/1.27.82', 'X-Amz-Date': b'20220929T065029Z', 'X-Amz-Content-SHA256': b'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'Authorization': b'AWS4-HMAC-SHA256 Credential=EBIAVLDBAMGWPWFMDQHA/20220929/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=8b7f685e9b8a9a807437088da293390ac21ed9a10acf51903a8da2281bdc9c45', 'amz-sdk-invocation-id': b'1795d992-7f27-43c5-ae48-06ef5ea88c6c', 'amz-sdk-request': b'attempt=1', 'Content-Length': '0'}>
+urllib3.connectionpool: DEBUG: Starting new HTTP connection (1): smithi196.front.sepia.ceph.com:80
+urllib3.connectionpool: DEBUG: http://smithi196.front.sepia.ceph.com:80 "PUT /test-client.0-2txq2dyjghs0vdf-335 HTTP/1.1" 200 0
+botocore.parsers: DEBUG: Response headers: {'x-amz-request-id': 'tx00000e29af2294ab8b56c-0063354035-1157-default', 'Content-Length': '0', 'Date': 'Thu, 29 Sep 2022 06:50:29 GMT', 'Connection': 'Keep-Alive'}
+botocore.parsers: DEBUG: Response body:
+b''
+botocore.hooks: DEBUG: Event needs-retry.s3.CreateBucket: calling handler <botocore.retryhandler.RetryHandler object at 0x7fb6de6597c0>
+botocore.retryhandler: DEBUG: No retry needed.
+GET
+/test-client.0-2txq2dyjghs0vdf-335
+tagging=
+host:smithi196.front.sepia.ceph.com
+x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+x-amz-date:20220929T065029Z
+
+host;x-amz-content-sha256;x-amz-date
+e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+botocore.auth: DEBUG: StringToSign:
+AWS4-HMAC-SHA256
+20220929T065029Z
+20220929/us-east-1/s3/aws4_request
+8a096d01796a8a6afca50c1bc3bc5c9098917c26a6dba7e752412ce31041c575
+botocore.auth: DEBUG: Signature:
+a58a94727b0c0d6d43e8783c91499ce9a9758260aa09a286524c0eb1bc4883d1
+botocore.hooks: DEBUG: Event request-created.s3.GetBucketTagging: calling handler <function add_retry_headers at 0x7fb6def031f0>
+botocore.endpoint: DEBUG: Sending http request: <AWSPreparedRequest stream_output=False, method=GET, url=http://smithi196.front.sepia.ceph.com:80/test-client.0-2txq2dyjghs0vdf-335?tagging, headers={'User-Agent': b'Boto3/1.24.82 Python/3.8.10 Linux/5.4.0-126-generic Botocore/1.27.82', 'X-Amz-Date': b'20220929T065029Z', 'X-Amz-Content-SHA256': b'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'Authorization': b'AWS4-HMAC-SHA256 Credential=EBIAVLDBAMGWPWFMDQHA/20220929/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=a58a94727b0c0d6d43e8783c91499ce9a9758260aa09a286524c0eb1bc4883d1', 'amz-sdk-invocation-id': b'c4afeb5a-6a87-4e29-83ef-b96195038217', 'amz-sdk-request': b'attempt=1'}>
+urllib3.connectionpool: DEBUG: Starting new HTTP connection (1): smithi196.front.sepia.ceph.com:80
+urllib3.connectionpool: DEBUG: http://smithi196.front.sepia.ceph.com:80 "GET /test-client.0-2txq2dyjghs0vdf-335?tagging HTTP/1.1" 404 248
+botocore.parsers: DEBUG: Response headers: {'Content-Length': '248', 'x-amz-request-id': 'tx00000ebc589e4bcad8d86-0063354035-1157-default', 'Accept-Ranges': 'bytes', 'Content-Type': 'application/xml', 'Date': 'Thu, 29 Sep 2022 06:50:29 GMT', 'Connection': 'Keep-Alive'}
+botocore.parsers: DEBUG: Response body:
+b'<?xml version="1.0" encoding="UTF-8"?><Error><Code>NoSuchTagSetError</Code><BucketName>test-client.0-2txq2dyjghs0vdf-335</BucketName><RequestId>tx00000ebc589e4bcad8d86-0063354035-1157-default</RequestId><HostId>1157-default-default</HostId></Error>'
+botocore.hooks: DEBUG: Event needs-retry.s3.GetBucketTagging: calling handler <botocore.retryhandler.RetryHandler object at 0x7fb6dec1ebe0>
+botocore.retryhandler: DEBUG: No retry needed.
+botocore.hooks: DEBUG: Event needs-retry.s3.GetBucketTagging: calling handler <bound method S3RegionRedirector.redirect_from_error of <botocore.utils.S3RegionRedirector object at 0x7fb6dec1eaf0>>
+--------------------- >> end captured logging << ---------------------]]></failure></testcase>
+</testsuite>
\ No newline at end of file