[pve-devel] [PATCH common v3 5/5] section config: add tests for separated property lists
Dominik Csapak
d.csapak at proxmox.com
Thu Nov 16 14:55:45 CET 2023
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 <d.csapak at proxmox.com>
---
test/Makefile | 1 +
test/section_config_separated_test.pl | 489 ++++++++++++++++++++++++++
2 files changed, 490 insertions(+)
create mode 100755 test/section_config_separated_test.pl
diff --git a/test/Makefile b/test/Makefile
index b0de1a5..30ad185 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -7,6 +7,7 @@ TESTS = lock_file.test \
section_config_test.test \
api_parameter_test.test \
is_deeply_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..0d4e4fe
--- /dev/null
+++ b/test/section_config_separated_test.pl
@@ -0,0 +1,489 @@
+#!/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,
+ },
+ },
+};
+
+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,
+ },
+ field2 => {
+ description => 'Field Two',
+ type => 'integer',
+ minimum => 10,
+ maximum => 19,
+ },
+ another => {
+ description => 'Another field',
+ type => 'string',
+ optional => 1,
+ },
+ arrayfield => {
+ description => "Array Field with property string",
+ optional => 1,
+ 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 },
+ };
+}
+
+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,
+ },
+ another => {
+ description => 'Another field',
+ type => 'string',
+ },
+ arrayfield => {
+ optional => 1,
+ 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 },
+ };
+}
+
+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 => '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',
+ type => 'array',
+ optional => 1
+ },
+ another => {
+ optional => 1,
+ type => 'string',
+ 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,
+ 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'
+ }
+ }
+ },
+ description => 'Array Field with property string'
+ },
+ another => {
+ description => 'Another field',
+ optional => 1,
+ type => 'string'
+ },
+ }
+};
+is_deeply($update_schema, $expected_update_schema, "separated update schema test");
+
+done_testing();
+
+1;
--
2.30.2
More information about the pve-devel
mailing list