Beispiel #1
0
def event_update(request, event_id):
    ev = get_object_or_404(models.Event, pk=event_id)
    ev_data = {'id': ev.pk,
        'complete': ev.complete,
        'last_modified': TimeUtils.display_time_str(ev.last_modified),
        'created': TimeUtils.display_time_str(ev.created),
        'status': ev.status_slug(),
      }
    ev_data['events'] = EventsStatus.multiline_events_info([ev])
    return JsonResponse(ev_data)
Beispiel #2
0
def num_tests(request):
    context = {}

    start = (TimeUtils.get_local_time() - datetime.timedelta(days=180)).replace(hour=0, minute=0)
    bins = get_bins(start, datetime.timedelta(days=7))
    set_passed(start, "week", "Passed tests in last 6 months, by week", context, "month_chart", "%m/%d", bins)

    start = (TimeUtils.get_local_time() - datetime.timedelta(days=7)).replace(hour=0, minute=0)
    bins = get_bins(start, datetime.timedelta(days=1))
    set_passed(start, "day", "Passed tests in last week, by day", context, "week_chart", "%m/%d", bins)
    return render(request, 'ci/num_tests.html', context)
Beispiel #3
0
    def handle(self, *args, **options):
        dryrun = options["dryrun"]
        days = options["days"]
        hours = options["hours"]
        allowed_fail = options["allowed_fail"]
        client_runner_user = options["client_runner_user"]

        if days:
            d = TimeUtils.get_local_time() - timedelta(days=days)
        elif hours:
            d = TimeUtils.get_local_time() - timedelta(hours=hours)

        jobs = models.Job.objects.filter(active=True,
                                         ready=True,
                                         status=models.JobStatus.NOT_STARTED,
                                         created__lt=d)
        if client_runner_user:
            if ":" not in client_runner_user:
                raise CommandError("Invalid format for username: %s" %
                                   client_runner_user)
            host, username = client_runner_user.split(":")
            git_server = models.GitServer.objects.get(name=host)
            git_user = models.GitUser.objects.get(name=username,
                                                  server=git_server)
            jobs = jobs.filter(
                (Q(recipe__client_runner_user=None)
                 & Q(recipe__build_user__build_key=git_user.build_key))
                | Q(recipe__client_runner_user__build_key=git_user.build_key))

        count = jobs.count()
        prefix = ""
        if dryrun:
            prefix = "DRY RUN: "

        if allowed_fail:
            err_msg = "Set to allowed to fail due to civet client not running this job in too long a time"
            status = models.JobStatus.FAILED_OK
            msg = "Job allowed to fail"
        else:
            err_msg = "Canceled due to civet client not running this job in too long a time"
            status = models.JobStatus.CANCELED
            msg = "Job canceled"

        for job in jobs.all():
            self.stdout.write("%s%s: %s: %s: %s" %
                              (prefix, msg, job.pk, job, job.created))
            if not dryrun:
                views.set_job_canceled(job, err_msg, status)
                UpdateRemoteStatus.job_complete(job)
                job.event.set_complete_if_done()
        if count == 0:
            self.stdout.write("No jobs to cancel")
Beispiel #4
0
def pr_update(request, pr_id):
    pr = get_object_or_404(models.PullRequest, pk=pr_id)
    closed = 'Open'
    if pr.closed:
        closed = 'Closed'
    pr_data = {'id': pr.pk,
        'closed': closed,
        'last_modified': TimeUtils.display_time_str(pr.last_modified),
        'created': TimeUtils.display_time_str(pr.created),
        'status': pr.status_slug(),
      }
    pr_data['events'] = EventsStatus.multiline_events_info(pr.events.all(), events_url=True)
    return JsonResponse(pr_data)
Beispiel #5
0
def repo_update(request):
    """
    Get the updates for the repo page.
    """
    if 'last_request' not in request.GET or 'limit' not in request.GET or 'repo_id' not in request.GET:
        return HttpResponseBadRequest('Missing parameters')

    this_request = TimeUtils.get_local_timestamp()
    repo_id = int(request.GET['repo_id'])
    limit = int(request.GET['limit'])
    last_request = int(float(request.GET['last_request'])) # in case it has decimals
    dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request)))
    repo = get_object_or_404(models.Repository, pk=repo_id)
    repos_status = RepositoryStatus.filter_repos_status([repo.pk], last_modified=dt)
    event_q = EventsStatus.get_default_events_query()
    event_q = event_q.filter(base__branch__repository=repo)[:limit]
    events_info = EventsStatus.multiline_events_info(event_q, last_modified=dt)
    # we also need to check if a PR closed recently
    closed = []
    for pr in models.PullRequest.objects.filter(repository=repo, closed=True, last_modified__gte=dt).values('id').all():
        closed.append({'id': pr['id']})

    return JsonResponse({'repo_status': repos_status,
        'closed': closed,
        'last_request': this_request,
        'events': events_info,
        'limit': limit,
        })
Beispiel #6
0
    def test_set_passed(self):
        result = utils.create_step_result()
        result.save()
        context = {}
        start = (TimeUtils.get_local_time() -
                 datetime.timedelta(days=1)).replace(hour=0, minute=0)
        bins = Stats.get_bins(start, datetime.timedelta(days=1))
        p = Stats.set_passed(start, "day",
                             "Passed tests in last 6 months, by day", context,
                             "month_chart", "%m/%d", bins)
        # no models.JobTestStatistics records
        for j in p[1:]:
            self.assertEqual(j[1], 0)
        self.assertIn("month_chart", context)

        context = {}
        models.JobTestStatistics.objects.create(job=result.job,
                                                passed=20,
                                                skipped=30,
                                                failed=40)
        p = Stats.set_passed(start, "day",
                             "Passed tests in last 6 months, by day", context,
                             "month_chart", "%m/%d", bins)
        self.assertNotEqual(context, {})
        self.assertEqual(len(p), 3)
        self.assertEqual(p[2][1], 20)
        self.assertIn("month_chart", context)
Beispiel #7
0
def clients_info():
    """
    Gets the information on all the currently active clients.
    Retruns:
      list of dicts containing client information
    """
    sclients = sorted_clients(models.Client.objects.exclude(status=models.Client.DOWN))
    active_clients = [] # clients that we've seen in <= 60 s
    inactive_clients = [] # clients that we've seen in > 60 s
    for c in sclients:
        d = {'pk': c.pk,
            "ip": c.ip,
            "name": c.name,
            "message": c.status_message,
            "status": c.status_str(),
            "lastseen": TimeUtils.human_time_str(c.last_seen),
            }
        if c.unseen_seconds() > 2*7*24*60*60: # 2 weeks
            # do it like this so that last_seen doesn't get updated
            models.Client.objects.filter(pk=c.pk).update(status=models.Client.DOWN)
        elif c.unseen_seconds() > 120:
            d["status_class"] = "client_NotSeen"
            inactive_clients.append(d)
        else:
            d["status_class"] = "client_%s" % c.status_slug()
            active_clients.append(d)
    clients = [] # sort these so that active clients (seen in < 60 s) are first
    for d in active_clients:
        clients.append(d)
    for d in inactive_clients:
        clients.append(d)
    return clients
Beispiel #8
0
def is_team_member(session, api, team, user):
    """
    Checks to see if a user is a team member and caches the results
    """
    teams = session.get("teams", {})
    # Check to see if their permissions are still valid
    if teams and team in teams and TimeUtils.get_local_timestamp(
    ) < teams[team][1]:
        return teams[team][0]

    is_member = api.is_member(team, user)
    logger.info("User '%s' member status of '%s': %s" %
                (user, team, is_member))
    teams[team] = (is_member, TimeUtils.get_local_timestamp() +
                   settings.COLLABORATOR_CACHE_TIMEOUT)
    session["teams"] = teams
    return is_member
Beispiel #9
0
def get_bins(start_date, step):
    bins = [start_date]
    now = TimeUtils.get_local_time().replace(hour=23, minute=59)
    prev = start_date
    while True:
        new = prev + step
        if new < now:
            bins.append(new)
            prev = new
        else:
            break
    return bins
Beispiel #10
0
def num_prs_by_repo(request):
    context = {}
    repos_q = models.Repository.objects.filter(active=True).order_by("name").values("id", "name").all()
    repo_map = { v.get("id"): v.get("name") for v in repos_q }

    start = (TimeUtils.get_local_time() - datetime.timedelta(days=180)).replace(hour=0, minute=0)
    bins = get_bins(start, datetime.timedelta(days=7))
    set_all_repo_prs(repos_q, start, "week", "Number of new PRs in last 6 months, by week", context, "%m/%d", bins)

    start = (TimeUtils.get_local_time() - datetime.timedelta(days=7)).replace(hour=0, minute=0)
    bins = get_bins(start, datetime.timedelta(days=1))
    set_all_repo_prs(repos_q, start, "day", "Number of new PRs in last week, by day", context, "%m/%d", bins)

    sorted_repos_by_name = sorted(list(repo_map.keys()), key=lambda v: repo_map[v].lower())
    repo_data = []
    for key in sorted_repos_by_name:
        repo_graphs = context.get("repo_graphs", {}).get(key, [])
        if repo_graphs:
            repo_data.append({"id": key, "name": repo_map[key], "graphs": repo_graphs})

    context["repos"] = repo_data
    return render(request, 'ci/num_prs.html', context)
Beispiel #11
0
def is_allowed_to_see_clients(session):
    """
    Check to see if the signed in user can see client information.
    We do this by checking the "authorized_users"
    "authorized_users" can contain orgs and teams
    """
    val = session.get("allowed_to_see_clients")
    # Check to see if their permissions are still valid
    if val and TimeUtils.get_local_timestamp() < val[1]:
        return val[0]

    user = None

    for server in settings.INSTALLED_GITSERVERS:
        gitserver = models.GitServer.objects.get(host_type=server["type"],
                                                 name=server["hostname"])
        auth = gitserver.auth()
        user = auth.signed_in_user(gitserver, session)
        if not user:
            continue

        api = user.api()
        for authed_user in server.get("authorized_users", []):
            if user.name == authed_user or is_team_member(
                    session, api, authed_user, user):
                logger.info(
                    "'%s' is a member of '%s' and is allowed to see clients" %
                    (user, authed_user))
                session["allowed_to_see_clients"] = (
                    True, TimeUtils.get_local_timestamp() +
                    settings.COLLABORATOR_CACHE_TIMEOUT)
                return True
        logger.info("%s is NOT allowed to see clients on %s" %
                    (user, gitserver))
    session["allowed_to_see_clients"] = (False,
                                         TimeUtils.get_local_timestamp() +
                                         settings.COLLABORATOR_CACHE_TIMEOUT)
    return False
Beispiel #12
0
def is_collaborator(request_session, build_user, repo, user=None):
    """
    Checks to see if the signed in user is a collaborator on a repo.
    This will cache the value for a time specified by settings.COLLABORATOR_CACHE_TIMEOUT
    Input:
      request_session: A session from HttpRequest.session
      build_user: models.GitUser who has access to check collaborators
      repo: models.Repository to check against
      user: models.GitUser: User to check for. If None then the user will be pulled from the request_session
    Return:
      (bool, models.GitUser) tuple: bool is whether the user is a collaborator
        GitUser is the user from the request_session or None if not signed in
    """
    server = repo.server()
    if not user:
        user = server.signed_in_user(request_session)
    if not user:
        return False

    auth = server.auth()
    if auth._collaborators_key in request_session:
        collab_dict = request_session[auth._collaborators_key]
        val = collab_dict.get(str(repo))
        timestamp = TimeUtils.get_local_timestamp()
        # Check to see if their permissions are still valid
        if val and timestamp < val[1]:
            return val[0]

    api = build_user.api()

    collab_dict = request_session.get(auth._collaborators_key, {})
    val = api.is_collaborator(user, repo)
    collab_dict[str(repo)] = (val, TimeUtils.get_local_timestamp() +
                              settings.COLLABORATOR_CACHE_TIMEOUT)
    request_session[auth._collaborators_key] = collab_dict
    logger.info("Is collaborator for user '%s' on %s: %s" % (user, repo, val))
    return val
Beispiel #13
0
    def check_event_row(self, ev):
        event_tds = self.selenium.find_elements_by_xpath(
            "//tr[@id='event_%s']/td" % ev.pk)
        sorted_jobs = ev.get_sorted_jobs()
        if sorted_jobs:
            num_boxes = len(
                sorted_jobs
            ) - 1  # each group will have a continuation box, except the last
            for group in sorted_jobs:
                num_boxes += len(group)
            num_boxes += 1  # this is the event description
            self.assertEqual(len(event_tds), num_boxes)

        depends = self.selenium.find_elements_by_xpath(
            '//td[@class="depends"]')
        for dep in depends:
            dep_html = dep.get_attribute('innerHTML')
            self.assertEqual(
                dep_html,
                '<span class="glyphicon glyphicon-arrow-right"></span>')

        ev_tr = self.selenium.find_element_by_id("event_%s" % ev.pk)
        self.assertIn(TimeUtils.sortable_time_str(ev.created),
                      ev_tr.get_attribute("data-date"))
        ev_status = self.check_class("event_status_%s" % ev.pk,
                                     "job_status_%s" % ev.status_slug())
        ev_html = ev_status.get_attribute('innerHTML')
        self.assertIn(str(ev.base.branch.repository.name), ev_html)
        if ev.pull_request:
            self.assertIn(escape(str(ev.pull_request)), ev_html)
        else:
            self.assertIn(str(ev.cause_str), ev_html)

        for job in ev.jobs.all():
            job_elem = self.check_class("job_%s" % job.pk,
                                        "job_status_%s" % job.status_slug())
            html = job_elem.get_attribute("innerHTML")
            self.assertIn(job.recipe.display_name, html)

            if job.invalidated:
                self.assertIn("Invalidated", html)
            else:
                self.assertNotIn("Invalidated", html)

            if job.failed_step:
                self.assertIn(job.failed_step, html)
Beispiel #14
0
def do_repo_page(request, repo):
    """
    Render the repo page. This has the same layout as the main page but only for single repository.
    Input:
        request[django.http.HttpRequest]
        repo[models.Repository]
    """
    limit = 30
    repos_status = RepositoryStatus.filter_repos_status([repo.pk])
    events_info = EventsStatus.events_filter_by_repo([repo.pk], limit=limit)

    params = {
        'repo': repo,
        'repos_status': repos_status,
        'events_info': events_info,
        'event_limit': limit,
        'last_request': TimeUtils.get_local_timestamp(),
        'update_interval': settings.HOME_PAGE_UPDATE_INTERVAL
        }
    return render(request, 'ci/repo.html', params)
Beispiel #15
0
def main(request):
    """
    Main view. Just shows the status of repos, with open prs, as
    well as a short list of recent jobs.
    Input:
      request: django.http.HttpRequest
    Return:
      django.http.HttpResponse based object
    """
    limit = 30
    repos, evs_info, default = get_user_repos_info(request, limit=limit)
    return render(request,
        'ci/main.html',
        {'repos': repos,
          'recent_events': evs_info,
          'last_request': TimeUtils.get_local_timestamp(),
          'event_limit': limit,
          'update_interval': settings.HOME_PAGE_UPDATE_INTERVAL,
          'default_view': default,
        })
Beispiel #16
0
def user_open_prs(request, username):
    """
    Get the updates for the main page.
    """
    users = models.GitUser.objects.filter(name=username)
    if users.count() == 0:
        return HttpResponseBadRequest('Bad username')

    if 'last_request' not in request.GET:
        return HttpResponseBadRequest('Missing parameters')

    this_request = TimeUtils.get_local_timestamp()
    last_request = int(float(request.GET['last_request'])) # in case it has decimals
    dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request)))
    repos = RepositoryStatus.get_user_repos_with_open_prs_status(username)
    repo_ids = []
    pr_ids = []
    for r in repos:
        repo_ids.append(r["id"])
        for pr in r["prs"]:
            pr_ids.append(pr["id"])
    event_list = EventsStatus.get_single_event_for_open_prs(pr_ids)
    evs_info = EventsStatus.multiline_events_info(event_list)
    ev_ids = []
    for e in evs_info:
        ev_ids.append(e["id"])
    # Now get the changed ones
    repos = RepositoryStatus.get_user_repos_with_open_prs_status(username, dt)
    evs_info = EventsStatus.multiline_events_info(event_list, dt)

    data = {'repos': repo_ids,
        'prs': pr_ids,
        'events': ev_ids,
        'repo_status': repos,
        'closed': [],
        'last_request': this_request,
        'changed_events': evs_info,
        }
    return JsonResponse(data)
Beispiel #17
0
def main_update(request):
    """
    Get the updates for the main page.
    """
    if 'last_request' not in request.GET or 'limit' not in request.GET:
        return HttpResponseBadRequest('Missing parameters')

    this_request = TimeUtils.get_local_timestamp()
    limit = int(request.GET['limit'])
    last_request = int(float(request.GET['last_request'])) # in case it has decimals
    dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request)))
    repos_data, einfo, default = views.get_user_repos_info(request, limit=limit, last_modified=dt)
    # we also need to check if a PR closed recently
    closed = []
    for pr in models.PullRequest.objects.filter(closed=True, last_modified__gte=dt).values('id').all():
        closed.append({'id': pr['id']})

    return JsonResponse({'repo_status': repos_data,
        'closed': closed,
        'last_request': this_request,
        'events': einfo,
        'limit': limit,
        })
Beispiel #18
0
 def test_sortable_time_str(self):
     TimeUtils.sortable_time_str(datetime.datetime.now())
Beispiel #19
0
    def test_cancel_old_jobs(self, mock_post, mock_get):
        out = StringIO()
        with self.assertRaises(CommandError):
            management.call_command("cancel_old_jobs", stdout=out)

        out = StringIO()
        self.set_counts()
        management.call_command("cancel_old_jobs",
                                "--dryrun",
                                "--days",
                                "1",
                                stdout=out)
        self.compare_counts()
        self.assertIn("No jobs to cancel", out.getvalue())

        j = utils.create_job()
        created = TimeUtils.get_local_time() - timedelta(days=2)
        utils.update_job(j,
                         ready=True,
                         active=True,
                         status=models.JobStatus.NOT_STARTED,
                         created=created,
                         complete=False)

        # Make sure dryrun doesn't change anything
        out = StringIO()
        self.set_counts()
        management.call_command("cancel_old_jobs",
                                "--dryrun",
                                "--days",
                                "1",
                                stdout=out)
        self.compare_counts()
        self.assertIn(str(j), out.getvalue())
        j.refresh_from_db()
        self.assertEqual(j.status, models.JobStatus.NOT_STARTED)

        # Should update the job and event status
        out = StringIO()
        self.set_counts()
        management.call_command("cancel_old_jobs", "--days", "1", stdout=out)
        self.compare_counts(active_branches=1,
                            canceled=1,
                            events_canceled=1,
                            num_changelog=1,
                            num_events_completed=1,
                            num_jobs_completed=1)
        self.assertIn(str(j), out.getvalue())
        j.refresh_from_db()
        j.event.refresh_from_db()
        self.assertTrue(j.complete)
        self.assertEqual(j.status, models.JobStatus.CANCELED)
        self.assertEqual(j.event.status, models.JobStatus.CANCELED)
        self.assertTrue(j.event.complete)

        # Should not change anything since it isn't old enough
        utils.update_job(j,
                         status=models.JobStatus.NOT_STARTED,
                         complete=False)
        out = StringIO()
        self.set_counts()
        management.call_command("cancel_old_jobs", "--days", "3", stdout=out)
        self.compare_counts()
        self.assertIn("No jobs to cancel", out.getvalue())
        self.assertNotIn(str(j), out.getvalue())
        j.refresh_from_db()
        self.assertEqual(j.status, models.JobStatus.NOT_STARTED)

        # Should update the job and event status
        created = TimeUtils.get_local_time() - timedelta(hours=2)
        utils.update_job(j,
                         status=models.JobStatus.NOT_STARTED,
                         complete=False,
                         created=created)
        out = StringIO()
        self.set_counts()
        management.call_command("cancel_old_jobs", "--hours", "1", stdout=out)
        self.compare_counts(canceled=1, num_changelog=1, num_jobs_completed=1)
        self.assertIn(str(j), out.getvalue())
        j.refresh_from_db()
        self.assertEqual(j.status, models.JobStatus.CANCELED)

        # Should not change anything since it isn't old enough
        utils.update_job(j,
                         status=models.JobStatus.NOT_STARTED,
                         complete=False,
                         created=created)
        out = StringIO()
        self.set_counts()
        management.call_command("cancel_old_jobs", "--hours", "3", stdout=out)
        self.compare_counts()
        self.assertIn("No jobs to cancel", out.getvalue())
        self.assertNotIn(str(j), out.getvalue())
        j.refresh_from_db()
        self.assertEqual(j.status, models.JobStatus.NOT_STARTED)

        # Make sure setting allowed to fail works
        utils.update_job(j,
                         status=models.JobStatus.NOT_STARTED,
                         complete=False,
                         created=created)
        out = StringIO()
        self.set_counts()
        management.call_command("cancel_old_jobs",
                                "--hours",
                                "1",
                                "--allowed-fail",
                                stdout=out)
        self.compare_counts(events_canceled=-1,
                            num_changelog=1,
                            num_jobs_completed=1)
        self.assertIn(str(j), out.getvalue())
        j.refresh_from_db()
        self.assertEqual(j.status, models.JobStatus.FAILED_OK)

        # Check the --client-runner-user option only accepts <host>:<user> syntax
        utils.update_job(j,
                         status=models.JobStatus.NOT_STARTED,
                         complete=False,
                         created=created)
        out = StringIO()
        self.set_counts()
        with self.assertRaises(CommandError):
            management.call_command("cancel_old_jobs",
                                    "--hours",
                                    "1",
                                    '--client-runner-user',
                                    'foo',
                                    stdout=out)
        self.compare_counts()

        # Valid --client-runner-user
        self.set_counts()
        management.call_command(
            "cancel_old_jobs",
            "--hours",
            "1",
            '--client-runner-user',
            "%s:%s" %
            (j.recipe.build_user.server.name, j.recipe.build_user.name),
            stdout=out)
        self.compare_counts(canceled=1,
                            num_changelog=1,
                            num_jobs_completed=1,
                            events_canceled=1)

        # --client-runner-user with no jobs
        utils.update_job(j,
                         status=models.JobStatus.NOT_STARTED,
                         complete=False,
                         created=created)
        other_user = utils.create_user(name="other_user")
        self.set_counts()
        management.call_command("cancel_old_jobs",
                                "--hours",
                                "1",
                                '--client-runner-user',
                                "%s:%s" %
                                (other_user.server.name, other_user.name),
                                stdout=out)
        self.compare_counts()
Beispiel #20
0
def job_results(request):
    """
    Returns the job results and job info in JSON.
    GET parameters:
      job_id: The pk of the job
      last_request: A timestamp of when client last requested this information. If the job
        hasn't been updated since that time we don't have to send as much information.
    """
    if 'last_request' not in request.GET or 'job_id' not in request.GET:
        return HttpResponseBadRequest('Missing parameters')

    this_request = TimeUtils.get_local_timestamp()
    job_id = int(request.GET['job_id'])
    last_request = int(float(request.GET['last_request'])) # in case it has decimals
    dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request)))
    job = get_object_or_404(models.Job.objects.select_related("recipe", "client").prefetch_related("step_results"), pk=job_id)
    if not Permissions.can_see_results(request.session, job.recipe):
        return HttpResponseForbidden("Can't see results")

    job_info = {
        'id': job.pk,
        'complete': job.complete,
        'status': job.status_slug(),
        'runtime': str(job.seconds),
        'ready': job.ready,
        'invalidated': job.invalidated,
        'active': job.active,
        'last_modified': TimeUtils.display_time_str(job.last_modified),
        'created': TimeUtils.display_time_str(job.created),
        'client_name': '',
        'client_url': '',
        'recipe_repo_sha': job.recipe_repo_sha[:6],
        'recipe_sha': job.recipe.filename_sha[:6],
        }

    if job.last_modified < dt:
        # always return the basic info since we need to update the
        # "natural" time
        return JsonResponse({'job_info': job_info, 'results': [], 'last_request': this_request})

    if job.client:
        can_see_client = Permissions.is_allowed_to_see_clients(request.session)
        if can_see_client:
            job_info['client_name'] = job.client.name
            job_info['client_url'] = reverse('ci:view_client', args=[job.client.pk,])

    result_info = []

    for result in job.step_results.all():
        if dt > result.last_modified:
            continue
        exit_status = ''
        if result.complete:
            exit_status = result.exit_status
        info = {'id': result.id,
            'name': result.name,
            'runtime': str(result.seconds),
            'exit_status': exit_status,
            'output': result.clean_output(),
            'status': result.status_slug(),
            'running': result.status != models.JobStatus.NOT_STARTED,
            'complete': result.complete,
            'output_size': result.output_size(),
            }
        result_info.append(info)

    return JsonResponse({'job_info': job_info, 'results': result_info, 'last_request': this_request})
Beispiel #21
0
 def test_std_time_str(self):
     TimeUtils.std_time_str(datetime.datetime.now())
Beispiel #22
0
 def test_get_local_timestamp(self):
     TimeUtils.get_local_timestamp()
Beispiel #23
0
 def test_human_time_str(self):
     TimeUtils.human_time_str(datetime.datetime.now())
Beispiel #24
0
 def test_display_time_str(self):
     TimeUtils.display_time_str(datetime.datetime.now())
Beispiel #25
0
 def __str__(self):
     out = "%s - %s" % (self.message, TimeUtils.display_time_str(self.created))
     return out
Beispiel #26
0
def events_info(events, last_modified=None, events_url=False):
    """
    Creates the information required for displaying events.
    Input:
      events: An iterable of models.Event. Usually a query or just a list.
      last_modified: DateTime: If model.Event.last_modified is before this it won't be included
    Return:
      list of event info dicts
    """
    event_info = []
    for ev in events:
        if last_modified and ev.last_modified <= last_modified:
            continue

        repo_url = reverse("ci:view_repo", args=[ev.base.branch.repository.pk])
        event_url = reverse("ci:view_event", args=[ev.pk])
        repo_link = format_html('<a href="{}">{}</a>', repo_url,
                                ev.base.branch.repository.name)
        pr_url = ''
        pr_desc = ''
        if ev.pull_request:
            pr_url = reverse("ci:view_pr", args=[ev.pull_request.pk])
            pr_desc = clean_str_for_format(str(ev.pull_request))
            icon_link = format_html('<a href="{}"><i class="{}"></i></a>',
                                    ev.pull_request.url,
                                    ev.base.server().icon_class())
            if events_url:
                event_desc = format_html('{} {} <a href="{}">{}</a>',
                                         icon_link, repo_link, event_url,
                                         pr_desc)
            else:
                event_desc = format_html('{} {} <a href="{}">{}</a>',
                                         icon_link, repo_link, pr_url, pr_desc)
        else:
            event_desc = format_html('{} <a href="{}">{}', repo_link,
                                     event_url, ev.base.branch.name)
            if ev.description:
                event_desc = format_html('{} : {}', mark_safe(event_desc),
                                         clean_str_for_format(ev.description))
            event_desc += '</a>'

        info = {
            'id': ev.pk,
            'status': ev.status_slug(),
            'sort_time': TimeUtils.sortable_time_str(ev.created),
            'description': format_html(event_desc),
            'pr_id': 0,
            'pr_title': "",
            'pr_status': "",
            'pr_number': 0,
            'pr_url': "",
            'git_pr_url': "",
            'pr_username': "",
            'pr_name': "",
        }
        if ev.pull_request:
            info["pr_id"] = ev.pull_request.pk
            info["pr_title"] = ev.pull_request.title
            info["pr_status"] = ev.pull_request.status_slug()
            info["pr_number"] = ev.pull_request.number
            info["git_pr_url"] = ev.pull_request.url
            info["pr_url"] = pr_url
            info["pr_username"] = ev.pull_request.username
            info["pr_name"] = pr_desc

        job_info = []
        for job_group in ev.get_sorted_jobs():
            job_group_info = []
            for job in job_group:
                if int(job.seconds.total_seconds()) == 0:
                    job_seconds = ""
                else:
                    job_seconds = str(job.seconds)

                jurl = reverse("ci:view_job", args=[job.pk])

                jinfo = {
                    'id': job.pk,
                    'status': job.status_slug(),
                }
                job_desc = format_html('<a href="{}">{}</a>', jurl,
                                       format_html(job.unique_name()))
                if job_seconds:
                    job_desc += format_html('<br />{}', job_seconds)
                if job.failed_step:
                    job_desc += format_html('<br />{}', job.failed_step)
                if job.running_step:
                    job_desc += format_html('<br />{}', job.running_step)
                if job.invalidated:
                    job_desc += '<br />(Invalidated)'
                jinfo["description"] = job_desc
                job_group_info.append(jinfo)
            job_info.append(job_group_info)
        info['job_groups'] = job_info

        event_info.append(info)

    return event_info