示例#1
0
def test_common_request_file_descriptor_closing():
    keywords = RequestsKeywords()
    session = keywords.create_session('alias', 'http://mocking.rules')
    # this prevents a real network call from being executed
    session.get = mock.MagicMock()
    with open(os.path.join(SCRIPT_DIR, '../atests/randombytes.bin'), 'rb') as f:
        keywords._common_request('get', session,
                                 'http://mocking.rules', data=f)
        assert f.closed is True
示例#2
0
 def __init__(self):
     self.params = Parameters()
     self.headers = Headers(APITEST="1")
     self.data = Data()
     self.requestBody = None
     self.status = Status()
     self.requestsKW = RequestsKeywords()
     self.fapiResponse = ''
     self.os = OperatingSystem()
     self.toObj = Json2Object()
示例#3
0
    def __init__(self):
        # disable requests warnings
        requests.packages.urllib3.disable_warnings()

        self.ROBOT_LIBRARY_LISTENER = self
        self.Request = RequestsKeywords()
        self.Request._utf8_urlencode = self._utf8_urlencode
        self.Request.__init__()

        self.alias = 'utfsession'
示例#4
0
class FapiKeywords(object):
    ROBOT_LIBRARY_SCOPE = 'Global'

    def __init__(self):
        self.params = Parameters()
        self.headers = Headers(APITEST="1")
        self.data = Data()
        self.requestBody = None
        self.status = Status()
        self.requestsKW = RequestsKeywords()
        self.fapiResponse = ''
        self.os = OperatingSystem()
        self.toObj = Json2Object()

    def fapi_headers_set(self, *key_value_pairs, **items):
        """Adds the given ``key_value_pairs`` and ``items`` to HTTP request headers.

        Giving items as ``key_value_pairs`` means giving keys and values
        as separate arguments:

        | Fapi Headers Set | key | value | second | ${2} |
        =>
        | headers = {'a': 1, 'key': 'value', 'second': 2}

        Starting from Robot Framework 2.8.1, items can also be given as kwargs
        using ``key=value`` syntax:

        | Fapi Headers Set |  key=value | second=${2} |

        The latter syntax is typically more convenient to use, but it has
        a limitation that keys must be strings.

        If given keys already exist in request headers, their values are updated.
        """
        self.headers.set(*key_value_pairs, **items)

    def fapi_headers_to_dictionary(self):
        """ Return all headers as a dictionary """
        return self.headers.to_dictionary()

    def fapi_headers_reset(self):
        """ Reset request headers """
        self.headers.reset()
        self.headers.set(APITEST="1")

    def fapi_params_set(self, *key_value_pairs, **items):
        """Adds the given ``key_value_pairs`` and ``items`` to HTTP request parameters.

        Giving items as ``key_value_pairs`` means giving keys and values
        as separate arguments:

        | Fapi Params Set | key | value | second | ${2} |
        =>
        | parameters = {'a': 1, 'key': 'value', 'second': 2}

        Starting from Robot Framework 2.8.1, items can also be given as kwargs
        using ``key=value`` syntax:

        | Fapi Params Set |  key=value | second=${2} |

        The latter syntax is typically more convenient to use, but it has
        a limitation that keys must be strings.

        If given keys already exist in request parameters, their values are updated.
        """
        self.params.set(*key_value_pairs, **items)

    def fapi_params_to_dictionary(self):
        """ Return all request parameters as a dictionary """
        return self.params.to_dictionary()

    def fapi_params_reset(self):
        """ Reset request parameters """
        self.params.reset()
        self.headers.set(APITEST="1")

    def fapi_create_session(self, alias, url, timeout=None):
        """ Fapi Create Session: create a HTTP session to a server

        ``alias`` Robot Framework alias to identify the session

        ``url`` Base url of the server

        ``timeout`` Connection timeout
        """
        fapiHeaders = self.fapi_headers_to_dictionary()
        self.requestsKW.create_session(alias,
                                       url,
                                       fapiHeaders,
                                       timeout=timeout)

    def fapi_post(self, alias, uri, data=None, timeout=None):
        """ Send a POST request on the session object found using the
        given `alias`

        ``alias`` that will be used to identify the Session object in the cache

        ``uri`` to send the POST request to

        ``data`` a dictionary of key-value pairs that will be urlencoded
               and sent as POST data
               or binary data that is sent as the raw body content

        ``timeout`` Connection timeout
        """
        self.requestBody = data
        fapiHeaders = self.fapi_headers_to_dictionary()
        fapiParams = self.fapi_params_to_dictionary()
        fBodyData, fParams = self._format_data_according_to_header(
            alias, fapiParams, fapiHeaders)
        self.fapiResponse = self.requestsKW.post_request(alias,
                                                         uri,
                                                         data=fBodyData,
                                                         params=fParams,
                                                         headers=fapiHeaders,
                                                         timeout=timeout)
        self.fapi_log_json(self.fapiResponse.content)
        self.fapi_params_reset()

    def fapi_post_files(self, alias, uri, filesDict, data=None, timeout=None):
        """ Upload a file to file server.

        ``alias`` that will be used to identify the Session object in the cache

        ``uri`` to send the POST request to

        ``filesDict`` a dictionary of file names containing file data to POST to the server

        ``data`` a dictionary of key-value pairs that will be urlencoded
               and sent as POST data
               or binary data that is sent as the raw body content

        ``timeout`` Connection timeout
        """
        self.requestBody = data
        fapiHeaders = self.fapi_headers_to_dictionary()
        fapiParams = self.fapi_params_to_dictionary()
        fBodyData, fParams = self._format_data_according_to_header(
            alias, fapiParams, fapiHeaders)
        self.fapiResponse = self.requestsKW.post_request(alias,
                                                         uri,
                                                         data=fBodyData,
                                                         params=fParams,
                                                         files=filesDict,
                                                         headers=fapiHeaders,
                                                         timeout=timeout)

        self.fapi_log_json(self.fapiResponse.content)
        self.fapi_params_reset()

    def fapi_get(self, alias, uri, timeout=None):
        """ Send a GET request on the session object found using the
        given `alias`

        ``alias`` that will be used to identify the Session object in the cache

        ``uri`` to send the GET request to

        ``timeout`` Connection timeout
        """
        fapiHeaders = self.fapi_headers_to_dictionary()
        fapiParams = self.fapi_params_to_dictionary()
        self.fapiResponse = self.requestsKW.get_request(alias,
                                                        uri,
                                                        params=fapiParams,
                                                        headers=fapiHeaders,
                                                        timeout=timeout)
        self.fapi_log_json(self.fapiResponse.content)
        self.fapi_params_reset()

    def fapi_put(self, alias, uri, data=None, timeout=None):
        """ Send a PUT request on the session object found using the
        given `alias`

        ``alias`` that will be used to identify the Session object in the cache

        ``uri`` to send the PUT request to

        ``data`` a dictionary of key-value pairs that will be urlencoded
               and sent as POST data
               or binary data that is sent as the raw body content

        ``timeout`` Connection timeout
        """
        self.requestBody = data
        fapiHeaders = self.fapi_headers_to_dictionary()
        fapiParams = self.fapi_params_to_dictionary()
        fBodyData, fParams = self._format_data_according_to_header(
            alias, fapiParams, fapiHeaders)
        self.fapiResponse = self.requestsKW.put_request(alias,
                                                        uri,
                                                        data=fBodyData,
                                                        params=fParams,
                                                        headers=fapiHeaders,
                                                        timeout=timeout)
        self.fapi_log_json(self.fapiResponse.content)
        self.fapi_params_reset()

    def fapi_delete(self, alias, uri, timeout=None):
        """ Send a DELETE request on the session object found using the
        given `alias`

        ``alias`` that will be used to identify the Session object in the cache

        ``uri`` to send the DELETE request to

        ``timeout`` Connection timeout
        """
        fapiHeaders = self.fapi_headers_to_dictionary()
        fapiParams = self.fapi_params_to_dictionary()
        self.fapiResponse = self.requestsKW.delete_request(alias,
                                                           uri,
                                                           params=fapiParams,
                                                           headers=fapiHeaders,
                                                           timeout=timeout)
        self.fapi_log_json(self.fapiResponse.content)
        self.fapi_params_reset()

    def fapi_delete_all_sessions(self):
        """ Removes all the session objects """
        self.requestsKW.delete_all_sessions()

    def fapi_request_should_be_succeed(self):
        """ Fapi HTTP response code should be 200 (means success) """
        print("HTTP response code is " + str(self.fapiResponse.status_code))
        assert self.fapiResponse.status_code == 200

    def fapi_response_code(self):
        """ Return Fapi HTTP response code
        """
        return self.fapiResponse.status_code

    def fapi_data_to_object(self):
        """ Convert Fapi response content to python object """
        if self.fapiResponse.content is None:
            return None
        obj = self.toObj.json_to_object(self.fapiResponse.content)
        return obj.data

    def fapi_response_data(self):
        """ Return Fapi response data """
        if self.fapiResponse.content is None:
            return None
        obj = json.loads(self.fapiResponse.content)
        data = obj['data']
        return data

    def fapi_response_data_to_object(self):
        """ Convert Fapi response content to python object """
        if self.fapiResponse.content is None:
            return None
        obj = self.toObj.json_to_object(self.fapiResponse.content)
        return obj

    def fapi_response_headers_to_dict(self):
        """ Convert Fapi response headers to dictionary """
        return self.fapiResponse.headers

    def fapi_data_field_count(self, pointer):
        """ Get element count specified by object pointer """
        return self.data.field_count(pointer)

    def fapi_data_field_count_should_be(self, pointer, expectedValue):
        """ Element count specified by object pointer should be equal to the given `expectedValue`

        ``expectedValue`` is the expected value of element count
        """
        actualValue = self.data.field_count(pointer)
        self.fapi_log("Actual value is: " + str(actualValue))
        assert actualValue == int(expectedValue)

    def fapi_data_field_count_should_not_be(self, pointer, expectedValue):
        """ Element count specified by object pointer should not be equal to the given `expectedValue`

        ``expectedValue`` is the not-expected value of element count
        """
        actualValue = self.data.field_count(pointer)
        assert actualValue != int(expectedValue)

    def fapi_status_should_be_succeed(self):
        """ Fapi response status code should be 0 (means success) """
        dataObj = self.toObj.json_to_object(self.fapiResponse.content)
        assert self.status.status_code(dataObj) == 0

    def fapi_status_should_be(self, expectedCode):
        """ Fapi response status code should be equal to the `expectedCode`

        ``expectedCode`` is the expected Fapi response status code
        """
        dataObj = self.toObj.json_to_object(self.fapiResponse.content)
        self.fapi_log("Actual status code is: " +
                      str(self.status.status_code(dataObj)))
        assert self.status.status_code(dataObj) == int(expectedCode)

    def fapi_status_should_not_be(self, expectedCode):
        """ Fapi response status code should not be equal to the `expectedCode`

        ``expectedCode`` is the not-expected Fapi response status code

        """
        dataObj = self.toObj.json_to_object(self.fapiResponse.content)
        self.fapi_log("Actual status code is: " +
                      str(self.status.status_code(dataObj)))
        assert self.status.status_code(dataObj) != int(expectedCode)

    def fapi_log_json(self, jsonStr):
        """ Log json strings to test report """
        try:
            json_ = json.loads(jsonStr)
            isFirstLine = True
            for line in json.dumps(json_, indent=2,
                                   ensure_ascii=False).split('\n'):
                if isFirstLine:
                    logger.write("JSON string is : " + line)
                    isFirstLine = False
                else:
                    logger.write(line)
        except Exception:
            pass

    def fapi_log(self, message, repr=False):
        """ Log `message` to test report """
        logger.write(message)

    def _format_data_according_to_header(self, alias, ftParams, headers):
        bodyData = None
        params = None

        if self.requestBody is not None and ftParams:
            bodyData = self.requestBody
            params = ftParams
        elif self.requestBody is not None:
            bodyData = self.requestBody
        else:
            if headers is not None and 'Content-Type' in headers and \
                    headers['Content-Type'].find("application/json") != -1:
                bodyData = ftParams
            elif headers is not None and 'Content-Type' in headers and \
                    headers['Content-Type'].find("application/x-www-form-urlencoded") != -1:
                params = ftParams

        return bodyData, params
示例#5
0
class UtfKeywords(object):
    ROBOT_LIBRARY_SCOPE = 'GLOBAL'
    ROBOT_LISTENER_API_VERSION = 2

    def __init__(self):
        # disable requests warnings
        requests.packages.urllib3.disable_warnings()

        self.ROBOT_LIBRARY_LISTENER = self
        self.Request = RequestsKeywords()
        self.Request._utf8_urlencode = self._utf8_urlencode
        self.Request.__init__()

        self.alias = 'utfsession'

    def login(self, url, user, password):
        data = {
            'fn': 'ajax_login',
            'args[]': [user, password],
        }

        self.Request.create_session(
            self.alias,
            url,
            headers={},
            cookies=None,
            auth=None,
            timeout=3,
            proxies=None,
            verify=False)  # do not verify ssl

        session = self.Request._cache.switch(self.alias)

        if url == 'http://127.0.0.1':
            session.trust_env = False  # do not use HTTP_PROXY from env if localhost

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok, \
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        good_token = re.compile("[0-9a-f]{64}")
        token = self._extract_result(response)

        if good_token.match(token):
            logged_cookie_val = {"name": 'user-session', "value": token, "domain": 'utf.avp.ru'}
            session.cookies.set(**logged_cookie_val)
            return
        else:
            raise AssertionError("Unable to obtain cookie token: {0} ".format(token))

    def utf_login(self, url, user, password):
        self.login(url, user, password)

    def add_vm(self, esx_id, datastore, vm_name):
        data = {
            'fn': 'ajax_add_vmachines',
            'args[]': (esx_id, "[{1}] {0}/{0}.vmx".format(vm_name, datastore)),
        }

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok, \
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        if not self._extract_result(response) == '1':
            raise AssertionError("Unable to add {0} machine".format(vm_name))

    def delete_vm(self, esx_id, vm_name):
        vm_id = self._get_vm_id_by_name(esx_id, vm_name)

        data = {
            'fn': 'ajax_delete_vmachines',
            'args[]': vm_id,
        }

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok, \
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        if not self._extract_result(response) == '1':
            raise AssertionError("Unable to delete {0} machine".format(vm_name))

    def revert_vm(self, esx_id, vm_name):
        vm_id = self._get_vm_id_by_name(esx_id, vm_name)
        data = {'fn': 'ajax_revert_vmachines', 'args[]': vm_id}

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok, \
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        if not self._extract_result(response) == '1':
            raise AssertionError("Unable to revert {0} machine".format(vm_name))

    def start_vm(self, esx_id, vm_name, params={}):
        vm_id = self._get_vm_id_by_name(esx_id, vm_name)

        args = list()
        args.append(params.get('clean_required', 1))
        args.append(params.get('keep_busy', 0))
        args.append(vm_id)

        data = {
            'fn': 'ajax_start_vmachines',
            'args[]': args,
        }

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok, \
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        if not self._extract_result(response) == '1':
            raise AssertionError("Unable to start {0} machine".format(vm_name))

    def set_vm_variables(self, esx_id, vm_name, params={}):
        if not esx_id or not vm_name:
            raise AssertionError("Please provide required parameters: esx_id/vm_name")

        vm_id = self._get_vm_id_by_name(esx_id, vm_name)

        for key in params.iterkeys():
            args = list()
            args.append(vm_id)
            args.append(key.encode('ascii'))
            args.append(params[key].encode('ascii'))

            data = {
                'fn': 'ajax_set_vmachine_var',
                'args[]': args
            }

            response = self.Request.post_request(alias=self.alias,
                                                 uri='/',
                                                 data=data,
                                                 allow_redirects=False)

            assert response.status_code == requests.codes.ok, \
                'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

            if not self._extract_result(response) == '1':
                raise AssertionError("Unable to add vm variable {0} to machine {1}".format(args, vm_name))

    def get_vm_variables(self, esx_id, vm_name, params={}):
        if not esx_id or not vm_name:
            raise AssertionError("Please provide required parameters: esx_id/vm_name")

        vm_id = self._get_vm_id_by_name(esx_id, vm_name)

        args = list()
        args.append(vm_id)

        data = {
            'fn': 'ajax_select_vmachine',
            'args[]': args
        }

        response = self.Request.get_request(alias=self.alias,
                                            uri='/',
                                            params=data,
                                            allow_redirects=True)

        assert response.status_code == requests.codes.ok, \
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        options = re.findall(r"<option value.+?>(.+?)=\"(.+?)\"<\/option", response.json()['result'][3], re.MULTILINE)

        options_dict = dict()

        for k, i in options:
            options_dict[k] = i

        return options_dict

    def set_project_variables(self, project_id, params={}):
        if not project_id:
            raise AssertionError("Please provide project id")

        for key in params.iterkeys():
            args = list()
            args.append(project_id)
            args.append(key.encode('ascii'))
            args.append(params[key].encode('ascii'))

            data = {
                'fn': 'ajax_set_project_var',
                'args[]': args
            }

            response = self.Request.post_request(alias=self.alias,
                                                 uri='/',
                                                 data=data,
                                                 headers=None,
                                                 files={},
                                                 allow_redirects=False)

            assert response.status_code == requests.codes.ok, \
                'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

            if not self._extract_result(response) == '1':
                raise AssertionError("Unable to set project variable {0}".format(args))

    def get_project_variables(self, project_id):
        if not project_id:
            raise AssertionError("Please provide project id")

        args = list()
        args.append(project_id)

        data = {
            'fn': 'ajax_load_project_vars',
            'args[]': args
        }

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok, \
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        response_str = self._extract_result(response)
        response_str = re.sub('<.*?>', '', response_str)
        param_list = re.findall(r"(.+?)=\"(.+?)\"", response_str, re.MULTILINE)

        param_dict = dict()

        for key, value in param_list:
            param_dict[key] = value

        return param_dict

    def set_vm_options(self, esx_id, vm_name, opts={}):
        if not esx_id or not vm_name:
            raise AssertionError("Please provide required parameters: esx_id/vm_name")

        opts_low = dict((k.lower(), v) for k, v in opts.iteritems())

        for k in opts_low.iterkeys():
            if k not in ('delay', 'static_ip'):
                raise AssertionError("Option {0} is unknown. Provide only delay and/or static_ip.".format(k))

        vm_id = self._get_vm_id_by_name(esx_id, vm_name)

        args = [
            vm_id,
            vm_name,
            '' if 'delay' not in opts else opts['delay'],
            '' if 'static_ip' not in opts else opts['static_ip'],
        ]

        data = {
            'fn': 'ajax_apply_vmachine_opts',
            'args[]': args
        }

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok, \
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        if not self._extract_result(response) == '1':
            raise AssertionError("Unable to set vm option {0} to machine {1}".format(opts, vm_name))

    def run_testset(self, esx_id, testset_id, vm_name, params={}):
        caller = 'ajax_run_testset'
        return self._runner(caller, esx_id, testset_id, vm_name, params)

    def run_test(self, esx_id, test_id, vm_name, params={}):
        caller = 'ajax_run_test'
        return self._runner(caller, esx_id, test_id, vm_name, params)

    def _runner(self, caller, esx_id, t_id, vm_name, params={}):
        params = self._asciize(params)

        if not t_id or not vm_name:
            raise AssertionError("Please provide required parameters: test or test suite id or vm id")

        if 'env' in params:
            if not isinstance(params['env'], dict):
                raise AssertionError("'env' from your parameters should be a dictionary")
            else:
                env = dict({}, **params['env'])
        else:
            env = {}

        for k in params.iterkeys():
            if k not in ('clean_required', 'manual', 'revert', 'force_revert', 'ignore_timeout', 'prepare_only', 'env'):
                self.builtin.log("Key: {0} not in specials, will be added as env".format(k), 'INFO')
                env[k] = params[k]

        vm_id = self._get_vm_id_by_name(esx_id, vm_name)

        args = [
            t_id,
            params.get('clean_required', 0),  # Clean machine is required (0 or 1),
            params.get('manual', 0),  # Keep machine BUSY after this job (0 or 1)
            params.get('revert', 0),  # Revert machine after this job (0 or 1)
            params.get('force_revert', 0),  # Revert after test/testset fatal fail (0 or 1)
            params.get('ignore_timeout', 0),  # Ignore execution timeouts (0 or 1)
            params.get('prepare_only', 0), # Just prepare test environment (0 or 1)
        ]

        if len(env) != 0:
            for key, value in env.iteritems():
                args.append(key + "=" + value)
        else:
            args.append('')

        args.append(vm_id)

        data = {
            'fn': caller,
            'args[]': args
        }

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok,\
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        response_res = self._extract_result(response)

        if re.search(r'\d{5}', response_res):
            return response_res
        else:
            raise AssertionError("Unable to run testset #{0}: {1}".format(t_id, response_res))

    def _get_vm_id_by_name(self, esx_id, vm_name):
        data = {
            'fn': 'ajax_load_vmachines',
            'args[]': esx_id
        }

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok,\
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        found = re.search('<option value=\"([\d]+)\"([^<>]+)>{0}<'.format(vm_name), self._extract_result(response))

        if not found:
            raise AssertionError("Unable to find {0} machine".format(vm_name))

        vm_id = found.group(1)

        return vm_id

    def vm_exists(self, esx_id, vm_name):
        try:
            self._get_vm_id_by_name(esx_id, vm_name)
            return True
        except AssertionError:
            return False

    def get_vm_ip_by_name(self, esx_id, vm_name):
        vm_id = self._get_vm_id_by_name(esx_id, vm_name)

        data = {
            'fn': 'ajax_select_vmachine',
            'args[]': vm_id
        }

        response = self.Request.post_request(alias=self.alias,
                                             uri='/',
                                             data=data,
                                             allow_redirects=False)

        assert response.status_code == requests.codes.ok,\
            'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

        return response.json()['result'][1].encode('ascii', 'ignore')

    def _extract_result(self, response):
        return response.json()['result'][0].encode('ascii', 'ignore')

    def _asciize(self, d={}):
        for k in d.iterkeys():
            if isinstance(d[k], dict):
                d[k] = self._asciize(d[k])
            else:
                d[k] = str(d[k]).encode('ascii', 'ignore')
        return d

    def wait_for_job_result(self, job_id):
        data = {
            'fn': 'ajax_get_job_batches',
            'args[]': job_id,
        }

        while True:
            try:
                response = self.Request.post_request(alias=self.alias,
                                                     uri='/',
                                                     data=data,
                                                     allow_redirects=False)
                assert response.status_code == requests.codes.ok,\
                    'Response code must be 200, actually ==> {error}'.format(error=response.status_code)

                response_str = self._extract_result(response)
                result = re.search('.*<div id=\"batch-' + str(job_id) + '\".*<div class=\"batch-header job-([a-z]+)\">.*', response_str, re.S)

                if result:
                    status = result.group(1)
                    if all([status != 'queued', status != 'running']):
                        return status.upper()
                else:
                    return 'JOB NOT FOUND'

                time.sleep(5)

            except Exception as err:
                logging.debug('ERROR ==> {}'.format(err))
                return 'EXCEPTION'

    def string_for_http_request(self, value=''):
        return re.compile('[^a-zA-Z0-9]').sub(lambda x: str(hex(ord(x.group()))).replace('0x', '%').upper(), value)

    def get_testset_name_by_id(self, project_id, testset_id):

        response = self.Request.get_request(alias=self.alias,
                                            uri='/?project=' + str(project_id) + '&page=tests')

        result = re.search('<option value=\"' + str(testset_id) + '\">(.+)</option>', response.text)

        if result is None:
            return 'TESTSET NOT FOUND'
        else:
            return result.group(1)

    def _utf8_urlencode(self, data):
        if type(data) is unicode:
            data = data.encode('utf-8')

        return data