def post_insert(self, db): """ If only some test cases must be in the plan, then create the corresponding TestCaseInPlan objects and relate them to this plan. """ self.env.log.debug(">>> post_insert") if not self.values['contains_all']: # Create a TestCaseInPlan for each test case specified by the User from testmanager.api import TestManagerSystem default_status = TestManagerSystem( self.env).get_default_tc_status() author = self.values['author'] for tc_page_name in self.selected_tcs: if tc_page_name != '': tc_id = tc_page_name.rpartition('TC')[2] tcip = TestCaseInPlan(self.env, tc_id, self.values['id']) if not tcip.exists: tc = TestCase(self.env, tc_id) tcip['page_name'] = tc['page_name'] if self.values['freeze_tc_versions']: # Set the wiki page version to the current latest version tcip['page_version'] = tc.wikipage.version tcip.set_status(default_status, author) tcip.insert() elif self.values['freeze_tc_versions']: # Create a TestCaseInPlan for each test case in the catalog, and # set the wiki page version to the current latest version self.env.log.debug(" - 1 -") tcat = TestCatalog(self.env, self.values['catid'], self.values['page_name']) from testmanager.api import TestManagerSystem default_status = TestManagerSystem( self.env).get_default_tc_status() author = self.values['author'] for tc in tcat.list_testcases(deep=True): self.env.log.debug(" - 2 -") tcip = TestCaseInPlan(self.env, tc.values['id'], self.values['id']) if not tcip.exists: tcip['page_name'] = tc['page_name'] tcip['page_version'] = tc.wikipage.version tcip.set_status(default_status, author) self.env.log.debug(" - 3 - %s %s", tcip['id'], tcip['page_name']) tcip.insert() self.env.log.debug("<<< post_insert")
def list_testcases(self, plan_id=None, deep=False, db=None): """ Returns a list of the test cases in this catalog. If plan_id is provided, returns a list of TestCaseInPlan objects, otherwise, of TestCase objects. :deep: if True indicates to return all TCs in the catalog and recursively in all the contained sub-catalogs. """ self.env.log.debug('>>> list_testcases') if plan_id is not None: from testmanager.api import TestManagerSystem default_status = TestManagerSystem( self.env).get_default_tc_status() tc_search = TestCase(self.env) tc_search['page_name'] = self.values['page_name'] + ('_TC%', '%_TC%')[deep] for tc in tc_search.list_matching_objects(exact_match=False, db=db): self.env.log.debug(' ---> Found testcase %s' % tc['id']) if plan_id is None: yield tc else: tcip = TestCaseInPlan(self.env, tc['id'], plan_id) if not tcip.exists: tcip['status'] = default_status yield tcip self.env.log.debug('<<< list_testcases')
def process_request(self, req): testmanagersystem = TestManagerSystem(self.env) tc_statuses = testmanagersystem.get_tc_statuses_by_color() if 'testmanager' in self.config: self.default_days_back = self.config.getint( 'testmanager', 'default_days_back', TESTMANAGER_DEFAULT_DAYS_BACK) self.default_interval = self.config.getint( 'testmanager', 'default_interval', TESTMANAGER_DEFAULT_INTERVAL) req_content = req.args.get('content') testplan = None catpath = None testplan_contains_all = True self.env.log.debug("Test Stats - process_request: %s" % req_content) grab_testplan = req.args.get('testplan') if grab_testplan and not grab_testplan == "__all": testplan = grab_testplan.partition('|')[0] catpath = grab_testplan.partition('|')[2] tp = TestPlan(self.env, testplan, catpath) testplan_contains_all = tp['contains_all'] today = datetime.today() today = today.replace(tzinfo=req.tz) + timedelta(2) # Stats start from two years back beginning = today - timedelta(720) if (not req_content == None) and (req_content == "piechartdata"): num_successful = 0 for tc_outcome in tc_statuses['green']: num_successful += self._get_num_tcs_by_status( beginning, today, tc_outcome, testplan, req) num_failed = 0 for tc_outcome in tc_statuses['red']: num_failed += self._get_num_tcs_by_status( beginning, today, tc_outcome, testplan, req) num_to_be_tested = 0 if testplan_contains_all: num_to_be_tested = self._get_num_testcases( beginning, today, catpath, req) - num_successful - num_failed else: for tc_outcome in tc_statuses['yellow']: num_to_be_tested += self._get_num_tcs_by_status( beginning, today, tc_outcome, testplan, req) jsdstr = """ [ {"response": "%s", "count": %s}, {"response": "%s", "count": %s}, {"response": "%s", "count": %s} ] """ % (_("Successful"), num_successful, _("Failed"), num_failed, _("To be tested"), num_to_be_tested) jsdstr = jsdstr.strip() if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return if not None in [ req.args.get('end_date'), req.args.get('start_date'), req.args.get('resolution') ]: # form submit grab_at_date = req.args.get('end_date') grab_from_date = req.args.get('start_date') grab_resolution = req.args.get('resolution') # validate inputs if None in [grab_at_date, grab_from_date]: raise TracError('Please specify a valid range.') if None in [grab_resolution]: raise TracError('Please specify the graph interval.') if 0 in [ len(grab_at_date), len(grab_from_date), len(grab_resolution) ]: raise TracError( 'Please ensure that all fields have been filled in.') if not grab_resolution.isdigit(): raise TracError( 'The graph interval field must be an integer, days.') at_date = parse_date(grab_at_date, req.tz) + timedelta(2) from_date = parse_date(grab_from_date, req.tz) graph_res = int(grab_resolution) else: # default data todays_date = datetime.today() at_date = todays_date #+ timedelta(1) # datetime.combine(todays_date,time(23,59,59,0,req.tz)) at_date = at_date.replace(tzinfo=req.tz) + timedelta(2) from_date = at_date - timedelta(self.default_days_back) graph_res = self.default_interval count = [] # Calculate 0th point last_date = from_date - timedelta(graph_res) # Calculate remaining points for cur_date in daterange(from_date, at_date, graph_res): datestr = format_date(cur_date) if graph_res != 1: datestr = "%s thru %s" % (format_date(last_date), datestr) if (not req_content == None) and (req_content == "ticketchartdata"): num_total = self._get_num_tickets_total( beginning, cur_date, testplan, req) num_closed = self._get_num_tickets_by_status( beginning, cur_date, 'closed', testplan, req) num_active = num_total - num_closed count.append({ 'from_date': format_date(last_date), 'to_date': datestr, 'date': datestr, 'active_tickets': num_active, 'closed_tickets': num_closed, 'tot_tickets': num_total }) else: # Handling custom test case outcomes here num_new = self._get_num_testcases(last_date, cur_date, catpath, req) num_successful = 0 for tc_outcome in tc_statuses['green']: num_successful += self._get_num_tcs_by_status( last_date, cur_date, tc_outcome, testplan, req) num_failed = 0 for tc_outcome in tc_statuses['red']: num_failed += self._get_num_tcs_by_status( last_date, cur_date, tc_outcome, testplan, req) num_all_successful = 0 for tc_outcome in tc_statuses['green']: num_all_successful += self._get_num_tcs_by_status( from_date, cur_date, tc_outcome, testplan, req) num_all_failed = 0 for tc_outcome in tc_statuses['red']: num_all_failed += self._get_num_tcs_by_status( from_date, cur_date, tc_outcome, testplan, req) num_all = 0 num_all_untested = 0 if testplan_contains_all: num_all = self._get_num_testcases(None, cur_date, catpath, req) num_all_untested = num_all - num_all_successful - num_all_failed else: for tc_outcome in tc_statuses['yellow']: num_all_untested += self._get_num_tcs_by_status( from_date, cur_date, tc_outcome, testplan, req) num_all = num_all_untested + num_all_successful + num_all_failed count.append({ 'from_date': format_date(last_date), 'to_date': datestr, 'date': datestr, 'new_tcs': num_new, 'successful': num_successful, 'failed': num_failed, 'all_tcs': num_all, 'all_successful': num_all_successful, 'all_untested': num_all_untested, 'all_failed': num_all_failed }) last_date = cur_date # if chartdata is requested, raw text is returned rather than data object # for templating if (not req_content == None) and (req_content == "chartdata"): jsdstr = '{"chartdata": [\n' for x in count: jsdstr += '{"date": "%s",' % x['date'] jsdstr += ' "new_tcs": %s,' % x['new_tcs'] jsdstr += ' "successful": %s,' % x['successful'] jsdstr += ' "failed": %s,' % x['failed'] jsdstr += ' "all_tcs": %s,' % x['all_tcs'] jsdstr += ' "all_successful": %s,' % x['all_successful'] jsdstr += ' "all_untested": %s,' % x['all_untested'] jsdstr += ' "all_failed": %s},\n' % x['all_failed'] jsdstr = jsdstr[:-2] + '\n]}' if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return elif (not req_content == None) and (req_content == "downloadcsv"): csvstr = "Date from;Date to;New Test Cases;Successful;Failed;Total Test Cases;Total Successful;Total Untested;Total Failed\r\n" for x in count: csvstr += '%s;' % x['from_date'] csvstr += '%s;' % x['to_date'] csvstr += '%s;' % x['new_tcs'] csvstr += '%s;' % x['successful'] csvstr += '%s;' % x['failed'] csvstr += '%s;' % x['all_tcs'] csvstr += '%s;' % x['all_successful'] csvstr += '%s;' % x['all_untested'] csvstr += '%s\r\n' % x['all_failed'] if isinstance(csvstr, unicode): csvstr = csvstr.encode('utf-8') req.send_header("Content-Length", len(csvstr)) req.send_header("Content-Disposition", "attachment;filename=Test_stats.csv") req.write(csvstr) return elif (not req_content == None) and (req_content == "ticketchartdata"): jsdstr = '{"ticketchartdata": [\n' for x in count: jsdstr += '{"date": "%s",' % x['date'] jsdstr += ' "tot_tickets": %s,' % x['tot_tickets'] jsdstr += ' "active_tickets": %s,' % x['active_tickets'] jsdstr += ' "closed_tickets": %s},\n' % x['closed_tickets'] jsdstr = jsdstr[:-2] + '\n]}' if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return else: # Normal rendering of first chart db = self.env.get_db_cnx() showall = req.args.get('show') == 'all' testplan_list = [] for planid, catid, catpath, name, author, ts_str in testmanagersystem.list_all_testplans( ): testplan_list.append({ 'planid': planid, 'catpath': catpath, 'name': name }) data = {} data['testcase_data'] = count data['start_date'] = format_date(from_date) data['end_date'] = format_date(at_date) data['resolution'] = str(graph_res) data['baseurl'] = req.base_url data['testplans'] = testplan_list data['ctestplan'] = testplan return 'testmanagerstats.html', data, None
def process_request(self, req): testmanagersystem = TestManagerSystem(self.env) tc_statuses = testmanagersystem.get_tc_statuses_by_color() if 'testmanager' in self.config: self.default_days_back = self.config.getint('testmanager', 'default_days_back', TESTMANAGER_DEFAULT_DAYS_BACK) self.default_interval = self.config.getint('testmanager', 'default_interval', TESTMANAGER_DEFAULT_INTERVAL) req_content = req.args.get('content') testplan = None catpath = None testplan_contains_all = True self.env.log.debug("Test Stats - process_request: %s" % req_content) grab_testplan = req.args.get('testplan') if grab_testplan and not grab_testplan == "__all": testplan = grab_testplan.partition('|')[0] catpath = grab_testplan.partition('|')[2] tp = TestPlan(self.env, testplan, catpath) testplan_contains_all = tp['contains_all'] today = datetime.today() today = today.replace(tzinfo = req.tz)+timedelta(2) # Stats start from two years back beginning = today - timedelta(720) if (not req_content == None) and (req_content == "piechartdata"): num_successful = 0 for tc_outcome in tc_statuses['green']: num_successful += self._get_num_tcs_by_status(beginning, today, tc_outcome, testplan, req) num_failed = 0 for tc_outcome in tc_statuses['red']: num_failed += self._get_num_tcs_by_status(beginning, today, tc_outcome, testplan, req) num_to_be_tested = 0 if testplan_contains_all: num_to_be_tested = self._get_num_testcases(beginning, today, catpath, req) - num_successful - num_failed else: for tc_outcome in tc_statuses['yellow']: num_to_be_tested += self._get_num_tcs_by_status(beginning, today, tc_outcome, testplan, req) jsdstr = """ [ {"response": "%s", "count": %s}, {"response": "%s", "count": %s}, {"response": "%s", "count": %s} ] """ % (_("Successful"), num_successful, _("Failed"), num_failed, _("To be tested"), num_to_be_tested) jsdstr = jsdstr.strip() if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return if not None in [req.args.get('end_date'), req.args.get('start_date'), req.args.get('resolution')]: # form submit grab_at_date = req.args.get('end_date') grab_from_date = req.args.get('start_date') grab_resolution = req.args.get('resolution') # validate inputs if None in [grab_at_date, grab_from_date]: raise TracError('Please specify a valid range.') if None in [grab_resolution]: raise TracError('Please specify the graph interval.') if 0 in [len(grab_at_date), len(grab_from_date), len(grab_resolution)]: raise TracError('Please ensure that all fields have been filled in.') if not grab_resolution.isdigit(): raise TracError('The graph interval field must be an integer, days.') at_date = parse_date(grab_at_date, req.tz)+timedelta(2) from_date = parse_date(grab_from_date, req.tz) graph_res = int(grab_resolution) else: # default data todays_date = datetime.today() at_date = todays_date #+ timedelta(1) # datetime.combine(todays_date,time(23,59,59,0,req.tz)) at_date = at_date.replace(tzinfo = req.tz)+timedelta(2) from_date = at_date - timedelta(self.default_days_back) graph_res = self.default_interval count = [] # Calculate 0th point last_date = from_date - timedelta(graph_res) # Calculate remaining points for cur_date in daterange(from_date, at_date, graph_res): datestr = format_date(cur_date) if graph_res != 1: datestr = "%s thru %s" % (format_date(last_date), datestr) if (not req_content == None) and (req_content == "ticketchartdata"): num_total = self._get_num_tickets_total(beginning, cur_date, testplan, req) num_closed = self._get_num_tickets_by_status(beginning, cur_date, 'closed', testplan, req) num_active = num_total - num_closed count.append( {'from_date': format_date(last_date), 'to_date': datestr, 'date' : datestr, 'active_tickets' : num_active, 'closed_tickets': num_closed, 'tot_tickets' : num_total} ) else: # Handling custom test case outcomes here num_new = self._get_num_testcases(last_date, cur_date, catpath, req) num_successful = 0 for tc_outcome in tc_statuses['green']: num_successful += self._get_num_tcs_by_status(last_date, cur_date, tc_outcome, testplan, req) num_failed = 0 for tc_outcome in tc_statuses['red']: num_failed += self._get_num_tcs_by_status(last_date, cur_date, tc_outcome, testplan, req) num_all_successful = 0 for tc_outcome in tc_statuses['green']: num_all_successful += self._get_num_tcs_by_status(from_date, cur_date, tc_outcome, testplan, req) num_all_failed = 0 for tc_outcome in tc_statuses['red']: num_all_failed += self._get_num_tcs_by_status(from_date, cur_date, tc_outcome, testplan, req) num_all = 0 num_all_untested = 0 if testplan_contains_all: num_all = self._get_num_testcases(None, cur_date, catpath, req) num_all_untested = num_all - num_all_successful - num_all_failed else: for tc_outcome in tc_statuses['yellow']: num_all_untested += self._get_num_tcs_by_status(from_date, cur_date, tc_outcome, testplan, req) num_all = num_all_untested + num_all_successful + num_all_failed count.append( {'from_date': format_date(last_date), 'to_date': datestr, 'date' : datestr, 'new_tcs' : num_new, 'successful': num_successful, 'failed': num_failed, 'all_tcs' : num_all, 'all_successful': num_all_successful, 'all_untested': num_all_untested, 'all_failed': num_all_failed }) last_date = cur_date # if chartdata is requested, raw text is returned rather than data object # for templating if (not req_content == None) and (req_content == "chartdata"): jsdstr = '{"chartdata": [\n' for x in count: jsdstr += '{"date": "%s",' % x['date'] jsdstr += ' "new_tcs": %s,' % x['new_tcs'] jsdstr += ' "successful": %s,' % x['successful'] jsdstr += ' "failed": %s,' % x['failed'] jsdstr += ' "all_tcs": %s,' % x['all_tcs'] jsdstr += ' "all_successful": %s,' % x['all_successful'] jsdstr += ' "all_untested": %s,' % x['all_untested'] jsdstr += ' "all_failed": %s},\n' % x['all_failed'] jsdstr = jsdstr[:-2] +'\n]}' if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return elif (not req_content == None) and (req_content == "downloadcsv"): csvstr = "Date from;Date to;New Test Cases;Successful;Failed;Total Test Cases;Total Successful;Total Untested;Total Failed\r\n" for x in count: csvstr += '%s;' % x['from_date'] csvstr += '%s;' % x['to_date'] csvstr += '%s;' % x['new_tcs'] csvstr += '%s;' % x['successful'] csvstr += '%s;' % x['failed'] csvstr += '%s;' % x['all_tcs'] csvstr += '%s;' % x['all_successful'] csvstr += '%s;' % x['all_untested'] csvstr += '%s\r\n' % x['all_failed'] if isinstance(csvstr, unicode): csvstr = csvstr.encode('utf-8') req.send_header("Content-Length", len(csvstr)) req.send_header("Content-Disposition", "attachment;filename=Test_stats.csv") req.write(csvstr) return elif (not req_content == None) and (req_content == "ticketchartdata"): jsdstr = '{"ticketchartdata": [\n' for x in count: jsdstr += '{"date": "%s",' % x['date'] jsdstr += ' "tot_tickets": %s,' % x['tot_tickets'] jsdstr += ' "active_tickets": %s,' % x['active_tickets'] jsdstr += ' "closed_tickets": %s},\n' % x['closed_tickets'] jsdstr = jsdstr[:-2] +'\n]}' if isinstance(jsdstr, unicode): jsdstr = jsdstr.encode('utf-8') req.send_header("Content-Length", len(jsdstr)) req.write(jsdstr) return else: # Normal rendering of first chart db = self.env.get_db_cnx() showall = req.args.get('show') == 'all' testplan_list = [] for planid, catid, catpath, name, author, ts_str in testmanagersystem.list_all_testplans(): testplan_list.append({'planid': planid, 'catpath': catpath, 'name': name}) data = {} data['testcase_data'] = count data['start_date'] = format_date(from_date) data['end_date'] = format_date(at_date) data['resolution'] = str(graph_res) data['baseurl'] = req.base_url data['testplans'] = testplan_list data['ctestplan'] = testplan return 'testmanagerstats.html', data, None
def __init__(self): self.testmanagersys = TestManagerSystem(self.env)
class TestManagerRPC(Component): implements(IXMLRPCHandler) def __init__(self): self.testmanagersys = TestManagerSystem(self.env) def xmlrpc_namespace(self): return "testmanager" def xmlrpc_methods(self): yield ("TEST_MODIFY", ((str, str, str, str),), self.createTestCatalog) yield ("TEST_MODIFY", ((str, str, str, str),), self.createTestCase) yield ("TEST_PLAN_ADMIN", ((str, str, str),), self.createTestPlan) yield (None, ((bool, str, str),), self.deleteTestObject) yield (None, ((bool, str, str), (bool, str, str, dict)), self.modifyTestObject) yield (None, ((bool, str, str, str),), self.setTestCaseStatus) yield ("TEST_VIEW", ((list, str), (list, str, str)), self.listTestCases) yield ("TEST_VIEW", ((list, str),), self.getTestCatalog) yield ("TEST_VIEW", ((list, str), (list, str, str)), self.getTestCase) yield ("TEST_VIEW", ((list, str, str),), self.getTestPlan) yield ("TEST_VIEW", ((list, str),), self.listSubCatalogs) yield ("TEST_VIEW", ((list, str),), self.listTestPlans) def createTestCatalog(self, req, parent_catalog_id, title, description): """ Creates a new test catalog, in the parent catalog specified, with the specified title and description. To create a root catalog, specify '' as the parent catalog. Returns the generated object ID, or '-1' if an error occurs. """ result = "-1" try: id = self.testmanagersys.get_next_id("catalog") pagename = None if parent_catalog_id is not None and parent_catalog_id != "": # Check parent catalog really exists, and get its page_name tcat = TestCatalog(self.env, parent_catalog_id) if not tcat.exists: self.env.log.error("Input parent test catalog with ID %s not found." % parent_catalog_id) return result pagename = tcat["page_name"] + "_TT" + id else: pagename = "TC_TT" + id author = get_reporter_id(req, "author") new_tc = TestCatalog(self.env, id, pagename, title, description) new_tc.author = author new_tc.remote_addr = req.remote_addr # This also creates the Wiki page new_tc.insert() result = id except: self.env.log.error( "Error adding test catalog with title '%s' in catalog with ID %s!" % (title, parent_catalog_id) ) self.env.log.error(formatExceptionInfo()) return id def createTestCase(self, req, catalog_id, title, description): """ Creates a new test case, in the catalog specified, with the specified title and description. Returns the generated object ID, or '-1' if an error occurs. """ result = "-1" try: if catalog_id is None or catalog_id == "": self.env.log.error("Cannot create a test plan on the root catalog container.") return result # Check catalog really exists, and get its page_name tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) return result author = get_reporter_id(req, "author") id = self.testmanagersys.get_next_id("testcase") pagename = tcat["page_name"] + "_TC" + id new_tc = TestCase(self.env, id, pagename, title, description) new_tc.author = author new_tc.remote_addr = req.remote_addr # This also creates the Wiki page new_tc.insert() result = id except: self.env.log.error( "Error adding test case with title '%s' in catalog with ID %s!" % (title, catalog_id) ) self.env.log.error(formatExceptionInfo()) return id def createTestPlan(self, req, catalog_id, name): """ Creates a new test plan, on the catalog specified, with the specified name. Returns the generated object ID, or '-1' if an error occurs. """ result = "-1" try: # Check catalog really exists, and get its page_name tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) return result author = get_reporter_id(req, "author") id = self.testmanagersys.get_next_id("testplan") pagename = tcat["page_name"] new_tp = TestPlan(self.env, id, catalog_id, pagename, name, author) new_tp.insert() result = id except: self.env.log.error("Error adding test plan with name '%s' for catalog with ID %s!" % (name, catalog_id)) self.env.log.error(formatExceptionInfo()) return result def deleteTestObject(self, req, objtype, id): """ Deletes the test object of the specified type identified by the given id. Returns True if successful, False otherwise. """ try: # Check the object exists obj = None if objtype == "testcatalog": req.perm.require("TEST_MODIFY") obj = TestCatalog(self.env, id) elif objtype == "testcase": req.perm.require("TEST_MODIFY") obj = TestCase(self.env, id) elif objtype == "testplan": req.perm.require("TEST_PLAN_ADMIN") obj = TestPlan(self.env, id) if not obj.exists: self.env.log.error("Input test object of type %s with ID %s not found." % (objtype, id)) return False obj.delete() except: self.env.log.error("Error deleting test object of type %s with ID %s." % (objtype, id)) self.env.log.error(formatExceptionInfo()) return False return True def modifyTestObject(self, req, objtype, id, attributes={}): """ Modifies the test object of the specified type identified by the given id. Returns True if successful, False otherwise. """ try: # Check the object exists obj = None if objtype == "testcatalog": req.perm.require("TEST_MODIFY") obj = TestCatalog(self.env, id) elif objtype == "testcase": req.perm.require("TEST_MODIFY") obj = TestCase(self.env, id) elif objtype == "testplan": req.perm.require("TEST_PLAN_ADMIN") obj = TestPlan(self.env, id) if not obj.exists: self.env.log.error("Input test object of type %s with ID %s not found." % (objtype, id)) return False author = get_reporter_id(req, "author") for k, v in attributes.iteritems(): if k == "title": obj.title = v elif k == "description": obj.description = v else: obj[k] = v obj.author = author obj.remote_addr = req.remote_addr obj.save_changes(author, "Changed through RPC.") except: self.env.log.error("Error modifying test object of type %s with ID %s." % (objtype, id)) self.env.log.error(formatExceptionInfo()) return False return True def setTestCaseStatus(self, req, testcase_id, plan_id, status): """ Sets the test case status. Returns True if successful, False otherwise. """ try: author = get_reporter_id(req, "author") tcip = TestCaseInPlan(self.env, testcase_id, plan_id) if tcip.exists: tcip.set_status(status, author) tcip.save_changes(author, "Status changed") else: tc = TestCase(self.env, testcase_id) tcip["page_name"] = tc["page_name"] tcip.set_status(status, author) tcip.insert() except: self.env.log.error( "Error setting the test case status with ID %s on plan %s to %s!" % (testcase_id, plan_id, status) ) self.env.log.error(formatExceptionInfo()) return False return True def getTestCatalog(self, req, catalog_id): """ Returns the catalog properties. The result is in the form, all strings: (wiki_page_name, title, description) """ try: # Check catalog really exists tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) else: return (tcat["page_name"], tcat.title, tcat.description) except: self.env.log.error("Error getting the test catalog with ID %s!" % catalog_id) self.env.log.error(formatExceptionInfo()) def getTestCase(self, req, testcase_id, plan_id=""): """ Returns the test case properties. If plan_id is provided, also the status of the test case in the plan will be returned. Each result is in the form, all strings: If plan_id is NOT provided: (wiki_page_name, title, description) If plan_id is provided: (wiki_page_name, title, description, status) """ try: # Check test case really exists tc = TestCase(self.env, testcase_id) if not tc.exists: self.env.log.error("Input test case with ID %s not found." % testcase_id) else: if plan_id is None or plan_id == "": return (tc["page_name"], tc.title, tc.description) else: tcip = TestCaseInPlan(self.env, testcase_id, plan_id) return (tc["page_name"], tc.title, tc.description, tcip["status"]) except: self.env.log.error("Error getting the test case with ID %s!" % testcase_id) self.env.log.error(formatExceptionInfo()) def getTestPlan(self, req, plan_id, catalog_id): """ Returns the test plan properties. The result is in the form, all strings: (wiki_page_name, name) """ try: # Check test plan really exists tp = TestPlan(self.env, plan_id, catalog_id) if not tp.exists: self.env.log.error("Input test plan with ID %s on catalog %s not found." % (plan_id, catalog_id)) else: return (tp["page_name"], tp["name"]) except: self.env.log.error("Error getting the test plan with ID %s on catalog %s." % (plan_id, catalog_id)) self.env.log.error(formatExceptionInfo()) def listSubCatalogs(self, req, catalog_id): """ Returns a iterator over the direct sub-catalogs of the specified catalog. Each result is in the form, all strings: (test_catalog_id, wiki_page_name, title, description) """ try: # Check catalog really exists tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) else: for tc in tcat.list_subcatalogs(): yield (tc["id"], tc["page_name"], tc.title, tc.description) except: self.env.log.error("Error listing the test catalogs!") self.env.log.error(formatExceptionInfo()) def listTestPlans(self, req, catalog_id): """ Returns a iterator over the test plans associated to the specified catalog. Each result is in the form, all strings: (testplan_id, name) """ try: # Check catalog really exists tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) else: for tp in tcat.list_testplans(): yield (tp["id"], tp["name"]) except: self.env.log.error("Error listing the test plans!") self.env.log.error(formatExceptionInfo()) def listTestCases(self, req, catalog_id, plan_id=""): """ Returns a iterator over the test cases directly in the specified catalog (no sub-catalogs). If plan_id is provided, also the status of the test case in the plan will be returned. Each result is in the form, all strings: If plan_id is NOT provided: (testcase_id, wiki_page_name, title, description) If plan_id is provided: (testcase_id, wiki_page_name, status) """ try: # Check catalog really exists tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) else: if plan_id is None or plan_id == "": for tc in tcat.list_testcases(): # Returned object is a TestCase yield (tc["id"], tc["page_name"], tc.title, tc.description) else: for tcip in tcat.list_testcases(plan_id): # Returned object is a TestCaseInPlan yield (tcip["id"], tcip["page_name"], tcip["status"]) except: self.env.log.error("Error listing the test cases in the catalog with ID %s!" % catalog_id) self.env.log.error(formatExceptionInfo())
class TestManagerRPC(Component): implements(IXMLRPCHandler) def __init__(self): self.testmanagersys = TestManagerSystem(self.env) def xmlrpc_namespace(self): return 'testmanager' def xmlrpc_methods(self): yield ('TEST_MODIFY', ((str, str, str, str),), self.createTestCatalog) yield ('TEST_MODIFY', ((str, str, str, str),), self.createTestCase) yield ('TEST_PLAN_ADMIN', ((str, str, str),), self.createTestPlan) yield (None, ((bool, str, str),), self.deleteTestObject) yield (None, ((bool, str, str),(bool, str, str, dict)), self.modifyTestObject) yield (None, ((bool, str, str, str),), self.setTestCaseStatus) yield ('TEST_VIEW', ((list, str),(list, str, str)), self.listTestCases) yield ('TEST_VIEW', ((list, str),), self.getTestCatalog) yield ('TEST_VIEW', ((list, str),(list, str, str)), self.getTestCase) yield ('TEST_VIEW', ((list, str, str),), self.getTestPlan) yield ('TEST_VIEW', ((list, str),), self.listSubCatalogs) yield ('TEST_VIEW', ((list, str),), self.listTestPlans) def createTestCatalog(self, req, parent_catalog_id, title, description): """ Creates a new test catalog, in the parent catalog specified, with the specified title and description. To create a root catalog, specify '' as the parent catalog. Returns the generated object ID, or '-1' if an error occurs. """ result = '-1' try: id = self.testmanagersys.get_next_id('catalog') pagename = None if parent_catalog_id is not None and parent_catalog_id != '': # Check parent catalog really exists, and get its page_name tcat = TestCatalog(self.env, parent_catalog_id) if not tcat.exists: self.env.log.error("Input parent test catalog with ID %s not found." % parent_catalog_id) return result pagename = tcat['page_name'] + '_TT' + id else: pagename = 'TC_TT' + id author = get_reporter_id(req, 'author') new_tc = TestCatalog(self.env, id, pagename, title, description) new_tc.author = author new_tc.remote_addr = req.remote_addr # This also creates the Wiki page new_tc.insert() result = id except: self.env.log.error("Error adding test catalog with title '%s' in catalog with ID %s!" % (title, parent_catalog_id)) self.env.log.error(formatExceptionInfo()) return id def createTestCase(self, req, catalog_id, title, description): """ Creates a new test case, in the catalog specified, with the specified title and description. Returns the generated object ID, or '-1' if an error occurs. """ result = '-1' try: if catalog_id is None or catalog_id == '': self.env.log.error("Cannot create a test plan on the root catalog container.") return result # Check catalog really exists, and get its page_name tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) return result author = get_reporter_id(req, 'author') id = self.testmanagersys.get_next_id('testcase') pagename = tcat['page_name'] + '_TC' + id new_tc = TestCase(self.env, id, pagename, title, description) new_tc.author = author new_tc.remote_addr = req.remote_addr # This also creates the Wiki page new_tc.insert() result = id except: self.env.log.error("Error adding test case with title '%s' in catalog with ID %s!" % (title, catalog_id)) self.env.log.error(formatExceptionInfo()) return id def createTestPlan(self, req, catalog_id, name): """ Creates a new test plan, on the catalog specified, with the specified name. Returns the generated object ID, or '-1' if an error occurs. """ result = '-1' try: # Check catalog really exists, and get its page_name tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) return result author = get_reporter_id(req, 'author') id = self.testmanagersys.get_next_id('testplan') pagename = tcat['page_name'] new_tp = TestPlan(self.env, id, catalog_id, pagename, name, author) new_tp.insert() result = id except: self.env.log.error("Error adding test plan with name '%s' for catalog with ID %s!" % (name, catalog_id)) self.env.log.error(formatExceptionInfo()) return result def deleteTestObject(self, req, objtype, id): """ Deletes the test object of the specified type identified by the given id. Returns True if successful, False otherwise. """ try: # Check the object exists obj = None if objtype == 'testcatalog': req.perm.require('TEST_MODIFY') obj = TestCatalog(self.env, id) elif objtype == 'testcase': req.perm.require('TEST_MODIFY') obj = TestCase(self.env, id) elif objtype == 'testplan': req.perm.require('TEST_PLAN_ADMIN') obj = TestPlan(self.env, id) if not obj.exists: self.env.log.error("Input test object of type %s with ID %s not found." % (objtype, id)) return False obj.delete() except: self.env.log.error("Error deleting test object of type %s with ID %s." % (objtype, id)) self.env.log.error(formatExceptionInfo()) return False return True def modifyTestObject(self, req, objtype, id, attributes={}): """ Modifies the test object of the specified type identified by the given id. Returns True if successful, False otherwise. """ try: # Check the object exists obj = None if objtype == 'testcatalog': req.perm.require('TEST_MODIFY') obj = TestCatalog(self.env, id) elif objtype == 'testcase': req.perm.require('TEST_MODIFY') obj = TestCase(self.env, id) elif objtype == 'testplan': req.perm.require('TEST_PLAN_ADMIN') obj = TestPlan(self.env, id) if not obj.exists: self.env.log.error("Input test object of type %s with ID %s not found." % (objtype, id)) return False author = get_reporter_id(req, 'author') for k, v in attributes.iteritems(): if k == 'title': obj.title = v elif k == 'description': obj.description = v else: obj[k] = v obj.author = author obj.remote_addr = req.remote_addr obj.save_changes(author, "Changed through RPC.") except: self.env.log.error("Error modifying test object of type %s with ID %s." % (objtype, id)) self.env.log.error(formatExceptionInfo()) return False return True def setTestCaseStatus(self, req, testcase_id, plan_id, status): """ Sets the test case status. Returns True if successful, False otherwise. """ try: author = get_reporter_id(req, 'author') tcip = TestCaseInPlan(self.env, testcase_id, plan_id) if tcip.exists: tcip.set_status(status, author) tcip.save_changes(author, "Status changed") else: tc = TestCase(self.env, testcase_id) tcip['page_name'] = tc['page_name'] tcip.set_status(status, author) tcip.insert() except: self.env.log.error("Error setting the test case status with ID %s on plan %s to %s!" % (testcase_id, plan_id, status)) self.env.log.error(formatExceptionInfo()) return False return True def getTestCatalog(self, req, catalog_id): """ Returns the catalog properties. The result is in the form, all strings: (wiki_page_name, title, description) """ try: # Check catalog really exists tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) else: return (tcat['page_name'], tcat.title, tcat.description) except: self.env.log.error("Error getting the test catalog with ID %s!" % catalog_id) self.env.log.error(formatExceptionInfo()) def getTestCase(self, req, testcase_id, plan_id=''): """ Returns the test case properties. If plan_id is provided, also the status of the test case in the plan will be returned. Each result is in the form, all strings: If plan_id is NOT provided: (wiki_page_name, title, description) If plan_id is provided: (wiki_page_name, title, description, status) """ try: # Check test case really exists tc = TestCase(self.env, testcase_id) if not tc.exists: self.env.log.error("Input test case with ID %s not found." % testcase_id) else: if plan_id is None or plan_id == '': return (tc['page_name'], tc.title, tc.description) else: tcip = TestCaseInPlan(self.env, testcase_id, plan_id) return (tc['page_name'], tc.title, tc.description, tcip['status']) except: self.env.log.error("Error getting the test case with ID %s!" % testcase_id) self.env.log.error(formatExceptionInfo()) def getTestPlan(self, req, plan_id, catalog_id): """ Returns the test plan properties. The result is in the form, all strings: (wiki_page_name, name) """ try: # Check test plan really exists tp = TestPlan(self.env, plan_id, catalog_id) if not tp.exists: self.env.log.error("Input test plan with ID %s on catalog %s not found." % (plan_id, catalog_id)) else: return (tp['page_name'], tp['name']) except: self.env.log.error("Error getting the test plan with ID %s on catalog %s." % (plan_id, catalog_id)) self.env.log.error(formatExceptionInfo()) def listSubCatalogs(self, req, catalog_id): """ Returns a iterator over the direct sub-catalogs of the specified catalog. Each result is in the form, all strings: (test_catalog_id, wiki_page_name, title, description) """ try: # Check catalog really exists tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) else: for tc in tcat.list_subcatalogs(): yield (tc['id'], tc['page_name'], tc.title, tc.description) except: self.env.log.error("Error listing the test catalogs!") self.env.log.error(formatExceptionInfo()) def listTestPlans(self, req, catalog_id): """ Returns a iterator over the test plans associated to the specified catalog. Each result is in the form, all strings: (testplan_id, name) """ try: # Check catalog really exists tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) else: for tp in tcat.list_testplans(): yield (tp['id'], tp['name']) except: self.env.log.error("Error listing the test plans!") self.env.log.error(formatExceptionInfo()) def listTestCases(self, req, catalog_id, plan_id=''): """ Returns a iterator over the test cases directly in the specified catalog (no sub-catalogs). If plan_id is provided, also the status of the test case in the plan will be returned. Each result is in the form, all strings: If plan_id is NOT provided: (testcase_id, wiki_page_name, title, description) If plan_id is provided: (testcase_id, wiki_page_name, status) """ try: # Check catalog really exists tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) else: if plan_id is None or plan_id == '': for tc in tcat.list_testcases(): # Returned object is a TestCase yield (tc['id'], tc['page_name'], tc.title, tc.description) else: for tcip in tcat.list_testcases(plan_id): # Returned object is a TestCaseInPlan yield (tcip['id'], tcip['page_name'], tcip['status']) except: self.env.log.error("Error listing the test cases in the catalog with ID %s!" % catalog_id) self.env.log.error(formatExceptionInfo())