App-LXC-Container
view release on metacpan or search on metacpan
t/03-setup.t view on Meta::CPAN
}
else
{ fail($name . ' has correct content after ' . $nr . ' run'); }
}
#########################################################################
# identical parts of messages:
my $re_msg_tail = qr/ at $0 line \d{2,}\.?$/;
my $re_msg_tail_m = qr/ at $0 line \d{2,}\.?$/m;
my $re_msg_tail_eval = qr/ at \(eval \d+\)(?:\[$0:\d{2,}\])? line \d+\.?$/;
# initial clean-up, only needed for re-run:
_remove_file('/lxc/conf/' . $_) foreach('tt-CNF-test.master',
'tt-MNT-test.mounts',
'tt-NOT-test.filter',
'tt-PKG-test.packages');
#########################################################################
# failing tests:
_remove_link(LXC_LINK);
_setup_dir('/home/.lxc-configuration');
$_ = fail_in_sub_perl(1);
like($_,
qr{t/tmp/home/.lxc-configuration is not a symbolic link at -e line \d\.$}m,
'bad configuration link should fail');
$_ = fail_in_sub_perl(2);
my $re = 'INTERNAL ERROR [^:]+: directory missing '
. 'in _save_configuration at -e line \d\.';
like($_, qr/^$re$/m,
'missing configuration directory should fail on save');
_remove_dir(LXC_LINK);
_setup_link(LXC_LINK, CONF_ROOT);
eval { App::LXC::Container::setup('bad-name!'); };
like($@,
qr/^The name of the container may only contain word char.*!$re_msg_tail/,
'bad container name fails');
App::LXC::Container::Texts::debug(0); # manual reset!
eval {
App::LXC::Container::Setup::_write_to('t/tmp/not-existing-dir/file', '');
};
like($@,
qr{^can't open 't/tmp/not-existing-dir/file': .*$re_msg_tail},
'bad file name fails');
#########################################################################
# simple writing tests:
my $abs_test_file = HOME_PATH . '/write.tst';
my $test_file = '/home/write.tst';
output_like
{ App::LXC::Container::Setup::_write_to($abs_test_file, '42'); }
qr{^$}, qr{^$},
'1st writing test did not fail';
output_like
{ App::LXC::Container::Setup::_write_to($abs_test_file, '47'); }
qr{^$}, qr{^$},
'2nd writing test did not fail';
_chmod(0444, $test_file);
output_like
{ App::LXC::Container::Setup::_write_to($abs_test_file, '0'); }
qr{^$}, qr{^using existing protected .*/t/tmp/home/write.tst$re_msg_tail},
'3rd writing test produced warning';
my $output = '';
if (-f $abs_test_file)
{
open my $in, '<', $abs_test_file
or die "can't open ", $abs_test_file, ': ', $!;
$output = join('', <$in>);
close $in;
}
is($output, "47\n", 'writing test produced expected output');
_remove_file($test_file);
#########################################################################
# regular expression parts for tests (hangs without possessive matching):
my $re_div = '----------\s++';
my $re_buttons_mp = '\[ - \]\s++\[ \+ \]\s++';
my $re_buttons_map = '\[ - \]\s++\[ \* \]\s++\[ \+ \]\s++';
my $re_buttons_mapp = '\[ - \]\s++\[ \* \]\s++\[ \+ \]\s++\[ \+\+ \]\s++';
my $re_listbox_head = '(?:<1> ++)?(?:0|[1-9][0-9]*-[1-9][0-9]*)/\d+\s++';
my $re_list_buttons_mp = $re_listbox_head . '[^[]*+' . $re_buttons_mp;
my $re_list_buttons_map = $re_listbox_head . '[^[]*+' . $re_buttons_map;
my $re_list_buttons_mapp = $re_listbox_head . '[^[]*+' . $re_buttons_mapp;
my $re_list_packages = 'packages\s++' . $re_list_buttons_mapp;
my $re_list_files = 'files\s++' . $re_list_buttons_map;
my $re_list_filter = 'filter\s++' . $re_list_buttons_map;
my $re_radio = '(?:<[1*]>\s++)?\([o ]\) ';
my $re_network =
'network\s++' .
$re_radio . 'none\s++' .
$re_radio . 'local\s++' .
$re_radio . 'full\s++' .
$re_div;
my $re_features =
'features\s++' .
'\[[ X]\] X11\s++' .
'\[[ X]\] audio\s++' .
$re_div;
my $re_list_users = 'users\s++' . $re_list_buttons_mp;
my $re_main_buttons =
'(?:<7> )?\[ Quit \]\s++' .
'(?:<8> )?\[ Help \]\s++' .
'(?:<9> )?\[ OK \]\s++';
my $re_select =
'^<0> leave (box|dialogue|window)\s++' .
'^----- enter number to choose next step: \d++\s++';
my $re_select_mp = '<1> \[ - \]\s++<2> \[ \+ \]\s++';
my $re_select_map = '<1> \[ - \]\s++<2> \[ \* \]\s++<3> \[ \+ \]\s++';
my $re_select_mapp =
'<1> \[ - \]\s++<2> \[ \* \]\s++<3> \[ \+ \]\s++<4> \[ \+\+ \]\s++';
my $re_select_listbox =
'^< ?0> ++leave listbox\s++' .
'^enter selection(?: \(\+/- scrolls\))?: \d++\s++';
my $re_select_radio =
'^enter selection \(0 to cancel\): \d++\s++';
my $re_window_content =
'<1>\s++' .
t/03-setup.t view on Meta::CPAN
('tt-CNF-test.master', '3rd',
qr{^network=1\nx11=1\naudio=1\nusers=$re_user$}m);
check_config_against_regexp
('tt-MNT-test.mounts', '3rd',
qr{\A\#\ mounts\ for\ container\ test$
.*/t/tmp/usr/bin/2something$
.*/t/tmp/usr/bin/2something\s+create=file,rw\s+tmpfs$
.*/t/tmp/usr/bin/2something\s+create=file,rw,bind$}msx);
check_config_against_regexp
('tt-NOT-test.filter', '3rd',
qr{^/var/log\s+empty\n
.*/t/tmp/usr/bin/2something\s+copy\n
.*/t/tmp/usr/bin/2something\s+nomerge\n
.*/t/tmp/usr/bin/2something\s+ignore\n}mx);
check_config_against_regexp
('tt-PKG-test.packages', '3rd',
qr{\A# package list for container test\n.*^chromium\n\Z}ms);
#########################################################################
# 4th round: read modified configuration again:
@input = qw(1 7);
$re_output =
$re_main_window .
$re_main_box .
'$';
output_like
{ _call_with_stdin(\@input, sub { App::LXC::Container::setup("test"); }); }
qr{$re_output}ms,
qr{$re_error_to_small},
'reading modified configuration again did not cause any errors';
#########################################################################
# simulate invalid configuration entries and other fatal errors:
eval { App::LXC::Container::Setup::_mark2filter('XX /bad-entry'); };
like($@,
qr/^INTERNAL ERROR [^:]+: bad mark 'XX' in _mark2filter$re_msg_tail/,
'bad filter entry fails');
eval { App::LXC::Container::Setup::_mark2mount('YY /bad-entry'); };
like($@,
qr/^INTERNAL ERROR [^:]+: bad mark 'YY' in _mark2mount$re_msg_tail/,
'bad mount entry fails');
eval { App::LXC::Container::Setup::_modify_entry(1,2,3, 1,2); };
like($@,
qr/^INTERNAL ERROR [^:]+: uneven list in _modify_entry$re_msg_tail/,
'short parameter list for _modify_entry fails');
eval { App::LXC::Container::Setup::_modify_entry(1,2,3, 1,2,3,4,5); };
like($@,
qr/^INTERNAL ERROR [^:]+: uneven list in _modify_entry$re_msg_tail/,
'uneven parameter list for _modify_entry fails');
my $dummy_obj = {name => 'not-accessible'};
sub test_not_accessible($)
{
my ($file) = @_;
my $short_path = '/lxc/conf/' . $file;
_remove_file($short_path);
_setup_file($short_path);
_chmod(0, $short_path);
my $re = "can't open '" . LXC_LINK . '/conf/' . $file . "'" . ': .*'
. $re_msg_tail_eval;
(my $func = $file) =~ s/^.*\.//;
$func = 'App::LXC::Container::Setup::_parse_' . $func . '($dummy_obj);';
eval "$func";
like($@, qr/^$re$/,
'reading non-accessible configuration file ' . $file . ' fails');
}
test_not_accessible('ne-NOT-not-accessible.filter');
test_not_accessible('ne-CNF-not-accessible.master');
test_not_accessible('ne-MNT-not-accessible.mounts');
test_not_accessible('ne-PKG-not-accessible.packages');
$dummy_obj = {name => 'bad'};
sub test_bad_config($@)
{
my $file = shift;
my $short_path = '/lxc/conf/' . $file;
_remove_file($short_path);
_setup_file($short_path, @_);
my $re = "ignoring unknown configuration item in '" . LXC_LINK .
'/conf/' . $file . "'" . ', line 1' . $re_msg_tail_eval;
(my $func = $file) =~ s/^.*\.//;
$func = 'App::LXC::Container::Setup::_parse_' . $func . '($dummy_obj);';
output_like
{ eval "$func"; }
qr{^$}, qr/^$re$/,
'reading bad configuration file ' . $file . ' fails';
}
test_bad_config('bd-NOT-bad.filter', 'bad entry');
test_bad_config('bd-CNF-bad.master', 'bad entry');
test_bad_config('bd-MNT-bad.mounts', 'bad-entry ');
test_bad_config('bd-PKG-bad.packages', 'bad entry');
#########################################################################
# simulate some more valid configuration entries:
like(App::LXC::Container::Setup::_mark2mount('RW /dev/disk'),
qr{^/dev/disk\s+create=dir,rw,bind,optional$},
'valid optional device directory');
like(App::LXC::Container::Setup::_mark2mount('RW /dev/somedevice'),
qr{^/dev/somedevice\s+create=file,rw,bind,optional$},
'valid optional device file');
like(App::LXC::Container::Setup::_mark2mount('OV /'),
qr{^/\s+create=dir,rw\s+tmpfs$},
'valid temporary directory');
#########################################################################
# run tests with other maximum screen sizes:
sub test_other_screen_size($$)
{
my ($w, $h) = @_;
my %dummy_obj = (MAIN_UI => UI::Various::Main->new(),
name => 'x', packages => [], mounts => [], filter => [],
network => 0, x11 => 0, audio => 0, users => []);
# Unfortunately we need to access UI::Various internal structure here to
# modify the maximum size of the virtual screen:
$dummy_obj{MAIN_UI}{max_width} = $w;
$dummy_obj{MAIN_UI}{max_height} = $h;
return bless \%dummy_obj, 'App::LXC::Container::Setup';
};
output_like
{
my $dummy_obj = test_other_screen_size(12, 99);
App::LXC::Container::Setup::_create_main_window($dummy_obj);
}
qr{^$}, qr{^$re_error_to_small},
'narrow window causes error';
output_like
{
my $dummy_obj = test_other_screen_size(99, 24);
App::LXC::Container::Setup::_create_main_window($dummy_obj);
}
qr{^$}, qr{^$re_error_to_small},
'low window causes error';
output_like
{
my $dummy_obj = test_other_screen_size(99, 99);
App::LXC::Container::Setup::_create_main_window($dummy_obj);
}
qr{^$}, qr{^$},
'large enough window removed error';
#########################################################################
# special tests for library dependencies (ldd):
package Dummy::UI
{
require Exporter;
our @ISA = qw(Exporter);
sub new($) { my $self = {}; bless $self, 'Dummy::UI'; }
sub add($@) { shift; print "ADD2UI\t", join(',', @_), "\n"; }
};
sub test_ldd_dummy_object(@)
{
my $dummy_ui = Dummy::UI->new();
App::LXC::Container::Setup::__add_library_packages_internal_code
($dummy_ui, @_);
}
stdout_like
{ test_ldd_dummy_object('/bin/ls'); }
qr{^ADD2UI\s+libc6(?::amd64|:i386)?$},
'test for existing library dependencies';
_setup_file('/usr/bin/3ls');
_setup_link(TMP_PATH . '/usr/libbad.so.0', '/usr/non-existing-dir/libbad.so');
chmod 0755, T_PATH . '/mockup/ldd'
or die "can't chmod 0755 ", T_PATH . '/mockup/ldd';
stdout_like
{ test_ldd_dummy_object(TMP_PATH . '/usr/bin/3ls'); }
qr{^$},
'ldd test with bad symbolic link';
stdout_like
{ test_ldd_dummy_object('/nowhere/to/be/found'); }
qr{^$},
'test for non-existing library dependencies';
_remove_link(TMP_PATH . '/usr/libbad.so.0');
chmod 0644, T_PATH . '/mockup/ldd'
or die "can't chmod 0644 ", T_PATH . '/mockup/ldd';
#########################################################################
# final statistics:
diag('big test statistic: ', $big_stat[0],
' inputs checked against a regular expression of size ', $big_stat[1]);
( run in 1.241 second using v1.01-cache-2.11-cpan-99c4e6809bf )