Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package openQA for openSUSE:Factory checked in at 2026-09-28 10:40:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openQA (Old) and /work/SRC/openSUSE:Factory/.openQA.new.383539 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openQA" Mon Sep 28 10:40:39 2026 rev:883 rq:1380339 version:5.1790312789.f59cf41c Changes: -------- --- /work/SRC/openSUSE:Factory/openQA/openQA.changes 2026-09-24 23:06:17.827442940 +0200 +++ /work/SRC/openSUSE:Factory/.openQA.new.383539/openQA.changes 2026-09-28 10:41:25.083298740 +0200 @@ -1,0 +2,26 @@ +Fri Sep 25 05:06:40 UTC 2026 - [email protected] + +- Update to version 5.1790312789.f59cf41c: + * chore(deps): Dependency cron 2026-09-25 + * refactor: Reduce parameters of `update_note` + * refactor: Reduce parameters of `job_statistics` + * feat(job-stats): Allow specifying the setting to add additional jobs by + * docs: Update documentation of `/isos/job_stats` after recent changes + * feat: Return only "latest" jobs in `/isos/job_stats` + * feat: Include additional jobs for submission in `/isos/job_stats` + * test(devel-fullstack): Fix waiting for `outstanding_images` + +------------------------------------------------------------------- +Thu Sep 24 19:06:47 UTC 2026 - [email protected] + +- Update to version 5.1790273241.6c254f29: + * refactor: Reduce parameters of `update_note` + * refactor: Reduce parameters of `job_statistics` + * feat(job-stats): Allow specifying the setting to add additional jobs by + * docs: Update documentation of `/isos/job_stats` after recent changes + * feat: Return only "latest" jobs in `/isos/job_stats` + * feat: Include additional jobs for submission in `/isos/job_stats` + * test(devel-fullstack): Fix waiting for `outstanding_images` + * feat(cli): Add worker reservation subcommand + +------------------------------------------------------------------- Old: ---- openQA-5.1790264833.381b79cd.obscpio New: ---- openQA-5.1790312789.f59cf41c.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openQA-client-test.spec ++++++ --- /var/tmp/diff_new_pack.1GbCbZ/_old 2026-09-28 10:41:27.849414731 +0200 +++ /var/tmp/diff_new_pack.1GbCbZ/_new 2026-09-28 10:41:27.850414773 +0200 @@ -18,7 +18,7 @@ %define short_name openQA-client Name: %{short_name}-test -Version: 5.1790264833.381b79cd +Version: 5.1790312789.f59cf41c Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA-devel-test.spec ++++++ --- /var/tmp/diff_new_pack.1GbCbZ/_old 2026-09-28 10:41:27.921417751 +0200 +++ /var/tmp/diff_new_pack.1GbCbZ/_new 2026-09-28 10:41:27.923417835 +0200 @@ -18,7 +18,7 @@ %define short_name openQA-devel Name: %{short_name}-test -Version: 5.1790264833.381b79cd +Version: 5.1790312789.f59cf41c Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA-test.spec ++++++ --- /var/tmp/diff_new_pack.1GbCbZ/_old 2026-09-28 10:41:27.987420518 +0200 +++ /var/tmp/diff_new_pack.1GbCbZ/_new 2026-09-28 10:41:27.991420686 +0200 @@ -18,7 +18,7 @@ %define short_name openQA Name: %{short_name}-test -Version: 5.1790264833.381b79cd +Version: 5.1790312789.f59cf41c Release: 0 Summary: Test package for openQA License: GPL-2.0-or-later ++++++ openQA-worker-test.spec ++++++ --- /var/tmp/diff_new_pack.1GbCbZ/_old 2026-09-28 10:41:28.054423328 +0200 +++ /var/tmp/diff_new_pack.1GbCbZ/_new 2026-09-28 10:41:28.059423538 +0200 @@ -18,7 +18,7 @@ %define short_name openQA-worker Name: %{short_name}-test -Version: 5.1790264833.381b79cd +Version: 5.1790312789.f59cf41c Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA.spec ++++++ --- /var/tmp/diff_new_pack.1GbCbZ/_old 2026-09-28 10:41:28.117425970 +0200 +++ /var/tmp/diff_new_pack.1GbCbZ/_new 2026-09-28 10:41:28.124426263 +0200 @@ -104,7 +104,7 @@ %define devel_requires %devel_no_selenium_requires chromedriver Name: openQA -Version: 5.1790264833.381b79cd +Version: 5.1790312789.f59cf41c Release: 0 Summary: Framework for automated system-level testing (web-frontend, scheduler and tools) Group: Development/Tools/Other ++++++ openQA-5.1790264833.381b79cd.obscpio -> openQA-5.1790312789.f59cf41c.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1790264833.381b79cd/lib/OpenQA/Schema/ResultSet/ScheduledProducts.pm new/openQA-5.1790312789.f59cf41c/lib/OpenQA/Schema/ResultSet/ScheduledProducts.pm --- old/openQA-5.1790264833.381b79cd/lib/OpenQA/Schema/ResultSet/ScheduledProducts.pm 2026-09-24 17:47:13.000000000 +0200 +++ new/openQA-5.1790312789.f59cf41c/lib/OpenQA/Schema/ResultSet/ScheduledProducts.pm 2026-09-25 07:06:29.000000000 +0200 @@ -5,6 +5,7 @@ use Mojo::Base 'DBIx::Class::ResultSet', -signatures; use Mojo::JSON qw(encode_json); +use OpenQA::Schema::Result::Jobs; use OpenQA::Schema::Result::ScheduledProducts qw(CANCELLED); use OpenQA::App; @@ -31,7 +32,7 @@ return {jobs_cancelled => $count}; } -sub update_note ($self, $distri, $version, $flavor, $arch, $build, $note) { +sub update_note ($self, $params, $note) { my $sth = $self->result_source->schema->storage->dbh->prepare( <<~'END_SQL' UPDATE scheduled_products SET results['note'] = ? where id = ( @@ -43,17 +44,13 @@ ) RETURNING id; END_SQL ); - $sth->bind_param(1, encode_json($note)); - $sth->bind_param(2, $distri); - $sth->bind_param(3, $version); - $sth->bind_param(4, $flavor); - $sth->bind_param(5, $arch); - $sth->bind_param(6, $build); - $sth->execute; + $sth->execute(encode_json($note), @$params); return {updated_product_id => $sth->fetchrow_arrayref->[0]}; } -sub job_statistics ($self, $distri, $version, $flavor, $arch, $build, $group_ids = undef, $include_null_groups = 0) { +my $MAIN_SETTINGS_GROUP_BY = join ',', OpenQA::Schema::Result::Jobs::MAIN_SETTINGS; + +sub job_statistics ($self, $params, $group_ids, $include_null_groups) { my $group_filter = ''; my @binds; if ($group_ids && @$group_ids) { @@ -64,6 +61,22 @@ my $sth = $self->result_source->schema->storage->dbh->prepare( <<~"END_SQL" WITH RECURSIVE + -- get the scheduled product + most_recent_scheduled_product AS ( + SELECT + max(id) as id, + max(t_created) as t_created, + any_value(settings ->> ?) as submission_id + FROM + scheduled_products + WHERE + status in ('new', 'scheduling', 'scheduled') and distri = ? and version = ? and flavor = ? and arch = ? and build = ? + GROUP BY + arch + ORDER BY + id DESC + LIMIT 1 + ), -- get the initial set of jobs in the scheduled product initial_job_ids AS ( SELECT @@ -72,16 +85,19 @@ FROM jobs WHERE - jobs.scheduled_product_id in ( - SELECT - max(id) - FROM - scheduled_products - WHERE - status in ('new', 'scheduling', 'scheduled') and distri = ? and version = ? and flavor = ? and arch = ? and build = ? - GROUP BY - arch - ) + jobs.scheduled_product_id in (SELECT id FROM most_recent_scheduled_product) + UNION ALL + SELECT + job_settings.job_id AS job_id, + null AS scheduled_product_id + FROM + job_settings + JOIN + jobs ON jobs.id = job_settings.job_id + WHERE + key = ? and value = (SELECT submission_id FROM most_recent_scheduled_product) + and jobs.t_created >= (SELECT t_created FROM most_recent_scheduled_product) + and distri = ? and version = ? and flavor = ? and arch = ? and build = ? ), -- find more recent jobs for each initial job recursively latest_id_resolver AS ( @@ -112,6 +128,7 @@ SELECT DISTINCT ON (job_id) job_id as initial_job_id, latest_job_id, + $MAIN_SETTINGS_GROUP_BY, mrj.state as latest_job_state, mrj.result as latest_job_result, mrj.scheduled_product_id as scheduled_product_id, @@ -123,16 +140,28 @@ latest_job_id IS NOT NULL $group_filter ORDER BY - job_id, + job_id DESC, $MAIN_SETTINGS_GROUP_BY, level DESC + ), + -- deduplicated jobs by $MAIN_SETTINGS_GROUP_BY returning only the "latest" + deduplicated_jobs AS ( + SELECT DISTINCT ON ($MAIN_SETTINGS_GROUP_BY) + latest_job_id, + latest_job_state, + latest_job_result, + scheduled_product_id, + $MAIN_SETTINGS_GROUP_BY + FROM most_recent_jobs + ORDER BY $MAIN_SETTINGS_GROUP_BY, latest_job_id DESC ) SELECT latest_job_state, latest_job_result, array_agg(latest_job_id) as job_ids, - array_agg(DISTINCT scheduled_product_id) as scheduled_product_ids + array_agg(DISTINCT scheduled_product_id) as scheduled_product_ids, + (SELECT submission_id from most_recent_scheduled_product) FROM - most_recent_jobs + deduplicated_jobs WHERE latest_job_id IS NOT NULL GROUP BY @@ -140,7 +169,7 @@ latest_job_result END_SQL ); - $sth->execute($distri, $version, $flavor, $arch, $build, @binds); + $sth->execute((@$params) x 2, @binds); return $sth->fetchall_hashref([qw(latest_job_state latest_job_result)]); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1790264833.381b79cd/lib/OpenQA/WebAPI/Controller/API/V1/Iso.pm new/openQA-5.1790312789.f59cf41c/lib/OpenQA/WebAPI/Controller/API/V1/Iso.pm --- old/openQA-5.1790264833.381b79cd/lib/OpenQA/WebAPI/Controller/API/V1/Iso.pm 2026-09-24 17:47:13.000000000 +0200 +++ new/openQA-5.1790312789.f59cf41c/lib/OpenQA/WebAPI/Controller/API/V1/Iso.pm 2026-09-25 07:06:29.000000000 +0200 @@ -66,8 +66,8 @@ specified DISTRI, VERSION, FLAVOR, ARCH and BUILD parameters. Scheduled products that are cancelling/cancelled are not considered. -This allows to determine whether all jobs that have been scheduled for a -certain purpose are done and whether the jobs have passed. If jobs have been +This allows determining whether all jobs that have been scheduled for a certain +purpose are done and whether the jobs have passed. If jobs have been cloned/restarted then only the state/result of the latest job is taken into account. @@ -86,6 +86,13 @@ product IDs for each combination are mainly returned for easier retracing but could also be used to generate a more detailed report. +If a scheduled product has a SUBMISSION_ID setting (or the setting specified via +`additional_jobs_by`), additional jobs that have been created with that setting +are returned as well. + +Jobs are deduplicated by their main settings like with `/jobs?latest` (see +documentation of that route for details). + =back =cut @@ -98,7 +105,8 @@ my $include_null_groups = ($self->validation->param('not_group_glob') && !$self->validation->param('group_glob')) ? 1 : 0; my $scheduled_products = $self->app->schema->resultset('ScheduledProducts'); - $self->render(json => $scheduled_products->job_statistics(@$params, $group_ids, $include_null_groups)); + unshift @$params, $self->param('additional_jobs_by') // 'SUBMISSION_ID'; + $self->render(json => $scheduled_products->job_statistics($params, $group_ids, $include_null_groups)); } =over 4 @@ -119,7 +127,7 @@ $validation->required('note'); return undef unless my $params = $self->_get_iso_params_and_validate; my $scheduled_products = $self->app->schema->resultset('ScheduledProducts'); - $self->render(json => $scheduled_products->update_note(@$params, $validation->param('note'))); + $self->render(json => $scheduled_products->update_note($params, $validation->param('note'))); } sub validate_create_parameters ($self) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1790264833.381b79cd/t/api/02-iso.t new/openQA-5.1790312789.f59cf41c/t/api/02-iso.t --- old/openQA-5.1790264833.381b79cd/t/api/02-iso.t 2026-09-24 17:47:13.000000000 +0200 +++ new/openQA-5.1790312789.f59cf41c/t/api/02-iso.t 2026-09-25 07:06:29.000000000 +0200 @@ -10,6 +10,7 @@ use lib "$FindBin::Bin/../lib", "$FindBin::Bin/../../external/os-autoinst-common/lib"; use Test::Mojo; use Test::Warnings ':report_warnings'; +use DateTime::Duration; use OpenQA::Jobs::Constants; use OpenQA::JobDependencies::Constants; use OpenQA::Test::TimeLimit '300'; @@ -27,6 +28,7 @@ my $products = $schema->resultset('Products'); my $test_suites = $schema->resultset('TestSuites'); my $jobs = $schema->resultset('Jobs'); +my $job_settings = $schema->resultset('JobSettings'); my $scheduled_products = $schema->resultset('ScheduledProducts'); my $gru_tasks = $schema->resultset('GruTasks'); my $limits = $cfg->{misc_limits}; @@ -319,20 +321,61 @@ subtest 'job statistics can be queried about the scheduled product' => sub { $schema->txn_begin; # assume some of the scheduled jobs are already done + my $scheduled_product = $scheduled_products->find(4); + my $second = DateTime::Duration->new(seconds => 1); + my @params = (DISTRI => 'opensuse', VERSION => '13.1', FLAVOR => 'DVD', ARCH => 'i586', BUILD => '0091'); $jobs->find(99985)->update({state => DONE, result => INCOMPLETE}); $jobs->find(99988)->update({state => DONE, result => FAILED}); - $jobs->find(99993)->update({state => DONE, result => PASSED}); - $jobs->find(99994)->update({state => DONE, result => PASSED}); + $jobs->find(99993)->update({state => DONE, result => PASSED, TEST => 'foo'}); + $jobs->find(99994)->update({state => DONE, result => PASSED, TEST => 'foo'}); + $jobs->find(80000)->update({@params, t_created => $scheduled_product->t_created - $second}); # older than sp + $jobs->find(99764)->update({@params, t_created => $scheduled_product->t_created + $second}); # newer than sp + $job_settings->create({job_id => 80000, key => 'SUBMISSION_ID', value => 'increment:1234'}); + $job_settings->create({job_id => 99764, key => 'SUBMISSION_ID', value => 'increment:1234'}); + $t->get_ok("/api/v1/isos/job_stats?$params")->status_is(200); - $schema->txn_rollback; my $json = $t->tx->res->json; is_deeply [sort keys %$json], [DONE, SCHEDULED], 'expected states present'; is_deeply [sort keys %{$json->{done}}], [FAILED, INCOMPLETE, PASSED], 'expected results present'; is_deeply [sort @{$json->{done}->{failed}->{job_ids}}], [99988], 'failed jobs'; is_deeply [sort @{$json->{done}->{incomplete}->{job_ids}}], [99985], 'incomplete jobs'; - is_deeply [sort @{$json->{done}->{passed}->{job_ids}}], [99993, 99994], 'passed jobs'; + is_deeply [sort @{$json->{done}->{passed}->{job_ids}}], [99994], 'passed jobs'; is_deeply [sort @{$json->{scheduled}->{none}->{job_ids}}], [99986, 99987, 99989, 99990, 99991, 99992], 'scheduled jobs'; + + subtest 'additional jobs for submission are pulled-in via SUBMISSION_ID' => sub { + $scheduled_product->update_setting(SUBMISSION_ID => 'increment:1234'); + $t->get_ok("/api/v1/isos/job_stats?$params")->status_is(200); + my $json = $t->tx->res->json; + is_deeply [sort keys %$json], [DONE, SCHEDULED], 'expected states present'; + is_deeply [sort keys %{$json->{done}}], [FAILED, INCOMPLETE, PASSED], 'expected results present'; + is_deeply [sort @{$json->{done}->{passed}->{job_ids}}], [99764, 99994], + 'passed jobs: job newer than sp with matching SUBMISSION_ID included'; + is_deeply [sort @{$json->{done}->{failed}->{job_ids}}], [99988], 'failed jobs'; + is_deeply [sort @{$json->{done}->{incomplete}->{job_ids}}], [99985], 'incomplete jobs'; + is_deeply [sort @{$json->{scheduled}->{none}->{job_ids}}], [99986, 99987, 99989, 99990, 99991, 99992], + 'scheduled jobs'; + }; + + subtest 'additional jobs can be pulled-in via custom setting using additional_jobs_by' => sub { + $scheduled_product->update_setting(SUBMISSION_ID => 'different_val'); + $scheduled_product->update_setting(REQUEST_ID => 'req:42'); + $job_settings->create({job_id => 99764, key => 'REQUEST_ID', value => 'req:42'}); + + # without additional_jobs_by, default SUBMISSION_ID is used and doesn't match + $t->get_ok("/api/v1/isos/job_stats?$params")->status_is(200); + my $json = $t->tx->res->json; + is_deeply [sort @{$json->{done}->{passed}->{job_ids}}], [99994], + 'job 99764 not included because SUBMISSION_ID does not match'; + + # with additional_jobs_by=REQUEST_ID, REQUEST_ID matches + $t->get_ok("/api/v1/isos/job_stats?$params&additional_jobs_by=REQUEST_ID")->status_is(200); + $json = $t->tx->res->json; + is_deeply [sort @{$json->{done}->{passed}->{job_ids}}], [99764, 99994], + 'passed jobs: job newer than sp with matching REQUEST_ID included via additional_jobs_by'; + }; + + $schema->txn_rollback; }; subtest 'job statistics can be filtered by job groups' => sub { @@ -362,7 +405,6 @@ $schema->txn_rollback; }; - subtest 'note can be updated by distri, version, flavor, arch and build parameters' => sub { $t->put_ok("/api/v1/experimental/isos/note?$params"); $t->status_is(400, 'error returned if parameter missing'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1790264833.381b79cd/tools/ci/autoinst.sha new/openQA-5.1790312789.f59cf41c/tools/ci/autoinst.sha --- old/openQA-5.1790264833.381b79cd/tools/ci/autoinst.sha 2026-09-24 17:47:13.000000000 +0200 +++ new/openQA-5.1790312789.f59cf41c/tools/ci/autoinst.sha 2026-09-25 07:06:29.000000000 +0200 @@ -1 +1 @@ -5.044000-282ca44441fdf0dfd37891bdf1d73c35bfc152de \ No newline at end of file +5.044000-67006216e29f8e8655bad025ea594b14fd2eaf79 \ No newline at end of file ++++++ openQA.obsinfo ++++++ --- /var/tmp/diff_new_pack.1GbCbZ/_old 2026-09-28 10:41:35.645741653 +0200 +++ /var/tmp/diff_new_pack.1GbCbZ/_new 2026-09-28 10:41:35.649741820 +0200 @@ -1,5 +1,5 @@ name: openQA -version: 5.1790264833.381b79cd -mtime: 1790264833 -commit: 381b79cd3be82c79d4499f5b7b66242a550ef46d +version: 5.1790312789.f59cf41c +mtime: 1790312789 +commit: f59cf41c9b1df25ef268f9beb77753a2fd8b132f
