Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to partially re-schedule a product from a job #5233

Merged
merged 4 commits into from Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 20 additions & 21 deletions assets/javascripts/audit_log.js
Expand Up @@ -186,27 +186,26 @@ function showScheduledProductResults(link) {
}
}

function rescheduleProduct(link) {
const rowData = dataForLink(link);
if (rowData === undefined) {
return;
function rescheduleProductForActionLink(link) {
const id = dataForLink(link)?.id;
if (id && window.confirm('Do you really want to reschedule all jobs for the product ' + id + '?')) {
rescheduleProduct(scheduledProductsTable.rescheduleUrlTemplate.replace('XXXXX', id));
}
const id = rowData.id;
if (!id || !window.confirm('Do you really want to reschedule all jobs for the product ' + id + '?')) {
return;
}
const url = scheduledProductsTable.rescheduleUrlTemplate.replace('XXXXX', id);
$.post(url, undefined, function () {
addFlash(
'info',
'Re-scheduling the product has been triggered. A new scheduled product should appear when refreshing the page.'
);
}).fail(function (response) {
const responseText = response.responseText;
if (responseText) {
addFlash('danger', 'Unable to trigger re-scheduling: ' + responseText);
} else {
addFlash('danger', 'Unable to trigger re-scheduling.');
}

function rescheduleProduct(url) {
$.post({
url: url,
success: (data, textStatus, jqXHR) => {
const id = jqXHR.responseJSON?.scheduled_product_id;
const msg =
typeof id === 'number'
? `The product has been re-triggered as <a href="/admin/productlog?id=${id}">${id}</a>.`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This results in

unterminated quoted string literal at /usr/lib/perl5/vendor_perl/5.26.1/Mojolicious/Plugin/AssetPack/Pipe/JavaScript.pm line 22.

in https://build.opensuse.org/package/live_build_log/devel:openQA/openQA/openSUSE_Leap_15.4/x86_64

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I proposed #5264 to address this

: 'Re-scheduling the product has been triggered.';
addFlash('info', msg);
},
error: (jqXHR, textStatus, errorThrown) => {
addFlash('danger', 'Unable to trigger re-scheduling: ' + getXhrError(jqXHR, textStatus, errorThrown));
}
});
}
Expand Down Expand Up @@ -288,7 +287,7 @@ function loadProductLogTable(dataTableUrl, rescheduleUrlTemplate, showActions) {
}
if (showActions) {
html +=
'<a href="#" onclick="rescheduleProduct(this); return true;">\
'<a href="#" onclick="rescheduleProductForActionLink(this); return true;">\
<i class="action fa fa-undo" title="Reschedule product tests"></i></a>';
}
return html;
Expand Down
8 changes: 0 additions & 8 deletions assets/javascripts/comments.js
Expand Up @@ -34,14 +34,6 @@ function renderCommentHeading(comment, commentId) {
return heading;
}

function getXhrError(jqXHR, textStatus, errorThrown) {
try {
return JSON.parse(jqXHR.responseText).error || errorThrown || textStatus;
} catch {
return errorThrown || textStatus;
}
}

function showXhrError(context, jqXHR, textStatus, errorThrown) {
window.alert(context + getXhrError(jqXHR, textStatus, errorThrown));
}
Expand Down
4 changes: 4 additions & 0 deletions assets/javascripts/openqa.js
Expand Up @@ -550,3 +550,7 @@ function renderHttpUrlAsLink(value) {
span.appendChild(document.createTextNode(value));
return span;
}

function getXhrError(jqXHR, textStatus, errorThrown) {
return jqXHR.responseJSON?.error || jqXHR.responseText || errorThrown || textStatus;
}
7 changes: 7 additions & 0 deletions assets/javascripts/test_result.js
Expand Up @@ -1123,4 +1123,11 @@ function renderDependencyGraph(container, nodes, edges, cluster, currentNode) {
// note: centering is achieved by centering the svg element itself like any other html block element
}

function rescheduleProductForJob(link) {
if (window.confirm('Do you really want to partially reschedule the product of this job?')) {
rescheduleProduct(link.dataset.url);
}
return false; // avoid usual link handling
}

module = {};
2 changes: 1 addition & 1 deletion lib/OpenQA/WebAPI/Controller/API/V1/Iso.pm
Expand Up @@ -129,7 +129,7 @@ sub create {
}
my $settings_to_clone = $previously_scheduled_product->settings // {};
for my $required_param (MANDATORY_PARAMETERS) {
if (!$settings_to_clone->{$required_param}) {
if (!defined $settings_to_clone->{$required_param}) {
return $self->render(
text => "Scheduled product to clone settings from misses $required_param.",
status => 404
Expand Down
8 changes: 2 additions & 6 deletions t/ui/17-product-log.t
Expand Up @@ -123,12 +123,8 @@ subtest 'trigger actions' => sub {
'confirmation prompt shown'
);
$driver->accept_alert;
wait_for_ajax;
is(
$driver->find_element('#flash-messages span')->get_text(),
'Re-scheduling the product has been triggered. A new scheduled product should appear when refreshing the page.',
'flash with info message occurs'
);
wait_for_ajax msg => 'info message for rescheduling';
$driver->element_text_is('#flash-messages span', 'The product has been re-triggered as 2.', 'info message shown'),;
};

subtest 'rescheduled ISO shown after refreshing page' => sub {
Expand Down
10 changes: 9 additions & 1 deletion t/ui/18-tests-details.t
Expand Up @@ -240,14 +240,22 @@ subtest 'bug reporting' => sub {

subtest 'scheduled product shown' => sub {
# still on test 99937
my $scheduled_product_link = $driver->find_element('#scheduled-product-info a');
my $scheduled_product_link = $driver->find_element('#scheduled-product-info > a');
my $expected_scheduled_product_id = $schema->resultset('Jobs')->find(99937)->scheduled_product_id;
is($scheduled_product_link->get_text(), 'distri-dvd-1234', 'scheduled product name');
like(
$scheduled_product_link->get_attribute('href'),
qr/\/admin\/productlog\?id=$expected_scheduled_product_id/,
'scheduled product href'
);
my $reschedule_link = $driver->find_element('#scheduled-product-info div > a');
my $expected_params = qr/scheduled_product_clone_id=$expected_scheduled_product_id&TEST=kde/;
like $reschedule_link->get_attribute('data-url'), $expected_params, 'reschedule link shown';
$reschedule_link->click;
$driver->accept_alert;
wait_for_ajax msg => 'message for rescheduling';
element_visible '#flash-messages .alert > span', qr/Scheduled product to clone settings from misses DISTRI/, undef,
'error shown';
$driver->get('/tests/99963');
like(
$driver->find_element_by_id('scheduled-product-info')->get_text(),
Expand Down
18 changes: 17 additions & 1 deletion templates/webapi/test/infopanel.html.ep
Expand Up @@ -134,7 +134,23 @@
<div id="scheduled-product-info">
Scheduled product:\
% if (my $scheduled_product = $job->scheduled_product) {
%= link_to $scheduled_product->to_string, url_for('admin_product_log')->query(id => $scheduled_product->id)
% my $sp_id = $scheduled_product->id;
%= link_to $scheduled_product->to_string, url_for('admin_product_log')->query(id => $sp_id)
% if (is_operator) {
<div class="btn-group btn-group-sm">
<a href="#"
onclick="return rescheduleProductForJob(this);" \
class="btn btn-link"\
data-url="<%= url_for('apiv1_create_iso')->query(scheduled_product_clone_id => $sp_id, TEST => $job->TEST, _SKIP_CHAINED_DEPS => 1, _INCLUDE_CHILDREN => 1) %>">\
<i class="fa fa-2 fa-refresh" title="Reschedule product from here"></i>
</a>
</div>
<%= help_popover('Partial product re-scheduling' => "
<p>Schedules the product again using the current job as starting point. That means chained parents of
the current job will not be scheduled again but all its children will be.</p>",
undef, undef, 'bottom');
%>
% }
% } else {
job has not been created by posting an ISO
% if ($clone_of) {
Expand Down