Acceptance tests using different clients concurrently. Environment deployed from packages.

Build: #3218 was successful

Job: Spaces basic was successful

user fails to add qos requirement to the share root directory[1oz 1op 1oc]: Test case result

The below summarizes the result of the test " user fails to add qos requirement to the share root directory[1oz 1op 1oc]" in build 3,218 of Onedata Products - mixed acceptance pkg - Spaces basic.
Description
user fails to add qos requirement to the share root directory[1oz 1op 1oc]
Test class
mixed.scenarios.test_spaces_basic
Method
test_user_fails_to_add_qos_requirement_to_the_share_root_directory[1oz_1op_1oc]
Jira Issue
Duration
13 secs
Status
Failed (Existing Failure)

Error Log

AssertionError
user = 'user1'
users = {'admin': <tests.utils.user_utils.AdminUser object at 0x7f1642a9e760>, 'admin2': <tests.utils.user_utils.User object a...s.user_utils.AdminUser object at 0x7f1642a9e790>, 'user1': <tests.utils.user_utils.User object at 0x7f1642a9efa0>, ...}
hosts = {'oneclient-1': {'container-id': 'a1665dfa9522de4c0d029815cb36d9f2e354b51c9bfe5c8f33b894c1bf45b5c9', 'ip': '10.244.216...f59396aa3ba6', 'hostname': 'dev-onezone.default.svc.cluster.local', 'ip': '10.244.216.98', 'name': 'dev-onezone', ...}}
host = 'oneprovider-1'
dir_id = '000000000084307A7368617265477569642373706163655F643061623139366161336138316632663235666365326366666530616435383963683...6663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'
expression = 'geo=PL'
err_msg = 'Qos requirement added to share root dir, but adding should have failed'

    def try_to_add_qos_to_special_dir_by_id(user, users, hosts, host, dir_id,
                                            expression, err_msg=''):
        try:
>           create_qos_requirement_in_op_by_id_rest(
                user, users, hosts, host, expression,
                dir_id)

tests/mixed/steps/rest/onezone/special_dirs.py:219: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

user = 'user1'
users = {'admin': <tests.utils.user_utils.AdminUser object at 0x7f1642a9e760>, 'admin2': <tests.utils.user_utils.User object a...s.user_utils.AdminUser object at 0x7f1642a9e790>, 'user1': <tests.utils.user_utils.User object at 0x7f1642a9efa0>, ...}
hosts = {'oneclient-1': {'container-id': 'a1665dfa9522de4c0d029815cb36d9f2e354b51c9bfe5c8f33b894c1bf45b5c9', 'ip': '10.244.216...f59396aa3ba6', 'hostname': 'dev-onezone.default.svc.cluster.local', 'ip': '10.244.216.98', 'name': 'dev-onezone', ...}}
host = 'oneprovider-1', expression = 'geo=PL'
file_id = '000000000084307A7368617265477569642373706163655F643061623139366161336138316632663235666365326366666530616435383963683...6663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'

    def create_qos_requirement_in_op_by_id_rest(user, users, hosts, host,
                                                expression, file_id):
        client = login_to_provider(user, users, hosts[host]['hostname'])
        qos_api = QoSApi(client)
        data = {
                "fileId": file_id,
                "expression": expression
                }
>       qos_api.add_qos_requirement(data)

tests/mixed/steps/rest/oneprovider/qos.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <oneprovider_client.api.qo_s_api.QoSApi object at 0x7f1642aaf550>
data = {'expression': 'geo=PL', 'fileId': '000000000084307A7368617265477569642373706163655F6430616231393661613361383166326632...663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'}
kwargs = {'_return_http_data_only': True}

    def add_qos_requirement(self, data, **kwargs):  # noqa: E501
        """Add QoS requirement  # noqa: E501
    
            Adds new QoS requirement for given file or directory. This triggers data replication (if needed) based on requirements defined in new QoS requirement.  For more information about QoS, please see [here](https://onedata.org/#/home/documentation/doc/using_onedata/qos.html).  ***Example cURL requests***  **Add QoS requirement for file** ```bash curl -H \"X-Auth-Token: $TOKEN\" -X POST \"https://$PROVIDER_HOST/api/v3/oneprovider/qos_requirements\" \\ -H \"Content-Type: application/json\" -d '{     \"expression\": \"country=FR\",     \"replicasNum\": 2,     \"fileId\": \"'$FILE_ID'\" }' ```   # noqa: E501
            This method makes a synchronous HTTP request by default. To make an
            asynchronous HTTP request, please pass async_req=True
            >>> thread = api.add_qos_requirement(data, async_req=True)
            >>> result = thread.get()
    
            :param async_req bool
            :param QosCreateRequest data: QoS requirement properties (required)
            :return: InlineResponse2014
                     If the method is called asynchronously,
                     returns the request thread.
            """
        kwargs['_return_http_data_only'] = True
        if kwargs.get('async_req'):
            return self.add_qos_requirement_with_http_info(data, **kwargs)  # noqa: E501
        else:
>           (data) = self.add_qos_requirement_with_http_info(data, **kwargs)  # noqa: E501

tests/mixed/oneprovider_client/api/qo_s_api.py:55: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <oneprovider_client.api.qo_s_api.QoSApi object at 0x7f1642aaf550>
data = {'expression': 'geo=PL', 'fileId': '000000000084307A7368617265477569642373706163655F6430616231393661613361383166326632...663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'}
kwargs = {'_return_http_data_only': True}
all_params = ['data', 'async_req', '_return_http_data_only', '_preload_content', '_request_timeout']
params = {'_return_http_data_only': True, 'all_params': ['data', 'async_req', '_return_http_data_only', '_preload_content', '_r...263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'}, ...}
key = '_return_http_data_only', val = True, collection_formats = {}
path_params = {}, query_params = []

    def add_qos_requirement_with_http_info(self, data, **kwargs):  # noqa: E501
        """Add QoS requirement  # noqa: E501
    
            Adds new QoS requirement for given file or directory. This triggers data replication (if needed) based on requirements defined in new QoS requirement.  For more information about QoS, please see [here](https://onedata.org/#/home/documentation/doc/using_onedata/qos.html).  ***Example cURL requests***  **Add QoS requirement for file** ```bash curl -H \"X-Auth-Token: $TOKEN\" -X POST \"https://$PROVIDER_HOST/api/v3/oneprovider/qos_requirements\" \\ -H \"Content-Type: application/json\" -d '{     \"expression\": \"country=FR\",     \"replicasNum\": 2,     \"fileId\": \"'$FILE_ID'\" }' ```   # noqa: E501
            This method makes a synchronous HTTP request by default. To make an
            asynchronous HTTP request, please pass async_req=True
            >>> thread = api.add_qos_requirement_with_http_info(data, async_req=True)
            >>> result = thread.get()
    
            :param async_req bool
            :param QosCreateRequest data: QoS requirement properties (required)
            :return: InlineResponse2014
                     If the method is called asynchronously,
                     returns the request thread.
            """
    
        all_params = ['data']  # noqa: E501
        all_params.append('async_req')
        all_params.append('_return_http_data_only')
        all_params.append('_preload_content')
        all_params.append('_request_timeout')
    
        params = locals()
        for key, val in six.iteritems(params['kwargs']):
            if key not in all_params:
                raise TypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method add_qos_requirement" % key
                )
            params[key] = val
        del params['kwargs']
        # verify the required parameter 'data' is set
        if self.api_client.client_side_validation and ('data' not in params or
                                                       params['data'] is None):  # noqa: E501
            raise ValueError("Missing the required parameter `data` when calling `add_qos_requirement`")  # noqa: E501
    
        collection_formats = {}
    
        path_params = {}
    
        query_params = []
    
        header_params = {}
    
        form_params = []
        local_var_files = {}
    
        body_params = None
        if 'data' in params:
            body_params = params['data']
        # HTTP header `Accept`
        header_params['Accept'] = self.api_client.select_header_accept(
            ['application/json'])  # noqa: E501
    
        # HTTP header `Content-Type`
        header_params['Content-Type'] = self.api_client.select_header_content_type(  # noqa: E501
            ['application/json'])  # noqa: E501
    
        # Authentication setting
        auth_settings = ['api_key1', 'api_key2']  # noqa: E501
    
>       return self.api_client.call_api(
            '/qos_requirements', 'POST',
            path_params,
            query_params,
            header_params,
            body=body_params,
            post_params=form_params,
            files=local_var_files,
            response_type='InlineResponse2014',  # noqa: E501
            auth_settings=auth_settings,
            async_req=params.get('async_req'),
            _return_http_data_only=params.get('_return_http_data_only'),
            _preload_content=params.get('_preload_content', True),
            _request_timeout=params.get('_request_timeout'),
            collection_formats=collection_formats)

tests/mixed/oneprovider_client/api/qo_s_api.py:119: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <oneprovider_client.api_client.ApiClient object at 0x7f1642aaf3d0>
resource_path = '/qos_requirements', method = 'POST', path_params = {}
query_params = []
header_params = {'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': 'Swagger-Codegen/21.02.5/python', 'X-...TA5NjVkYmNoZmQzMAowMDFhY2lkIHRpbWUgPCAxNzU2MzQwNDM00CjAwMmZzaWduYXR1cmUgmabz5hB2IVWWVg3nUnU3IlNRnAyxL9mgn7dbLnUwGJ00K'}
body = {'expression': 'geo=PL', 'fileId': '000000000084307A7368617265477569642373706163655F6430616231393661613361383166326632...663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'}
post_params = [], files = {}, response_type = 'InlineResponse2014'
auth_settings = ['api_key1', 'api_key2'], async_req = None
_return_http_data_only = True, collection_formats = {}, _preload_content = True
_request_timeout = None

    def call_api(self, resource_path, method,
                 path_params=None, query_params=None, header_params=None,
                 body=None, post_params=None, files=None,
                 response_type=None, auth_settings=None, async_req=None,
                 _return_http_data_only=None, collection_formats=None,
                 _preload_content=True, _request_timeout=None):
        """Makes the HTTP request (synchronous) and returns deserialized data.
    
            To make an async request, set the async_req parameter.
    
            :param resource_path: Path to method endpoint.
            :param method: Method to call.
            :param path_params: Path parameters in the url.
            :param query_params: Query parameters in the url.
            :param header_params: Header parameters to be
                placed in the request header.
            :param body: Request body.
            :param post_params dict: Request post form parameters,
                for `application/x-www-form-urlencoded`, `multipart/form-data`.
            :param auth_settings list: Auth Settings names for the request.
            :param response: Response data type.
            :param files dict: key -> filename, value -> filepath,
                for `multipart/form-data`.
            :param async_req bool: execute request asynchronously
            :param _return_http_data_only: response data without head status code
                                           and headers
            :param collection_formats: dict of collection formats for path, query,
                header, and post parameters.
            :param _preload_content: if False, the urllib3.HTTPResponse object will
                                     be returned without reading/decoding response
                                     data. Default is True.
            :param _request_timeout: timeout setting for this request. If one
                                     number provided, it will be total request
                                     timeout. It can also be a pair (tuple) of
                                     (connection, read) timeouts.
            :return:
                If async_req parameter is True,
                the request will be called asynchronously.
                The method will return the request thread.
                If parameter async_req is False or missing,
                then the method will return the response directly.
            """
        if not async_req:
>           return self.__call_api(resource_path, method,
                                   path_params, query_params, header_params,
                                   body, post_params, files,
                                   response_type, auth_settings,
                                   _return_http_data_only, collection_formats,
                                   _preload_content, _request_timeout)

tests/mixed/oneprovider_client/api_client.py:326: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <oneprovider_client.api_client.ApiClient object at 0x7f1642aaf3d0>
resource_path = '/qos_requirements', method = 'POST', path_params = {}
query_params = []
header_params = {'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': 'Swagger-Codegen/21.02.5/python', 'X-...TA5NjVkYmNoZmQzMAowMDFhY2lkIHRpbWUgPCAxNzU2MzQwNDM00CjAwMmZzaWduYXR1cmUgmabz5hB2IVWWVg3nUnU3IlNRnAyxL9mgn7dbLnUwGJ00K'}
body = {'expression': 'geo=PL', 'fileId': '000000000084307A7368617265477569642373706163655F6430616231393661613361383166326632...663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'}
post_params = [], files = {}, response_type = 'InlineResponse2014'
auth_settings = ['api_key1', 'api_key2'], _return_http_data_only = True
collection_formats = {}, _preload_content = True, _request_timeout = None

    def __call_api(
            self, resource_path, method, path_params=None,
            query_params=None, header_params=None, body=None, post_params=None,
            files=None, response_type=None, auth_settings=None,
            _return_http_data_only=None, collection_formats=None,
            _preload_content=True, _request_timeout=None):
    
        config = self.configuration
    
        # header parameters
        header_params = header_params or {}
        header_params.update(self.default_headers)
        if self.cookie:
            header_params['Cookie'] = self.cookie
        if header_params:
            header_params = self.sanitize_for_serialization(header_params)
            header_params = dict(self.parameters_to_tuples(header_params,
                                                           collection_formats))
    
        # path parameters
        if path_params:
            path_params = self.sanitize_for_serialization(path_params)
            path_params = self.parameters_to_tuples(path_params,
                                                    collection_formats)
            for k, v in path_params:
                # specified safe chars, encode everything
                resource_path = resource_path.replace(
                    '{%s}' % k,
                    quote(str(v), safe=config.safe_chars_for_path_param)
                )
    
        # query parameters
        if query_params:
            query_params = self.sanitize_for_serialization(query_params)
            query_params = self.parameters_to_tuples(query_params,
                                                     collection_formats)
    
        # post parameters
        if post_params or files:
            post_params = self.prepare_post_parameters(post_params, files)
            post_params = self.sanitize_for_serialization(post_params)
            post_params = self.parameters_to_tuples(post_params,
                                                    collection_formats)
    
        # auth setting
        self.update_params_for_auth(header_params, query_params, auth_settings)
    
        # body
        if body:
            body = self.sanitize_for_serialization(body)
    
        # request url
        url = self.configuration.host + resource_path
    
        # perform request and return response
>       response_data = self.request(
            method, url, query_params=query_params, headers=header_params,
            post_params=post_params, body=body,
            _preload_content=_preload_content,
            _request_timeout=_request_timeout)

tests/mixed/oneprovider_client/api_client.py:158: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <oneprovider_client.api_client.ApiClient object at 0x7f1642aaf3d0>
method = 'POST'
url = 'https://dev-oneprovider-krakow.default.svc.cluster.local:443/api/v3/oneprovider/qos_requirements'
query_params = []
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': 'Swagger-Codegen/21.02.5/python', 'X-...TA5NjVkYmNoZmQzMAowMDFhY2lkIHRpbWUgPCAxNzU2MzQwNDM00CjAwMmZzaWduYXR1cmUgmabz5hB2IVWWVg3nUnU3IlNRnAyxL9mgn7dbLnUwGJ00K'}
post_params = []
body = {'expression': 'geo=PL', 'fileId': '000000000084307A7368617265477569642373706163655F6430616231393661613361383166326632...663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'}
_preload_content = True, _request_timeout = None

    def request(self, method, url, query_params=None, headers=None,
                post_params=None, body=None, _preload_content=True,
                _request_timeout=None):
        """Makes the HTTP request using RESTClient."""
        if method == "GET":
            return self.rest_client.GET(url,
                                        query_params=query_params,
                                        _preload_content=_preload_content,
                                        _request_timeout=_request_timeout,
                                        headers=headers)
        elif method == "HEAD":
            return self.rest_client.HEAD(url,
                                         query_params=query_params,
                                         _preload_content=_preload_content,
                                         _request_timeout=_request_timeout,
                                         headers=headers)
        elif method == "OPTIONS":
            return self.rest_client.OPTIONS(url,
                                            query_params=query_params,
                                            headers=headers,
                                            post_params=post_params,
                                            _preload_content=_preload_content,
                                            _request_timeout=_request_timeout,
                                            body=body)
        elif method == "POST":
>           return self.rest_client.POST(url,
                                         query_params=query_params,
                                         headers=headers,
                                         post_params=post_params,
                                         _preload_content=_preload_content,
                                         _request_timeout=_request_timeout,

tests/mixed/oneprovider_client/api_client.py:368: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <oneprovider_client.rest.RESTClientObject object at 0x7f1642aaf400>
url = 'https://dev-oneprovider-krakow.default.svc.cluster.local:443/api/v3/oneprovider/qos_requirements'
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': 'Swagger-Codegen/21.02.5/python', 'X-...TA5NjVkYmNoZmQzMAowMDFhY2lkIHRpbWUgPCAxNzU2MzQwNDM00CjAwMmZzaWduYXR1cmUgmabz5hB2IVWWVg3nUnU3IlNRnAyxL9mgn7dbLnUwGJ00K'}
query_params = [], post_params = []
body = {'expression': 'geo=PL', 'fileId': '000000000084307A7368617265477569642373706163655F6430616231393661613361383166326632...663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'}
_preload_content = True, _request_timeout = None

    def POST(self, url, headers=None, query_params=None, post_params=None,
             body=None, _preload_content=True, _request_timeout=None):
>       return self.request("POST", url,
                            headers=headers,
                            query_params=query_params,
                            post_params=post_params,
                            _preload_content=_preload_content,
                            _request_timeout=_request_timeout,
                            body=body)

tests/mixed/oneprovider_client/rest.py:269: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <oneprovider_client.rest.RESTClientObject object at 0x7f1642aaf400>
method = 'POST'
url = 'https://dev-oneprovider-krakow.default.svc.cluster.local:443/api/v3/oneprovider/qos_requirements'
query_params = []
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': 'Swagger-Codegen/21.02.5/python', 'X-...TA5NjVkYmNoZmQzMAowMDFhY2lkIHRpbWUgPCAxNzU2MzQwNDM00CjAwMmZzaWduYXR1cmUgmabz5hB2IVWWVg3nUnU3IlNRnAyxL9mgn7dbLnUwGJ00K'}
body = {'expression': 'geo=PL', 'fileId': '000000000084307A7368617265477569642373706163655F6430616231393661613361383166326632...663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'}
post_params = {}, _preload_content = True, _request_timeout = None

    def request(self, method, url, query_params=None, headers=None,
                body=None, post_params=None, _preload_content=True,
                _request_timeout=None):
        """Perform requests.
    
            :param method: http request method
            :param url: http request url
            :param query_params: query parameters in the url
            :param headers: http request headers
            :param body: request json body, for `application/json`
            :param post_params: request post parameters,
                                `application/x-www-form-urlencoded`
                                and `multipart/form-data`
            :param _preload_content: if False, the urllib3.HTTPResponse object will
                                     be returned without reading/decoding response
                                     data. Default is True.
            :param _request_timeout: timeout setting for this request. If one
                                     number provided, it will be total request
                                     timeout. It can also be a pair (tuple) of
                                     (connection, read) timeouts.
            """
        method = method.upper()
        assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
                          'PATCH', 'OPTIONS']
    
        if post_params and body:
            raise ValueError(
                "body parameter cannot be used with post_params parameter."
            )
    
        post_params = post_params or {}
        headers = headers or {}
    
        timeout = None
        if _request_timeout:
            if isinstance(_request_timeout, (int, ) if six.PY3 else (int, long)):  # noqa: E501,F821
                timeout = urllib3.Timeout(total=_request_timeout)
            elif (isinstance(_request_timeout, tuple) and
                  len(_request_timeout) == 2):
                timeout = urllib3.Timeout(
                    connect=_request_timeout[0], read=_request_timeout[1])
    
        if 'Content-Type' not in headers:
            headers['Content-Type'] = 'application/json'
    
        try:
            # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
            if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
                if query_params:
                    url += '?' + urlencode(query_params)
                if re.search('json', headers['Content-Type'], re.IGNORECASE):
                    request_body = '{}'
                    if body is not None:
                        request_body = json.dumps(body)
                    r = self.pool_manager.request(
                        method, url,
                        body=request_body,
                        preload_content=_preload_content,
                        timeout=timeout,
                        headers=headers)
                elif headers['Content-Type'] == 'application/x-www-form-urlencoded':  # noqa: E501
                    r = self.pool_manager.request(
                        method, url,
                        fields=post_params,
                        encode_multipart=False,
                        preload_content=_preload_content,
                        timeout=timeout,
                        headers=headers)
                elif headers['Content-Type'] == 'multipart/form-data':
                    # must del headers['Content-Type'], or the correct
                    # Content-Type which generated by urllib3 will be
                    # overwritten.
                    del headers['Content-Type']
                    r = self.pool_manager.request(
                        method, url,
                        fields=post_params,
                        encode_multipart=True,
                        preload_content=_preload_content,
                        timeout=timeout,
                        headers=headers)
                # Pass a `string` parameter directly in the body to support
                # other content types than Json when `body` argument is
                # provided in serialized form
                elif isinstance(body, str):
                    request_body = body
                    r = self.pool_manager.request(
                        method, url,
                        body=request_body,
                        preload_content=_preload_content,
                        timeout=timeout,
                        headers=headers)
                else:
                    # Cannot generate the request from given parameters
                    msg = """Cannot prepare a request message for provided
                                 arguments. Please check that your arguments match
                                 declared content type."""
                    raise ApiException(status=0, reason=msg)
            # For `GET`, `HEAD`
            else:
                r = self.pool_manager.request(method, url,
                                              fields=query_params,
                                              preload_content=_preload_content,
                                              timeout=timeout,
                                              headers=headers)
        except urllib3.exceptions.SSLError as e:
            msg = "{0}\n{1}".format(type(e).__name__, str(e))
            raise ApiException(status=0, reason=msg)
    
        if _preload_content:
            r = RESTResponse(r)
    
            # In the python 3, the response.data is bytes.
            # we need to decode it to string.
            if six.PY3:
                r.data = r.data.decode('utf8')
    
            # log response body
            logger.debug("response body: %s", r.data)
    
        if not 200 <= r.status <= 299:
>           raise ApiException(http_resp=r)
E           oneprovider_client.rest.ApiException: (400)
E           Reason: Bad Request
E           HTTP response headers: HTTPHeaderDict({'access-control-allow-origin': '*', 'content-length': '110', 'content-type': 'application/json', 'date': 'Wed, 28 Aug 2024 00:20:39 GMT', 'server': 'Cowboy'})
E           HTTP response body: {"error":{"id":"posix","details":{"errno":"eperm"},"description":"Operation failed with POSIX error: eperm."}}

tests/mixed/oneprovider_client/rest.py:228: ApiException

During handling of the above exception, another exception occurred:

request = <FixtureRequest for <Function 'test_user_fails_to_add_qos_requirement_to_the_share_root_directory[1oz_1op_1oc]'>>

    @pytest.mark.usefixtures(*function_args)
    def scenario_wrapper(request):
>       _execute_scenario(feature, scenario, request, encoding)

/usr/local/lib/python3.8/dist-packages/pytest_bdd/scenario.py:227: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python3.8/dist-packages/pytest_bdd/scenario.py:189: in _execute_scenario
    _execute_step_function(request, scenario, step, step_func)
/usr/local/lib/python3.8/dist-packages/pytest_bdd/scenario.py:130: in _execute_step_function
    step_func(**kwargs)
tests/utils/bdd_utils.py:78: in wrapper
    return fun(*ba.args, **ba.kwargs)
tests/mixed/steps/rest/onezone/special_dirs.py:210: in try_to_add_qos_to_special_dir
    try_to_add_qos_to_special_dir_by_id(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

user = 'user1'
users = {'admin': <tests.utils.user_utils.AdminUser object at 0x7f1642a9e760>, 'admin2': <tests.utils.user_utils.User object a...s.user_utils.AdminUser object at 0x7f1642a9e790>, 'user1': <tests.utils.user_utils.User object at 0x7f1642a9efa0>, ...}
hosts = {'oneclient-1': {'container-id': 'a1665dfa9522de4c0d029815cb36d9f2e354b51c9bfe5c8f33b894c1bf45b5c9', 'ip': '10.244.216...f59396aa3ba6', 'hostname': 'dev-onezone.default.svc.cluster.local', 'ip': '10.244.216.98', 'name': 'dev-onezone', ...}}
host = 'oneprovider-1'
dir_id = '000000000084307A7368617265477569642373706163655F643061623139366161336138316632663235666365326366666530616435383963683...6663653263666665306164353839636833343232233631633562653365323136663730623237613638363630336665323561393863636839356234'
expression = 'geo=PL'
err_msg = 'Qos requirement added to share root dir, but adding should have failed'

    def try_to_add_qos_to_special_dir_by_id(user, users, hosts, host, dir_id,
                                            expression, err_msg=''):
        try:
            create_qos_requirement_in_op_by_id_rest(
                user, users, hosts, host, expression,
                dir_id)
            raise Exception(err_msg)
        except ApiException as e:
            ex_err_msg = 'You are not authorized to perform this operation.'
>           assert ex_err_msg in str(e)
E           AssertionError

tests/mixed/steps/rest/onezone/special_dirs.py:225: AssertionError