App-LXC-Container

 view release on metacpan or  search on metacpan

t/06-update.t  view on Meta::CPAN

is($_->{x11}, 0, 'master test 4 X11 is correct');

$_ = App::LXC::Container::Update->new('update-test-1', 'update-test-2');
$_->_parse_master();
is($_->{audio}, 1, 'master test 5 audio is correct');
is($_->{network}, 2, 'master test 5 network is correct');
is($_->{network_from}, 'update-test-2',
   'master test 5 network has correct origin');
is_deeply([sort keys %{$_->{users}}], [1001, 1002, 1003],
	  'master test 5 user ids are correct');
is_deeply([sort values %{$_->{users}}], ['u1', 'u2', 'u3'],
	  'master test 5 users are correct');
is_deeply($_->{users_from}, ['update-test-1', 'update-test-2'],
	  'master test 5 users have correct origin');
is($_->{x11}, 1, 'master test 5 X11 is correct');

$_ = App::LXC::Container::Update->new('update-test-1', 'update-test-2');
$_->_parse_master();
is($_->{audio}, 1, 'master test 6 audio is correct');
is($_->{network}, 2, 'master test 6 network is correct');
is($_->{network_from}, 'update-test-2',
   'master test 6 network has correct origin');
is_deeply([sort keys %{$_->{users}}], [1001, 1002, 1003],
	  'master test 6 user ids are correct');
is_deeply([sort values %{$_->{users}}], ['u1', 'u2', 'u3'],
	  'master test 6 users are correct');
is_deeply($_->{users_from}, ['update-test-1', 'update-test-2'],
	  'master test 6 users have correct origin');
is($_->{x11}, 1, 'master test 6 X11 is correct');

$_ = App::LXC::Container::Update->new('update-test-3');
output_like
{   $_->_parse_master();   }
    qr{^$},
    qr{^audio will not work without local or global network$re_msg_tail\Z},
    'audio without network prints warning';
is($_->{audio}, 1, 'master test 7 audio is correct');
is($_->{network}, 0, 'master test 7 network is correct');
is($_->{network_from}, '???',
   'master test 7 network has correct origin');
is_deeply([sort keys %{$_->{users}}], [1003, 1004],
	  'master test 7 user ids are correct');
is_deeply([sort values %{$_->{users}}], ['u3', 'u4'],
	  'master test 7 users are correct');
is_deeply($_->{users_from}, ['update-test-3'],
	  'master test 7 users have correct origin');
is($_->{x11}, 1, 'master test 7 X11 is correct');

$_ = App::LXC::Container::Update->new('update-test-4');
$_->_parse_master();
is($_->{audio}, 0, 'master test 8 audio is correct');
is($_->{network}, 0, 'master test 8 network is correct');
is_deeply([sort keys %{$_->{users}}], [0],
	  'master test 8 users are correct');
is_deeply([sort values %{$_->{users}}], ['root'],
	  'master test 8 users are correct');
is_deeply($_->{users_from}, ['update-test-4'],
	  'master test 8 users have correct origin');
is($_->{x11}, 0, 'master test 8 X11 is correct');
$_->_parse_users();
like($_->{mount_entry}{'/root'}, qr{^/root\s+root\s+none create=dir,rw,bind$},
     'user test 8 created correct mount entry');
is($_->{mount_source}{'/root'}, 'container users',
   'user test 8 created correct mount source');
is($_->{mounts_of_source}{'container users'}[0], '/root',
   'user test 8 created correct mount source list');

#########################################################################
# test for packages files:
_setup_file('/lxc/conf/u1-PKG-update-test-1.packages',
	    '# 2 identical', '', 'chromium', 'chromium');
_setup_file('/lxc/conf/u2-PKG-update-test-2.packages',
	    '# 2 different', '', 'chromium', 'evince');

$_ = App::LXC::Container::Update->new('update-test-1');
$_->_parse_packages();
is_deeply($_->{package_sources},
	  ['30-PKG-default.packages', 'u1-PKG-update-test-1.packages'],
	  'packages test 1 has correct source list');
# some Smokers don't have a dash, so it's not part of the default package list:
if (5 == @{$_->{packages}})
{
    is_deeply($_->{packages},
	      [qw(coreutils dash libc-bin util-linux chromium)],
	      'packages test 1 has correct content');
}
else
{
    diag(join(' ', 'PACKAGES:', @{$_->{packages}}));
    is_deeply($_->{packages},
	      [qw(coreutils libc-bin util-linux chromium)],
	      'packages test 1a has correct content');
}
is($_->{package_source}{chromium}, 'u1-PKG-update-test-1.packages',
   'packages test 1 chromium entry is correct');

$_ = App::LXC::Container::Update->new('update-test-2');
$_->_parse_packages();
is_deeply($_->{package_sources},
	  ['30-PKG-default.packages', 'u2-PKG-update-test-2.packages'],
	  'packages test 2 has correct source list');
if (6 == @{$_->{packages}})
{
    is_deeply($_->{packages},
	      [qw(coreutils dash libc-bin util-linux chromium evince)],
	      'packages test 2 has correct content');
}
else
{
    is_deeply($_->{packages},
	      [qw(coreutils libc-bin util-linux chromium evince)],
	      'packages test 2a has correct content');
}
is($_->{package_source}{chromium}, 'u2-PKG-update-test-2.packages',
   'packages test 2 chromium entry is correct');
is($_->{package_source}{evince}, 'u2-PKG-update-test-2.packages',
   'packages test 2 evince entry is correct');

$_ = App::LXC::Container::Update->new('update-test-1', 'update-test-2');
$_->_parse_packages();
is_deeply($_->{package_sources},

t/06-update.t  view on Meta::CPAN

   'packages test 3 chromium entry is correct');
is($_->{package_source}{evince}, 'u2-PKG-update-test-2.packages',
   'packages test 3 evince entry is correct');

$_ = App::LXC::Container::Update->new('update-test-2', 'update-test-1');
$_->_parse_master();		# now with audio packages!
$_->_parse_packages();
is_deeply($_->{package_sources},
	  ['30-PKG-default.packages',
	   '31-PKG-network.packages',
	   '60-PKG-X11.packages',
	   '70-PKG-audio.packages',
	   'u2-PKG-update-test-2.packages',
	   'u1-PKG-update-test-1.packages'],
	  'packages test 4 has correct source list');
if (9 == @{$_->{packages}})
{
    is_deeply($_->{packages},
	      [qw(coreutils dash libc-bin util-linux iproute2
		  fontconfig-config pulseaudio-utils chromium evince)],
	      'packages test 4 has correct content');
}
else
{
    diag(join(' ', 'PACKAGES:', @{$_->{packages}}));
    is_deeply($_->{packages},
	      [qw(coreutils libc-bin util-linux iproute2
		  fontconfig-config pulseaudio-utils chromium evince)],
	      'packages test 4a has correct content');
}
is($_->{package_source}{evince}, 'u2-PKG-update-test-2.packages',
   'packages test 4 evince entry is correct');
is($_->{package_source}{'pulseaudio-utils'}, '70-PKG-audio.packages',
   'packages test 4 evince entry is correct');

#########################################################################
# test for mounts files:
my $path2something = TMP_PATH . '/usr/bin/2something';
_setup_file('/lxc/conf/u1-MNT-update-test-1.mounts',
	    '# 1st gets overwritten by 2nd',
	    '',
	    TMP_PATH . '/usr/bin/2something create=unused tmpfs',
	    $path2something);
_setup_file('/lxc/conf/u2-MNT-update-test-2.mounts',
	    '# same as in u1...',
	    '',
	    $path2something);
_setup_file('/lxc/conf/u1-SPC-update-test-1.special',
	    '# special test entry:',
	    '',
	    'lxc.namespace.keep=ipc');

$update_object = App::LXC::Container::Update->new('update-test-1');
$update_object->_parse_mounts();
obj_keys_in_range('mount_entry', 8, 12,
		  'mounts test 1 has correct entry count');
obj_keys_in_range('mount_source', 8, 12,
		  'mounts test 1 has correct source count');
is($update_object->{mount_entry}{$path2something},
   $path2something . ' ' . substr($path2something, 1)
   . ' none create=file,ro,bind 0 0',
   'mounts test 1 source entry is correct');
is($update_object->{mount_source}{$path2something}, 'u1-MNT-update-test-1.mounts',
   'mounts test 1 source entry is correct');

$update_object = App::LXC::Container::Update->new('update-test-2');
$update_object->_parse_master();		# now with X11 mounts!
$update_object->_parse_mounts();
obj_keys_in_range('mount_entry', 18, 22,
		  'mounts test 2 has correct entry count');
obj_keys_in_range('mount_source', 18, 22,
		  'mounts test 2 has correct source count');
is($update_object->{mount_entry}{$path2something},
   $path2something . ' ' . substr($path2something, 1)
   . ' none create=file,ro,bind 0 0',
   'mounts test 2 source entry is correct');
is($update_object->{mount_source}{$path2something}, 'u2-MNT-update-test-2.mounts',
   'mounts test 2 source entry is correct');
is($update_object->{mount_entry}{'/usr/share/icons'},
   '/usr/share/icons usr/share/icons none create=dir,ro,bind 0 0',
   'mounts test 2 source entry for X11 is correct');
is($update_object->{mount_source}{'/usr/share/icons'}, '61-MNT-X11.mounts',
   'mounts test 2 source entry for X11 is correct');

$update_object = App::LXC::Container::Update->new('update-test-1', 'update-test-2');
$update_object->_parse_mounts();
obj_keys_in_range('mount_entry', 8, 12,
		  'mounts test 3 has correct entry count');
obj_keys_in_range('mount_source', 8, 12,
		  'mounts test 3 has correct source count');
is($update_object->{mount_entry}{$path2something},
   $path2something . ' ' . substr($path2something, 1)
   . ' none create=file,ro,bind 0 0',
   'mounts test 3 source entry is correct');
is($update_object->{mount_source}{$path2something}, 'u2-MNT-update-test-2.mounts',
   'mounts test 3 source entry is correct');

$update_object = App::LXC::Container::Update->new('update-test-2', 'update-test-1');
$update_object->_parse_mounts();
obj_keys_in_range('mount_entry', 8, 12,
		  'mounts test 4 has correct entry count');
obj_keys_in_range('mount_source', 8, 12,
		  'mounts test 4 has correct source count');
is($update_object->{mount_entry}{$path2something},
   $path2something . ' ' . substr($path2something, 1)
   . ' none create=file,ro,bind 0 0',
   'mounts test 4 source entry is correct');
is($update_object->{mount_source}{$path2something}, 'u1-MNT-update-test-1.mounts',
   'mounts test 4 source entry is correct');

#########################################################################
# test for filter files:
_setup_file('/lxc/conf/u1-NOT-update-test-1.filter',
	    '# 2nd overwrites 1st',
	    TMP_PATH . '/usr/lib nomerge',
	    TMP_PATH . '/var/log empty',
	    TMP_PATH . '/.Xdummy empty');
_setup_file('/lxc/conf/u2-NOT-update-test-2.filter',
	    '# 2nd overwrites 1st',
	    TMP_PATH . '/var/log copy');

$update_object = App::LXC::Container::Update->new('update-test-1');
$update_object->_parse_filter();
is($update_object->{filter}{TMP_PATH . '/usr/lib'}, 'nomerge',
   'filter test 1 /usr/lib entry is correct');
is($update_object->{filter}{TMP_PATH . '/var/log'}, 'empty',
   'filter test 1 /var/log entry is correct');
my $count1 = scalar(keys %{$update_object->{filter}});

$update_object = App::LXC::Container::Update->new('update-test-2');
$update_object->_parse_filter();
is(scalar(keys %{$update_object->{filter}}), $count1 - 2,
   'filter test 2 has correct count');
is($update_object->{filter}{TMP_PATH . '/var/log'}, 'copy',
   'filter test 2 /var/log entry is correct');

$update_object =
    App::LXC::Container::Update->new('update-test-1', 'update-test-2');
$update_object->_parse_filter();
is($update_object->{filter}{TMP_PATH . '/var/log'}, 'copy',
   'filter test 3 /var/log entry is correct');

$update_object =
    App::LXC::Container::Update->new('update-test-2', 'update-test-1');
$update_object->_parse_filter();
is($update_object->{filter}{TMP_PATH . '/var/log'}, 'empty',
   'filter test 4 /var/log entry is correct');

#########################################################################
# full test:

SKIP:{
    # Some smokers don't have the needed directory /usr/share/ssl-cert, so
    # hopefully we can create it:
    unless (-d '/usr/share/ssl-cert')
    {
	$< == 0
	    or  skip 'rest of tests not possible without /usr/share/ssl-cert', 62;
	mkdir '/usr/share/ssl-cert'
	    or  warn 'failed to mkdir /usr/share/ssl-cert';
    }
    # Running these tests in a sub-directory below /tmp cause
    # inconsistencies as that is one of our special directories:
    TMP_PATH =~ m|^/tmp/|  and  skip 'rest of tests not working below /tmp', 62;

    _setup_link(TMP_PATH . '/usr/bin/3link', '2something');

t/06-update.t  view on Meta::CPAN


    output_like			# last name becomes container name!
    {   App::LXC::Container::update('update-test-2', 'update-test-1');   }
    qr{^$},
    qr{\A$re_err2$re_err4$re_err_o1$re_err3\Z},
    'full test run with expected output';

    ok(-f CONF_ROOT . '/update-test-1.conf',
       'LXC configuration file has been created');
    $re = join
	("\n",
	 '^# container description created by App::LXC::Container::Update',
	 '# MASTER: G5,X,A',
	 'lxc\.uts\.name = update-test-1',
	 'lxc\.rootfs\.path = /.+/tmp/lxc/update-test-1',
	 'lxc\.rootfs\.options = idmap=container',
	 '',
	 '#+ update-test-2, 10-NET-default\.conf #+',
	 'lxc\.net\.0\.type = veth',
	 'lxc\.net\.0\.flags = up',
	 'lxc\.net\.0\.link = lxcbr0',
	 'lxc\.net\.0\.name = eth0',
	 'lxc\.net\.0\.ipv4\.address = 10\.0\.3\.5/24',
	 'lxc\.net\.0\.hwaddr = 00:16:3e:xx:xx:xx',
	 '',
	 '#+ 20-DEV-default\.conf #+',
	 'lxc\.pty\.max = 8',
	 'lxc\.mount\.auto = cgroup:ro proc:mixed sys:ro',
	 '',
	 '#+ update-test-2, update-test-1 #+',
	 '# root:',
	 'lxc\.idmap = u 0 0 1',
	 'lxc\.idmap = u 1 100001 1000',
	 '# u1:',
	 'lxc\.idmap = u 1001 1001 1',
	 '# u2:',
	 'lxc\.idmap = u 1002 1002 1',
	 '# u3:',
	 'lxc\.idmap = u 1003 1003 1',
	 'lxc\.idmap = u 1004 101004 64532',
	 '# root:',
	 'lxc\.idmap = g 0 0 1',
	 'lxc\.idmap = g 1 100001 1000',
	 '# u1:',
	 'lxc\.idmap = g 1001 1001 1',
	 '# u2:',
	 'lxc\.idmap = g 1002 1002 1',
	 '# u3:',
	 'lxc\.idmap = g 1003 1003 1',
	 'lxc\.idmap = g 1004 101004 64532',
	 '',
	 '#+ special configuration #+',
	 'lxc.namespace.keep=ipc',
	 '',
	 '#+ container users #+',
	 '',
	 '#+ 40-MNT-default\.mounts #+',
	 # distributions may have additional non-symlink directories here,
	 # some are missing /dev/shm:
	 '.*(lxc\.mount\.entry = tmpfs dev/shm tmpfs create=dir,rw 0 0',
	 ')?lxc\.mount\.entry = /etc/login.defs etc/login.defs none create=file,ro,bind 0 0',
	 'lxc\.mount\.entry = /etc/pam.d etc/pam.d none create=dir,ro,bind 0 0',
	 'lxc\.mount\.entry = /etc/security etc/security none create=dir,ro,bind 0 0',
	 '.*lxc\.mount\.entry = tmpfs root tmpfs create=dir,rw,mode=700 0 0',
	 '.*lxc\.mount\.entry = /tmp tmp none create=dir,rw,bind 0 0',
	 'lxc\.mount\.entry = tmpfs var/tmp tmpfs create=dir,rw 0 0',
	 '(lxc\.mount\.entry = /etc/debian_version etc/debian_version none create=file,ro,bind 0 0',
	 ')?',
	 '#+ 41-MNT-network\.mounts #+',
	 'lxc\.mount\.entry = /etc/ssl/certs etc/ssl/certs none create=dir,ro,bind 0 0',
	 'lxc\.mount\.entry = /usr/lib/ssl usr/lib/ssl none create=dir,ro,bind 0 0',
	 'lxc\.mount\.entry = /usr/share/ca-certificates usr/share/ca-certificates none create=dir,ro,bind 0 0',
	 'lxc\.mount\.entry = /usr/share/ssl-cert usr/share/ssl-cert none create=dir,ro,bind 0 0',
	 '',
	 '#+ 61-MNT-X11\.mounts #+',
	 '[^#]+#+ u2-MNT-update-test-2\.mounts #+',
	 '',
	 '#+ u1-MNT-update-test-1\.mounts #+',
	 'lxc\.mount\.entry = /.+/bin/2something none create=file,ro,bind 0 0',
	 'lxc\.mount\.entry = /.+/bin/2something none create=file,ro,bind 0 0',
	 '',
	 '#+ 30-PKG-default\.packages #+',
	 '# coreutils',
	 '# dash',
	 '# libc-bin',
	 '# util-linux',
	 '#+ 31-PKG-network.packages #+',
	 '# iproute2',
	 '#+ 60-PKG-X11.packages #+',
	 '# fontconfig-config',
	 '#+ 70-PKG-audio\.packages #+',
	 '# pulseaudio-utils',
	 '#+ u2-PKG-update-test-2\.packages #+',
	 '# chromium',
	 '# evince',
	 '#+ u1-PKG-update-test-1\.packages #+',
	 '',
	 '#+ empty filters #+',
	 'lxc\.mount\.entry = tmpfs .+/tmp/var/log tmpfs create=dir,rw 0 0',
	 'lxc\.mount\.entry = tmpfs var/log tmpfs create=dir,rw 0 0',
	 '',
	 '#+ mounts derived from above packages #+',
	 'lxc\.mount\.entry = /.+/tmp/usr/bin/1chromium .+/tmp/usr/bin/1chromium none create=file,ro,bind 0 0',
	 'lxc\.mount\.entry = /.+/tmp/usr/lib/some/directory/with .+/tmp/usr/lib/some/directory/with none create=dir,ro,bind 0 0'
# helper expression to update test after modifying Data/*.pm (move up/down):
#(1?():(
##))
	);
    my $conf = '';
    if (-f CONF_ROOT . '/update-test-1.conf')
    {
	open my $in, '<', CONF_ROOT . '/update-test-1.conf'
	    or  die "can't open ", CONF_ROOT, '/update-test-1.conf: ', $!;
	$conf = join('', <$in>);
	close $in;
    }
    like($conf, qr{^$re}s, 'LXC configuration file looks correct');

    foreach (qw(bin lib lib32 lib64 libx32 sbin))
    {
    SKIP:{
	    -l '/' . $_  or  skip "/$_ not symbolic link on $os", 1;
	    ok(-l CONF_ROOT . '/update-test-1/' . $_,  'got link: /' . $_);
	}
    }
    my $tmp_sub = substr(TMP_PATH, 1);
    foreach (qw(root tmp var var/log),
	     map { $tmp_sub . '/' . $_ }
	     qw(usr usr/bin usr/lib usr/lib/some/directory/with var var/log))
    {
	ok(-d CONF_ROOT . '/update-test-1/' . $_,  'got directory: /' . $_);
    }
    ok(! -e  CONF_ROOT . '/update-test-1/usr/lib/some/directory/with/file-1.txt',
       'no file-1.txt in /update-test-1/usr/lib/some/directory/with');
    foreach my $bin (qw(1chromium 2something 3link))
    {
	$_ = $tmp_sub . '/usr/bin/' . $bin;
	ok(-f CONF_ROOT . '/update-test-1/' . $_,  'got file: /' . $_);
    }
    $_ = $tmp_sub . '/usr/bin/3link';
    ok(-l CONF_ROOT . '/update-test-1/' . $_,  'got link: /' . $_);
    is((stat(CONF_ROOT . '/update-test-1/root'))[2] & 07777, 0700,
       '/root has correct permission');
    is((stat(CONF_ROOT . '/update-test-1/tmp'))[2] & 07777, 01777,
       '/tmp has correct permission');

    #####################################################################
    # tests of local-network and network container:
    foreach my $network ('local-network', 'network')
    {
	output_like		# last name becomes container name!
	{   App::LXC::Container::update($network);   }
	qr{^$},
	qr{\A$re_err2$re_err3\Z},
	'test run for container "' . $network . '" had expected output';

	my $conf_file = CONF_ROOT . '/' . $network . '.conf';
	ok(-f $conf_file,
	   'LXC configuration file has been created - ' . $network);
	my $net_key = $network eq 'network' ? 'G' : 'L';
	my $net_id = $network eq 'network' ? 3 : 2;
	$re = join
	    ("\n",
	     '^# container description created by App::LXC::Container::Update',
	     '# MASTER: ' . $net_key . $net_id . ',-,-',
	     'lxc\.uts\.name = ' . $network,
	     'lxc\.rootfs\.path = /.+/tmp/lxc/' . $network,
	     'lxc\.rootfs\.options = idmap=container',
	     '',
	     '#+ ' . $network . ', 10-NET-default\.conf #+',
	     'lxc\.net\.0\.type = veth',
	     'lxc\.net\.0\.flags = up',
	     'lxc\.net\.0\.link = lxcbr0',
	     'lxc\.net\.0\.name = eth0',
	     'lxc\.net\.0\.ipv4\.address = 10\.0\.3\.' . $net_id . '/24',
	     'lxc\.net\.0\.hwaddr = 00:16:3e:xx:xx:xx',
	     '',
	     '#+ 20-DEV-default\.conf #+',
	     'lxc\.pty\.max = 8',
	     'lxc\.mount\.auto = cgroup:ro proc:mixed sys:ro',
	     '',
	     '#+ -no privileged users- #+',
	     'lxc\.idmap = u 0 100000 65536',
	     'lxc\.idmap = g 0 100000 65536',
	     '',
	     '#+ 40-MNT-default\.mounts #+',
	     # distributions may have additional non-symlink directories here,
	     # some are missing /dev/shm:
	     '.*(lxc\.mount\.entry = tmpfs dev/shm tmpfs create=dir,rw 0 0',
	     ')?lxc\.mount\.entry = /etc/login.defs etc/login.defs none create=file,ro,bind 0 0',
	     'lxc\.mount\.entry = /etc/pam.d etc/pam.d none create=dir,ro,bind 0 0',
	     'lxc\.mount\.entry = /etc/security etc/security none create=dir,ro,bind 0 0',
	     '.*lxc\.mount\.entry = tmpfs root tmpfs create=dir,rw,mode=700 0 0',
	     '.*lxc\.mount\.entry = /tmp tmp none create=dir,rw,bind 0 0',
	     'lxc\.mount\.entry = tmpfs var/tmp tmpfs create=dir,rw 0 0',
	     '(lxc\.mount\.entry = /etc/debian_version etc/debian_version none create=file,ro,bind 0 0',
	     ')?',
	     '#+ 41-MNT-network\.mounts #+',
	     'lxc\.mount\.entry = /etc/ssl/certs etc/ssl/certs none create=dir,ro,bind 0 0',
	     'lxc\.mount\.entry = /usr/lib/ssl usr/lib/ssl none create=dir,ro,bind 0 0',
	     'lxc\.mount\.entry = /usr/share/ca-certificates usr/share/ca-certificates none create=dir,ro,bind 0 0',
	     'lxc\.mount\.entry = /usr/share/ssl-cert usr/share/ssl-cert none create=dir,ro,bind 0 0',
	     '',
	     '#+ 30-PKG-default\.packages #+',
	     '# coreutils',
	     '# dash',
	     '# libc-bin',
	     '# util-linux',
	     '#+ 31-PKG-network.packages #+',
	     '# iproute2',
	     '',
	     '#+ empty filters #+',
	     'lxc.mount.entry = tmpfs var/log tmpfs create=dir,rw 0 0',
	     '',
	     '#+ mounts derived from above packages #+',
	     'lxc\.mount\.entry = /.+/tmp/usr/bin/2something .+/tmp/usr/bin/2something none create=file,ro,bind 0 0'
# helper expression to update test after modifying Data/*.pm (move up/down):
#(1?():(
#))
	    );
	if (-f $conf_file)
	{
	    open my $in, '<', $conf_file
		or  die "can't open ", $conf_file . ': ', $!;
	    $conf = join('', <$in>);
	    close $in;
	}
	like($conf, qr{^$re}s,
	     'LXC configuration file looks correct - ' . $network);

	my $conf_dir = CONF_ROOT . '/' . $network . '/';
	foreach (qw(bin lib lib32 lib64 libx32 sbin))
	{
	SKIP:{
		-l '/' . $_  or  skip "/$_ not symbolic link on $os", 1;
		ok(-l $conf_dir . $_,  'got link /' . $_ . ' in ' . $network);
	    }
	}
	foreach (qw(root tmp var var/log),
		 map { $tmp_sub . '/' . $_ } qw(usr usr/bin))
	{
	    ok(-d $conf_dir . $_,  'got directory /' . $_ . ' in ' . $network);
	}
	$_ = $tmp_sub . '/usr/bin/2something';
	ok(-f $conf_dir . $_,  'got file /' . $_ . ' in ' . $network);
	is((stat(CONF_ROOT . '/' . $network . '/root'))[2] & 07777, 0700,
	   '/root has correct permission in ' . $network);
	is((stat(CONF_ROOT . '/' . $network . '/tmp'))[2] & 07777, 01777,
	   '/tmp has correct permission in ' . $network);
    }

} # end of big SKIP block



( run in 0.603 second using v1.01-cache-2.11-cpan-2398b32b56e )