]> git.apps.os.sepia.ceph.com Git - teuthology.git/commitdiff
add utils/tests/test_scanner.py
authorVallari Agrawal <val.agl002@gmail.com>
Tue, 19 Sep 2023 15:04:28 +0000 (20:34 +0530)
committerVallari Agrawal <val.agl002@gmail.com>
Mon, 27 Nov 2023 16:25:42 +0000 (21:55 +0530)
and test_run_unit_test in test_remote.py

Signed-off-by: Vallari Agrawal <val.agl002@gmail.com>
teuthology/orchestra/test/test_remote.py
teuthology/orchestra/test/xml_files/test_scan_nose.xml [deleted file]
teuthology/util/test/files/test_unit_test.xml [new file with mode: 0644]
teuthology/util/test/files/test_valgrind.xml [new file with mode: 0644]
teuthology/util/test/test_scanner.py [new file with mode: 0644]

index 76eae68bad892895d8edb7ff683df589dabf4fe8..a953835e7c0d63d18319c55202fe86212728b15f 100644 (file)
@@ -1,10 +1,12 @@
 from mock import patch, Mock, MagicMock
+from pytest import raises
 
 from io import BytesIO
 
 from teuthology.orchestra import remote
 from teuthology.orchestra import opsys
 from teuthology.orchestra.run import RemoteProcess
+from teuthology.exceptions import CommandFailedError, UnitTestError
 
 
 class TestRemote(object):
@@ -66,6 +68,23 @@ class TestRemote(object):
         assert result is proc
         assert result.remote is rem
 
+    @patch('teuthology.util.scanner.UnitTestScanner.scan_and_write')
+    def test_run_unit_test(self, m_scan_and_write):
+        m_transport = MagicMock()
+        m_transport.getpeername.return_value = ('name', 22)
+        self.m_ssh.get_transport.return_value = m_transport
+        m_run = MagicMock(name="run", side_effect=CommandFailedError('mocked error', 1, 'smithi'))
+        args = [
+            'something',
+            'more',
+        ]
+        rem = remote.Remote(name='jdoe@xyzzy.example.com', ssh=self.m_ssh)
+        rem._runner = m_run
+        m_scan_and_write.return_value = "Error Message"
+        with raises(UnitTestError) as exc:
+            rem.run_unit_test(args=args, xml_path_regex="xml_path", output_yaml="yaml_path")
+        assert str(exc.value) == "Unit test failed on smithi with status 1: 'Error Message'"
+
     def test_hostname(self):
         m_transport = MagicMock()
         m_transport.getpeername.return_value = ('name', 22)
diff --git a/teuthology/orchestra/test/xml_files/test_scan_nose.xml b/teuthology/orchestra/test/xml_files/test_scan_nose.xml
deleted file mode 100644 (file)
index d0fab48..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?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
diff --git a/teuthology/util/test/files/test_unit_test.xml b/teuthology/util/test/files/test_unit_test.xml
new file mode 100644 (file)
index 0000000..bd9c734
--- /dev/null
@@ -0,0 +1,7 @@
+<?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'"></failure></testcase>
+</testsuite>
\ No newline at end of file
diff --git a/teuthology/util/test/files/test_valgrind.xml b/teuthology/util/test/files/test_valgrind.xml
new file mode 100644 (file)
index 0000000..41bf837
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<valgrindoutput>
+<error>
+  <unique>0x870fc</unique>
+  <tid>1</tid>
+  <kind>Leak_DefinitelyLost</kind>
+  <xwhat>
+    <text>1,234 bytes in 1 blocks are definitely lost in loss record 198 of 201</text>
+    <leakedbytes>1234</leakedbytes>
+    <leakedblocks>1</leakedblocks>
+  </xwhat>
+  <stack>
+    <frame>
+      <ip>0x4C39B6F</ip>
+      <obj>/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so</obj>
+      <fn>operator new[](unsigned long)</fn>
+      <dir>/builddir/build/BUILD/valgrind-3.19.0/coregrind/m_replacemalloc</dir>
+      <file>vg_replace_malloc.c</file>
+      <line>640</line>
+    </frame>
+    <frame>
+      <ip>0xF3F4B5</ip>
+      <obj>/usr/bin/ceph-osd</obj>
+      <fn>ceph::common::leak_some_memory()</fn>
+      <dir>/usr/src/debug/ceph-18.0.0-5567.g64a4fc94.el8.x86_64/src/common</dir>
+      <file>ceph_context.cc</file>
+      <line>510</line>
+    </frame>
+  </stack>
+</error>
+</valgrindoutput>
diff --git a/teuthology/util/test/test_scanner.py b/teuthology/util/test/test_scanner.py
new file mode 100644 (file)
index 0000000..1c7c89f
--- /dev/null
@@ -0,0 +1,191 @@
+from mock import patch, MagicMock
+
+from io import BytesIO
+import os, io
+
+from teuthology.orchestra import remote
+from teuthology.util.scanner import UnitTestScanner, ValgrindScanner
+
+
+class MockFile(io.StringIO):
+    def close(self):
+        pass
+
+
+class TestUnitTestScanner(object):
+
+    def setup_method(self):
+        self.remote = remote.Remote(
+            name='jdoe@xyzzy.example.com', ssh=MagicMock())
+        self.test_values = {
+            "xml_path": os.path.dirname(__file__) + "/files/test_unit_test.xml",
+            "error_msg": "FAILURE: Test `test_set_bucket_tagging` of `s3tests_boto3.functional.test_s3`. \
+Reason: 'NoSuchTagSetError' != 'NoSuchTagSet'.",
+            "summary_data": [{'failed_testsuites': {'s3tests_boto3.functional.test_s3': 
+                                [{'kind': 'failure', 'testcase': 'test_set_bucket_tagging', 
+                                  'message': "'NoSuchTagSetError' != 'NoSuchTagSet'"}]}, 
+                              'num_of_failures': 1, 
+                              'file_path': f'{os.path.dirname(__file__)}/files/test_unit_test.xml'}],
+            "yaml_data": r"""- failed_testsuites:
+    s3tests_boto3.functional.test_s3:
+    - kind: failure
+      message: '''NoSuchTagSetError'' != ''NoSuchTagSet'''
+      testcase: test_set_bucket_tagging
+  file_path: {file_dir}/files/test_unit_test.xml
+  num_of_failures: 1
+""".format(file_dir=os.path.dirname(__file__))
+        }
+
+    @patch('teuthology.util.scanner.UnitTestScanner.write_summary')
+    def test_scan_and_write(self, m_write_summary):
+        xml_path = self.test_values["xml_path"]
+        self.remote.ssh.exec_command.return_value = (None, BytesIO(xml_path.encode('utf-8')), None)
+        m_open = MagicMock()
+        m_open.return_value = open(xml_path, "rb")
+        self.remote._sftp_open_file = m_open
+        result = UnitTestScanner(remote=self.remote).scan_and_write(xml_path, "test_summary.yaml")
+        assert result == self.test_values["error_msg"]
+
+    def test_parse(self):
+        xml_content = b'<?xml version="1.0" encoding="UTF-8"?>\n<testsuite name="xyz" tests="1" \
+errors="0" failures="1">\n<testcase classname="xyz" name="abc" time="0.059"><failure \
+type="builtins.AssertionError" message="error_msg"></failure></testcase>\n</testsuite>'
+        scanner = UnitTestScanner(self.remote)
+        result = scanner._parse(xml_content)
+        assert result == (
+            'FAILURE: Test `abc` of `xyz`. Reason: error_msg.', 
+            {'failed_testsuites': {'xyz': 
+                [{'kind': 'failure','message': 'error_msg','testcase': 'abc'}]},
+            'num_of_failures': 1
+            }
+        )
+    
+    def test_scan_file(self):
+        xml_path = self.test_values["xml_path"]
+        m_open = MagicMock()
+        m_open.return_value = open(xml_path, "rb")
+        self.remote._sftp_open_file = m_open
+        scanner = UnitTestScanner(remote=self.remote)
+        result = scanner.scan_file(xml_path)
+        assert result == self.test_values["error_msg"]
+        assert scanner.summary_data == self.test_values["summary_data"]
+
+    def test_scan_all_files(self):
+        xml_path = self.test_values["xml_path"]
+        self.remote.ssh.exec_command.return_value = (None, BytesIO(xml_path.encode('utf-8')), None)
+        m_open = MagicMock()
+        m_open.return_value = open(xml_path, "rb")
+        self.remote._sftp_open_file = m_open
+        scanner = UnitTestScanner(remote=self.remote)
+        result = scanner.scan_all_files(xml_path)
+        assert result == [self.test_values["error_msg"]]
+                          
+    @patch('builtins.open')
+    def test_write_summary(self, m_open):
+        scanner = UnitTestScanner(self.remote)
+        mock_yaml_file = MockFile()
+        scanner.summary_data = self.test_values["summary_data"]
+        m_open.return_value = mock_yaml_file
+        scanner.write_summary("path/file.yaml")
+        written_content = mock_yaml_file.getvalue()             
+        assert written_content == self.test_values["yaml_data"]    
+
+
+class TestValgrindScanner(object):
+
+    def setup_method(self):
+        self.remote = remote.Remote(
+            name='jdoe@xyzzy.example.com', ssh=MagicMock())
+        self.test_values = {
+            "xml_path": os.path.dirname(__file__) + "/files/test_valgrind.xml",
+            "error_msg": "valgrind error: Leak_DefinitelyLost\noperator new[]\
+(unsigned long)\nceph::common::leak_some_memory()",
+            "summary_data": [{'kind': 'Leak_DefinitelyLost', 'traceback': [{'file': 
+                '/builddir/build/BUILD/valgrind-3.19.0/coregrind/m_replacemalloc/vg_replace_malloc.c', 
+                'line': '640', 'function': 'operator new[](unsigned long)'}, 
+                {'file': '/usr/src/debug/ceph-18.0.0-5567.g64a4fc94.el8.x86_64/src/common/ceph_context.cc', 
+                 'line': '510', 'function': 'ceph::common::leak_some_memory()'}], 'file_path': 
+                 f'{os.path.dirname(__file__)}/files/test_valgrind.xml'}],
+            "yaml_data": r"""- file_path: {file_dir}/files/test_valgrind.xml
+  kind: Leak_DefinitelyLost
+  traceback:
+  - file: /builddir/build/BUILD/valgrind-3.19.0/coregrind/m_replacemalloc/vg_replace_malloc.c
+    function: operator new[](unsigned long)
+    line: '640'
+  - file: /usr/src/debug/ceph-18.0.0-5567.g64a4fc94.el8.x86_64/src/common/ceph_context.cc
+    function: ceph::common::leak_some_memory()
+    line: '510'
+""".format(file_dir=os.path.dirname(__file__))
+        }
+
+    def test_parse_with_traceback(self):
+        xml_content = b'''<?xml version="1.0"?>
+<valgrindoutput>
+<error>
+  <kind>Leak_DefinitelyLost</kind>
+  <stack>
+    <frame>
+      <fn>func()</fn>
+      <dir>/dir</dir>
+      <file>file1.ext</file>
+      <line>640</line>
+    </frame>
+  </stack>
+</error>
+</valgrindoutput>
+'''
+        scanner = ValgrindScanner(self.remote)
+        result = scanner._parse(xml_content)
+        assert result == (
+            'valgrind error: Leak_DefinitelyLost\nfunc()', 
+            {'kind': 'Leak_DefinitelyLost', 'traceback': 
+                [{'file': '/dir/file1.ext', 'line': '640', 'function': 'func()'}]
+            }
+        )
+
+    def test_parse_without_trackback(self):
+        xml_content = b'''<?xml version="1.0"?>
+<valgrindoutput>
+<error>
+  <kind>Leak_DefinitelyLost</kind>
+  <stack>
+  </stack>
+</error>
+</valgrindoutput>
+'''
+        scanner = ValgrindScanner(self.remote)
+        result = scanner._parse(xml_content)
+        assert result == (
+            'valgrind error: Leak_DefinitelyLost\n', 
+            {'kind': 'Leak_DefinitelyLost', 'traceback': []}
+        )
+    
+    def test_scan_file(self):
+        xml_path = self.test_values["xml_path"]
+        m_open = MagicMock()
+        m_open.return_value = open(xml_path, "rb")
+        self.remote._sftp_open_file = m_open
+        scanner = ValgrindScanner(remote=self.remote)
+        result = scanner.scan_file(xml_path)
+        assert result == self.test_values["error_msg"]
+        assert scanner.summary_data == self.test_values["summary_data"]
+
+    def test_scan_all_files(self):
+        xml_path = self.test_values["xml_path"]
+        self.remote.ssh.exec_command.return_value = (None, BytesIO(xml_path.encode('utf-8')), None)
+        m_open = MagicMock()
+        m_open.return_value = open(xml_path, "rb")
+        self.remote._sftp_open_file = m_open
+        scanner = ValgrindScanner(remote=self.remote)
+        result = scanner.scan_all_files(xml_path)
+        assert result == [self.test_values["error_msg"]]
+                          
+    @patch('builtins.open')
+    def test_write_summary(self, m_open):
+        scanner = ValgrindScanner(self.remote)
+        mock_yaml_file = MockFile()
+        scanner.summary_data = self.test_values["summary_data"]
+        m_open.return_value = mock_yaml_file
+        scanner.write_summary("path/file.yaml")
+        written_content = mock_yaml_file.getvalue()             
+        assert written_content == self.test_values["yaml_data"]
\ No newline at end of file