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):
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)
+++ /dev/null
-<?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' -------------------- >> begin captured logging << -------------------- botocore.hooks: DEBUG: Event choose-service-name: calling handler <function handle_service_name_alias at 0x7fb6def62d30> botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler <function add_generate_presigned_post at 0x7fb6defdad30> botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler <function lazy_call.<locals>._handler at 0x7fb6debf5d30> botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler <function add_generate_presigned_url at 0x7fb6defdaaf0> botocore.endpoint: DEBUG: Setting s3 timeout as (60, 60) botocore.client: DEBUG: Registering retry handlers for service: s3 botocore.hooks: DEBUG: Event before-parameter-build.s3.CreateBucket: calling handler <function validate_bucket_name at 0x7fb6def01430> botocore.hooks: DEBUG: Event before-parameter-build.s3.CreateBucket: calling handler <bound method S3RegionRedirector.redirect_from_cache of <botocore.utils.S3RegionRedirector object at 0x7fb6de659d30>> botocore.hooks: DEBUG: Event before-parameter-build.s3.CreateBucket: calling handler <bound method S3ArnParamHandler.handle_arn of <botocore.utils.S3ArnParamHandler object at 0x7fb6de659580>> botocore.hooks: DEBUG: Event before-parameter-build.s3.CreateBucket: calling handler <function generate_idempotent_uuid at 0x7fb6def01280> botocore.hooks: DEBUG: Event before-call.s3.CreateBucket: calling handler <function add_expect_header at 0x7fb6def01790> botocore.hooks: DEBUG: Event before-call.s3.CreateBucket: calling handler <bound method S3RegionRedirector.set_request_url of <botocore.utils.S3RegionRedirector object at 0x7fb6de659d30>> botocore.hooks: DEBUG: Event before-call.s3.CreateBucket: calling handler <function add_recursion_detection_header at 0x7fb6deef7ee0> botocore.hooks: DEBUG: Event before-call.s3.CreateBucket: calling handler <function inject_api_version_header_if_needed at 0x7fb6def02af0> 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': <botocore.config.Config object at 0x7fb6de1298b0>, 'has_streaming_input': False, 'auth_type': None, 'signing': {'bucket': 'test-client.0-2txq2dyjghs0vdf-335'}}} botocore.hooks: DEBUG: Event request-created.s3.CreateBucket: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x7fb6de129e20>> botocore.hooks: DEBUG: Event choose-signer.s3.CreateBucket: calling handler <bound method S3EndpointSetter.set_signer of <botocore.utils.S3EndpointSetter object at 0x7fb6de6598b0>> botocore.hooks: DEBUG: Event choose-signer.s3.CreateBucket: calling handler <function set_operation_specific_signer at 0x7fb6def01160> botocore.hooks: DEBUG: Event before-sign.s3.CreateBucket: calling handler <bound method S3EndpointSetter.set_endpoint of <botocore.utils.S3EndpointSetter object at 0x7fb6de6598b0>> botocore.utils: DEBUG: Using S3 path style addressing. botocore.auth: DEBUG: Calculating signature using v4 auth. botocore.auth: DEBUG: CanonicalRequest: 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. botocore.hooks: DEBUG: Event needs-retry.s3.CreateBucket: calling handler <bound method S3RegionRedirector.redirect_from_error of <botocore.utils.S3RegionRedirector object at 0x7fb6de659d30>> botocore.hooks: DEBUG: Event choose-service-name: calling handler <function handle_service_name_alias at 0x7fb6def62d30> botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler <function add_generate_presigned_post at 0x7fb6defdad30> botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler <function lazy_call.<locals>._handler at 0x7fb6debf5d30> botocore.hooks: DEBUG: Event creating-client-class.s3: calling handler <function add_generate_presigned_url at 0x7fb6defdaaf0> botocore.endpoint: DEBUG: Setting s3 timeout as (60, 60) botocore.client: DEBUG: Registering retry handlers for service: s3 botocore.hooks: DEBUG: Event before-parameter-build.s3.GetBucketTagging: calling handler <function validate_bucket_name at 0x7fb6def01430> botocore.hooks: DEBUG: Event before-parameter-build.s3.GetBucketTagging: calling handler <bound method S3RegionRedirector.redirect_from_cache of <botocore.utils.S3RegionRedirector object at 0x7fb6dec1eaf0>> botocore.hooks: DEBUG: Event before-parameter-build.s3.GetBucketTagging: calling handler <bound method S3ArnParamHandler.handle_arn of <botocore.utils.S3ArnParamHandler object at 0x7fb6dec1ec10>> botocore.hooks: DEBUG: Event before-parameter-build.s3.GetBucketTagging: calling handler <function generate_idempotent_uuid at 0x7fb6def01280> botocore.hooks: DEBUG: Event before-call.s3.GetBucketTagging: calling handler <function add_expect_header at 0x7fb6def01790> botocore.hooks: DEBUG: Event before-call.s3.GetBucketTagging: calling handler <bound method S3RegionRedirector.set_request_url of <botocore.utils.S3RegionRedirector object at 0x7fb6dec1eaf0>> botocore.hooks: DEBUG: Event before-call.s3.GetBucketTagging: calling handler <function add_recursion_detection_header at 0x7fb6deef7ee0> botocore.hooks: DEBUG: Event before-call.s3.GetBucketTagging: calling handler <function inject_api_version_header_if_needed at 0x7fb6def02af0> 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': <botocore.config.Config object at 0x7fb6de2c5220>, 'has_streaming_input': False, 'auth_type': None, 'signing': {'bucket': 'test-client.0-2txq2dyjghs0vdf-335'}}} botocore.hooks: DEBUG: Event request-created.s3.GetBucketTagging: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x7fb6de2c5dc0>> botocore.hooks: DEBUG: Event choose-signer.s3.GetBucketTagging: calling handler <bound method S3EndpointSetter.set_signer of <botocore.utils.S3EndpointSetter object at 0x7fb6dec1e760>> botocore.hooks: DEBUG: Event choose-signer.s3.GetBucketTagging: calling handler <function set_operation_specific_signer at 0x7fb6def01160> botocore.hooks: DEBUG: Event before-sign.s3.GetBucketTagging: calling handler <bound method S3EndpointSetter.set_endpoint of <botocore.utils.S3EndpointSetter object at 0x7fb6dec1e760>> botocore.utils: DEBUG: Using S3 path style addressing. botocore.auth: DEBUG: Calculating signature using v4 auth. botocore.auth: DEBUG: CanonicalRequest: 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 << ---------------------"><![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
--- /dev/null
+<?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
--- /dev/null
+<?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>
--- /dev/null
+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