Skip to content

Commit

Permalink
Add /job_groups/id/build_results API route
Browse files Browse the repository at this point in the history
Issue: https://progress.opensuse.org/issues/152939

I moved `_map_tags_into_build` into the `compute_build_results()` function.

The command lime to get the last "published" build would look like this:

    openqa-cli api job_groups/1/build_results only_tagged=1 \
      | jq -r '[.build_results[] | select(.tag.description=="published") | select(.version=="Tumbleweed") | .build ][0]'

To only get the latest build:

    openqa-cli api job_groups/1/build_results | jq -r '[.build_results[] | .build ][0]'
  • Loading branch information
perlpunk committed Jan 23, 2024
1 parent 88c92b7 commit f5d9a23
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 23 deletions.
19 changes: 17 additions & 2 deletions lib/OpenQA/BuildResults.pm
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ sub find_child_groups ($group, $subgroup_filter) {
return filter_subgroups($group, $subgroup_filter);
}

sub compute_build_results ($group, $limit, $time_limit_days, $tags, $subgroup_filter) {
sub compute_build_results ($group, $limit, $time_limit_days, $tags, $subgroup_filter, $show_tags) {

# find relevant child groups taking filter into account
my $child_groups = find_child_groups($group, $subgroup_filter);
Expand Down Expand Up @@ -233,8 +233,23 @@ sub compute_build_results ($group, $limit, $time_limit_days, $tags, $subgroup_fi
$max_jobs = $jr{total} if ($jr{total} > $max_jobs);
}
$result{max_jobs} = $max_jobs;
_map_tags_into_build($result{build_results}, $show_tags) if $show_tags;
return \%result;
}

1;
sub _map_tags_into_build ($results, $tags) {
for my $res (@$results) {
if (my $full_tag = $tags->{$res->{key}}) {
$res->{tag} = $full_tag;
}
elsif (my $build_only_tag = $tags->{$res->{build}}) {
# as fallback we are looking for build and not other criteria we can end
# up with multiple tags if the build appears more than once, e.g.
# for each version
$res->{tag} = $build_only_tag;
}
}
}


1;
1 change: 1 addition & 0 deletions lib/OpenQA/WebAPI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ sub startup ($self) {
$api_public_r->get('/job_groups')->name('apiv1_list_job_groups')->to('job_group#list');
$api_public_r->get('/job_groups/<group_id:num>')->name('apiv1_get_job_group')->to('job_group#list');
$api_public_r->get('/job_groups/<group_id:num>/jobs')->name('apiv1_get_job_group_jobs')->to('job_group#list_jobs');
$api_public_r->get('/job_groups/<group_id:num>/build_results')->name('apiv1_get_job_group_jobs')->to('job_group#build_results');
$api_ra->post('/job_groups')->name('apiv1_post_job_group')->to('job_group#create');
$api_ra->put('/job_groups/<group_id:num>')->name('apiv1_put_job_group')->to('job_group#update');
$api_ra->delete('/job_groups/<group_id:num>')->name('apiv1_delete_job_group')->to('job_group#delete');
Expand Down
40 changes: 40 additions & 0 deletions lib/OpenQA/WebAPI/Controller/API/V1/JobGroup.pm
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,44 @@ sub delete ($self) {
$self->render(json => $event_data);
}

=over 4
=item build_results()
Shows build results for a job group, similar to what the group_overview page
provides.
Currently it does not support parent job groups.
Use limit_builds=n to limit the number of returned builds.
Use time_limit_days=n to only go back n days.
Use only_tagged=1 to only return tagged builds.
Use show_tags=1 to show tags for each build. only_tagged implies show_tags.
=back
=cut

sub build_results ($self) {
my $group = $self->find_group() or return;
my $validation = $self->validation;
$validation->optional('limit_builds')->num;
$validation->optional('time_limit_days')->like(qr/^[0-9.]+$/);
$validation->optional('only_tagged');
$validation->optional('show_tags');
my $limit_builds = $validation->param('limit_builds') // 10;
my $time_limit_days = $validation->param('time_limit_days') // 0;
my $only_tagged = $validation->param('only_tagged') // 0;
my $show_tags = $validation->param('show_tags') // $only_tagged;

my $tags = $show_tags ? $group->tags : undef;
my $cbr = OpenQA::BuildResults::compute_build_results($group, $limit_builds,
$time_limit_days, $only_tagged ? $tags : undef, [], $tags
);
$self->render(json => $cbr);
}

1;
25 changes: 4 additions & 21 deletions lib/OpenQA/WebAPI/Controller/Main.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,6 @@ use OpenQA::BuildResults;
use OpenQA::Utils;
use Mojo::File qw(path);

sub _map_tags_into_build ($results, $tags) {
for my $res (@$results) {
if (my $full_tag = $tags->{$res->{key}}) {
$res->{tag} = $full_tag;
}
elsif (my $build_only_tag = $tags->{$res->{build}}) {
# as fallback we are looking for build and not other criteria we can end
# up with multiple tags if the build appears more than once, e.g.
# for each version
$res->{tag} = $build_only_tag;
}
}
}

sub dashboard_build_results ($self) {
my $validation = $self->validation;
$validation->optional('limit_builds')->num;
Expand Down Expand Up @@ -56,10 +42,9 @@ sub dashboard_build_results ($self) {
my $build_results
= OpenQA::BuildResults::compute_build_results($group, $limit_builds, $time_limit_days,
$only_tagged ? $tags : undef,
$group_params);
$group_params, $show_tags ? $tags : undef);

my $build_results_for_group = $build_results->{build_results};
_map_tags_into_build($build_results_for_group, $tags) if $show_tags;
push(@results, $build_results) if @{$build_results_for_group};
}
};
Expand Down Expand Up @@ -135,19 +120,17 @@ sub _group_overview ($self, $resultset, $template) {

my $tags = $group->tags;
my $cbr = eval {
OpenQA::BuildResults::compute_build_results($group, $limit_builds, $time_limit_days,
$only_tagged ? $tags : undef,
$group_params);
OpenQA::BuildResults::compute_build_results($group, $limit_builds,
$time_limit_days, $only_tagged ? $tags : undef, $group_params, $tags)
};
if (my $error = $@) {
die $error unless $error =~ qr/^invalid regex: /;
return $self->_respond_error_for_group_overview($error);
}
my $build_results = $cbr->{build_results};
my $max_jobs = $cbr->{max_jobs};
$self->stash(children => $cbr->{children});

_map_tags_into_build($build_results, $tags);
$self->stash(children => $cbr->{children});
$self->stash(build_results => $build_results, max_jobs => $max_jobs);

my $is_parent_group = $group->can('children');
Expand Down
54 changes: 54 additions & 0 deletions t/api/10-jobgroups.t
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,60 @@ my $schema = $t->app->schema;
my $audit_events = $schema->resultset('AuditEvents');

my $opensuse_group = '1001';


subtest 'build results' => sub {
subtest 'default' => sub {
$t->get_ok("/api/v1/job_groups/$opensuse_group/build_results?time_limit_days=99999")->status_is(200);
$t->json_is('/build_results/4/all_passed' => '');
$t->json_is('/build_results/4/build' => '0091');
$t->json_is('/build_results/4/key' => '13.1-0091');
$t->json_is('/build_results/4/comments' => 0);
$t->json_is('/build_results/4/commented' => 1);
$t->json_is('/build_results/4/escaped_id' => '13_1-0091');
$t->json_is('/build_results/4/escaped_build' => '0091');
$t->json_is('/build_results/4/escaped_version' => '13_1');
$t->json_is('/build_results/4/failed' => 0);
$t->json_is('/build_results/4/labeled' => 0);
$t->json_is('/build_results/4/passed' => 2);
$t->json_is('/build_results/4/reviewed' => 1);
$t->json_is('/build_results/4/skipped' => 1);
$t->json_is('/build_results/4/softfailed' => 0);
$t->json_is('/build_results/4/total' => 5);
$t->json_is('/build_results/4/unfinished' => 2);
$t->json_is('/build_results/4/version' => '13.1');
$t->json_is('/build_results/3/build' => '0092');
$t->json_is('/build_results/2/build' => '0048');
$t->json_is('/build_results/1/build' => '0048@0815');
$t->json_is('/build_results/0/build' => '87.5011');
$t->json_is('/build_results/0/tag' => undef);
$t->json_is('/build_results/5' => undef);
$t->json_is('/max_jobs' => 5, );
$t->json_is('/group/id' => $opensuse_group);
$t->json_is('/group/name' => 'opensuse');
};

subtest 'tags' => sub {
$t->get_ok("/api/v1/job_groups/$opensuse_group/build_results?time_limit_days=99999&show_tags=1")->status_is(200);
$t->json_is('/build_results/0/tag' => undef);

$t->get_ok("/api/v1/job_groups/$opensuse_group/build_results?time_limit_days=99999&only_tagged=1&show_tags=1")->status_is(200);
$t->json_is('/build_results/0' => undef, 'no tagged build is shown');

my $comment = 'tag:0091:published:published';
$t->post_ok("/api/v1/groups/$opensuse_group/comments" => form => {text => $comment})->status_is(200, 'comment can be created')
->or(sub { diag 'error: ' . $t->tx->res->json->{error} });
my $cid = $t->tx->res->json->{id};
$t->get_ok("/api/v1/job_groups/$opensuse_group/build_results?time_limit_days=99999&only_tagged=1&show_tags=1")->status_is(200);
my $json = $t->tx->res->json;
$t->json_is('/build_results/0/build' => '0091', 'one tagged build is shown');
$t->json_is('/build_results/0/tag/build' => '0091');
$t->json_is('/build_results/0/tag/description' => 'published');
$t->json_is('/build_results/0/tag/type' => 'published');
$t->json_is('/build_results/0/tag/version' => undef);
};
};

subtest 'list job groups' => sub() {
$t->get_ok('/api/v1/job_groups')->status_is(200);
is_deeply(
Expand Down

0 comments on commit f5d9a23

Please sign in to comment.