Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package openQA for openSUSE:Factory checked 
in at 2025-05-02 15:01:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openQA (Old)
 and      /work/SRC/openSUSE:Factory/.openQA.new.30101 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openQA"

Fri May  2 15:01:15 2025 rev:689 rq:1273980 version:5.1746018652.10b1e438

Changes:
--------
--- /work/SRC/openSUSE:Factory/openQA/openQA.changes    2025-04-25 
22:19:37.232321200 +0200
+++ /work/SRC/openSUSE:Factory/.openQA.new.30101/openQA.changes 2025-05-02 
15:02:35.301991041 +0200
@@ -1,0 +2,14 @@
+Fri May 02 09:26:33 UTC 2025 - ok...@suse.com
+
+- Update to version 5.1746018652.10b1e438:
+  * Bump datatables.net-bs5 from 2.2.2 to 2.3.0
+  * Follow symlinks but only delete files with dump-db script
+  * Avoid unbound variable error in dump-db script
+  * Fix result in case of giving up gru jobs without GruTasks
+  * Add nice and ionice to dump-db script
+  * Documented the PROVE_COMMAND and prove_wrapper feature
+  * Add explicit test for `obsolete_minion_jobs`
+  * Avoid leftover Minion jobs after failing txn when scheduling jobs
+  * Wrap prove to prevent unhandled output
+
+-------------------------------------------------------------------

Old:
----
  openQA-5.1745500773.055f94fe.obscpio

New:
----
  openQA-5.1746018652.10b1e438.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ openQA-client-test.spec ++++++
--- /var/tmp/diff_new_pack.8GdElH/_old  2025-05-02 15:02:36.370035929 +0200
+++ /var/tmp/diff_new_pack.8GdElH/_new  2025-05-02 15:02:36.370035929 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-client
 Name:           %{short_name}-test
-Version:        5.1745500773.055f94fe
+Version:        5.1746018652.10b1e438
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA-devel-test.spec ++++++
--- /var/tmp/diff_new_pack.8GdElH/_old  2025-05-02 15:02:36.406037442 +0200
+++ /var/tmp/diff_new_pack.8GdElH/_new  2025-05-02 15:02:36.406037442 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-devel
 Name:           %{short_name}-test
-Version:        5.1745500773.055f94fe
+Version:        5.1746018652.10b1e438
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA-test.spec ++++++
--- /var/tmp/diff_new_pack.8GdElH/_old  2025-05-02 15:02:36.434038619 +0200
+++ /var/tmp/diff_new_pack.8GdElH/_new  2025-05-02 15:02:36.438038786 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA
 Name:           %{short_name}-test
-Version:        5.1745500773.055f94fe
+Version:        5.1746018652.10b1e438
 Release:        0
 Summary:        Test package for openQA
 License:        GPL-2.0-or-later

++++++ openQA-worker-test.spec ++++++
--- /var/tmp/diff_new_pack.8GdElH/_old  2025-05-02 15:02:36.474040299 +0200
+++ /var/tmp/diff_new_pack.8GdElH/_new  2025-05-02 15:02:36.474040299 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-worker
 Name:           %{short_name}-test
-Version:        5.1745500773.055f94fe
+Version:        5.1746018652.10b1e438
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA.spec ++++++
--- /var/tmp/diff_new_pack.8GdElH/_old  2025-05-02 15:02:36.502041476 +0200
+++ /var/tmp/diff_new_pack.8GdElH/_new  2025-05-02 15:02:36.502041476 +0200
@@ -94,7 +94,7 @@
 %define devel_requires %devel_no_selenium_requires chromedriver
 
 Name:           openQA
-Version:        5.1745500773.055f94fe
+Version:        5.1746018652.10b1e438
 Release:        0
 Summary:        The openQA web-frontend, scheduler and tools
 License:        GPL-2.0-or-later

++++++ node_modules.obscpio ++++++
Binary files old/datatables.net-2.2.2.tgz and new/datatables.net-2.2.2.tgz 
differ
Binary files old/datatables.net-2.3.0.tgz and new/datatables.net-2.3.0.tgz 
differ
Binary files old/datatables.net-bs5-2.2.2.tgz and 
new/datatables.net-bs5-2.2.2.tgz differ
Binary files old/datatables.net-bs5-2.3.0.tgz and 
new/datatables.net-bs5-2.3.0.tgz differ

++++++ node_modules.spec.inc ++++++
--- /var/tmp/diff_new_pack.8GdElH/_old  2025-05-02 15:02:37.122067535 +0200
+++ /var/tmp/diff_new_pack.8GdElH/_new  2025-05-02 15:02:37.126067703 +0200
@@ -67,8 +67,8 @@
 Source1066:         
https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz#/d3-zoom-3.0.0.tgz
 Source1067:         
https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz#/dagre-0.8.5.tgz
 Source1068:         
https://registry.npmjs.org/dagre-d3/-/dagre-d3-0.6.4.tgz#/dagre-d3-0.6.4.tgz
-Source1069:         
https://registry.npmjs.org/datatables.net/-/datatables.net-2.2.2.tgz#/datatables.net-2.2.2.tgz
-Source1070:         
https://registry.npmjs.org/datatables.net-bs5/-/datatables.net-bs5-2.2.2.tgz#/datatables.net-bs5-2.2.2.tgz
+Source1069:         
https://registry.npmjs.org/datatables.net/-/datatables.net-2.3.0.tgz#/datatables.net-2.3.0.tgz
+Source1070:         
https://registry.npmjs.org/datatables.net-bs5/-/datatables.net-bs5-2.3.0.tgz#/datatables.net-bs5-2.3.0.tgz
 Source1071:         
https://registry.npmjs.org/debug/-/debug-4.4.0.tgz#/debug-4.4.0.tgz
 Source1072:         
https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz#/deep-is-0.1.4.tgz
 Source1073:         
https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz#/delaunator-5.0.1.tgz

++++++ openQA-5.1745500773.055f94fe.obscpio -> 
openQA-5.1746018652.10b1e438.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1745500773.055f94fe/Makefile 
new/openQA-5.1746018652.10b1e438/Makefile
--- old/openQA-5.1745500773.055f94fe/Makefile   2025-04-24 15:19:33.000000000 
+0200
+++ new/openQA-5.1746018652.10b1e438/Makefile   2025-04-30 15:10:52.000000000 
+0200
@@ -16,6 +16,8 @@
 TESTS ?=
 # EXTRA_PROVE_ARGS: Additional prove arguments to pass
 EXTRA_PROVE_ARGS ?=
+# PROVE: Test application for Perl tests
+PROVE ?= prove
 ifeq ($(TESTS),)
 PROVE_ARGS ?= --trap -r ${EXTRA_PROVE_ARGS} t
 else
@@ -240,7 +242,7 @@
        export GLOBIGNORE="$(GLOBIGNORE)";\
        export DEVEL_COVER_DB_FORMAT=JSON;\
        export PERL5OPT="$(COVEROPT)$(PERL5OPT) -It/lib -I$(PWD)/t/lib 
-I$(PWD)/external/os-autoinst-common/lib -MOpenQA::Test::PatchDeparse";\
-       RETRY=${RETRY} HOOK=./tools/delete-coverdb-folder timeout -s SIGINT -k 
5 -v ${TIMEOUT_RETRIES} tools/retry prove ${PROVE_LIB_ARGS} ${PROVE_ARGS}
+       RETRY=${RETRY} HOOK=./tools/delete-coverdb-folder timeout -s SIGINT -k 
5 -v ${TIMEOUT_RETRIES} tools/retry "${PROVE}" ${PROVE_LIB_ARGS} ${PROVE_ARGS}
 
 .PHONY: setup-database
 setup-database:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1745500773.055f94fe/docs/Contributing.asciidoc 
new/openQA-5.1746018652.10b1e438/docs/Contributing.asciidoc
--- old/openQA-5.1745500773.055f94fe/docs/Contributing.asciidoc 2025-04-24 
15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/docs/Contributing.asciidoc 2025-04-30 
15:10:52.000000000 +0200
@@ -267,6 +267,18 @@
 
 See the docs for details https://metacpan.org/pod/Devel::Cover
 
+To run the tests with a different command than `prove` you can set the
+`PROVE` variable in the Makefile. For example, in our CircleCI tests we
+use `tools/prove_wrapper` to run the tests. This wrapper is a simple script 
that
+will run `prove` and fail the test if there is unhandled output. This is useful
+to avoid having unhandled output in tests. To run the tests with
+`tools/prove_wrapper` you can do:
+
+[source,sh]
+----
+PROVE=tools/prove_wrapper make test TESTS=t/foo.t
+----
+
 There are some ways to save some time when executing local tests:
 
 * One option is selecting individual tests to run as explained above
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1745500773.055f94fe/lib/OpenQA/Schema/Result/ScheduledProducts.pm 
new/openQA-5.1746018652.10b1e438/lib/OpenQA/Schema/Result/ScheduledProducts.pm
--- 
old/openQA-5.1745500773.055f94fe/lib/OpenQA/Schema/Result/ScheduledProducts.pm  
    2025-04-24 15:19:33.000000000 +0200
+++ 
new/openQA-5.1746018652.10b1e438/lib/OpenQA/Schema/Result/ScheduledProducts.pm  
    2025-04-30 15:10:52.000000000 +0200
@@ -248,7 +248,7 @@
 }
 
 sub _create_jobs_in_database ($self, $jobs, $failed_job_info, 
$skip_chained_deps, $include_children,
-    $successful_job_ids)
+    $successful_job_ids, $minion_ids = undef)
 {
     my $schema = $self->result_source->schema;
     my $jobs_resultset = $schema->resultset('Jobs');
@@ -307,8 +307,8 @@
             $tmp_downloads{$_}->{blocked_job_id}]
     } keys %tmp_downloads;
     my $gru = OpenQA::App->singleton->gru;
-    $gru->enqueue_download_jobs(\%downloads);
-    $gru->enqueue_git_clones(\%clones, $successful_job_ids) if keys %clones;
+    $gru->enqueue_download_jobs(\%downloads, $minion_ids);
+    $gru->enqueue_git_clones(\%clones, $successful_job_ids, $minion_ids) if 
keys %clones;
 }
 
 =over 4
@@ -399,16 +399,22 @@
     # define function to create jobs in the database; executed as transaction
     my @successful_job_ids;
     my @failed_job_info;
+    my @minion_ids;
+    my $gru = OpenQA::App->singleton->gru;
 
     try {
         $schema->txn_do_retry_on_deadlock(
             sub {
                 $self->_create_jobs_in_database($jobs, \@failed_job_info, 
$skip_chained_deps, $include_children,
-                    \@successful_job_ids);
+                    \@successful_job_ids, \@minion_ids);
             },
-            sub { (@successful_job_ids, @failed_job_info) = () });
+            sub {   # this handler is generally covered but tests are unable 
to reproduce the deadlock 100 % of the time
+                $gru->obsolete_minion_jobs(\@minion_ids);    # uncoverable 
statement
+                (@successful_job_ids, @failed_job_info, @minion_ids) = ();    
# uncoverable statement
+            });
     }
     catch ($e) {
+        $gru->obsolete_minion_jobs(\@minion_ids);
         push(@notes, "Transaction failed: $e");
         push(@failed_job_info, map { {job_id => $_, error_messages => [$e]} } 
@successful_job_ids);
         @successful_job_ids = ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1745500773.055f94fe/lib/OpenQA/Shared/GruJob.pm 
new/openQA-5.1746018652.10b1e438/lib/OpenQA/Shared/GruJob.pm
--- old/openQA-5.1745500773.055f94fe/lib/OpenQA/Shared/GruJob.pm        
2025-04-24 15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/lib/OpenQA/Shared/GruJob.pm        
2025-04-30 15:10:52.000000000 +0200
@@ -10,7 +10,9 @@
 sub _grutasks ($self) { $self->minion->app->schema->resultset('GruTasks'); }
 
 sub execute ($self) {
-    my $gru_id = $self->info->{notes}{gru_id};
+    my $notes = $self->info->{notes};
+    return $self->finish if $notes->{obsolete};
+    my $gru_id = $notes->{gru_id};
     if ($gru_id and not $self->info->{finished}) {
         # We have a gru_id and this is the first run of the job
         my $gru = $self->_grutasks->find($gru_id);
@@ -21,7 +23,8 @@
             my $delay = 2**(1 + $retried);
             my $msg = "Could not find GruTask '$gru_id' after $retried 
retries";
             if ($retried > $max_retries) {
-                return $self->note(stop_reason => "$msg, giving up");
+                $self->note(stop_reason => "$msg, giving up");
+                return undef;
             }
             log_debug("$msg, delaying ${delay}s");
             return $self->retry({delay => $delay});
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1745500773.055f94fe/lib/OpenQA/Shared/Plugin/Gru.pm 
new/openQA-5.1746018652.10b1e438/lib/OpenQA/Shared/Plugin/Gru.pm
--- old/openQA-5.1745500773.055f94fe/lib/OpenQA/Shared/Plugin/Gru.pm    
2025-04-24 15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/lib/OpenQA/Shared/Plugin/Gru.pm    
2025-04-30 15:10:52.000000000 +0200
@@ -174,6 +174,13 @@
         });
 }
 
+sub obsolete_minion_jobs ($self, $job_ids) {
+    my $minion = $self->app->minion;
+    for my $job_id (@$job_ids) {
+        if (my $job = $minion->job($job_id)) { $job->note(obsolete => 1) }
+    }
+}
+
 sub enqueue ($self, $task, $args = [], $options = {}, $jobs = []) {
     my $ttl = $options->{ttl};
     my $limit = $options->{limit} ? $options->{limit} : undef;
@@ -216,13 +223,14 @@
 # enqueues the limit_assets task with the default parameters
 sub enqueue_limit_assets ($self) { $self->enqueue('limit_assets', [], 
{priority => 0, ttl => 172800, limit => 1}) }
 
-sub enqueue_download_jobs ($self, $downloads) {
+sub enqueue_download_jobs ($self, $downloads, $minion_ids = undef) {
     return unless %$downloads;
     # array of hashrefs job_id => id; this is what create needs
     # to create entries in a related table (gru_dependencies)
     for my $url (keys %$downloads) {
         my ($path, $do_extract, $block_job_ids) = @{$downloads->{$url}};
-        $self->enqueue('download_asset', [$url, $path, $do_extract], {priority 
=> 10}, $block_job_ids);
+        my $job = $self->enqueue('download_asset', [$url, $path, $do_extract], 
{priority => 10}, $block_job_ids);
+        push @$minion_ids, $job->{minion_id} if $minion_ids;
     }
 }
 
@@ -253,7 +261,7 @@
     $self->enqueue('git_clone', \%clones, {priority => 10});
 }
 
-sub enqueue_git_clones ($self, $clones, $job_ids) {
+sub enqueue_git_clones ($self, $clones, $job_ids, $minion_ids = undef) {
     return unless keys %$clones;
     return unless OpenQA::App->singleton->config->{'scm 
git'}->{git_auto_clone} eq 'yes';
     # $clones is a hashref with paths as keys and git urls as values
@@ -267,7 +275,10 @@
     }
 
     my $found = $self->_find_existing_minion_job('git_clone', $clones_sr, 
$job_ids);
-    $self->enqueue('git_clone', $clones_sr, {priority => 10}, $job_ids) unless 
$found;
+    return $found if $found;
+    my $job = $self->enqueue('git_clone', $clones_sr, {priority => 10}, 
$job_ids);
+    push @$minion_ids, $job->{minion_id} if $minion_ids;
+    return $job;
 }
 
 sub enqueue_and_keep_track {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1745500773.055f94fe/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm 
new/openQA-5.1746018652.10b1e438/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm
--- old/openQA-5.1745500773.055f94fe/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm 
2025-04-24 15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm 
2025-04-30 15:10:52.000000000 +0200
@@ -316,7 +316,7 @@
 
 =cut
 
-sub _create_job ($self, $global_params, $job_suffix = undef, 
$job_specific_params = {}) {
+sub _create_job ($self, $global_params, $job_suffix, $job_specific_params, 
$minion_ids) {
     # job_create expects upper case keys
     my %up_params = map { uc $_ => $global_params->{$_} } keys %$global_params;
     $up_params{uc $_} = $job_specific_params->{$_} for keys 
%$job_specific_params;
@@ -344,9 +344,9 @@
 
     # enqueue gru jobs and calculate blocked by
     push @{$downloads->{$_}}, [$job_id] for keys %$downloads;
-    $self->gru->enqueue_download_jobs($downloads);
+    $self->gru->enqueue_download_jobs($downloads, $minion_ids);
     my $clones = create_git_clone_list($job_settings);
-    $self->gru->enqueue_git_clones($clones, [$job_id]) if keys %$clones;
+    $self->gru->enqueue_git_clones($clones, [$job_id], $minion_ids) if keys 
%$clones;
     return $job_id;
 }
 
@@ -391,14 +391,14 @@
 
 =cut
 
-sub _create_jobs ($self, $global_params, $grouped_params) {
+sub _create_jobs ($self, $global_params, $grouped_params, $minion_ids) {
     if (keys %$grouped_params) {
         # create as many jobs as unique ":"-suffixes exist
-        $self->_create_job($global_params, $_, $grouped_params->{$_}) for keys 
%$grouped_params;
+        $self->_create_job($global_params, $_, $grouped_params->{$_}, 
$minion_ids) for keys %$grouped_params;
     }
     else {
         # create a single job if there are no job-specific parameters
-        $self->_create_job($global_params);
+        $self->_create_job($global_params, undef, {}, $minion_ids);
     }
     $self->_create_dependencies;
 }
@@ -421,8 +421,12 @@
     my $json = $self->{_json} = {};
     my $event_data = $self->{_event_data} = [];
     my $dependencies = $self->{_dependencies} = [];
+    my @minion_ids;
+    my $gru = OpenQA::App->singleton->gru;
     try {
-        $self->schema->txn_do_retry_on_deadlock(sub { 
$self->_create_jobs($global_params, $grouped_params) });
+        $self->schema->txn_do_retry_on_deadlock(
+            sub { $self->_create_jobs($global_params, $grouped_params, 
\@minion_ids) },
+            sub { $gru->obsolete_minion_jobs(\@minion_ids) });
         OpenQA::Scheduler::Client->singleton->wakeup;
     }
     catch ($e) {
@@ -430,6 +434,7 @@
         $json->{error} = $e;
         delete $json->{id};
         delete $json->{ids};
+        $gru->obsolete_minion_jobs(\@minion_ids);
     }
 
     $self->emit_event(openqa_job_create => $_) for @$event_data;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1745500773.055f94fe/package-lock.json 
new/openQA-5.1746018652.10b1e438/package-lock.json
--- old/openQA-5.1745500773.055f94fe/package-lock.json  2025-04-24 
15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/package-lock.json  2025-04-30 
15:10:52.000000000 +0200
@@ -15,7 +15,7 @@
         "chosen-js": "^1.8.7",
         "d3": "^7.9.0",
         "dagre-d3": "^0.6.4",
-        "datatables.net-bs5": "^2.2.2",
+        "datatables.net-bs5": "^2.3.0",
         "fork-awesome": "^1.2.0",
         "jquery": "^3.7.1",
         "jquery-ujs": "^1.2.3",
@@ -835,21 +835,21 @@
       }
     },
     "node_modules/datatables.net": {
-      "version": "2.2.2",
-      "resolved": 
"https://registry.npmjs.org/datatables.net/-/datatables.net-2.2.2.tgz";,
-      "integrity": 
"sha512-gfODIKE3gpgbVeZy2QGj2Dq9roO6hy00S+k1knklrqlMyAMrh1wt0Q6ryBUM7gU96U77ysbq8dYhxFdmcC/oPQ==",
+      "version": "2.3.0",
+      "resolved": 
"https://registry.npmjs.org/datatables.net/-/datatables.net-2.3.0.tgz";,
+      "integrity": 
"sha512-IX5Dsc7bTNqI3RyT4B7imtFicLMCg7ZLwwx/gvR6cbwYgfG+mLX2KAVm7BNmnwOhUdMMcGSGSE19RpTn31TTGQ==",
       "license": "MIT",
       "dependencies": {
         "jquery": ">=1.7"
       }
     },
     "node_modules/datatables.net-bs5": {
-      "version": "2.2.2",
-      "resolved": 
"https://registry.npmjs.org/datatables.net-bs5/-/datatables.net-bs5-2.2.2.tgz";,
-      "integrity": 
"sha512-0mAbpUf0EpnIEc0RlN6vSrSk9y/+NuReiwDpjHYY3RfzdvH6Lt0+7Q9OU5RIbYxaFxES/z60thxdrw7IUFnBhw==",
+      "version": "2.3.0",
+      "resolved": 
"https://registry.npmjs.org/datatables.net-bs5/-/datatables.net-bs5-2.3.0.tgz";,
+      "integrity": 
"sha512-JvcYrf2kEVzHY7NKsJxV132kehhc5+iRIpZAYmYqSW52yCcMiQYWtw1Z4+Wb/FMbJDQwP9exCtTwroLYPKwkeQ==",
       "license": "MIT",
       "dependencies": {
-        "datatables.net": "2.2.2",
+        "datatables.net": "2.3.0",
         "jquery": ">=1.7"
       }
     },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1745500773.055f94fe/package.json 
new/openQA-5.1746018652.10b1e438/package.json
--- old/openQA-5.1745500773.055f94fe/package.json       2025-04-24 
15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/package.json       2025-04-30 
15:10:52.000000000 +0200
@@ -24,7 +24,7 @@
     "chosen-js": "^1.8.7",
     "d3": "^7.9.0",
     "dagre-d3": "^0.6.4",
-    "datatables.net-bs5": "^2.2.2",
+    "datatables.net-bs5": "^2.3.0",
     "fork-awesome": "^1.2.0",
     "jquery": "^3.7.1",
     "jquery-ujs": "^1.2.3",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1745500773.055f94fe/script/dump-db 
new/openQA-5.1746018652.10b1e438/script/dump-db
--- old/openQA-5.1745500773.055f94fe/script/dump-db     2025-04-24 
15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/script/dump-db     2025-04-30 
15:10:52.000000000 +0200
@@ -2,7 +2,7 @@
 set -euo pipefail
 DUMP_FOLDER=${DUMP_FOLDER:-"/var/lib/openqa/SQL-DUMPS"}
 DAYS_TO_KEEP=${DAYS_TO_KEEP:-"7"}
-[[ $1 = '-h' ]] || [[ $1 = '--help' ]] && echo "Dump the openQA postgresql 
database to ${DUMP_FOLDER} and clean-up backups older than ${DAYS_TO_KEEP} 
days." && exit
+[[ ${1-} = '-h' ]] || [[ ${1-} = '--help' ]] && echo "Dump the openQA 
postgresql database to ${DUMP_FOLDER} and clean-up backups older than 
${DAYS_TO_KEEP} days." && exit
 
-pg_dump -Fc -c openqa -f "${DUMP_FOLDER}/$(date -Idate).dump"
-find "${DUMP_FOLDER}" -mtime "+${DAYS_TO_KEEP}" -print0 -delete
+ionice -c3 nice -n19 pg_dump -Fc -c openqa -f "${DUMP_FOLDER}/$(date 
-Idate).dump"
+find -L "${DUMP_FOLDER}" -type f -mtime "+${DAYS_TO_KEEP}" -print0 -delete
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1745500773.055f94fe/t/14-grutasks.t 
new/openQA-5.1746018652.10b1e438/t/14-grutasks.t
--- old/openQA-5.1745500773.055f94fe/t/14-grutasks.t    2025-04-24 
15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/t/14-grutasks.t    2025-04-30 
15:10:52.000000000 +0200
@@ -626,7 +626,7 @@
 
         $t->app->minion->job($id)->retry({delay => 0});    # retries=6
         perform_minion_jobs($t->app->minion);
-        is $job->info->{state}, 'failed', 'Job finally failed';
+        is $job->info->{state}, 'finished', 'job finished successfully';
         like $job->info->{notes}->{stop_reason}, qr{Could not find GruTask 
'\d+' after 6 retries.*},
           'Message is logged as job result';
         is $job->info->{retries}, 6, 'job retried because there is no GruTasks 
entry';
@@ -864,6 +864,11 @@
     };
 };
 
+subtest 'marking Minion jobs as obsolete' => sub {
+    my $job_id = $app->minion->jobs->next->{id};
+    $app->gru->obsolete_minion_jobs([$job_id]);
+    ok $app->minion->job($job_id)->info->{notes}->{obsolete}, "job $job_id 
marked as obsolete";
+};
 
 done_testing();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1745500773.055f94fe/t/15-assets.t 
new/openQA-5.1746018652.10b1e438/t/15-assets.t
--- old/openQA-5.1745500773.055f94fe/t/15-assets.t      2025-04-24 
15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/t/15-assets.t      2025-04-30 
15:10:52.000000000 +0200
@@ -346,6 +346,9 @@
 };
 
 subtest 'concurrent asset creation' => sub {
+    my $minion = $t->app->minion;
+    $minion->reset({all => 1});
+
     # allow configuring a delay so this test will always trigger the deadlock 
case
     my $delay = $ENV{OPENQA_ASSET_TESTS_DELAY} // 1;
     my $jobs_mock = Test::MockModule->new('OpenQA::Schema::ResultSet::Jobs');
@@ -362,8 +365,8 @@
       = (DISTRI => 'sle', VERSION => '12-SP5', FLAVOR => 'Server-DVD-Updates', 
ARCH => 'x86_64', TEST => 'base');
     my $asset_name_1 = 
'SLES-12-SP5-x86_64-mru-install-desktop-with-addons-Build20250211-1.qcow2';
     my $asset_name_2 = 
'SLES-12-SP5-x86_64-mru-install-desktop-with-addons-Build20250211-2.qcow2';
-    my %settings_1 = (%base_settings, TEST => 'job1', HDD_1 => $asset_name_1);
-    my %settings_2 = (%base_settings, TEST => 'job2', HDD_1 => $asset_name_2);
+    my %settings_1 = (%base_settings, TEST => 'job1', HDD_1 => $asset_name_1, 
HDD_1_URL => "http://foo/$asset_name_1";);
+    my %settings_2 = (%base_settings, TEST => 'job2', HDD_1 => $asset_name_2, 
HDD_1_URL => "http://foo/$asset_name_2";);
 
     # define functions to create jobs using the web API
     my $post_job = sub ($delay, @settings) {
@@ -422,6 +425,22 @@
     subtest 'posting a single set of jobs' => sub { 
$create_jobs->($post_jobs_1, $post_jobs_2) };
     subtest 'scheduling a product' => sub { 
$create_jobs->($schedule_product_1, $schedule_product_2) };
     subtest 'track coverage of helpers' => sub { $_->(0, \%base_settings) for 
$post_job, $schedule_product };
+
+    subtest 'no leftover Minion jobs after handling deadlocks' => sub {
+        my $jobs = $minion->jobs;
+        my $count = 0;
+        my $gru_tasks = $schema->resultset('GruTasks');
+        while (my $info = $jobs->next) {
+            next if $info->{notes}->{obsolete};
+            my $job_id = $info->{id};
+            my $gru_id = $info->{notes}->{gru_id};
+            ++$count;
+            is $info->{task}, 'download_asset', "Minion job $job_id is of 
expected task";
+            ok $gru_tasks->find($gru_id), "Minion job $job_id refers to Gru 
task with valid ID $gru_id"
+              or always_explain $info;
+        }
+        is $count, 8, 'one Minion job per openQA job, excluding obsolete jobs';
+    };
 };
 
 done_testing();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1745500773.055f94fe/tools/ci/run_unit_tests.sh 
new/openQA-5.1746018652.10b1e438/tools/ci/run_unit_tests.sh
--- old/openQA-5.1745500773.055f94fe/tools/ci/run_unit_tests.sh 2025-04-24 
15:19:33.000000000 +0200
+++ new/openQA-5.1746018652.10b1e438/tools/ci/run_unit_tests.sh 2025-04-30 
15:10:52.000000000 +0200
@@ -22,4 +22,5 @@
 export OPENQA_TEST_TIMEOUT_SCALE_CI=3
 export EXTRA_PROVE_ARGS="-v"
 export OPENQA_FULLSTACK_TEMP_DIR=$PWD/test-results/fullstack
+export PROVE="tools/prove_wrapper"
 make test-$target
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1745500773.055f94fe/tools/prove_wrapper 
new/openQA-5.1746018652.10b1e438/tools/prove_wrapper
--- old/openQA-5.1745500773.055f94fe/tools/prove_wrapper        1970-01-01 
01:00:00.000000000 +0100
+++ new/openQA-5.1746018652.10b1e438/tools/prove_wrapper        2025-04-30 
15:10:52.000000000 +0200
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+set -euo pipefail
+
+OUTPUT=$(mktemp)
+
+echo "Running prove with TAP output check ..."
+
+prove "$@" 2>&1 | tee "$OUTPUT"
+STATUS=${PIPESTATUS[0]}
+
+if [ "$STATUS" -ne 0 ]; then
+    echo "not ok - prove failed"
+    exit "$STATUS"
+fi
+
+sed -E '
+  s/^\[[0-9]{2}:[0-9]{2}:[0-9]{2}\][[:space:]]*//
+  /^All tests successful\./,$d
+' "$OUTPUT" > "$OUTPUT.processed"
+
+UNHANDLED=$(grep -vE '^t/.*([0-9]{2}-|)([[:alpha:]]|_|-)+\.t \.+' 
"$OUTPUT.processed" || true)
+
+if [ -n "$UNHANDLED" ]; then
+    echo "not ok - unhandled output found"
+    echo "Run with PROVE_COMMAND=tools/prove_wrapper to reproduce locally"
+    exit 1
+else
+    echo "ok - no unhandled output found"
+    exit 0
+fi

++++++ openQA.obsinfo ++++++
--- /var/tmp/diff_new_pack.8GdElH/_old  2025-05-02 15:02:57.426923236 +0200
+++ /var/tmp/diff_new_pack.8GdElH/_new  2025-05-02 15:02:57.426923236 +0200
@@ -1,5 +1,5 @@
 name: openQA
-version: 5.1745500773.055f94fe
-mtime: 1745500773
-commit: 055f94fee5dbce696c292af7344c2343d96a3852
+version: 5.1746018652.10b1e438
+mtime: 1746018652
+commit: 10b1e43840bddcc9839be91ebb46fb422effe601
 

Reply via email to