Пример #1
0
    def AddTestToTestSet(self, test_case_id, test_set_id):
        '''
        See https://sharenet-ims.inside.nsn.com/livelink/livelink/Download/392499262

        Return value is very intersting, because it tells the test instance ID:
            <return_message>
              <status>True</status>
              <return_value>
                <test_instance_id>62</test_instance_id>
              </return_value>
            </return_message>
        '''
        parameters = ElementTree.Element('parameters')
        ElementTree.SubElement(parameters, 'test_set_id').text = test_set_id
        instances = ElementTree.SubElement(parameters, 'test_instances')
        instance = ElementTree.SubElement(instances, 'test_instance')
        fields = ElementTree.SubElement(instance, 'fields')
        ElementTree.SubElement(fields, 'TC_TEST_ID').text = test_case_id
        ElementTree.SubElement(instance, 'attachments')
        input_xml = self._constructInputXML('AddTests2TestSet', parameters)
        Log.debug(self._removePassword(input_xml))
        returnXML = self._QcXmlApiCall("AddTests2TestSet", input_xml)
        element = ElementTree.XML(returnXML)
        test_instance_ids = element.findall('return_value')[0].findall('test_instance_id')
        if len(test_instance_ids) != 1:
            raise Exception("Did not get unique (or any) test instance ID.")
        else:
            return test_instance_ids[0].text
Пример #2
0
 def _report(self, testset_opt, testset_id_opt, release=None, build=None):
     Log.critical("Trying to connect QualityCenter...")
     # Log.info('Connected to QCXML version %s' % client.GetVersion())
     Log.critical("Validating data...")
     if testset_id_opt:
         testset_qcid = testset_id_opt
     else:
         testset_path, testset_name = self._split_testset_argument(
             testset_opt)
         try:
             testset_qcid = self.client.FindTestSet(testset_path,
                                                    testset_name)
         except:
             testset_qcid = self.client.AddTestSet(testset_path,
                                                   testset_name)
     already_added_cases = self.client.GetTestSetInstances(testset_qcid)
     Log.info(
         'QC internal ID for the test set is "%s". It contains instances for %s test cases'
         % (testset_qcid, len(already_added_cases)))
     results = []
     for result in self.results:
         # Extend result dicts with QC internal IDs for test cases
         try:
             test_case_id = result['test_case_id'].split()[0]
             qcid = self.client.FindTestCase(test_case_id)
             Log.info('QC internal ID for test case "%s" is "%s"' %
                      (test_case_id, qcid))
             result['qcid'] = qcid
             qcstatus = "Passed" if result['status'] == "PASS" else "Failed"
             result['qcstatus'] = qcstatus
             results.append(result)
         except Exception, errmsg:
             Log.info("test case id <%s> error: %s" %
                      (test_case_id, errmsg))
Пример #3
0
 def initialize_client(self):
     self.client = QcRestClient(self.config.server_url,
                                self.config.username, self.config.password,
                                self.config.domain, self.config.project,
                                self.config.proxy)
     Log.critical("Authenticating to QC REST API...")
     self.client.authenticate()
Пример #4
0
 def wait(self):
     if self.attempt >= self.max_attempts:
         raise RetryLimitExceeded(self.max_attempts)
     Log.debug("Retry attempt:%s, next sleep:%s" %
               (self.attempt, self.next_sleep()))
     time.sleep(self.next_sleep())
     self.attempt += 1
Пример #5
0
    def AddTestSet(self, path, test_set_name):
        '''
        Add test set by path and name
        More details, See: <https://qc-api.inside.nsn.com/QcXmlWebSite/>
        Excpected return value from API
        <return_message>
          <status>True</status>
          <return_value>
            <id>1803</id>
          </return_value>
        </return_message>
        '''
        parameters = ElementTree.Element('parameters')
        ElementTree.SubElement(parameters, 'path').text = path
        test_set = ElementTree.SubElement(parameters, 'test_set')
        ElementTree.SubElement(test_set, 'attachments').text = ''
        fields = ElementTree.SubElement(test_set, 'fields')
        ElementTree.SubElement(fields, 'CY_CYCLE').text = test_set_name
        ElementTree.SubElement(fields, 'CY_USER_01').text = 'RCP0'
        ElementTree.SubElement(fields, 'CY_USER_02').text = 'EnTe - Functional Test'
        ElementTree.SubElement(fields, 'CY_USER_13').text = 'Draft'
        ElementTree.SubElement(fields, 'CY_USER_18').text = 'N/A'
        ElementTree.SubElement(fields, 'CY_USER_51').text = 'cWLC'
        input_xml = self._constructInputXML('AddTestSet', parameters)
        Log.debug(self._removePassword(input_xml))

        returnXML = self._QcXmlApiCall("AddTestSet", input_xml)
        element = ElementTree.XML(returnXML)        
        return element.findall('return_value')[0].findall('id')[0].text
Пример #6
0
 def map_tc2req(self, qc_test_id, requirement_id):
     coverage = self.client.getReqCoverageByTCID(qc_test_id)
     if requirement_id in coverage:
         Log.info('Requirement map already exists - no need to create')
     else:
         Log.info('Requirement map missing - creating')
         self.client.addReqCoverage(qc_test_id, requirement_id)
Пример #7
0
 def initialize_client(self):
     self.client = QcXmlClient(self.config.xml_api_url,
                               self.config.username, self.config.password,
                               self.config.domain, self.config.project,
                               self.config.test_case_search_root,
                               self.config.proxy)
     Log.critical("Initialized QC XML API client")
     self.client.initialize()
Пример #8
0
 def authenticate(self):
     path = 'qcbin/authentication-point/alm-authenticate'
     data = ("<?xml version='1.0' encoding='utf-8'?>"
             "<alm-authentication>"
             "<user>%s</user>"
             "<password>%s</password>"
             "</alm-authentication>") % (self.username, self.password)
     q = RestHeaderQuery(path, "post", data=data)
     headers = q.request(self.server, proxies=self.proxy)
     self.cookie = headers['set-cookie']
     Log.debug("Got cookie: %s" % self.cookie)
Пример #9
0
 def __init__(self, server, username, password, domain, project, proxy):
     super(QcRestClient, self).__init__()
     self.server = server
     self.username = username
     self.password = password
     self.domain = domain
     self.project = project
     self.proxy = proxy
     self.cookie = None
     logvars = copy.deepcopy(vars())
     del logvars['password']
     Log.debug('Initialized QC REST client with: %s' % logvars)
Пример #10
0
 def _split_testset_argument(testset_input):
     Log.debug("Parsing test set '%s'" % testset_input)
     match = re.search(r'\\', testset_input)
     if not match:
         raise QcReporterException(
             "Test set path must look like 'Root\\Folder\\...\\Test set name' "
             "and it must contain at least one path separator character ('\\')"
         )
     testset_components = testset_input.rsplit('\\', 1)
     testset_path = testset_components[0]
     testset_name = testset_components[1]
     Log.debug("Looking for test set %s in path %s" %
               (testset_name, testset_path))
     return (testset_path, testset_name)
Пример #11
0
 def add_tc(self, test_path, test_id, test_name, test_prio):
     parent_id = self.client.resolveTestFolderQcId(test_path)
     existing_test_id = self.client.getTestCaseByTCID(
         test_id, parent_id=parent_id, raise_on_empty_match=False)
     if existing_test_id:
         Log.info('test %s: id=%s already exists - updating' %
                  (test_id, existing_test_id))
         self.client.updateTestCase(existing_test_id, parent_id, test_id,
                                    test_name, test_prio)
     else:
         Log.info('test %s: not existing - adding' % (test_id))
         existing_test_id = self.client.addTestCase(parent_id, test_id,
                                                    test_name, test_prio)
     return int(existing_test_id)
Пример #12
0
 def _QcXmlApiCall(self, method_name, inputXML):
     Log.debug('Calling %s on %s' % (method_name, self.url))
     delay = RetryDelay(40)
     while True:
         try:
             ret = getattr(self.client.service, method_name)(inputXML)
             return self._FilterQcXmlExceptions(ret)
         except QcXmlException:
             raise
         except Exception, e:
             Log.warn('Temporary problem in QualityCenter (%s). Retrying in %s s...' %
                                 (e, delay.next_sleep()))
             delay.wait()  # Will throw exception after max attempts
             self.initialize()
Пример #13
0
 def GetUserProjects(self):
     '''
     Excpected return value from API
     <return_message>
       <status>True</status>
       <return_value>
         <project_name>FP</project_name>
       </return_value>
     </return_message>
     '''
     input_xml = self._constructInputXML('GetUserProjects')
     Log.debug(self._removePassword(input_xml))
     returnXML = self._QcXmlApiCall("GetUserProjects", input_xml)
     element = ElementTree.XML(returnXML)
     return [x.text for x in element.findall('return_value')[0].findall('project_name')]
Пример #14
0
 def equals_query(queries):
     """
     Query to be appended to URL after "?"
     queries - dict of key-value pairs that must match. e.g. {'user-01': 'EXAMPLE_001'}}
     No support for spaces or special characters. Add the support in this fuction if you need them.
     """
     key_value_pair_strings = []
     for key, value in queries.items():
         if type(value) is str:
             value = value.replace('&', '%26')
         if type(value) == int:
             value_str = '%s' % value
         else:
             value_str = "'%s'" % value
         Log.debug("############################# STR: %s" % value_str)
         key_value_pair_strings.append('%s[%s]' % (key, value_str))
     return "query={%s}" % (';'.join(key_value_pair_strings))
Пример #15
0
    def FindTestCase(self, test_case_id, path=None):
        '''
        Finds test case's numeric ID by the test_case_id string.
        test_case_id is the "Test Case ID" in QC web UI. In the database
        this field is called TS_USER_01. Numeric test case id is internal
        to QC and not visible in the web user interface.

        Expected return value, e.g.
            <return_message>
              <status>True</status>
              <return_value>
                <test_case>
                  <id>28</id>
                  <name>Authentication configuration of NTP</name>
                  <path>\Subject\VGP&amp;LCC\NECC\Operability Interfaces\NTP\NECC provides clock synchronization to vNE</path>
                </test_case>
              </return_value>
            </return_message>
        '''
        if not path:
            path = self.test_case_search_root
        parameters = ElementTree.Element('parameters')
        path_elem = ElementTree.SubElement(parameters, 'path')
        ElementTree.SubElement(parameters, 'recursive').text = 'true'
        ElementTree.SubElement(parameters, 'include_attachments').text = 'false'
        ElementTree.SubElement(parameters, 'include_test_case_details').text = 'false'
        fields = ElementTree.SubElement(parameters, 'fields')
        test_case_id_elem = ElementTree.SubElement(fields, 'TS_USER_01')
        path_elem.text = path
        test_case_id_elem.text = '"%s"' % test_case_id
        input_xml = self._constructInputXML('GetTestCaseList', parameters)
        Log.debug(self._removePassword(input_xml))
        returnXML = self._QcXmlApiCall("GetTestCaseList", input_xml)
        element = ElementTree.XML(returnXML)
        testcases = element.findall('return_value')[0].findall('test_case')
        if len(testcases) > 1:
            raise QcClientException("Test case ID %s is not unique. Candidates are: %s" %
                                    (test_case_id, [x.findall('name')[0].text for x in testcases]))
        elif len(testcases) < 1:
            raise QcClientException('No test cases found with ID "%s" under path "%s"' %
                                    (test_case_id, self.test_case_search_root))
        else:
            return testcases[0].findall('id')[0].text
Пример #16
0
    def _analyze_result(self, response, headers=None):
        """ This function could be overriden if the response might contain more than one acceptable return codes """
        Log.debug("result: %d" % response.status_code)
        Log.log(5, "response text: %s" % response.text)
        Log.log(5, "response headers: %s" % response.headers)
        if headers:
            Log.log(5, "headers: %s" % headers)

        if response.status_code == self.result:
            return self._parse_result_parameters(response)

        raise RestQueryException("Status code mismatch, expected %d, got %d" %
                                 (self.result, response.status_code), response.text)
Пример #17
0
    def FindTestSetFolder(self, path, folder_name):
        '''
        Finds test set folder by the folder name
        More details, See: <https://qc-api.inside.nsn.com/QcXmlWebSite/>
        Excpected return value from API
        <return_message>
            <status>True</status>
            <return_value>
                <folder_tree_node>
                    <folder>
                        <name>lidong_test</name>
                        <path>Root\lidong_test</path>
                    </folder>
                  <folder_tree_node>
                      <folder>
                          <name>testfolder_cj_01</name>
                          <path>Root\lidong_test\testfolder_cj_01</path>
                      </folder>
                    </folder_tree_node>
                    <folder_tree_node>
                        <folder>
                            <name>testfolder_cj_02</name>
                            <path>Root\lidong_test\testfolder_cj_02</path>
                        </folder>
                    </folder_tree_node>
                </folder_tree_node>
            </return_value>
        </return_message>
        '''
        parameters = ElementTree.Element('parameters')
        ElementTree.SubElement(parameters, 'path').text = path
        ElementTree.SubElement(parameters, 'include_attachments').text = 'false'        
        ElementTree.SubElement(parameters, 'recursive').text = 'false'
        input_xml = self._constructInputXML('GetTestSetFolderTree', parameters)
        Log.debug(self._removePassword(input_xml))
        returnXML = self._QcXmlApiCall("GetTestSetFolderTree", input_xml)
        element = ElementTree.XML(returnXML)
        nodes = element.findall('return_value')[0].findall('folder_tree_node')
#         parent = nodes[0].findall('folder')[0].findall('name')[0].text
        childrens = [n[0].findall('name')[0].text for n in nodes[0].findall('folder_tree_node')]
        return (folder_name in childrens)    
Пример #18
0
 def FindTestSet(self, path, test_set_name):
     '''
     Finds test set id by the test set name
     '''
     parameters = ElementTree.Element('parameters')
     ElementTree.SubElement(parameters, 'path').text = path
     ElementTree.SubElement(parameters, 'include_attachments').text = 'false'
     ElementTree.SubElement(parameters, 'include_test_set_details').text = 'false'
     ElementTree.SubElement(parameters, 'recursive').text = 'false'
     fields = ElementTree.SubElement(parameters, 'fields')
     ElementTree.SubElement(fields, 'CY_CYCLE').text = '"%s"' % test_set_name
     input_xml = self._constructInputXML('GetTestSetList', parameters)
     Log.debug(self._removePassword(input_xml))
     returnXML = self._QcXmlApiCall("GetTestSetList", input_xml)
     element = ElementTree.XML(returnXML)
     testsets = element.findall('return_value')[0].findall('test_set')
     if len(testsets) > 1:
         raise QcClientException("Test set %s is not unique. Candidates are: %s" %
                                 (test_set_name, [x.findall('name')[0].text for x in testsets]))
     elif len(testsets) < 1:
         raise QcClientException("No test sets found with name %s" % (test_set_name))
     else:
         return testsets[0].findall('id')[0].text
Пример #19
0
 def AddTestSetFolder(self, path, folder_name):
     '''
     Add test set folder by path and folder name
     More details, See: <https://qc-api.inside.nsn.com/QcXmlWebSite/>
     Excpected return value from API
     <return_message>
       <status>True</status>
       <return_value>
         <id>62</id>
       </return_value>
     </return_message>
     '''
     parameters = ElementTree.Element('parameters')        
     test_set_folder = ElementTree.SubElement(parameters, 'folder')
     ElementTree.SubElement(test_set_folder, 'attachments').text = ''
     ElementTree.SubElement(test_set_folder, 'name').text = folder_name
     ElementTree.SubElement(test_set_folder, 'path').text = path        
     input_xml = self._constructInputXML('AddTestSetFolder', parameters)
     Log.debug(self._removePassword(input_xml))
     
     returnXML = self._QcXmlApiCall("AddTestSetFolder", input_xml)
     element = ElementTree.XML(returnXML)             
     return element.findall('return_value')[0].findall('id')[0].text        
Пример #20
0
 def debug_print_fields(entity, title=None):
     if title:
         Log.debug(title)
     else:
         Log.debug("----------------------------------")
     for field in entity['Fields']:
         for value in field['values']:
             if 'value' in value:
                 Log.debug("%-20s: %s" % (field['Name'], value['value']))
Пример #21
0
 def resolveTestFolderQcId(self, folder_path):
     folder_path_dirs = re.split(r'[/\\]', folder_path)
     parent_id = 0
     parent_name = ""
     for d in folder_path_dirs:
         path_frag = 'test-folders?' + self.equals_query({
             'parent-id': parent_id,
             'name': d
         })
         response = self.query(path_frag)
         if int(response['TotalResults']) < 1:
             raise QcClientException(
                 'No matches found with dir "%s" and parent \"%s\"' %
                 (d, parent_name))
         if int(response['TotalResults']) > 1:
             raise QcClientException(
                 'More than one match found with dir "%s" and parent \"%s\"'
                 % (d, parent_name))
         entity = response['entities'][0]
         self.debug_print_fields(entity)
         Log.debug('dir \"%s\" found' % (d))
         parent_id = self.get_field_value(entity, 'id')
         parent_name = self.get_field_value(entity, 'name')
     return self.get_field_value(entity, 'id')
Пример #22
0
 def AddRunToTestSet(self, test_case_id, test_set_id, result, release=None, build=None, set_date=True):
     '''
     See https://sharenet-ims.inside.nsn.com/livelink/livelink/Download/392499262
     '''
     parameters = ElementTree.Element('parameters')
     ElementTree.SubElement(parameters, 'test_set_id').text = test_set_id
     runs = ElementTree.SubElement(parameters, 'runs')
     run = ElementTree.SubElement(runs, 'run')
     ElementTree.SubElement(run, 'attachments')
     fields = ElementTree.SubElement(run, 'fields')
     ElementTree.SubElement(fields, 'RN_RUN_NAME').text = 'CloudTAF %s' % time.ctime()
     if set_date:
         ElementTree.SubElement(fields, 'RN_EXECUTION_DATE').text = time.strftime("%Y-%m-%d", time.gmtime())
         ElementTree.SubElement(fields, 'RN_EXECUTION_TIME').text = time.strftime("%H:%M:%S", time.gmtime())
     if release:
         ElementTree.SubElement(fields, 'RN_USER_03').text = release
     if build:
         ElementTree.SubElement(fields, 'RN_USER_01').text = build
     ElementTree.SubElement(fields, 'RN_TESTCYCL_ID').text = test_case_id
     ElementTree.SubElement(fields, 'RN_STATUS').text = result
     run = ElementTree.SubElement(run, 'steps')
     input_xml = self._constructInputXML('AddTestSetRuns', parameters)
     Log.debug(self._removePassword(input_xml))
     self._QcXmlApiCall("AddTestSetRuns", input_xml)
Пример #23
0
    def GetTestSetInstances(self, test_set_id):
        '''
        Get a list of test case IDs that have already been added in this test set.

        Return value from GetTestSet api call is very long. We need to check if the test
        instance corresponding the test case is already added, so the essentials are:
            <return_message>
              <status>True</status>
              <return_value>
                <test_set>
                  <id>1207</id>
                  <name>QC Integration Test Test Set</name>
                  <fields>
                    ...
                  </fields>
                  <test_instance>
                    <id>63</id>
                    <name>[7]Example TC</name>
                    <fields>
                      ...
                      <TC_TEST_ID label="Test" type="number" size="10">1</TC_TEST_ID>
                      ...
                    </fields>
                  </test_instance>
                  ...
                </test_set>
              </return_value>
            </return_message>
        '''
        parameters = ElementTree.Element('parameters')
        ElementTree.SubElement(parameters, 'include_attachments').text = 'false'
        ElementTree.SubElement(parameters, 'include_test_cases').text = 'false'
        set_fields = ElementTree.SubElement(parameters, 'testset_fields')
        ElementTree.SubElement(set_fields, 'CY_CYCLE_ID').text = 'CY_CYCLE_ID'
        instance_fields = ElementTree.SubElement(parameters, 'testinstance_fields')
        ElementTree.SubElement(instance_fields, 'TC_TEST_ID').text = 'TC_TEST_ID'
        ElementTree.SubElement(parameters, 'id').text = test_set_id
        input_xml = self._constructInputXML('GetTestSetByID', parameters)
        Log.debug(self._removePassword(input_xml))
        returnXML = self._QcXmlApiCall("GetTestSetByID", input_xml)
        Log.debug(returnXML)
        element = ElementTree.XML(returnXML)
        test_instances = element.findall('return_value')[0].findall('test_set')[0].findall('test_instance')
        instances_for_cases = dict()
        for i in test_instances:
            instance_qcid = i.findall('id')[0].text
            test_qcid = i.findall('fields')[0].findall('TC_TEST_ID')[0].text
            Log.debug('Test Case "%s" has a Test Instance "%s" in this test set' % (test_qcid, instance_qcid))
            instances_for_cases[test_qcid] = instance_qcid
        return instances_for_cases
Пример #24
0
 def main(self, args=None):
     args = QcUtilsParser().parse_args(args)
     Log.set_logging(args.verbosity)
     Log.debug('args:%s' % (args))
     try:
         command = args.cmd()
         command.initialize_client()
         command.run(args)
         self._exit(0)
     except QcUtilsDetailedException as e:
         Log.critical('\n\n----- Start error trace -----\n%s\n----- End error trace -----\n' % e.detail)
         Log.critical('Error: "%s"' % e)
         Log.critical('See stack trace above for more details')
         self._exit(1)
     except QcUtilsException as e:
         Log.critical('Error: "%s"' % e)
         self._exit(1)
Пример #25
0
 def _send_request(self, url, headers, payload, proxies):
     print_payload = self._remove_xml_password(payload)
     Log.log(5, "payload: %s" % print_payload)
     Log.debug("url: %s" % url)
     Log.log(5, "headers: %s" % headers)
     return self._analyze_result(self.method(url, data=payload, headers=headers, proxies=proxies), headers=headers)
Пример #26
0
 def test_case_search_root(self):
     Log.info('Password not given in configuration %s' % self.config_path)
     tc_root = self.config.get('test_case_search_root')
     return re.sub('&', '&amp;', tc_root)
Пример #27
0
 def print_results(results):
     Log.debug("Found the following test results to report")
     for r in results:
         Log.debug('%s (%s): %s' %
                   (r['name'], r['test_case_id'], r['status']))
Пример #28
0
class RobotToQcReporter(QcXmlHandler):
    def __init__(self):
        super(RobotToQcReporter, self).__init__()
        self.results = None

    def run(self, args):
        self.results = RobotResultParser(args.report).get_results()
        self._report(args.testset, args.testset_id, args.release, args.build)

    @staticmethod
    def _split_testset_argument(testset_input):
        Log.debug("Parsing test set '%s'" % testset_input)
        match = re.search(r'\\', testset_input)
        if not match:
            raise QcReporterException(
                "Test set path must look like 'Root\\Folder\\...\\Test set name' "
                "and it must contain at least one path separator character ('\\')"
            )
        testset_components = testset_input.rsplit('\\', 1)
        testset_path = testset_components[0]
        testset_name = testset_components[1]
        Log.debug("Looking for test set %s in path %s" %
                  (testset_name, testset_path))
        return (testset_path, testset_name)

    def _report(self, testset_opt, testset_id_opt, release=None, build=None):
        Log.critical("Trying to connect QualityCenter...")
        # Log.info('Connected to QCXML version %s' % client.GetVersion())
        Log.critical("Validating data...")
        if testset_id_opt:
            testset_qcid = testset_id_opt
        else:
            testset_path, testset_name = self._split_testset_argument(
                testset_opt)
            try:
                testset_qcid = self.client.FindTestSet(testset_path,
                                                       testset_name)
            except:
                testset_qcid = self.client.AddTestSet(testset_path,
                                                      testset_name)
        already_added_cases = self.client.GetTestSetInstances(testset_qcid)
        Log.info(
            'QC internal ID for the test set is "%s". It contains instances for %s test cases'
            % (testset_qcid, len(already_added_cases)))
        results = []
        for result in self.results:
            # Extend result dicts with QC internal IDs for test cases
            try:
                test_case_id = result['test_case_id'].split()[0]
                qcid = self.client.FindTestCase(test_case_id)
                Log.info('QC internal ID for test case "%s" is "%s"' %
                         (test_case_id, qcid))
                result['qcid'] = qcid
                qcstatus = "Passed" if result['status'] == "PASS" else "Failed"
                result['qcstatus'] = qcstatus
                results.append(result)
            except Exception, errmsg:
                Log.info("test case id <%s> error: %s" %
                         (test_case_id, errmsg))

        Log.critical("Reporting results...")
        for r in results:
            Log.info('Reporting "%s" ("%s", QC: %s) as "%s"' %
                     (r['name'], r['test_case_id'], r['qcid'], r['qcstatus']))
            if r['qcid'] in already_added_cases:
                instance_qcid = already_added_cases[r['qcid']]
            else:
                instance_qcid = self.client.AddTestToTestSet(
                    r['qcid'], testset_qcid)
            self.client.AddRunToTestSet(instance_qcid, testset_qcid,
                                        r['qcstatus'], release, build)
        Log.info("Source result [%s] -> uploaded result [%s]" %
                 (self.results.__len__(), results.__len__()))
        Log.critical("Reporting completed")