def get_ticket_status(ticket, base=None, machine=None): """ Return the status of the ticket in the database. INPUT: - ``ticket`` -- dictionary - ``base`` -- keyword passed to ``current_reports`` - ``machine`` -- if given, only look at this machine's reports OUTPUT: a triple (number of reports, single status, composite status) Note that ``Spkg``, ``NoPatch`` and ``New`` are not got from any report. """ all = current_reports(ticket, base=base) if machine is not None: all = [r for r in all if r['machine'] == machine] if all: status_list = [report['status'] for report in all] if len(set(status_list)) == 1: composite = single = status_list[0] else: composite = ','.join(status_list) single = min_status(status_list) return len(all), single, composite elif ticket['spkgs']: return 0, 'Spkg', 'Spkg' elif not ticket.get('git_commit'): return 0, 'NoPatch', 'NoPatch' else: return 0, 'New', 'New'
def rate_ticket(ticket, **conf): rating = 0 if ticket['spkgs']: return # can't handle these yet elif not ticket['patches']: return # nothing to do for dep in ticket['depends_on']: if isinstance(dep, basestring) and '.' in dep: if compare_version(conf['base'], dep) < 0: # Depends on a newer version of Sage than we're running. return None for author in ticket['authors']: if author not in conf['trusted_authors']: return rating += conf['bonus'].get(author, 0) for participant in ticket['participants']: rating += conf['bonus'].get(participant, 0) # doubled for authors rating += len(ticket['participants']) # TODO: remove condition if 'component' in ticket: rating += conf['bonus'].get(ticket['component'], 0) rating += conf['bonus'].get(ticket['status'], 0) rating += conf['bonus'].get(ticket['priority'], 0) rating += conf['bonus'].get(str(ticket['id']), 0) redundancy = (100,) prune_pending(ticket) if not ticket.get('retry'): for reports in current_reports(ticket, base=conf['base']): redundancy = min(redundancy, compare_machines(reports['machine'], conf['machine'], conf['machine_match'])) if not redundancy[-1]: return # already did this one return redundancy, rating, -int(ticket['id'])
def filter_reports(all): for ticket in all: current = sorted(current_reports(ticket), key=lambda report: report['time']) ticket['reports'] = list(reversed(current))[:10] for report in ticket['reports']: report['plugins'] = '...' yield ticket
def render_ticket_status(ticket): try: info = trac.scrape(ticket, db=db) except: info = tickets.find_one({'id': ticket}) if 'reports' in info: base = latest_version(current_reports(info)) else: base = None status = get_ticket_status(info, base=base)[2] response = make_response(create_status_image(status, base=base)) response.headers['Content-type'] = 'image/png' response.headers['Cache-Control'] = 'no-cache' return response
def get_ticket_status(ticket, base=None, machine=None): all = current_reports(ticket, base=base) if machine is not None: all = [r for r in all if r['machine'] == machine] if len(all): status_list = [report['status'] for report in all] if len(set(status_list)) == 1: composite = single = status_list[0] else: composite = ','.join(status_list) single = min_status(status_list) return len(all), single, composite elif ticket['spkgs']: return 0, 'Spkg', 'Spkg' elif not ticket['patches']: return 0, 'NoPatch', 'NoPatch' else: return 0, 'New', 'New'
def main(args): global conf # Most configuration is done in the config file, which is reread between # each ticket for live configuration of the patchbot. parser = OptionParser() parser.add_option("--config", dest="config") parser.add_option("--sage-root", dest="sage_root", default=os.environ.get('SAGE_ROOT')) parser.add_option("--server", dest="server", default="http://patchbot.sagemath.org/") parser.add_option("--count", dest="count", default=1000000) parser.add_option("--ticket", dest="ticket", default=None) parser.add_option("--list", dest="list", default=False) parser.add_option("--skip-base", dest="skip_base", default=False) (options, args) = parser.parse_args(args) conf_path = options.config and os.path.abspath(options.config) if options.ticket: tickets = [int(t) for t in options.ticket.split(',')] count = len(tickets) else: tickets = None count = int(options.count) conf = get_conf(conf_path, options.server) if options.list: for score, ticket in get_ticket(base=get_base(options.sage_root), server=options.server, return_all=True, **conf): print score, ticket['id'], ticket['title'] print ticket print sys.exit(0) print "WARNING: Assuming sage-main is pristine." if options.sage_root == os.environ.get('SAGE_ROOT'): print "WARNING: Do not use this copy of sage while the patchbot is running." if not options.skip_base: clean = lookup_ticket(options.server, 0) def good(report): return report['machine'] == conf['machine'] and report['status'] == 'TestsPassed' if not any(good(report) for report in current_reports(clean, base=get_base(options.sage_root))): res = test_a_ticket(ticket=0, sage_root=options.sage_root, server=options.server) if res != 'TestsPassed': print "\n\n" while True: print "Failing tests in your install: %s. Continue anyways? [y/N] " % res ans = sys.stdin.readline().lower().strip() if ans == '' or ans[0] == 'n': sys.exit(1) elif ans[0] == 'y': break for _ in range(count): try: if tickets: ticket = tickets.pop(0) else: ticket = None conf = get_conf(conf_path, options.server) if check_time_of_day(conf['time_of_day']): test_a_ticket(ticket=ticket, sage_root=options.sage_root, server=options.server) else: print "Idle." time.sleep(conf['idle']) except urllib2.HTTPError: traceback.print_exc() time.sleep(conf['idle'])
def current_reports(self, ticket, newer=False): if isinstance(ticket, (int, str)): ticket = self.lookup_ticket(ticket) return current_reports(ticket, base=self.base, newer=newer)