Similar to `schema_comparison_test.pl`, add `schema_isolated_test.pl` for tests specific to PVE::SectionConfig's property isolation mode.
The purpose of these tests is to document the existing quirks of the isolated mode of PVE::SectionConfig as well as to ensure that we catch any regressions, should we need to make any changes to the inner machinery of PVE::SectionConfig in the future. This test script works similar to `schema_comparison_test.pl`, expect that its cases are (obviously) not tested against their counterparts in unified mode, as that simply doesn't apply for them. Add a simple basic test case for child plugins that define identical properties under isolated mode. Signed-off-by: Max R. Carrara <[email protected]> --- test/SectionConfig/Makefile | 1 + test/SectionConfig/schema_isolated_test.pl | 239 +++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100755 test/SectionConfig/schema_isolated_test.pl diff --git a/test/SectionConfig/Makefile b/test/SectionConfig/Makefile index d1c2b1a..b0dfc93 100644 --- a/test/SectionConfig/Makefile +++ b/test/SectionConfig/Makefile @@ -1,5 +1,6 @@ TESTS = \ schema_comparison_test.pl \ + schema_isolated_test.pl \ all: diff --git a/test/SectionConfig/schema_isolated_test.pl b/test/SectionConfig/schema_isolated_test.pl new file mode 100755 index 0000000..bc2c551 --- /dev/null +++ b/test/SectionConfig/schema_isolated_test.pl @@ -0,0 +1,239 @@ +#!/usr/bin/perl + +use v5.36; + +use lib qw( + .. + ../../src/ +); + +use Data::Dumper; + +$Data::Dumper::Terse = 1; +$Data::Dumper::Indent = 1; +$Data::Dumper::Useqq = 1; +$Data::Dumper::Deparse = 1; +$Data::Dumper::Quotekeys = 0; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Trailingcomma = 1; + +use Test::More; + +use SectionConfig::Helpers qw( + symbol_table_has + get_subpackages + get_plugin_system_within_package + dump_symbol_table +); + +package TestPackage { + use Carp qw(confess); + + sub expected_isolated_createSchema($class) { + confess "not implemented"; + } + + sub expected_isolated_updateSchema($class) { + confess "not implemented"; + } + + sub desc($class) { + return undef; + } +}; + +package IdenticalPropertiesOnDifferentPlugins { + use base qw(TestPackage); + + sub desc($class) { + return "defining identical properties on different plugins does not lead to" + . " 'oneOf' being used inside either createSchema or updateSchema"; + } + + package IdenticalPropertiesOnDifferentPlugins::PluginBase { + use base qw(PVE::SectionConfig); + + my $DEFAULT_DATA = {}; + + sub private($class) { + return $DEFAULT_DATA; + } + }; + + package IdenticalPropertiesOnDifferentPlugins::PluginOne { + use base qw(IdenticalPropertiesOnDifferentPlugins::PluginBase); + + sub type($class) { + return 'one'; + } + + sub properties($class) { + return { + 'prop-one' => { + type => 'string', + optional => 1, + }, + 'prop-two' => { + type => 'string', + optional => 1, + }, + }; + } + + sub options($class) { + return { + 'prop-one' => { + optional => 1, + }, + 'prop-two' => { + optional => 1, + }, + }; + } + }; + + package IdenticalPropertiesOnDifferentPlugins::PluginTwo { + use base qw(IdenticalPropertiesOnDifferentPlugins::PluginBase); + + sub type($class) { + return 'two'; + } + + sub properties($class) { + return { + 'prop-one' => { + type => 'string', + optional => 1, + }, + 'prop-two' => { + type => 'string', + optional => 1, + }, + }; + } + + sub options($class) { + return { + 'prop-one' => { + optional => 1, + }, + 'prop-two' => { + optional => 1, + }, + }; + } + }; + + sub expected_isolated_createSchema($class) { + return { + type => 'object', + additionalProperties => 0, + properties => { + type => { + type => 'string', + enum => [ + "one", "two", + ], + }, + 'prop-one' => { + type => 'string', + optional => 1, + }, + 'prop-two' => { + type => 'string', + optional => 1, + }, + }, + }; + } + + sub expected_isolated_updateSchema($class) { + return { + type => 'object', + additionalProperties => 0, + properties => { + type => { + type => 'string', + enum => [ + "one", "two", + ], + }, + 'prop-one' => { + type => 'string', + optional => 1, + }, + 'prop-two' => { + type => 'string', + optional => 1, + }, + $SectionConfig::Helpers::UPDATE_SCHEMA_DEFAULT_PROPERTIES->%*, + }, + }; + } +} + +sub test_compare_deeply($got, $expected, $test_name, $test_package) { + $test_name = "$test_package - $test_name"; + my $description = $test_package->desc(); + + if (!is_deeply($got, $expected, $test_name)) { + note("\nDescription: ", $description // "(none)", "\n"); + note("Got:"); + note(Dumper($got)); + note("Expected:"); + note(Dumper($expected)); + note("=" x 40); + } + + return; +} + +sub init_and_run_tests($package) { + my $system = get_plugin_system_within_package($package); + + my ($base, $plugins) = $system->@{qw(base plugins)}; + + for my $plugin ($plugins->@*) { + $plugin->register(); + } + + $base->init(property_isolation => 1); + + test_compare_deeply( + $base->createSchema(), + $package->expected_isolated_createSchema(), + "isolated - createSchema comparison", + $package, + ); + + test_compare_deeply( + $base->updateSchema(), + $package->expected_isolated_updateSchema(), + "isolated - updateSchema comparison", + $package, + ); + + return; +} + +sub main() { + my $subpackages = get_subpackages('main'); + + my $test_packages = []; + + for my $package (sort $subpackages->@*) { + if ($package !~ m/TestPackage/ && $package->isa('TestPackage')) { + push($test_packages->@*, $package); + } + } + + for my $package ($test_packages->@*) { + init_and_run_tests($package); + } + + done_testing(); + + return 0; +} + +main(); -- 2.47.3 _______________________________________________ pve-devel mailing list [email protected] https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
