From e832b9c3a62f4fcbd266ebe00104dfe890247aa3 Mon Sep 17 00:00:00 2001 From: Jaroslav Rohel Date: Mon, 28 Oct 2024 16:22:42 +0100 Subject: [PATCH 1/4] swig: Move VarsWeakPtr wpapper to conf module The vars.hpp file is included in the conf module and the Vars class is wrapped in the conf module. VarsWeakPtr was packaged in the base module. Which will bring problems in the following changes. So the VarsWeakPtr wrapper has been moved to the conf module. --- bindings/libdnf5/base.i | 1 - bindings/libdnf5/conf.i | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/libdnf5/base.i b/bindings/libdnf5/base.i index 53249bea5..61a6bed2e 100644 --- a/bindings/libdnf5/base.i +++ b/bindings/libdnf5/base.i @@ -48,7 +48,6 @@ #define CV __perl_CV %template(BaseWeakPtr) libdnf5::WeakPtr; -%template(VarsWeakPtr) libdnf5::WeakPtr; %ignore std::vector::insert; %ignore std::vector::pop; diff --git a/bindings/libdnf5/conf.i b/bindings/libdnf5/conf.i index a3cce6361..d79f76f89 100644 --- a/bindings/libdnf5/conf.i +++ b/bindings/libdnf5/conf.i @@ -111,6 +111,7 @@ wrap_unique_ptr(StringUniquePtr, std::string); %ignore libdnf5::ReadOnlyVariableError; %include "libdnf5/conf/vars.hpp" +%template(VarsWeakPtr) libdnf5::WeakPtr; %include "libdnf5/conf/config.hpp" %include "libdnf5/conf/config_main.hpp" From 879c6901eac078a2777590f17470585e17f66b73 Mon Sep 17 00:00:00 2001 From: Jaroslav Rohel Date: Mon, 28 Oct 2024 16:36:35 +0100 Subject: [PATCH 2/4] swig: Modify `Vars::detect_release` to return `char *` The original `Vars::detect_release` returns `std::unique_ptr` This makes it complicated for wrapping into other languages. The modified version returns `char *` - a standard C string. --- bindings/CMakeLists.txt | 1 + bindings/libdnf5/conf.i | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index caf1eed33..7114a855e 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -34,6 +34,7 @@ set(SWIG_COMPILE_OPTIONS -Wno-strict-aliasing -Wno-unused-function -Wno-unused-parameter + -Wno-unused-but-set-variable ) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") diff --git a/bindings/libdnf5/conf.i b/bindings/libdnf5/conf.i index d79f76f89..e056b6816 100644 --- a/bindings/libdnf5/conf.i +++ b/bindings/libdnf5/conf.i @@ -109,6 +109,19 @@ wrap_unique_ptr(StringUniquePtr, std::string); %ignore ConfigParserOptionNotFoundError; %include "libdnf5/conf/config_parser.hpp" +%newobject libdnf5::Vars::detect_release; +%extend libdnf5::Vars { + static char * detect_release(const BaseWeakPtr & base, const std::string & install_root_path) { + std::unique_ptr release = libdnf5::Vars::detect_release(base, install_root_path); + if (release) { + char * release_cstr = new char[release->size() + 1]; + strcpy(release_cstr, release->c_str()); + return release_cstr; + } + return nullptr; + } +}; +%ignore libdnf5::Vars::detect_release; %ignore libdnf5::ReadOnlyVariableError; %include "libdnf5/conf/vars.hpp" %template(VarsWeakPtr) libdnf5::WeakPtr; From dd802d62312341bc9dc60195fc862dd776ec93f7 Mon Sep 17 00:00:00 2001 From: Jaroslav Rohel Date: Mon, 28 Oct 2024 22:22:59 +0100 Subject: [PATCH 3/4] Make `BaseTestCase` for Perl unit test --- dnf5.spec | 1 + test/perl5/CMakeLists.txt | 2 +- test/perl5/libdnf5/BaseTestCase.pm | 110 +++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 test/perl5/libdnf5/BaseTestCase.pm diff --git a/dnf5.spec b/dnf5.spec index e6707ae63..df770b0eb 100644 --- a/dnf5.spec +++ b/dnf5.spec @@ -242,6 +242,7 @@ BuildRequires: perl(strict) BuildRequires: perl(Test::More) BuildRequires: perl(Test::Exception) BuildRequires: perl(warnings) +BuildRequires: perl(FindBin) %endif %endif diff --git a/test/perl5/CMakeLists.txt b/test/perl5/CMakeLists.txt index f07c757a4..923955d3d 100644 --- a/test/perl5/CMakeLists.txt +++ b/test/perl5/CMakeLists.txt @@ -4,7 +4,7 @@ endif() find_package(Perl REQUIRED) -foreach(MODULE "strict" "Test::More" "Test::Exception" "warnings") +foreach(MODULE "strict" "Test::More" "Test::Exception" "warnings" "FindBin") message(STATUS "Checking for ${MODULE} Perl module") execute_process( COMMAND "${PERL_EXECUTABLE}" -e "require ${MODULE}" diff --git a/test/perl5/libdnf5/BaseTestCase.pm b/test/perl5/libdnf5/BaseTestCase.pm new file mode 100644 index 000000000..95112fa2e --- /dev/null +++ b/test/perl5/libdnf5/BaseTestCase.pm @@ -0,0 +1,110 @@ +# Copyright Contributors to the libdnf project. +# +# This file is part of libdnf: https://github.com/rpm-software-management/libdnf/ +# +# Libdnf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Libdnf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with libdnf. If not, see . + +package BaseTestCase; + +use strict; +use warnings; + +use File::Temp qw(tempdir); +use File::Spec::Functions 'catfile'; + +use libdnf5::base; +use libdnf5::repo; + + +my $PROJECT_BINARY_DIR = $ENV{"PROJECT_BINARY_DIR"}; +my $PROJECT_SOURCE_DIR = $ENV{"PROJECT_SOURCE_DIR"}; + +sub new { + my $class = shift; + my $self = {}; + + $self->{base} = new libdnf5::base::Base(); + + $self->{tmpdir} = tempdir("libdnf5_perl5_unittest.XXXX", TMPDIR => 1, CLEANUP => 1); + + my $config = $self->{base}->get_config(); + $config->get_installroot_option()->set($libdnf5::conf::Option::Priority_RUNTIME, $self->{tmpdir}."/installroot"); + $config->get_cachedir_option()->set($libdnf5::conf::Option::Priority_RUNTIME, $self->{tmpdir}."/cache"); + $config->get_optional_metadata_types_option()->set($libdnf5::conf::Option::Priority_RUNTIME, $libdnf5::conf::OPTIONAL_METADATA_TYPES); + + # Prevent loading plugins from host + $config->get_plugins_option()->set(0); + + my $vars = $self->{base}->get_vars()->get(); + $vars->set("arch", "x86_64"); + + $self->{base}->setup(); + + $self->{repo_sack} = $self->{base}->get_repo_sack(); + $self->{package_sack} = $self->{base}->get_rpm_package_sack(); + + return bless ($self, $class); +} + +sub tearDown { + my $self = shift; + # shutil.rmtree(self.temp_dir) +} + +sub _add_repo { + # Add a repo from `repo_path`. + my $self = shift; + my $repoid = shift; + my $repo_path = shift; + my $load = shift // 1; # True is default + + my $repo = $self->{repo_sack}->create_repo($repoid); + $repo->get_config()->get_baseurl_option()->set($libdnf5::conf::Option::Priority_RUNTIME, "file://".$repo_path); + if ($load) { + $self->{repo_sack}->load_repos($libdnf5::repo::Repo::Type_AVAILABLE); + } + + return $repo +} + +sub add_repo_repomd { + # Add a repo from PROJECT_SOURCE_DIR/test/data/repos-repomd//repodata + my $self = shift; + my $repoid = shift; + my $load = shift // 1; # True is default + + my $repo_path = catfile($PROJECT_SOURCE_DIR, "/test/data/repos-repomd", $repoid); + return $self->_add_repo($repoid, $repo_path, $load) +} + +sub add_repo_rpm { + # Add a repo from PROJECT_BINARY_DIR/test/data/repos-rpm//repodata + my $self = shift; + my $repoid = shift; + my $load = shift // 1; # True is default + + my $repo_path = catfile($PROJECT_BINARY_DIR, "test/data/repos-rpm", $repoid); + return $self->_add_repo($repoid, $repo_path, $load) +} + +sub add_repo_solv { + # Add a repo from PROJECT_SOURCE_DIR/test/data/repos-solv/.repo + my $self = shift; + my $repoid = shift; + + my $repo_path = catfile($PROJECT_SOURCE_DIR, "/test/data/repos-solv", $repoid.".repo"); + return $self->{repo_sack}->create_repo_from_libsolv_testcase($repoid, $repo_path); +} + +1; From ec76b7af508fe6750d51ab08ce8dc11ff8878983 Mon Sep 17 00:00:00 2001 From: Jaroslav Rohel Date: Mon, 28 Oct 2024 22:21:38 +0100 Subject: [PATCH 4/4] Unit tests for `Vars::detect_release()` SWIG bindings Tests in Python, Ruby, Perl. It only tests the situation where a release cannot be detected. To detect an installed release, a system database with the corresponding installed packages is required. --- test/perl5/libdnf5/conf/test_vars.t | 43 ++++++++++++++++++++++++++ test/python3/libdnf5/conf/test_vars.py | 11 +++++++ test/ruby/libdnf5/conf/test_vars.rb | 33 ++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 test/perl5/libdnf5/conf/test_vars.t create mode 100644 test/ruby/libdnf5/conf/test_vars.rb diff --git a/test/perl5/libdnf5/conf/test_vars.t b/test/perl5/libdnf5/conf/test_vars.t new file mode 100644 index 000000000..7379deb54 --- /dev/null +++ b/test/perl5/libdnf5/conf/test_vars.t @@ -0,0 +1,43 @@ +# Copyright Contributors to the libdnf project. +# +# This file is part of libdnf: https://github.com/rpm-software-management/libdnf/ +# +# Libdnf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Libdnf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with libdnf. If not, see . + +use strict; +use warnings; + +use Test::More; + +use FindBin; +use lib "$FindBin::Bin/.."; # Add to search path +use BaseTestCase; + +use File::Spec::Functions 'catfile'; + +use libdnf5::conf; + + +# test_detect_release +{ + my $test = new BaseTestCase(); + + my $installroot = $test->{base}->get_config()->get_installroot_option()->get_value(); + + # Cannot detect release in nonexistent directory, return undef + my $release = libdnf5::conf::Vars::detect_release($test->{base}->get_weak_ptr(), catfile($installroot, "nonexist")); + is($release, undef); +} + +done_testing(); diff --git a/test/python3/libdnf5/conf/test_vars.py b/test/python3/libdnf5/conf/test_vars.py index 8ec24e8a9..b146c3cdf 100644 --- a/test/python3/libdnf5/conf/test_vars.py +++ b/test/python3/libdnf5/conf/test_vars.py @@ -15,6 +15,10 @@ # You should have received a copy of the GNU General Public License # along with libdnf. If not, see . +import os + +import libdnf5 + import base_test_case @@ -22,3 +26,10 @@ class TestVars(base_test_case.BaseTestCase): def test_getting_undefined_variable(self): vars = self.base.get_vars() self.assertRaises(IndexError, vars.get_value, "undefined") + + def test_detect_release(self): + installroot = self.base.get_config().installroot + # Cannot detect release in nonexistent directory, return None + release = libdnf5.conf.Vars.detect_release( + self.base.get_weak_ptr(), os.path.join(installroot, "nonexist")) + self.assertEqual(release, None) diff --git a/test/ruby/libdnf5/conf/test_vars.rb b/test/ruby/libdnf5/conf/test_vars.rb new file mode 100644 index 000000000..4dba4922d --- /dev/null +++ b/test/ruby/libdnf5/conf/test_vars.rb @@ -0,0 +1,33 @@ +# Copyright Contributors to the libdnf project. +# +# This file is part of libdnf: https://github.com/rpm-software-management/libdnf/ +# +# Libdnf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Libdnf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with libdnf. If not, see . + +require 'test/unit' +include Test::Unit::Assertions + +require 'libdnf5/conf' + +require 'base_test_case' + + +class TestVars < BaseTestCase + def test_detect_release() + installroot = @base.get_config().get_installroot_option().get_value() + # Cannot detect release in nonexistent directory, return nil + release = Conf::Vars::detect_release(@base.get_weak_ptr(), File.join(installroot, "nonexist")) + assert_equal(nil, release) + end +end