From 7a62440f022f1372dfe19d13de24e0b9c3374023 Mon Sep 17 00:00:00 2001 From: Michael Prokop Date: Tue, 19 Mar 2013 01:51:09 +0100 Subject: [PATCH] Initial checkin --- ce/01_hostname-and-interfaces.t | 114 +++++++++++++++++++++++++++++++ ce/01_running-processes.t | 80 ++++++++++++++++++++++ ce/02_disk-free.t | 103 ++++++++++++++++++++++++++++ ce/test-server.yaml | 33 +++++++++ debian/changelog | 6 ++ debian/compat | 1 + debian/control | 19 ++++++ debian/copyright | 23 +++++++ debian/ngcp-system-tests.install | 3 + debian/rules | 3 + pro/01_hostname-and-interfaces.t | 114 +++++++++++++++++++++++++++++++ pro/01_running-processes.t | 1 + testrunner | 25 +++++++ 13 files changed, 525 insertions(+) create mode 100644 ce/01_hostname-and-interfaces.t create mode 100644 ce/01_running-processes.t create mode 100644 ce/02_disk-free.t create mode 100644 ce/test-server.yaml create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/ngcp-system-tests.install create mode 100755 debian/rules create mode 100644 pro/01_hostname-and-interfaces.t create mode 120000 pro/01_running-processes.t create mode 100755 testrunner diff --git a/ce/01_hostname-and-interfaces.t b/ce/01_hostname-and-interfaces.t new file mode 100644 index 0000000..f788ad9 --- /dev/null +++ b/ce/01_hostname-and-interfaces.t @@ -0,0 +1,114 @@ +#!/usr/bin/perl + +=head1 NAME + +hostname-and-interfaces - check hostname and ip resolution on interfaces + +=head2 SYNOPSIS + + NONE + +=head2 DESCRIPTION + +Checks the hostname short name and fqdn. Cheks the ip adresses on the interfaces +if resolv to some hostname. + +=cut + +use strict; +use warnings; + +use Test::More 'tests' => 5; +use Test::Differences; + +use List::MoreUtils 'any'; +use Sys::Net 'resolv', 'interfaces'; + +my $HOSTNAME_CMD = 'hostname'; + +exit main(); + + +sub main { + my $hostname_short_ip; + my $hostname_fqdn_ip; + SKIP: { + my $hostname = `$HOSTNAME_CMD`; + skip 'hostname command not found', 2 + if not defined $hostname; + + my $hostname_short = `$HOSTNAME_CMD --short`; + $hostname_short =~ s/^\s*(.*)\s*$/$1/; + diag 'short hostname - ', $hostname_short + if $ENV{TEST_VERBOSE}; + my $hostname_fqdn = `$HOSTNAME_CMD --fqdn`; + $hostname_fqdn =~ s/^\s*(.*)\s*$/$1/; + diag 'fqdn hostname - ', $hostname_fqdn + if $ENV{TEST_VERBOSE}; + + is($hostname_short, $hostname_fqdn, 'short hostname should be the same as fqdn'); + + # short hostname from fqdn + my ($short) = split /\./, $hostname_fqdn; + + is($short, $hostname_short, 'check short hostname'); + + # resolv ip-s for short and fqdn hostname + $hostname_short_ip = resolv($hostname_short); + $hostname_fqdn_ip = resolv($hostname_fqdn); + is( + $hostname_short_ip, + $hostname_fqdn_ip, + 'ip-s of short hostname and fqdn should be the same - '.$hostname_fqdn_ip, + ); + } + + SKIP: { + skip 'fqdn not found', 2 + if not defined $hostname_fqdn_ip; + + # get interfaces + my %if_named = %{interfaces()}; + + skip 'no interfaces found', 2 + if not keys %if_named; + + ok( + (any { $_->{'ip'} eq $hostname_fqdn_ip } values %if_named ), + 'there should be at leas one interface with hostname ip - '.$hostname_fqdn_ip, + ); + + # loop through all interfaces + foreach my $ifname (keys %if_named) { + my $iface = $if_named{$ifname}; + + # resolv interface ip to hostnames + $iface->{'hostname'} = resolv($iface->{'ip'}); + diag 'if ', $ifname, ' ip ', $iface->{'ip'}, ' resolves to ', $iface->{'hostname'} + if $ENV{TEST_VERBOSE}; + } + + # check if every interface has a hostname set (different from the ip) + eq_or_diff( + [ map { + $_->{'hostname'} + && ($_->{'hostname'} ne $_->{'ip'}) + ? $_->{'ip'} + : 'not resolving' + } values %if_named ], + [ map { $_->{'ip'} } values %if_named ], + 'every interface ip should resolv to a name', + ); + } + + return 0; +} + + +__END__ + +=head1 AUTHOR + +Jozef Kutej + +=cut diff --git a/ce/01_running-processes.t b/ce/01_running-processes.t new file mode 100644 index 0000000..d69fc68 --- /dev/null +++ b/ce/01_running-processes.t @@ -0,0 +1,80 @@ +#!/usr/bin/perl + +=head1 NAME + +running-processes - check running processes + +=head2 SYNOPSIS + + cat >> test-server.yaml << __YAML_END__ + running-processes: + should-run: + - dhclient3 + - /usr/sbin/sshd + - /usr/sbin/cron + __YAML_END__ + + +=cut + +use strict; +use warnings; + +use Test::More; +use Test::Differences; +use List::MoreUtils 'any'; +use Carp::Clan 'croak'; +use FindBin '$Bin'; +use YAML::Syck 'LoadFile'; + +eval "use Proc::ProcessTable"; +plan 'skip_all' => "need Proc::ProcessTable to run processes tests" if $@; + +my $config = LoadFile($Bin.'/test-server.yaml'); +plan 'skip_all' => "no configuration sections for 'running-processes'" + if (not $config or not $config->{'running-processes'}); + + +exit main(); + +sub main { + plan 'tests' => 1; + + my $process_table = Proc::ProcessTable->new; + + SKIP: { + skip 'no should-run section, not checking running processes', 1 + if ref $config->{'running-processes'}->{'should-run'} ne 'ARRAY'; + my @should_run = @{$config->{'running-processes'}->{'should-run'}}; + eq_or_diff( + [ map { $process_table->is_running($_) ? $_ : undef } @should_run ], + [ @should_run ], + 'check if all processes are running', + ); + } + + return 0; +} + +sub Proc::ProcessTable::is_running { + my $self = shift; + my $process_string = shift; + + croak 'pass process name' + if not defined $process_string; + + return any { $_->cmndline =~ $process_string } @{$self->table}; +} + + +__END__ + +=head1 NOTE + +Process listing depends on L. + +=head1 AUTHOR + +Jozef Kutej + +=cut diff --git a/ce/02_disk-free.t b/ce/02_disk-free.t new file mode 100644 index 0000000..eb56951 --- /dev/null +++ b/ce/02_disk-free.t @@ -0,0 +1,103 @@ +#!/usr/bin/perl + +=head1 NAME + +disk-free - check disk free space and free inodes + +=head2 SYNOPSIS + + cat >> test-server.yaml << __YAML_END__ + disk-free: + /: + max-used: 95% + max-inodes: 90% + /var: + max-df: 1G + max-inodes: 64875 + __YAML_END__ + + +=cut + +use strict; +use warnings; + +use Test::More; +use Test::Differences; + +use FindBin '$Bin'; +use YAML::Syck 'LoadFile'; +use Test::Server::Util qw(parse_size format_size); + +eval "use Filesys::DiskSpace"; +plan 'skip_all' => "need Filesys::DiskSpace to run disk free tests" if $@; + +my $config = LoadFile($Bin.'/test-server.yaml'); + +# by default check root filesystem +$config->{'disk-free'} = { '/' => undef } + if not $config->{'disk-free'}; + +$config = $config->{'disk-free'}; + +exit main(); + +sub main { + plan 'tests' => scalar(keys %$config)*2; + + foreach my $dir (keys %$config) { + my $max_used = $config->{$dir}->{'max-used'} || '95%'; + my $max_inodes = $config->{$dir}->{'max-inodes'} || '90%'; + + my ($fs_type, $fs_desc, $used_space, $avail_space, $used_inodes, $avail_inodes) + = Filesys::DiskSpace::df($dir); + + my $current_used; + my $diff_used; + + # check used disk space + if ($max_used =~ m/^(.+)%\s*$/) { + $max_used = $1; + $current_used = int($used_space*100/($avail_space+$used_space)); + $diff_used = ($current_used - $max_used).'%'; + } + else { + $max_used = parse_size($max_used); + $current_used = $used_space * 1024; + $diff_used = format_size($current_used - $max_used); + } + + cmp_ok($current_used, '<=', $max_used, 'check disk space on '.$dir) + or diag('difference is ', $diff_used); + + # check used inodes + if ($max_inodes =~ m/^(.+)%\s*$/) { + $max_inodes = $1; + $current_used = int($used_inodes*100/($avail_inodes+$used_inodes)); + $diff_used = ($current_used - $max_inodes).'%'; + } + else { + $max_inodes = parse_size($max_inodes); + $current_used = $used_inodes; + $diff_used = $current_used - $max_inodes; + } + + cmp_ok($current_used, '<=', $max_inodes, 'check inodes on '.$dir) + or diag('difference is ', $diff_used); + } + + return 0; +} + + +__END__ + +=head1 NOTE + +Disk Free checking depends on L. + +=head1 AUTHOR + +Jozef Kutej + +=cut diff --git a/ce/test-server.yaml b/ce/test-server.yaml new file mode 100644 index 0000000..5494622 --- /dev/null +++ b/ce/test-server.yaml @@ -0,0 +1,33 @@ +disk-free: + /: + max-used : 80% + max-inodes: 80% + +running-processes: + should-run: + - /bin/sh -c /usr/bin/logger -p daemon.info -t csc + - /bin/sh -c /usr/bin/logger -p daemon.info -t oss + - /bin/sh -c /usr/bin/logger -p daemon.info -t oss + - /bin/sh /usr/bin/mysqld_safe + - collectd -C /etc/collectd/collectd.conf -f + - nginx + - rate-o-mat + - startpar -f -- ngcp-rate-o-mat + - /usr/bin/logger -p daemon.info -t csc + - /usr/bin/logger -p daemon.info -t oss + - /usr/bin/logger -p daemon.info -t oss + - /usr/bin/mediator -D /var/run/mediator.pid -i 10 -h localhost -o 3306 -u kamailio + - /usr/sbin/acpid + - /usr/sbin/apache2 + - /usr/sbin/asterisk -n + - /usr/sbin/collectdmon -P /var/run/collectdmon.pid -- -C /etc/collectd/collectd.con + - /usr/sbin/cron + - /usr/sbin/exim4 -bd -q30m + - /usr/sbin/kamailio -f /etc/kamailio/lb/kamailio.cfg -P /var/run/kamailio/kamailio.lb.pid + - /usr/sbin/kamailio -f /etc/kamailio/proxy/kamailio.cfg -P /var/run/kamailio/kamailio.proxy.pid + - /usr/sbin/mediaproxy-ng + - /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/log/mysql/mysqld.err --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 + - /usr/sbin/ntpd -p /var/run/ntpd.pid + - /usr/sbin/rsyslogd + - /usr/sbin/sems -P /var/run/sems/sems.pid -u sems -g sems -f /etc/sems/sems.conf + - /usr/sbin/sshd diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..c6d5e7e --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +ngcp-system-tests (0.01~dev) unstable; urgency=low + + * Initial release. + + -- Michael Prokop Tue, 19 Mar 2013 01:19:26 +0100 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +8 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..07f3c2c --- /dev/null +++ b/debian/control @@ -0,0 +1,19 @@ +Source: ngcp-system-tests +Section: admin +Priority: extra +Maintainer: Sipwise Development Team +Build-Depends: debhelper (>= 8) +Standards-Version: 3.9.4 +Homepage: http://sipwise.com/ + +Package: ngcp-system-tests +Architecture: all +Depends: libfilesys-diskspace-perl, + libproc-processtable-perl, + libtest-server-perl, + ${misc:Depends}, + ${perl:Depends} +Description: run system tests against NGCP systems + This package provides test scripts to check the system + state of the SIP based Open Source Class5 VoIP soft-switch platform + by Sipwise.com. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..b448b27 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,23 @@ +Upstream Author: The Sipwise Team - http://sipwise.com +Copyright: 2013, Sipwise GmbH, Austria +License: GPL-3+ + This program is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later + version. + . + This program is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the GNU General Public License for more + details. + . + You should have received a copy of the GNU General Public + License along with this package; if not, write to the Free + Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301 USA + . + On Debian systems, the full text of the GNU General Public + License version 3 can be found in the file + `/usr/share/common-licenses/GPL-3'. diff --git a/debian/ngcp-system-tests.install b/debian/ngcp-system-tests.install new file mode 100644 index 0000000..0d2f0f5 --- /dev/null +++ b/debian/ngcp-system-tests.install @@ -0,0 +1,3 @@ +ce/* /usr/share/ngcp-tests/ce/ +pro/* /usr/share/ngcp-tests/pro/ +testrunner /usr/share/ngcp-tests/ diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..cbe925d --- /dev/null +++ b/debian/rules @@ -0,0 +1,3 @@ +#!/usr/bin/make -f +%: + dh $@ diff --git a/pro/01_hostname-and-interfaces.t b/pro/01_hostname-and-interfaces.t new file mode 100644 index 0000000..b189ff1 --- /dev/null +++ b/pro/01_hostname-and-interfaces.t @@ -0,0 +1,114 @@ +#!/usr/bin/perl + +=head1 NAME + +hostname-and-interfaces - check hostname and ip resolution on interfaces + +=head2 SYNOPSIS + + NONE + +=head2 DESCRIPTION + +Checks the hostname short name and fqdn. Cheks the ip adresses on the interfaces +if resolv to some hostname. + +=cut + +use strict; +use warnings; + +use Test::More 'tests' => 5; +use Test::Differences; + +use List::MoreUtils 'any'; +use Sys::Net 'resolv', 'interfaces'; + +my $HOSTNAME_CMD = 'hostname'; + +exit main(); + + +sub main { + my $hostname_short_ip; + my $hostname_fqdn_ip; + SKIP: { + my $hostname = `$HOSTNAME_CMD`; + skip 'hostname command not found', 2 + if not defined $hostname; + + my $hostname_short = `$HOSTNAME_CMD --short`; + $hostname_short =~ s/^\s*(.*)\s*$/$1/; + diag 'short hostname - ', $hostname_short + if $ENV{TEST_VERBOSE}; + my $hostname_fqdn = `$HOSTNAME_CMD --fqdn`; + $hostname_fqdn =~ s/^\s*(.*)\s*$/$1/; + diag 'fqdn hostname - ', $hostname_fqdn + if $ENV{TEST_VERBOSE}; + + isnt($hostname_short, $hostname_fqdn, 'short hostname should not be the same as fqdn'); + + # short hostname from fqdn + my ($short) = split /\./, $hostname_fqdn; + + is($short, $hostname_short, 'check short hostname'); + + # resolv ip-s for short and fqdn hostname + $hostname_short_ip = resolv($hostname_short); + $hostname_fqdn_ip = resolv($hostname_fqdn); + is( + $hostname_short_ip, + $hostname_fqdn_ip, + 'ip-s of short hostname and fqdn should be the same - '.$hostname_fqdn_ip, + ); + } + + SKIP: { + skip 'fqdn not found', 2 + if not defined $hostname_fqdn_ip; + + # get interfaces + my %if_named = %{interfaces()}; + + skip 'no interfaces found', 2 + if not keys %if_named; + + ok( + (any { $_->{'ip'} eq $hostname_fqdn_ip } values %if_named ), + 'there should be at leas one interface with hostname ip - '.$hostname_fqdn_ip, + ); + + # loop through all interfaces + foreach my $ifname (keys %if_named) { + my $iface = $if_named{$ifname}; + + # resolv interface ip to hostnames + $iface->{'hostname'} = resolv($iface->{'ip'}); + diag 'if ', $ifname, ' ip ', $iface->{'ip'}, ' resolves to ', $iface->{'hostname'} + if $ENV{TEST_VERBOSE}; + } + + # check if every interface has a hostname set (different from the ip) + eq_or_diff( + [ map { + $_->{'hostname'} + && ($_->{'hostname'} ne $_->{'ip'}) + ? $_->{'ip'} + : 'not resolving' + } values %if_named ], + [ map { $_->{'ip'} } values %if_named ], + 'every interface ip should resolv to a name', + ); + } + + return 0; +} + + +__END__ + +=head1 AUTHOR + +Jozef Kutej + +=cut diff --git a/pro/01_running-processes.t b/pro/01_running-processes.t new file mode 120000 index 0000000..320f346 --- /dev/null +++ b/pro/01_running-processes.t @@ -0,0 +1 @@ +../ce/01_running-processes.t \ No newline at end of file diff --git a/testrunner b/testrunner new file mode 100755 index 0000000..67b10d8 --- /dev/null +++ b/testrunner @@ -0,0 +1,25 @@ +#!/bin/bash + +REPORT_DIRECTORY='reports/' + +if [ $# -lt 1 ] ; then + echo "Usage: $0 " >&2 + echo + echo "Usage example: $0 /usr/share/ngcp-tests/ce/" + exit 1 +fi + +if ! [ -d "$1" ] ; then + echo "$1 is not a directory" >&2 + exit 1 +fi + +rm -rf "${REPORT_DIRECTORY}" +mkdir "${REPORT_DIRECTORY}" + +for test in ${1}/*.t ; do + perl "$test" > "${REPORT_DIRECTORY}/$(basename ${test}).tap" +done + +tar acf reports.tar.gz "${REPORT_DIRECTORY}" +echo "Generated reports.tar.gz"