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-03-04 21:05:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openQA (Old) and /work/SRC/openSUSE:Factory/.openQA.new.561 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openQA" Wed Mar 4 21:05:47 2026 rev:816 rq:1336150 version:5.1772550094.48b5cce5 Changes: -------- --- /work/SRC/openSUSE:Factory/openQA/openQA.changes 2026-03-03 15:32:04.243864105 +0100 +++ /work/SRC/openSUSE:Factory/.openQA.new.561/openQA.changes 2026-03-04 21:06:12.754899919 +0100 @@ -1,0 +2,21 @@ +Tue Mar 03 15:10:02 UTC 2026 - [email protected] + +- Update to version 5.1772550094.48b5cce5: + * refactor: Improve code for testing OpenID auth + * test: Consider everything under `lib/OpenQA/WebAPI/` covered + * test: Cover all code for OpenID auth + * test: Cover retrying of OBS rsync tasks + * fix: Return correctly when OBS dirty status cannot be determined + * refactor: Remove unused local variable in OBS rsync code + * test: Cover parameter validation warnings code for API descriptions + * fix(config): Drop max_conns to allow proper queueing + * refactor: Improve code in `renderTestLists()` + * feat: Pass all parameters when making AJAX requests on "All tests" page + * feat: Allow use of `job_setting` parameter also on "All tests" page + * refactor: Simplify code for passing query parameters on "All tests" + * fix(dependencies): add missing "make" to devel sub-package + * test: remove stabilized tests from tools/unstable_tests.txt + * test(lib): remove unused "disconnect" function + * test(lib): mark uncovered line + +------------------------------------------------------------------- Old: ---- openQA-5.1772475695.6c6c7eda.obscpio New: ---- openQA-5.1772550094.48b5cce5.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openQA-client-test.spec ++++++ --- /var/tmp/diff_new_pack.VAvh2Z/_old 2026-03-04 21:06:14.910989004 +0100 +++ /var/tmp/diff_new_pack.VAvh2Z/_new 2026-03-04 21:06:14.914989169 +0100 @@ -18,7 +18,7 @@ %define short_name openQA-client Name: %{short_name}-test -Version: 5.1772475695.6c6c7eda +Version: 5.1772550094.48b5cce5 Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA-devel-test.spec ++++++ --- /var/tmp/diff_new_pack.VAvh2Z/_old 2026-03-04 21:06:14.942990326 +0100 +++ /var/tmp/diff_new_pack.VAvh2Z/_new 2026-03-04 21:06:14.946990491 +0100 @@ -18,7 +18,7 @@ %define short_name openQA-devel Name: %{short_name}-test -Version: 5.1772475695.6c6c7eda +Version: 5.1772550094.48b5cce5 Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA-test.spec ++++++ --- /var/tmp/diff_new_pack.VAvh2Z/_old 2026-03-04 21:06:14.974991648 +0100 +++ /var/tmp/diff_new_pack.VAvh2Z/_new 2026-03-04 21:06:14.974991648 +0100 @@ -18,7 +18,7 @@ %define short_name openQA Name: %{short_name}-test -Version: 5.1772475695.6c6c7eda +Version: 5.1772550094.48b5cce5 Release: 0 Summary: Test package for openQA License: GPL-2.0-or-later ++++++ openQA-worker-test.spec ++++++ --- /var/tmp/diff_new_pack.VAvh2Z/_old 2026-03-04 21:06:15.014993301 +0100 +++ /var/tmp/diff_new_pack.VAvh2Z/_new 2026-03-04 21:06:15.014993301 +0100 @@ -18,7 +18,7 @@ %define short_name openQA-worker Name: %{short_name}-test -Version: 5.1772475695.6c6c7eda +Version: 5.1772550094.48b5cce5 Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA.spec ++++++ --- /var/tmp/diff_new_pack.VAvh2Z/_old 2026-03-04 21:06:15.054994954 +0100 +++ /var/tmp/diff_new_pack.VAvh2Z/_new 2026-03-04 21:06:15.054994954 +0100 @@ -94,12 +94,12 @@ # The following line is generated from dependencies.yaml %define cover_requires perl(Devel::Cover) perl(Devel::Cover::Report::Codecovbash) # The following line is generated from dependencies.yaml -%define devel_no_selenium_requires %build_requires %cover_requires %qemu %style_check_requires %test_requires curl perl(Perl::Tidy) perl(Test::CheckGitStatus) postgresql-devel rsync sudo tar xorg-x11-fonts +%define devel_no_selenium_requires %build_requires %cover_requires %qemu %style_check_requires %test_requires curl make perl(Perl::Tidy) perl(Test::CheckGitStatus) postgresql-devel rsync sudo tar xorg-x11-fonts # The following line is generated from dependencies.yaml %define devel_requires %devel_no_selenium_requires chromedriver Name: openQA -Version: 5.1772475695.6c6c7eda +Version: 5.1772550094.48b5cce5 Release: 0 Summary: The openQA web-frontend, scheduler and tools License: GPL-2.0-or-later ++++++ openQA-5.1772475695.6c6c7eda.obscpio -> openQA-5.1772550094.48b5cce5.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/.circleci/config.yml new/openQA-5.1772550094.48b5cce5/.circleci/config.yml --- old/openQA-5.1772475695.6c6c7eda/.circleci/config.yml 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/.circleci/config.yml 2026-03-03 16:01:34.000000000 +0100 @@ -301,10 +301,10 @@ - ui: <<: *requires # put unstable tests in tools/unstable_tests.txt and uncomment if necessary to handle with retries - - unstable: - requires: - - cache - - cache-npm + # - unstable: + # requires: + # - cache + # - cache-npm - cache-fullstack: <<: *requires - fullstack: &requires_fullstack @@ -319,7 +319,7 @@ - heavy - api - ui - - unstable + # - unstable - fullstack - fullstack-unstable - build-docs: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/assets/javascripts/tests.js new/openQA-5.1772550094.48b5cce5/assets/javascripts/tests.js --- old/openQA-5.1772475695.6c6c7eda/assets/javascripts/tests.js 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/assets/javascripts/tests.js 2026-03-03 16:01:34.000000000 +0100 @@ -251,18 +251,14 @@ function renderTestLists() { // determine params for AJAX queries - var pageQueryParams = parseQueryParams(); - var ajaxQueryParams = {}; - ajaxQueryParams.addFirstParam = function (paramName) { - var paramValues = pageQueryParams[paramName]; - if (paramValues && paramValues.length > 0) { - this[paramName] = paramValues[0]; + const pageQueryParams = parseQueryParams(); + const ajaxQueryParams = new URLSearchParams(); + ['limit', 'groupid', 'match', 'group_glob', 'not_group_glob', 'comment', 'job_setting'].forEach(paramName => { + const paramValues = pageQueryParams[paramName]; + if (Array.isArray(paramValues)) { + paramValues.forEach(paramValue => ajaxQueryParams.append(paramName, paramValue)); } - }; - jQuery.each(['limit', 'groupid', 'match', 'group_glob', 'not_group_glob', 'comment'], (index, paramName) => { - ajaxQueryParams.addFirstParam(paramName); }); - delete ajaxQueryParams.addFirstParam; filters.forEach(filter => { const param = pageQueryParams[filter]; if (Array.isArray(param)) { @@ -271,11 +267,10 @@ }); // initialize data tables for running, scheduled and finished jobs - var runningTable = $('#running').DataTable({ + $('#running').DataTable({ order: [], // no initial resorting ajax: { - url: urlWithBase('/tests/list_running_ajax'), - data: ajaxQueryParams, + url: urlWithBase('/tests/list_running_ajax?') + ajaxQueryParams.toString(), dataSrc: function (json) { // update heading when JSON is available let text = json.data.length + ' jobs are running'; @@ -309,20 +304,19 @@ } ] }); - var scheduledTable = $('#scheduled').DataTable({ + $('#scheduled').DataTable({ order: [], // no initial resorting ajax: { - url: urlWithBase('/tests/list_scheduled_ajax'), - data: ajaxQueryParams, + url: urlWithBase('/tests/list_scheduled_ajax?') + ajaxQueryParams.toString(), dataSrc: function (json) { // update heading when JSON is available - var blockedCount = 0; + let blockedCount = 0; jQuery.each(json.data, function (index, row) { if (typeof row.blocked_by_id === 'number') { ++blockedCount; } }); - var text = json.data.length + ' scheduled jobs'; + let text = json.data.length + ' scheduled jobs'; if (blockedCount > 0) { text += ' (' + blockedCount + ' blocked by other jobs)'; } @@ -353,19 +347,19 @@ } ] }); - var table = $('#results').DataTable({ + const makeAjaxUrlWithFiltering = () => { + filters.forEach(filter => { + ajaxQueryParams.set(filter, document.getElementById(filter + 'filter').checked ? 1 : 0); + }); + return urlWithBase('/tests/list_ajax?') + ajaxQueryParams.toString(); + }; + const table = $('#results').DataTable({ lengthMenu: [ [10, 25, 50], [10, 25, 50] ], ajax: { - url: urlWithBase('/tests/list_ajax'), - data: function () { - filters.forEach(filter => { - ajaxQueryParams[filter] = document.getElementById(filter + 'filter').checked ? 1 : 0; - }); - return ajaxQueryParams; - }, + url: makeAjaxUrlWithFiltering(), dataSrc: function (json) { // update heading when JSON is available $('#finished_jobs_heading').text('Last ' + json.data.length + ' finished jobs'); @@ -399,18 +393,21 @@ // register event listener to the two range filtering inputs to redraw on input filters.forEach(filter => { - document.getElementById(filter + 'filter').onchange = () => table.ajax.reload(); + document.getElementById(filter + 'filter').onchange = () => { + table.ajax.url(makeAjaxUrlWithFiltering()); + table.ajax.reload(); + }; }); // initialize filter for result (of finished jobs) as chosen - var finishedJobsResultFilter = $('#finished-jobs-result-filter'); + const finishedJobsResultFilter = $('#finished-jobs-result-filter'); finishedJobsResultFilter.chosen(); // ensure the table is re-drawn when a filter is added/removed finishedJobsResultFilter.change(function (event) { // update data table table.draw(); // update query params - var params = parseQueryParams(); + const params = parseQueryParams(); params.resultfilter = finishedJobsResultFilter.val(); updateQueryParams(params); }); @@ -444,7 +441,7 @@ }); // apply filter from query params - var filter = parseQueryParams().resultfilter; + const filter = parseQueryParams().resultfilter; if (filter) { finishedJobsResultFilter.val(filter).trigger('chosen:updated').trigger('change'); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/codecov.yml new/openQA-5.1772550094.48b5cce5/codecov.yml --- old/openQA-5.1772475695.6c6c7eda/codecov.yml 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/codecov.yml 2026-03-03 16:01:34.000000000 +0100 @@ -23,7 +23,7 @@ - lib/OpenQA/Worker/ - lib/OpenQA/Worker.pm - lib/OpenQA/Utils.pm - - lib/OpenQA/WebAPI/Controller/ + - lib/OpenQA/WebAPI/ - lib/OpenQA/Shared/ - lib/OpenQA/Task/ tests: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/dependencies.yaml new/openQA-5.1772550094.48b5cce5/dependencies.yaml --- old/openQA-5.1772475695.6c6c7eda/dependencies.yaml 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/dependencies.yaml 2026-03-03 16:01:34.000000000 +0100 @@ -78,6 +78,7 @@ '%qemu': '%cover_requires': curl: + make: rsync: postgresql-devel: sudo: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/dist/rpm/openQA.spec new/openQA-5.1772550094.48b5cce5/dist/rpm/openQA.spec --- old/openQA-5.1772475695.6c6c7eda/dist/rpm/openQA.spec 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/dist/rpm/openQA.spec 2026-03-03 16:01:34.000000000 +0100 @@ -94,7 +94,7 @@ # The following line is generated from dependencies.yaml %define cover_requires perl(Devel::Cover) perl(Devel::Cover::Report::Codecovbash) # The following line is generated from dependencies.yaml -%define devel_no_selenium_requires %build_requires %cover_requires %qemu %style_check_requires %test_requires curl perl(Perl::Tidy) perl(Test::CheckGitStatus) postgresql-devel rsync sudo tar xorg-x11-fonts +%define devel_no_selenium_requires %build_requires %cover_requires %qemu %style_check_requires %test_requires curl make perl(Perl::Tidy) perl(Test::CheckGitStatus) postgresql-devel rsync sudo tar xorg-x11-fonts # The following line is generated from dependencies.yaml %define devel_requires %devel_no_selenium_requires chromedriver diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/etc/nginx/vhosts.d/openqa-upstreams.inc new/openQA-5.1772550094.48b5cce5/etc/nginx/vhosts.d/openqa-upstreams.inc --- old/openQA-5.1772475695.6c6c7eda/etc/nginx/vhosts.d/openqa-upstreams.inc 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/etc/nginx/vhosts.d/openqa-upstreams.inc 2026-03-03 16:01:34.000000000 +0100 @@ -1,7 +1,7 @@ upstream webui { zone upstream_webui 128k; - # max_conns should match -w (worker/prefork count) in scripts/openqa-webui-daemon - server [::1]:9526 max_conns=30; + # never mark upstream as broken, just pass what it gives us to the client and let it decide + server [::1]:9526 max_fails=0; } upstream websocket { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/lib/OpenQA/WebAPI/Controller/Test.pm new/openQA-5.1772550094.48b5cce5/lib/OpenQA/WebAPI/Controller/Test.pm --- old/openQA-5.1772475695.6c6c7eda/lib/OpenQA/WebAPI/Controller/Test.pm 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/lib/OpenQA/WebAPI/Controller/Test.pm 2026-03-03 16:01:34.000000000 +0100 @@ -209,6 +209,7 @@ my $scope = $self->param('relevant'); $scope = $scope && $scope ne 'false' && $scope ne '0' ? 'relevant' : ''; my $limits = OpenQA::App->singleton->config->{misc_limits}; + $self->validation->optional('job_setting', 'not_empty')->like(qr/.+=.*/); my @jobs = $self->schema->resultset('Jobs')->complex_query( state => [OpenQA::Jobs::Constants::FINAL_STATES], scope => $scope, @@ -220,6 +221,7 @@ $self->param('limit') // $limits->{all_tests_default_finished_jobs} ), order_by => \'COALESCE(me.t_finished, me.t_updated) DESC, me.id DESC', + job_settings => $self->every_key_value_param('job_setting'), columns => [ qw(id MACHINE DISTRI VERSION FLAVOR ARCH BUILD TEST state clone_id result group_id t_finished t_updated @@ -288,12 +290,14 @@ } sub list_running_ajax ($self) { + $self->validation->optional('job_setting', 'not_empty')->like(qr/.+=.*/); my $running = $self->schema->resultset('Jobs')->complex_query( state => [OpenQA::Jobs::Constants::EXECUTION_STATES], match => $self->get_match_param, comment_text => $self->param('comment'), groupid => $self->param('groupid'), order_by => [{-desc => 'me.t_started'}, {-desc => 'me.id'}], + job_settings => $self->every_key_value_param('job_setting'), columns => [ qw(id MACHINE DISTRI VERSION FLAVOR ARCH BUILD TEST state result clone_id group_id t_started blocked_by_id priority @@ -334,6 +338,7 @@ sub list_scheduled_ajax ($self) { my $limits = OpenQA::App->singleton->config->{misc_limits}; my $limit = min($limits->{generic_max_limit}, $self->param('limit') // $limits->{generic_default_limit}); + $self->validation->optional('job_setting', 'not_empty')->like(qr/.+=.*/); my $scheduled = $self->schema->resultset('Jobs')->complex_query( state => [OpenQA::Jobs::Constants::PRE_EXECUTION_STATES], @@ -341,6 +346,7 @@ comment_text => $self->param('comment'), groupid => $self->param('groupid'), order_by => [{-desc => 'me.t_created'}, {-desc => 'me.id'}], + job_settings => $self->every_key_value_param('job_setting'), columns => [ qw(id MACHINE DISTRI VERSION FLAVOR ARCH BUILD TEST state clone_id result group_id t_created diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/lib/OpenQA/WebAPI/Plugin/ObsRsync/Task.pm new/openQA-5.1772550094.48b5cce5/lib/OpenQA/WebAPI/Plugin/ObsRsync/Task.pm --- old/openQA-5.1772475695.6c6c7eda/lib/OpenQA/WebAPI/Plugin/ObsRsync/Task.pm 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/lib/OpenQA/WebAPI/Plugin/ObsRsync/Task.pm 2026-03-03 16:01:34.000000000 +0100 @@ -42,7 +42,6 @@ my $project = $args->{project}; my $helper = $app->obs_rsync; my $home = $helper->home; - my $queue_limit = $helper->queue_limit; my $retry_interval_on_exception = 120; my $retry_max_count_on_exception = 200; @@ -54,7 +53,7 @@ my $dirty = 0; try { $dirty = $helper->is_status_dirty($project, 1) } catch ($e) { - _retry_or_finish($job, $helper, $project, $retry_interval_on_exception, $retry_max_count_on_exception) + return _retry_or_finish($job, $helper, $project, $retry_interval_on_exception, $retry_max_count_on_exception); } return _retry_or_finish($job, $helper, $project) if $dirty; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/script/openqa-webui-daemon new/openQA-5.1772550094.48b5cce5/script/openqa-webui-daemon --- old/openQA-5.1772475695.6c6c7eda/script/openqa-webui-daemon 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/script/openqa-webui-daemon 2026-03-03 16:01:34.000000000 +0100 @@ -17,7 +17,7 @@ # start openQA in the background # note: Our API commands are very expensive, so the default timeouts are too tight. - # note: -w (workers/preforks) should match max_conns in /etc/nginx/vhosts.d/openqa-upstreams.inc + # note: Despite -w (workers/preforks) beeing rather low, nginx will queue connections for us "$openqa_dir"/openqa prefork -m "$OPENQA_WEBUI_MODE" --proxy -i 100 -H 900 -w 30 -c 1 -G 800 -P "$pid_file" "${openqa_args[@]}" & pid=$! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/t/03-auth-openid.t new/openQA-5.1772550094.48b5cce5/t/03-auth-openid.t --- old/openQA-5.1772475695.6c6c7eda/t/03-auth-openid.t 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/t/03-auth-openid.t 2026-03-03 16:01:34.000000000 +0100 @@ -6,51 +6,71 @@ use Test::Warnings ':report_warnings'; use Test::MockModule; use Test::MockObject; +use Test::Output 'combined_like'; use FindBin; use lib "$FindBin::Bin/lib", "$FindBin::Bin/../external/os-autoinst-common/lib"; use OpenQA::Test::TimeLimit '10'; use OpenQA::WebAPI::Auth::OpenID; - +use Mojo::Headers; +use Mojo::URL; is OpenQA::WebAPI::Auth::OpenID::_first_last_name({'value.firstname' => 'Mordred'}), 'Mordred ', '_first_last_name concats also with empty fields'; + my (%openid_res, %openid_res2); my $vident = Test::MockObject->new->set_series('signed_extension_fields', \%openid_res, \%openid_res2); my $user = $vident->{identity} = 'mordred'; my $users = Test::MockObject->new->set_always('create_user', 1); my $schema = Test::MockObject->new->set_always(resultset => $users); my %session; -my $c = Test::MockObject->new->set_always(schema => $schema); +my $url = Mojo::URL->new(base => Mojo::URL->new('openqa')); +my $c = Test::MockObject->new->set_always(schema => $schema)->set_always(param => 'foo'); +$c->set_always(config => {openid => {provider => 'foo'}}); ok OpenQA::WebAPI::Auth::OpenID::_create_user($c, $user, 'nobody\@example.com', $user, $user), 'can call _create_user'; $c->set_always(session => \%session); ok +OpenQA::WebAPI::Auth::OpenID::_handle_verified($c, $vident), 'can call _handle_verified'; $users->called_ok('create_user', 'new user is created for initial login'); is + ($users->call_args(2))[1], 'mordred', 'new user created with details'; -$c->set_always( - req => Test::MockObject->new->set_always( - params => Test::MockObject->new->set_always(pairs => ['openid.op_endpoint', 'https://www.opensuse.org/openid/']) - )->set_always(url => Test::MockObject->new->set_always(base => 'openqa'))) - ->set_always( - app => Test::MockObject->new->set_always(config => {})->set_always(log => Test::MockObject->new->set_true('error'))) - ->set_true('flash'); + +my $params = Test::MockObject->new->set_always(pairs => ['openid.op_endpoint', 'https://www.opensuse.org/openid/']); +my $req = Test::MockObject->new->set_always(params => $params)->set_always(url => $url); +my $log = Test::MockObject->new->set_true('error'); +my $app = Test::MockObject->new->set_always(config => {})->set_always(log => $log); +$c->set_always(req => $req)->set_always(app => $app)->set_true('flash'); is +OpenQA::WebAPI::Auth::OpenID::auth_response($c), 0, 'can call auth_response'; $c->app->log->called_ok('error', 'an error was logged for call without proper config'); my $mock_openid_consumer = Test::MockModule->new('Net::OpenID::Consumer'); $mock_openid_consumer->redefine( - 'handle_server_response', - sub ($self, %res_handlers) { - return $res_handlers{setup_needed} - ? $res_handlers{setup_needed}->('https://www.opensuse.org/openid/setup') - : undef; + handle_server_response => sub ($self, %res_handlers) { + $res_handlers{setup_needed} ? $res_handlers{setup_needed}->('https://www.opensuse.org/openid/setup') : undef; }); -$c->set_always( - req => Test::MockObject->new->set_always( - params => Test::MockObject->new->set_always(pairs => ['openid.op_endpoint', 'https://www.opensuse.org/openid/']) - )->set_always(url => Test::MockObject->new->set_always(base => 'openqa'))) - ->set_always( - app => Test::MockObject->new->set_always(config => {})->set_always(log => Test::MockObject->new->set_true('debug'))) - ->set_true('flash'); +$c->set_always(headers => Mojo::Headers->new); +$app->set_always(log => Test::MockObject->new->set_true('debug')); is OpenQA::WebAPI::Auth::OpenID::auth_response($c), 0, 'can handle setup_needed response'; $c->app->log->called_ok('debug', 'a debug message is logged when setup_needed respond'); + +subtest 'claiming identity provider fails' => sub { + $mock_openid_consumer->redefine(claimed_identity => undef); + combined_like { OpenQA::WebAPI::Auth::OpenID::auth_login($c) } qr/claiming.*identity.*failed/i, 'error logged'; +}; + +subtest 'login fails' => sub { + my $claimed_id = Test::MockObject->new->set_true('set_extension_args')->set_false('check_url'); + $mock_openid_consumer->redefine(claimed_identity => $claimed_id); + $mock_openid_consumer->redefine(err => 'test error'); + my %res = OpenQA::WebAPI::Auth::OpenID::auth_login($c); + is_deeply \%res, {error => 'test error'}, 'error returned' or always_explain \%res; +}; + +subtest 'debug logging' => sub { + my $csr; + $mock_openid_consumer->redefine(new => sub (@args) { $csr = $mock_openid_consumer->original('new')->(@args) }); + my %res = OpenQA::WebAPI::Auth::OpenID::auth_response($c); + $csr->{debug}->('foo', 'bar'); + $c->app->log->called_pos_ok(3, 'debug', 'a debug message is logged'); + $c->app->log->called_args_pos_is(3, 2, 'Net::OpenID::Consumer: foo bar', 'log message contains arguments'); + is_deeply \%res, {redirect => 'index', error => 0}, 'redirected to index' or always_explain \%res; +}; + done_testing; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/t/31-api_descriptions.t new/openQA-5.1772550094.48b5cce5/t/31-api_descriptions.t --- old/openQA-5.1772475695.6c6c7eda/t/31-api_descriptions.t 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/t/31-api_descriptions.t 2026-03-03 16:01:34.000000000 +0100 @@ -29,4 +29,10 @@ } qr/\[WARN\].*get_pod_from_controllers/, 'Warning when file does not exist'; +subtest 'parameter validation warnings' => sub { + combined_like { set_api_desc('foo', 'bar') } qr /expected HASH/i, 'invalid description'; + combined_like { set_api_desc({}, 'bar') } qr /expected.*Route/i, 'invalid route'; + combined_like { OpenQA::WebAPI::Description::_itemize('foo', 'bar') } qr /expected.*Node/i, 'invalid node'; +}; + done_testing; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/t/lib/OpenQA/Test/Database.pm new/openQA-5.1772550094.48b5cce5/t/lib/OpenQA/Test/Database.pm --- old/openQA-5.1772475695.6c6c7eda/t/lib/OpenQA/Test/Database.pm 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/t/lib/OpenQA/Test/Database.pm 2026-03-03 16:01:34.000000000 +0100 @@ -86,7 +86,7 @@ $ids{$row->result_source->from} = $ri->{id} if $ri->{id}; } catch ($e) { - croak 'Could not insert fixture ' . path($fixture)->to_rel($cwd) . ": $e"; + croak 'Could not insert fixture ' . path($fixture)->to_rel($cwd) . ": $e"; # uncoverable statement } } } @@ -101,12 +101,6 @@ } } -sub disconnect ($schema) { - my $dbh = $schema->storage->dbh; - if (my $search_path = $schema->search_path_for_tests) { $dbh->do("drop schema $search_path") } - return $dbh->disconnect; -} - 1; =head1 NAME @@ -134,8 +128,4 @@ Insert fixtures into database -=head2 disconnect ($schema) - -Disconnect from database handle - =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/t/ui/27-plugin_obs_rsync_gru.t new/openQA-5.1772550094.48b5cce5/t/ui/27-plugin_obs_rsync_gru.t --- old/openQA-5.1772475695.6c6c7eda/t/ui/27-plugin_obs_rsync_gru.t 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/t/ui/27-plugin_obs_rsync_gru.t 2026-03-03 16:01:34.000000000 +0100 @@ -9,6 +9,8 @@ use Test::Mojo; use OpenQA::Test::TimeLimit '8'; use OpenQA::Test::ObsRsync 'setup_obs_rsync_test'; +use OpenQA::WebAPI::Plugin::ObsRsync::Task; +use Test::MockObject; my ($t, $tempdir, $home, $params) = setup_obs_rsync_test; my $app = $t->app; @@ -18,6 +20,7 @@ use Mojo::Base -base, -signatures; has id => 0; has app => sub { $app }; + has retries => 200; sub finish { $_[0]->{state} = 'finished'; $_[0]->{result} = $_[1] } sub info { {notes => {project_lock => 1}} } } # uncoverable statement @@ -48,4 +51,13 @@ 'files_iso.lst has been created'; }; +subtest 'retrying' => sub { + my $obs_rsync = Test::MockObject->new->set_always(home => 'home')->set_true('unlock'); + $obs_rsync->mock(is_status_dirty => sub { die "is_status_dirty failed\n" }); + my $job = FakeMinionJob->new(app => Test::MockObject->new->set_always(obs_rsync => $obs_rsync)); + OpenQA::WebAPI::Plugin::ObsRsync::Task::run($job, {project => 'foo'}); + is $job->{state}, 'finished', 'job finished after retires exceeded'; + like $job->{result}->{message}, qr/exceeded retry count/i, 'result about retrying assigned'; +}; + done_testing(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1772475695.6c6c7eda/tools/unstable_tests.txt new/openQA-5.1772550094.48b5cce5/tools/unstable_tests.txt --- old/openQA-5.1772475695.6c6c7eda/tools/unstable_tests.txt 2026-03-02 19:21:35.000000000 +0100 +++ new/openQA-5.1772550094.48b5cce5/tools/unstable_tests.txt 2026-03-03 16:01:34.000000000 +0100 @@ -1,2 +0,0 @@ -t/ui/26-jobs_restart.t -t/ui/13-admin.t ++++++ openQA.obsinfo ++++++ --- /var/tmp/diff_new_pack.VAvh2Z/_old 2026-03-04 21:06:30.095617324 +0100 +++ /var/tmp/diff_new_pack.VAvh2Z/_new 2026-03-04 21:06:30.115618154 +0100 @@ -1,5 +1,5 @@ name: openQA -version: 5.1772475695.6c6c7eda -mtime: 1772475695 -commit: 6c6c7edada7129e05ca4af692bfdd5631a21369f +version: 5.1772550094.48b5cce5 +mtime: 1772550094 +commit: 48b5cce540fe4b70075d79605e9033cd2d7c358e
