From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 26410997CF for ; Tue, 14 Nov 2023 11:34:14 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id EF4001DE78 for ; Tue, 14 Nov 2023 11:33:43 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Tue, 14 Nov 2023 11:33:42 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 57127427C6 for ; Tue, 14 Nov 2023 11:33:42 +0100 (CET) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Tue, 14 Nov 2023 11:33:39 +0100 Message-Id: <20231114103340.2850162-5-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20231114103340.2850162-1-d.csapak@proxmox.com> References: <20231114103340.2850162-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.017 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pve-devel] [PATCH common 4/4] section config: add tests for separated property lists X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Nov 2023 10:34:14 -0000 more or less a copy from the normal section config test, but now with properties defined multiple times as well as conflicting options Signed-off-by: Dominik Csapak --- test/Makefile | 1 + test/section_config_separated_test.pl | 486 ++++++++++++++++++++++++++ 2 files changed, 487 insertions(+) create mode 100755 test/section_config_separated_test.pl diff --git a/test/Makefile b/test/Makefile index 82f40ab..3e9fef2 100644 --- a/test/Makefile +++ b/test/Makefile @@ -6,6 +6,7 @@ TESTS = lock_file.test \ format_test.test \ section_config_test.test \ api_parameter_test.test \ + section_config_separated_test.test\ all: diff --git a/test/section_config_separated_test.pl b/test/section_config_separated_test.pl new file mode 100755 index 0000000..234f444 --- /dev/null +++ b/test/section_config_separated_test.pl @@ -0,0 +1,486 @@ +#!/usr/bin/perl + +use lib '../src'; + +package Conf; +use strict; +use warnings; + +use Test::More; + +use base qw(PVE::SectionConfig); + +my $defaultData = { + propertyList => { + type => { description => "Section type." }, + id => { + description => "ID", + type => 'string', + format => 'pve-configid', + maxLength => 64, + }, + common => { + type => 'string', + description => 'common value', + maxLength => 512, + }, + }, + options => { + id => {}, + type => {}, + }, +}; + +sub private { + return $defaultData; +} + +sub expect_success { + my ($class, $filename, $expected, $raw, $allow_unknown) = @_; + + my $res = $class->parse_config($filename, $raw, $allow_unknown); + delete $res->{digest}; + + is_deeply($res, $expected, $filename); + + my $written = $class->write_config($filename, $res, $allow_unknown); + my $res2 = $class->parse_config($filename, $written, $allow_unknown); + delete $res2->{digest}; + + is_deeply($res, $res2, "$filename - verify rewritten data"); +} + +sub expect_fail { + my ($class, $filename, $expected, $raw) = @_; + + eval { $class->parse_config($filename, $raw) }; + die "test '$filename' succeeded unexpectedly\n" if !$@; + ok(1, "$filename should fail to parse"); +} + +package Conf::One; +use strict; +use warnings; + +use base 'Conf'; + +sub type { + return 'one'; +} + +sub properties { + return { + field1 => { + description => 'Field One', + type => 'integer', + minimum => 3, + maximum => 9, + }, + another => { + description => 'Another field', + type => 'string', + }, + field2 => { + description => 'Field Two', + type => 'integer', + minimum => 10, + maximum => 19, + } + }; +} + +sub options { + return { + common => { optional => 1 }, + field1 => {}, + field2 => {}, + another => { optional => 1 }, + arrayfield => { optional => 1, type => 'two' }, + }; +} + +package Conf::Two; +use strict; +use warnings; + +use base 'Conf'; + +sub type { + return 'two'; +} + +sub properties { + return { + field2 => { + description => 'Field Two but different', + type => 'integer', + minimum => 3, + maximum => 9, + }, + arrayfield => { + description => "Array Field with property string", + type => 'array', + items => { + type => 'string', + description => 'a property string', + format => { + subfield1 => { + type => 'string', + description => 'first subfield' + }, + subfield2 => { + type => 'integer', + minimum => 0, + optional => 1, + }, + }, + }, + }, + }; +} + +sub options { + return { + common => { optional => 1 }, + field2 => {}, + another => { type => 'one' }, + arrayfield => { optional => 1 }, + }; +} + +package main; + +use strict; +use warnings; + +use Test::More; + +Conf::One->register(); +Conf::Two->register(); +Conf->init(1); + +# FIXME: allow development debug warnings?! +local $SIG{__WARN__} = sub { die @_; }; + +my sub enum { + my $n = 1; + return { map { $_ => $n++ } @_ }; +} + +Conf->expect_success( + 'separated-test1', + { + ids => { + t1 => { + type => 'one', + common => 'foo', + field1 => 3, + field2 => 10, + arrayfield => [ 'subfield1=test' ], + }, + t2 => { + type => 'one', + common => 'foo2', + field1 => 4, + field2 => 15, + another => 'more-text', + }, + t3 => { + type => 'two', + field2 => 5, + another => 'even more text', + }, + }, + order => { t1 => 1, t2 => 2, t3 => 3 }, + }, + <<"EOF"); +one: t1 + common foo + field1 3 + field2 10 + arrayfield subfield1=test + +one: t2 + common foo2 + field1 4 + field2 15 + another more-text + +two: t3 + field2 5 + another even more text +EOF + +my $with_unknown_data = { + ids => { + t1 => { + type => 'one', + common => 'foo', + field1 => 3, + field2 => 10, + }, + t2 => { + type => 'one', + common => 'foo2', + field1 => 4, + field2 => 15, + another => 'more-text', + }, + t3 => { + type => 'two', + field2 => 5, + another => 'even more text', + arrayfield => [ + 'subfield1=test,subfield2=2', + 'subfield1=test2', + ], + }, + invalid => { + type => 'bad', + common => 'omg', + unknownfield => 'shouldnotbehere', + unknownarray => ['entry1', 'entry2'], + }, + }, + order => enum(qw(t1 t2 invalid t3)), +}; +my $with_unknown_text = <<"EOF"; +one: t1 + common foo + field1 3 + field2 10 + +one: t2 + common foo2 + field1 4 + field2 15 + another more-text + +bad: invalid + common omg + unknownfield shouldnotbehere + unknownarray entry1 + unknownarray entry2 + +two: t3 + field2 5 + another even more text + arrayfield subfield1=test,subfield2=2 + arrayfield subfield1=test2 +EOF + +my $wrong_field_schema_data = { + ids => { + t1 => { + type => 'one', + common => 'foo', + field1 => 3, + field2 => 5, # this should fail + }, + }, + order => enum(qw(t1)), +}; + +my $wrong_field_schema_text = <<"EOF"; +one: t1 + common foo + field1 3 + field2 5 +EOF + +Conf->expect_fail('separated-wrong-field-schema', $wrong_field_schema_data, $wrong_field_schema_text); +Conf->expect_fail('separated-unknown-forbidden', $with_unknown_data, $with_unknown_text); +Conf->expect_success('separated-unknown-allowed', $with_unknown_data, $with_unknown_text, 1); + +# schema tests +my $create_schema = Conf->createSchema(); +my $expected_create_schema = { + additionalProperties => 0, + type => 'object', + properties => { + id => { + description => "ID", + type => 'string', + format => 'pve-configid', + maxLength => 64, + }, + type => { + description => 'Section type.', + enum => [ 'one', 'two' ], + type => 'string' + }, + common => { + maxLength => 512, + optional => 1, + 'type-property' => 'type', + 'instance-types' => [ 'one', 'two' ], + type => 'string', + description => 'common value' + }, + field1 => { + type => 'integer', + 'type-property' => 'type', + 'instance-types' => [ 'one' ], + maximum => 9, + optional => 1, + minimum => 3, + description => 'Field One' + }, + field2 => { + oneOf => [ + { + description => 'Field Two', + optional => 1, + minimum => 10, + 'instance-types' => [ 'one' ], + type => 'integer', + maximum => 19 + }, + { + optional => 1, + minimum => 3, + description => 'Field Two but different', + type => 'integer', + 'instance-types' => [ 'two' ], + maximum => 9 + } + ], + 'type-property' => 'type' + }, + arrayfield => { + items => { + type => 'string', + format => { + subfield1 => { + description => 'first subfield', + type => 'string' + }, + subfield2 => { + minimum => 0, + type => 'integer', + optional => 1 + } + }, + description => 'a property string' + }, + description => 'Array Field with property string', + 'instance-types' => [ 'one', 'two' ], + 'type-property' => 'type', + type => 'array', + optional => 1 + }, + another => { + optional => 1, + type => 'string', + 'type-property' => 'type', + 'instance-types' => [ 'one', 'two' ], + description => 'Another field' + }, + }, +}; + +is_deeply($create_schema, $expected_create_schema, "separated create schema test"); + +my $update_schema = Conf->updateSchema(); +my $expected_update_schema = { + additionalProperties => 0, + type => 'object', + properties => { + id => { + description => "ID", + type => 'string', + format => 'pve-configid', + maxLength => 64, + }, + type => { + type => 'string', + enum => [ 'one', 'two' ], + description => 'Section type.' + }, + digest => { + optional => 1, + type => 'string', + description => 'Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.', + maxLength => 64 + }, + delete => { + description => 'A list of settings you want to delete.', + maxLength => 4096, + format => 'pve-configid-list', + optional => 1, + type => 'string' + }, + common => { + maxLength => 512, + 'instance-types' => [ 'one', 'two' ], + 'type-property' => 'type', + description => 'common value', + type => 'string', + optional => 1 + }, + field1 => { + description => 'Field One', + maximum => 9, + 'instance-types' => [ 'one' ], + 'type-property' => 'type', + minimum => 3, + optional => 1, + type => 'integer' + }, + field2 => { + 'type-property' => 'type', + oneOf => [ + { + type => 'integer', + minimum => 10, + optional => 1, + maximum => 19, + 'instance-types' => [ 'one' ], + description => 'Field Two' + }, + { + description => 'Field Two but different', + maximum => 9, + 'instance-types' => [ 'two' ], + minimum => 3, + optional => 1, + type => 'integer' + } + ] + }, + arrayfield => { + type => 'array', + optional => 1, + items => { + description => 'a property string', + type => 'string', + format => { + subfield2 => { + type => 'integer', + minimum => 0, + optional => 1 + }, + subfield1 => { + description => 'first subfield', + type => 'string' + } + } + }, + 'instance-types' => [ 'one', 'two' ], + 'type-property' => 'type', + description => 'Array Field with property string' + }, + another => { + description => 'Another field', + 'instance-types' => [ 'one', 'two' ], + 'type-property' => 'type', + optional => 1, + type => 'string' + }, + } +}; +is_deeply($update_schema, $expected_update_schema, "separated update schema test"); + +done_testing(); + +1; -- 2.30.2