feat: add full Zonemaster stack with Docker and Spanish UI
- Clone all 5 Zonemaster component repos (LDNS, Engine, CLI, Backend, GUI) - Dockerfile.backend: 8-stage multi-stage build LDNS→Engine→CLI→Backend - Dockerfile.gui: Astro static build served via nginx - docker-compose.yml: backend (internal) + frontend (port 5353) - nginx.conf: root redirects to /es/, /api/ proxied to backend - zonemaster-gui/config.ts: defaultLanguage set to 'es' (Spanish) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
891
zonemaster-backend/t/config.t
Normal file
891
zonemaster-backend/t/config.t
Normal file
@@ -0,0 +1,891 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use Test::More tests => 2;
|
||||
use Test::NoWarnings;
|
||||
use Test::Differences;
|
||||
use Test::Exception;
|
||||
use Log::Any::Test; # Must come before use Log::Any
|
||||
|
||||
use File::Basename qw( dirname );
|
||||
use File::Slurp qw( read_file );
|
||||
use File::Spec::Functions qw( catfile );
|
||||
use Log::Any qw( $log );
|
||||
|
||||
subtest 'Everything but NoWarnings' => sub {
|
||||
|
||||
use_ok( 'Zonemaster::Backend::Config' );
|
||||
|
||||
subtest 'Set values' => sub {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = sqlite
|
||||
polling_interval = 1.5
|
||||
|
||||
[MYSQL]
|
||||
host = mysql-host
|
||||
port = 3456
|
||||
user = mysql_user
|
||||
password = mysql_password
|
||||
database = mysql_database
|
||||
|
||||
[POSTGRESQL]
|
||||
host = postgresql-host
|
||||
port = 6543
|
||||
user = postgresql_user
|
||||
password = postgresql_password
|
||||
database = postgresql_database
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[LANGUAGE]
|
||||
locale = sv_FI
|
||||
|
||||
[PUBLIC PROFILES]
|
||||
default = /path/to/default.profile
|
||||
two = /path/to/two.profile
|
||||
|
||||
[PRIVATE PROFILES]
|
||||
three = /path/to/three.profile
|
||||
four = /path/to/four.profile
|
||||
|
||||
[ZONEMASTER]
|
||||
max_zonemaster_execution_time = 1200
|
||||
number_of_processes_for_frontend_testing = 30
|
||||
number_of_processes_for_batch_testing = 40
|
||||
lock_on_queue = 1
|
||||
age_reuse_previous_test = 800
|
||||
};
|
||||
my $config = Zonemaster::Backend::Config->parse( $text );
|
||||
isa_ok $config, 'Zonemaster::Backend::Config', 'parse() return value';
|
||||
is $config->DB_engine, 'SQLite', 'set: DB.engine';
|
||||
is $config->DB_polling_interval, 1.5, 'set: DB.polling_interval';
|
||||
is $config->MYSQL_host, 'mysql-host', 'set: MYSQL.host';
|
||||
is $config->MYSQL_port, 3456, 'set: MYSQL.port';
|
||||
is $config->MYSQL_user, 'mysql_user', 'set: MYSQL.user';
|
||||
is $config->MYSQL_password, 'mysql_password', 'set: MYSQL.password';
|
||||
is $config->MYSQL_database, 'mysql_database', 'set: MYSQL.database';
|
||||
is $config->POSTGRESQL_host, 'postgresql-host', 'set: POSTGRESQL.host';
|
||||
is $config->POSTGRESQL_port, 6543, 'set: POSTGRESQL.port';
|
||||
is $config->POSTGRESQL_user, 'postgresql_user', 'set: POSTGRESQL.user';
|
||||
is $config->POSTGRESQL_password, 'postgresql_password', 'set: POSTGRESQL.password';
|
||||
is $config->POSTGRESQL_database, 'postgresql_database', 'set: POSTGRESQL.database';
|
||||
is $config->SQLITE_database_file, '/var/db/zonemaster.sqlite', 'set: SQLITE.database_file';
|
||||
eq_or_diff { $config->LANGUAGE_locale }, { sv => 'sv_FI' }, 'set: LANGUAGE.locale';
|
||||
eq_or_diff { $config->PUBLIC_PROFILES }, { #
|
||||
default => '/path/to/default.profile',
|
||||
two => '/path/to/two.profile'
|
||||
},
|
||||
'set: PUBLIC PROFILES';
|
||||
eq_or_diff { $config->PRIVATE_PROFILES }, { #
|
||||
three => '/path/to/three.profile',
|
||||
four => '/path/to/four.profile'
|
||||
},
|
||||
'set: PRIVATE PROFILES';
|
||||
is $config->ZONEMASTER_max_zonemaster_execution_time, 1200, 'set: ZONEMASTER.max_zonemaster_execution_time';
|
||||
is $config->ZONEMASTER_number_of_processes_for_frontend_testing, 30, 'set: ZONEMASTER.number_of_processes_for_frontend_testing';
|
||||
is $config->ZONEMASTER_number_of_processes_for_batch_testing, 40, 'set: ZONEMASTER.number_of_processes_for_batch_testing';
|
||||
is $config->ZONEMASTER_lock_on_queue, 1, 'set: ZONEMASTER.lock_on_queue';
|
||||
is $config->ZONEMASTER_age_reuse_previous_test, 800, 'set: ZONEMASTER.age_reuse_previous_test';
|
||||
};
|
||||
|
||||
subtest 'Default values' => sub {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
};
|
||||
my $config = Zonemaster::Backend::Config->parse( $text );
|
||||
cmp_ok abs( $config->DB_polling_interval - 0.5 ), '<', 0.000001, 'default: DB.polling_interval';
|
||||
is $config->MYSQL_port, 3306, 'default: MYSQL.port';
|
||||
is $config->POSTGRESQL_port, 5432, 'default: POSTGRESQL.port';
|
||||
eq_or_diff { $config->LANGUAGE_locale }, { en => 'en_US' }, 'default: LANGUAGE.locale';
|
||||
eq_or_diff { $config->PUBLIC_PROFILES }, { default => undef }, 'default: PUBLIC_PROFILES';
|
||||
eq_or_diff { $config->PRIVATE_PROFILES }, {}, 'default: PRIVATE_PROFILES';
|
||||
is $config->ZONEMASTER_max_zonemaster_execution_time, 600, 'default: ZONEMASTER.max_zonemaster_execution_time';
|
||||
is $config->ZONEMASTER_number_of_processes_for_frontend_testing, 20, 'default: ZONEMASTER.number_of_processes_for_frontend_testing';
|
||||
is $config->ZONEMASTER_number_of_processes_for_batch_testing, 20, 'default: ZONEMASTER.number_of_processes_for_batch_testing';
|
||||
is $config->ZONEMASTER_lock_on_queue, 0, 'default: ZONEMASTER.lock_on_queue';
|
||||
is $config->ZONEMASTER_age_reuse_previous_test, 600, 'default: ZONEMASTER.age_reuse_previous_test';
|
||||
|
||||
is $config->RPCAPI_enable_add_api_user, 0, 'default: RPCAPI.enable_add_api_user';
|
||||
is $config->RPCAPI_enable_add_batch_job, 1, 'default: RPCAPI.enable_add_batch_job';
|
||||
};
|
||||
|
||||
SKIP: {
|
||||
skip "no more deprecated values", 1;
|
||||
|
||||
subtest 'Deprecated values and fallbacks that are unconditional' => sub {
|
||||
$log->clear();
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
};
|
||||
my $config = Zonemaster::Backend::Config->parse( $text );
|
||||
};
|
||||
}
|
||||
|
||||
subtest 'Warnings' => sub {
|
||||
$log->clear();
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = localhost
|
||||
port = 3333
|
||||
user = mysql_user
|
||||
password = mysql_password
|
||||
database = mysql_database
|
||||
};
|
||||
my $config = Zonemaster::Backend::Config->parse( $text );
|
||||
$log->contains_ok( qr/MYSQL\.port.*MYSQL\.host/, 'warning: MYSQL.host is "localhost" and MYSQL.port defined' );
|
||||
is $config->MYSQL_host, 'localhost', 'set: MYSQL.host';
|
||||
is $config->MYSQL_port, 3333, 'set: MYSQL.port';
|
||||
};
|
||||
|
||||
throws_ok {
|
||||
$log->clear();
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
[LANGUAGE]
|
||||
locale =
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/Use of empty LANGUAGE.locale property is not permitted/, 'die: Invalid empty locale tag';
|
||||
|
||||
throws_ok {
|
||||
my $text = '{"this":"is","not":"a","valid":"ini","file":"!"}';
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/Failed to parse config/, 'die: Invalid INI format';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = Excel
|
||||
|
||||
[SQLITE]
|
||||
databse_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[ZNMEOTAESR]
|
||||
lock_on_queue = 1
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{section.*ZNMEOTAESR}, 'die: Invalid section name';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
pnlilog_iatnvrel = 0.5
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{property.*pnlilog_iatnvrel}, 'die: Invalid property name';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = Excel
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/DB\.engine.*Excel/, 'die: Invalid DB.engine value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
polling_interval = hourly
|
||||
|
||||
[SQLITE]
|
||||
databse_file = /var/db/zonemaster.sqlite
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{DB\.polling_interval.*hourly}, 'die: Invalid DB.polling_interval value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = 192.0.2.1:3306
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{MYSQL\.host.*192.0.2.1:3306}, 'die: Invalid MYSQL.host value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
user = Robert'); DROP TABLE Students;--
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{MYSQL\.user.*Robert'\); DROP TABLE Students;--}, 'die: Invalid MYSQL.user value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster
|
||||
password = (╯°□°)╯︵ ┻━┻
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{MYSQL\.password.*\(╯°□°\)╯︵ ┻━┻}, 'die: Invalid MYSQL.password value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
database = |)/-\'|'/-\|3/-\$[-
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{MYSQL\.database.*|\)/-\'|'/-\\|3/-\\$[-}, 'die: Invalid MYSQL.database value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = 192.0.2.1:5432
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{POSTGRESQL\.host.*192.0.2.1:5432}, 'die: Invalid POSTGRESQL.host value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
user = Robert'); DROP TABLE Students;--
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{POSTGRESQL\.user.*Robert'\); DROP TABLE Students;--}, 'die: Invalid POSTGRESQL.user value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster
|
||||
password = (╯°□°)╯︵ ┻━┻
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{POSTGRESQL\.password.*\(╯°□°\)╯︵ ┻━┻}, 'die: Invalid POSTGRESQL.password value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
database = |)/-\'|'/-\|3/-\$[-
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{POSTGRESQL\.database.*|\)/-\'|'/-\\|3/-\\$[-}, 'die: Invalid POSTGRESQL.database value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = ./relative/path/to/zonemaster.sqlite
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{SQLITE\.database_file.*\./relative/path/to/zonemaster.sqlite}, 'die: Invalid SQLITE.database_file value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[ZONEMASTER]
|
||||
max_zonemaster_execution_time = 0
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{ZONEMASTER\.max_zonemaster_execution_time.*0}, 'die: Invalid ZONEMASTER.max_zonemaster_execution_time value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[ZONEMASTER]
|
||||
lock_on_queue = -1
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{ZONEMASTER\.lock_on_queue.*-1}, 'die: Invalid ZONEMASTER.lock_on_queue value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[ZONEMASTER]
|
||||
number_of_processes_for_frontend_testing = 0
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{ZONEMASTER\.number_of_processes_for_frontend_testing.*0}, 'die: Invalid ZONEMASTER.number_of_processes_for_frontend_testing value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[ZONEMASTER]
|
||||
number_of_processes_for_batch_testing = 100000
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{ZONEMASTER\.number_of_processes_for_batch_testing.*100000}, 'die: Invalid ZONEMASTER.number_of_processes_for_batch_testing value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[ZONEMASTER]
|
||||
age_reuse_previous_test = 0
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr{ZONEMASTER\.age_reuse_previous_test.*0}, 'die: Invalid ZONEMASTER.age_reuse_previous_test value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/MYSQL\.host/, 'die: Missing MYSQL.host value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/MYSQL\.user/, 'die: Missing MYSQL.user value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/MYSQL\.password/, 'die: Missing MYSQL.password value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/MYSQL\.database/, 'die: Missing MYSQL.database value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/POSTGRESQL\.host/, 'die: Missing POSTGRESQL.host value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/POSTGRESQL\.user/, 'die: Missing POSTGRESQL.user value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/POSTGRESQL\.password/, 'die: Missing POSTGRESQL.password value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/POSTGRESQL\.database/, 'die: Missing POSTGRESQL.database value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/MYSQL\.host/, 'die: Missing MYSQL.host value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/MYSQL\.user/, 'die: Missing MYSQL.user value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/MYSQL\.password/, 'die: Missing MYSQL.password value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = MySQL
|
||||
|
||||
[MYSQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/MYSQL\.database/, 'die: Missing MYSQL.database value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/POSTGRESQL\.host/, 'die: Missing POSTGRESQL.host value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
password = zonemaster_password
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/POSTGRESQL\.user/, 'die: Missing POSTGRESQL.user value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
database = zonemaster_database
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/POSTGRESQL\.password/, 'die: Missing POSTGRESQL.password value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = PostgreSQL
|
||||
|
||||
[POSTGRESQL]
|
||||
host = zonemaster-host
|
||||
user = zonemaster_user
|
||||
password = zonemaster_password
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/POSTGRESQL\.database/, 'die: Missing POSTGRESQL.database value';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[LANGUAGE]
|
||||
locale = English
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/LANGUAGE\.locale.*English/, 'die: Invalid locale_tag in LANGUAGE.locale';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[LANGUAGE]
|
||||
locale = en_GB en_US
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/LANGUAGE\.locale.*en/, 'die: Repeated language code in LANGUAGE.locale';
|
||||
|
||||
lives_and {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PUBLIC PROFILES]
|
||||
DEFAULT = /path/to/my.profile
|
||||
|
||||
[PRIVATE PROFILES]
|
||||
SECRET = /path/to/my.profile
|
||||
};
|
||||
my $config = Zonemaster::Backend::Config->parse( $text );
|
||||
eq_or_diff { $config->PUBLIC_PROFILES }, { default => '/path/to/my.profile' }, 'normalize profile names under PUBLIC PROFILES';
|
||||
eq_or_diff { $config->PRIVATE_PROFILES }, { secret => '/path/to/my.profile' }, 'normalize profile names under PRIVATE PROFILES';
|
||||
};
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PUBLIC PROFILES]
|
||||
-invalid-name- = /path/to/my.profile
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/PUBLIC PROFILES.*-invalid-name-/, 'die: Invalid profile name in PUBLIC PROFILES';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PRIVATE PROFILES]
|
||||
-invalid-name- = /path/to/my.profile
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/PRIVATE PROFILES.*-invalid-name-/, 'die: Invalid profile name in PRIVATE PROFILES';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PUBLIC PROFILES]
|
||||
valid-name = relative/path/to/my.profile
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/absolute.*valid-name/, 'die: Invalid absolute path in PUBLIC PROFILES';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PRIVATE PROFILES]
|
||||
valid-name = relative/path/to/my.profile
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/absolute.*valid-name/, 'die: Invalid absolute path in PRIVATE PROFILES';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PUBLIC PROFILES]
|
||||
valid-name = /path/to/my.profile
|
||||
valid-name = /path/to/my.profile
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/unique.*valid-name/, 'die: Repeated profile name in PUBLIC PROFILES section';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PRIVATE PROFILES]
|
||||
valid-name = /path/to/my.profile
|
||||
valid-name = /path/to/my.profile
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/unique.*valid-name/, 'die: Repeated profile name in PRIVATE PROFILES section';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PUBLIC PROFILES]
|
||||
pub-and-priv = /path/to/my.profile
|
||||
|
||||
[PRIVATE PROFILES]
|
||||
pub-and-priv = /path/to/my.profile
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/unique.*pub-and-priv/, 'die: Repeated profile name across sections';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[PRIVATE PROFILES]
|
||||
default = /path/to/my.profile
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/PRIVATE PROFILES.*default/, 'die: Default profile in PRIVATE PROFILES';
|
||||
|
||||
subtest 'RPCAPI experimental aliases' => sub {
|
||||
subtest 'default values' => sub {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
};
|
||||
my $config = Zonemaster::Backend::Config->parse( $text );
|
||||
is $config->RPCAPI_enable_add_api_user, 0, 'default: RPCAPI.enable_add_api_user';
|
||||
is $config->RPCAPI_enable_add_batch_job, 1, 'default: RPCAPI.enable_add_batch_job';
|
||||
is $config->RPCAPI_enable_user_create, 0, 'default: RPCAPI.enable_user_create';
|
||||
is $config->RPCAPI_enable_batch_create, 1, 'default: RPCAPI.enable_batch_create';
|
||||
};
|
||||
|
||||
subtest 'specifying stable and experimental parameters is forbidden' => sub {
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[RPCAPI]
|
||||
enable_user_create = no
|
||||
enable_add_api_user = yes
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/Error:.+RPCAPI\.enable_add_api_user.+RPCAPI\.enable_user_create/, 'die: RPCAPI stable and experimental alias (add_api_user/user_create)';
|
||||
|
||||
throws_ok {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[RPCAPI]
|
||||
enable_add_batch_job = no
|
||||
enable_batch_create = no
|
||||
};
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
}
|
||||
qr/Error:.+RPCAPI\.enable_add_batch_job.+RPCAPI\.enable_batch_create/, 'die: RPCAPI stable and experimental alias (batch_job/batch_create)';
|
||||
};
|
||||
|
||||
subtest 'setting alias' => sub {
|
||||
my $text = q{
|
||||
[DB]
|
||||
engine = SQLite
|
||||
|
||||
[SQLITE]
|
||||
database_file = /var/db/zonemaster.sqlite
|
||||
|
||||
[RPCAPI]
|
||||
enable_user_create = no
|
||||
enable_batch_create = no
|
||||
};
|
||||
my $config = Zonemaster::Backend::Config->parse( $text );
|
||||
is $config->RPCAPI_enable_user_create, 0, 'set: RPCAPI.enable_user_create';
|
||||
is $config->RPCAPI_enable_batch_create, 0, 'set: RPCAPI.enable_batch_create';
|
||||
is $config->RPCAPI_enable_add_api_user, 0, 'aliased: RPCAPI.enable_add_api_user';
|
||||
is $config->RPCAPI_enable_add_batch_job, 0, 'aliased: RPCAPI.enable_add_batch_job';
|
||||
};
|
||||
};
|
||||
|
||||
{
|
||||
my $path = catfile( dirname( $0 ), '..', 'share', 'backend_config.ini' );
|
||||
my $text = read_file( $path );
|
||||
lives_ok {
|
||||
Zonemaster::Backend::Config->parse( $text );
|
||||
} 'default config is valid';
|
||||
}
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user