=head1 Name

accounting


=head1 Ziel

Testen der korrekten Verarbeitung von Accountingdaten


=head1 Testfälle

Es wird getestet:

=over 4

=item *

ISDN-Accountingdatensatz

=item *

Mails (neu: Exim)

=item *

E-Mail-E<gt>SMS-Gateway

=back


=head1 nicht-Testfälle

Folgende Tests sind noch nicht implementiert:

=over 4

=item *

WWW

=item *

Mails (alt: Zmailer)

=item *

Cache

=item *

IP (Brick)

=item *

IP (Cisco)

=back


=cut


package Test::accounting;
use utf8;
use warnings;
use strict; use warnings;
BEGIN { unshift(@INC,($ENV{'POPHOME'}||'@POPHOME@').'/lib')
			unless $ENV{'KUNDE_NO_PERLPATH'};
      }

use Test::More tests => 94; $| = 1;
use Dbase::Test;
use Dbase::Globals qw(get_kunde);

my $time=time;

use Date::Format qw(time2str);
use Dbase::Help qw(Do isodate DoFn);
use Dbase::Globals qw(gen_descr);
use Fehler qw();
use Cf qw($POPHOME $WDESCR $DESCR $MAILDOM $CACHEDIR);
use Loader qw(delete_kunde writer add_dienst delete_person);
use File::Path qw(rmtree);

foreach my $i ( qw(isdn multi radius test), $WDESCR ) {
		okS "quelle//$i",
			sub {gen_descr("quelle",undef,"$i")};
}

foreach my $i(qw(ip minuten zeit)) {
foreach my $j(qw(dialin ipass sdsl tdsl wlan)) {
	okS "dienst//$i-$j",
		sub {add_dienst(undef,"$i-$j")};
}}

{
my $z = 200;
foreach my $f(qw(arcor qsc local tollfree tdsl-zisp tdsl-ilk telefonica)) {
	okS "ziel//$f",
		sub {gen_descr("ziel",$z++,$f,"RADIUS: $f")};
}
}

okS "ipflags/no_accounting", sub {gen_descr('ipflags',undef,'no_accounting')};

foreach my $i(qw(general ip www cache mail mail-in mail-out zeit isdn sms ipass)) {
		okS "dienst//$i",
			sub {add_dienst(undef,"$i")};
}

okF "delete from exim_cache_1";
okF "delete from exim_cache_2";
okF "delete from radacct";

okS "acziel//de", sub {gen_descr("acziel",100,"de")}; # 'd'
okS "acziel//dtag", sub {gen_descr("acziel",116,"dtag")}; # 't'
okS "acziel//*", sub {gen_descr("acziel",119,"*")}; # 'w'

my $net_de = 'net.de.' . time2str('%Y%m', $^T);
okS "write $net_de", sub { writer("",$CACHEDIR."/$net_de"); };

okS "quelle//$WDESCR",sub {gen_descr("quelle",undef,$WDESCR)};
okS "quelle//multi",sub {gen_descr("quelle",undef,"multi")};

okF "delete from quelle";

{
    my $kid;
	
	$kid = DoFn("select id from kunde where name = 'accttest'");
    if($kid) {
		okS "Kunde löschen",sub {delete_kunde($kid,3);};
	} else {
		pass("kein Altlast-Kunde 1");
	}

	$kid = DoFn("select id from kunde where name = 'radtest'");
    if($kid) {
		okS "Kunde löschen",sub {delete_kunde($kid,3);};
	} else {
		pass("kein Altlast-Kunde R");
	}

    $kid = DoFn("select id from kunde where name = 'accttest2'");
    if($kid) {
		okS "Kunde löschen",sub {delete_kunde($kid,3);};
	} else {
		pass("kein Altlast-Kunde 2");
	}
}
okF "insert into kunde set name='accttest'";
okF "insert into domainkunde set domain='accttest.de', kunde=%KUNDE%accttest%";
okF "insert into ipkunde set kunde=%KUNDE%accttest%, %IPNR_I%10.101.0.0/16%, tarif=%DIENST%ip%, dest=100"; # 'd'

okF "insert into kunde set name='accttest2'";
okF "insert into domainkunde set domain='accttest2.de', kunde=%KUNDE%accttest2%";
okF "insert into ipkunde set kunde=%KUNDE%accttest2%, %IPNR_I%10.102.0.0/16%, tarif=%DIENST%ip%, dest=119"; # 'w'

okF "insert into kunde set name='radtest'";
okF "insert into person set kunde=%KUNDE%radtest%, user='radiant'";
{
    my $accttest  = get_kunde 'accttest';
    my $accttest2 = get_kunde 'accttest2';
	my $ap;

	$ap = DoFn "select id from person where user='acctp'";
	if($ap) {
		Do "delete from ipassacct where person=$ap";
		delete_person $ap;
	}
    	okF "insert into person set kunde=$accttest, user='acctp'";

	$ap = DoFn "select id from person where user='acctp2'";
	if($ap) {
		Do "delete from ipassacct where person=$ap";
		delete_person $ap;
	}
	okF "insert into person set kunde=$accttest2, user='acctp2'";

	okF "delete from acct where dienst=%DIENST%ipass%";
}

okF "delete from acctassoc using acct,acctassoc where acct.kunde=1 and acct.`hash`=acctassoc.`hash` and acct.seq=acctassoc.seq","kill acctassoc";
okF "delete from acct where kunde=1";
okQ "select count(*) from acct where kunde=%KUNDE%accttest%",0;
okQ "select count(*) from acct where kunde=%KUNDE%accttest2%",0;

my $log="/tmp/atest.$$";
mkdir($log,0700);
mkdir("$log/incoming",0700);

END {
	rmtree($log) if defined $log;
}
$ENV{'LOGDIR'}=$log;

mkdir("$log/incoming/localhost/",0700);
mkdir("$log/incoming/localhost/radius/",0700);
mkdir("$log/incoming/localhost/type_radius/",0700);
mkdir("$log/incoming/localhost/brick/",0700);
writer(<<'END',"$log/incoming/localhost/brick/".($time-61));
Dec 20 06:44:09 wall ACCT: ISDN: 20.12.2001,06:42:04,06:42:55,50,1378,4507,16,15,20 Units,O,9352222,9119337640,7/0,90,0,accttest
Dec 20 06:44:09 wall ACCT: ISDN: 20.12.2001,06:42:14,06:42:55,40,1378,4507,16,15,,O,9352222,9119337640,7/0,90,0,
Dec 20 06:44:09 wall ACCT: ISDN: 20.12.2001,06:42:04,06:42:55,50,1378,4507,16,15,,I,9352222,9119337640,7/0,90,0,accttest
END

mkdir("$log/incoming/localhost/ip.multi/",0700);
writer(<<'END',"$log/incoming/localhost/ip.multi/".($time-61));
 172.16.4.16      10.102.3.6                      16              100000
 10.101.4.13      172.16.3.3                       1                2500
 10.101.1.11      10.102.2.1                       1                1000
 10.102.1.12      10.101.2.2                       1                1000
 10.101.4.13      172.16.3.3                       1                2500
 172.16.4.14      10.101.3.4                       8               20000
 10.102.4.15      172.16.3.5                       1                6250
 10.102.4.16      172.16.3.6                       1                6250
 10.102.4.17      172.16.3.7                       1                6250
 10.102.4.18      172.16.3.8                       1                6250
 10.102.4.19      172.16.3.9                       1                6250
 10.102.4.20      172.16.3.10                      1                6250
 10.102.4.21      172.16.3.5                       1                6250
 10.102.4.22      172.16.3.5                       1                6250
 10.102.4.15      172.16.3.5                       1                6250
 10.102.4.15      172.16.3.5                       1                6250
 10.102.4.15      172.16.3.5                       1                6250
 10.102.4.15      172.16.3.5                       1                6250
 10.102.4.15      172.16.3.5                       1                6250
 172.16.4.17      172.16.3.7                      64             1000000
 10.101.4.13      172.16.3.3                       1                2500
 10.102.1.12      10.101.2.2                       1                1000
 10.101.4.13      172.16.3.3                       1                2500
 10.102.4.15      172.16.3.5                       1                6250
 10.102.4.15      172.16.3.5                       1                6250
 10.102.4.15      172.16.3.5                       1                6250
 172.16.4.16      10.102.3.6                      16              100000
END

my($y,$m,$d)=isodate($time);
my $ymd = sprintf("%04d-%02d-%02d",$y,$m,$d);

mkdir("$log/incoming/localhost/",0700);
mkdir("$log/incoming/localhost/mainlog/",0700);

writer(<<END,"$log/incoming/localhost/mainlog/".($time-61));

$ymd 00:34:46 1BUYtC-0001Nz-QI <= <> H=xmail.accttest.de [10.101.10.24] P=esmtp X=TLS-1.0:RSA_ARCFOUR_SHA:16 S=1111 id=E1BUYtC-0008RM-5J\@xmail.accttest.de
$ymd 00:34:54 1BUYtC-0001Nz-QI ** m.sheppard_zo\@unbekannt.cl F=<> R=dnslookup T=remote_smtp: SMTP error from remote mailer after RCPT TO:<m.sheppard_zo\@unbekannt.cl>: host neptuno.unbekannt.cl [200.72.36.98]: 550 5.1.1 <m.sheppard_zo\@unbekannt.cl>... User unknown
$ymd 00:34:54 1BUYtC-0001Nz-QI Frozen (delivery error message)
$ymd 00:35:30 1BUYtC-0001Nz-QI Unfrozen by errmsg timer
$ymd 00:35:38 1BUYtC-0001Nz-QI neptuno.unbekannt.cl [200.72.36.98]: Connection timed out
$ymd 00:35:43 1BUYtC-0001Nz-QI orion.unbekannt.cl [200.72.36.100]: Connection timed out
$ymd 00:35:43 1BUYtC-0001Nz-QI => m.sheppard_zo\@unbekannt.cl F=<> R=dnslookup T=remote_smtp H=mailq.accttest.de [62.128.1.230] X=TLS-1.0:RSA_ARCFOUR_SHA:16 DN="C=DE,ST=Bavaria,L=Nuernberg,O=Testerei,OU=Secure Mail Server,CN=mailq.accttest.de,EMAIL=postmaster\@accttest.de" C="250 OK id=1BUvNf-0007lM-Pn"
$ymd 00:35:43 1BUYtC-0001Nz-QI Completed

$ymd 00:11:43 1BS1C3-0004Fa-5k <= bounce=Markus-Wohlhoefer#at-online.de=88=edaa=werner.schmid\@gmx.de H=mx0.gmx.de (mx0.gmx.net) [213.165.64.100] P=smtp S=39427 id=1BS0bC-1A8rWi0\@fwd07.sul.t-online.com

$ymd 06:25:49 1BSpz8-0003RF-W8 Virus_found tester\@accttest.de F=Webmaster\@accttest2.de Virus=(Win32.HLLM.Generic.292) S=54321
$ymd 06:25:49 1BSpz8-0003RF-W8 H=mithril.dwu.de (webmaster.com) [217.29.34.250] F=<Webmaster\@accttest2.de> rejected after DATA: This message contains malware (Win32.HLLM.Generic.292)

$ymd 08:19:39 1BQKQU-00079Q-0L <= test-sender\@accttest.de H=xmail.accttest.de (accttest.de) [62.128.1.109] P=smtp S=1234567 id=test-msgid\@accttest.de
$ymd 08:19:47 1BQKQU-00079Q-0L => test-empfaenger\@accttest2.de F=<test-sender\@accttest.de> R=dnslookup T=remote_smtp H=mailq.$MAILDOM [62.128.1.230] X=TLS-1.0:RSA_ARCFOUR_SHA:16 DN="C=DE,ST=Bavaria,L=Nuernberg,O=$DESCR,OU=Secure Mail Server,CN=mailq.$MAILDOM,EMAIL=postmaster\@$MAILDOM" C="250 OK id=1BQKQc-0007Yr-IX"
$ymd 08:19:47 1BQKQU-00079Q-0L Completed
$ymd 02:39:24 1Bb7Pg-0003QT-1k <= "No-IP Alerts cleanup"\@pop3.noris.net H=websmtp01.no-ip.com [63.215.241.231] P=smtp S=2062
$ymd 02:39:24 1Bb7Pg-0003QT-1k => gro1\@accttest.de <grosser\@accttest.de> F=<"No-IP Alerts cleanup"\@pop3.noris.net> R=smtp_route_a T=remote_smtp H=imap1.noris.net [62.128.1.111] C="250 OK id=1Bb7Pg-0006Md-00"
$ymd 00:39:43 1Bb7Pg-0003QT-1k Completed
END

mkdir("$log/incoming/localhost/dienst_sms");
writer(<<'_', "$log/incoming/localhost/dienst_sms/".($time-61));
1085663866	1	accttest	hostmon@accttest.de	+491234567890
1085664445	42	accttest	hostmon@accttest.de	+491234567890
1085664567	1	accttest2	hostmon@accttest.de	+491234567890
1085669216	1	accttest	kunden@monitor1.noris.net	+461234567890
1086788954	2	accttest2	exagent@accttest.de	+491234567890
_

okS "ipass_access_type/DIAL", sub { gen_descr( ipass_access_type => undef, 'DIAL' ) };
okS "ipass_service_type/DIAL", sub { gen_descr( ipass_service_type => undef, 'usage' ) };
mkdir("$log/incoming/localhost/dienst_ipass");
writer(<<'_', "$log/incoming/localhost/dienst_ipass/".($time-61));
"091:7195375","3694255","acctp","$WDESCR","DE,TOLLFREE-DE","01-Apr-2004 13:40:13","01-Apr-2004 13:40:13","128","2.0","0.07","DIAL","usage"
"092:7164565","3260458","acctp","$WDESCR","DE,All Cities-DE","01-Apr-2004 13:43:43","01-Apr-2004 13:43:43","169","1.65","0.08","DIAL","usage"
"054:76202176","2681634","acctp2","$WDESCR","DE,All Cities-DE","01-Apr-2004 13:55:56","01-Apr-2004 13:55:56","670","1.65","0.31","DIAL","usage"
"091:7213113","3694255","acctp2","$WDESCR","DE,TOLLFREE-DE","02-Apr-2004 05:55:39","02-Apr-2004 05:55:39","53","2.0","0.03","DIAL","usage"
_

chmod 0755,"acct/acctrun";

chomp(my $path = `pwd`);
my $prefix = $ENV{'REAL_TEST'} ? "/usr/pop/acct" : "$path/acct";
my $acctrun_cmd = (defined $DB::single)
	? $ENV{'REAL_TEST'}
		? "perl -d $prefix/acctrun"
		: "perl -I$path/lib -d $prefix/acctrun"
	: $ENV{'REAL_TEST'}
		? "$prefix/acctrun >&2"
		: "perl -I$path/lib $prefix/acctrun >&2";
sys($acctrun_cmd);

writer(<<END,"$log/incoming/localhost/mainlog/".($time-60));
$ymd 08:19:47 1BQKQc-0007Yr-IX <= test-sender\@accttest.de H=mail03.$MAILDOM [62.128.1.223] P=esmtp X=TLS-1.0:RSA_ARCFOUR_SHA:16 S=123456 id=test-msgid\@accttest.de
END
sys($acctrun_cmd);

writer(<<END,"$log/incoming/localhost/mainlog/".($time-59));
$ymd 08:20:05 1BQKQc-0007Yr-IX => test-empfaenger\@accttest2.de R=dnslookup T=remote_smtp H=blubber.accttest2.de [194.25.134.9]
$ymd 08:20:05 1BQKQc-0007Yr-IX Completed
END

use POSIX qw(strftime);
my $now = strftime("%a %b %e %H:%M:%S %Y", localtime);

writer(<<END,"$log/incoming/localhost/type_radius/".($time-59));
$now
        Acct-Session-Id = "00085B02"
        Tunnel-Server-Endpoint:0 = "62.128.0.234"
        Acct-Tunnel-Client-Endpoint:0 = "213.148.128.40"
        Tunnel-Assignment-Id:0 = "QSC-Dial-in"
        Tunnel-Type:0 = L2TP
        Acct-Tunnel-Connection-Id:0 = "2623960248"
        Tunnel-Client-Auth-Id:0 = "dial1.muc"
        Tunnel-Server-Auth-Id:0 = "rt1-ffm3.core"
        Framed-Protocol = PPP
        Framed-IP-Address = 10.130.1.6
        User-Name = "radiant"
        Acct-Authentic = RADIUS
        Attr-196 = "\000\000\000<"
        Attr-198 = "\000\000\000"
        Attr-255 = "\000\000\372"
        Attr-197 = "\000\000\372"
        Acct-Session-Time = 123
        Acct-Input-Octets = 10876
        Acct-Output-Octets = 53918
        Attr-190 = "\000\000\000"
        Attr-191 = "\000\000\000O"
        Acct-Input-Packets = 108
        Acct-Output-Packets = 105
        Attr-192 = "\000\000\000"
        Attr-193 = "\000\000\000\003"
        Acct-Terminate-Cause = User-Request
        Attr-195 = "\000\000\000-"
        Acct-Status-Type = Stop
        NAS-Port-Type = 5
        NAS-Port = 374
        Calling-Station-Id = "7157560238"
        Called-Station-Id = "08001016140"
        Service-Type = Framed-User
        NAS-IP-Address = 62.128.0.234
        Acct-Delay-Time = 0
        Client-IP-Address = 62.128.0.234
        Timestamp = 1194390257
        Request-Authenticator = Verified

END

sys($acctrun_cmd);

okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = 1 AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%zeit% AND quelle = %DESCR%quelle%isdn%",40,1;
okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%zeit% AND quelle = %DESCR%quelle%isdn%",100,2;
okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%isdn% AND quelle = %DESCR%quelle%$WDESCR%",20,1;

okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest% AND jjmm = $y*100+$m AND tt = $d AND dienst in ( %DIENST%mail-in%, %DIENST%mail-out% ) AND quelle = %DESCR%quelle%$WDESCR%",1234567+54321+1111+123456+2062,5;
okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest2% AND jjmm = $y*100+$m AND tt = $d AND dienst in ( %DIENST%mail-in%, %DIENST%mail-out% ) AND quelle = %DESCR%quelle%$WDESCR%",1234567+54321+123456,3;

okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%mail-out% AND quelle = %DESCR%quelle%$WDESCR%",1111+123456+1234567,3;
okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%mail-in% AND quelle = %DESCR%quelle%$WDESCR%",2062+54321,2;

okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%ip% AND quelle = %DESCR%quelle%multi%",33000,1+2+4+8;
okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest2% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%ip% AND quelle = %DESCR%quelle%multi%",303000,1+2+16+32;

okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%sms% AND quelle = %DESCR%quelle%$WDESCR%",44,3;
okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest2% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%sms% AND quelle = %DESCR%quelle%$WDESCR%",3,2;

okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%ipass% AND quelle = %DESCR%quelle%$WDESCR%",15,297;
okQ "SELECT SUM(bytes),SUM(pakete) FROM acct WHERE kunde = %KUNDE%accttest2% AND jjmm = $y*100+$m AND tt = $d AND dienst = %DIENST%ipass% AND quelle = %DESCR%quelle%$WDESCR%",34,723;

okQ "select count(*) from quelle",15;
okQ "select sum(bytes) from quelle where kunde=%KUNDE%accttest%",33000;
okQ "select sum(bytes) from quelle where kunde=%KUNDE%accttest2%",303000;

is DoFn("select count(*) from exim_cache_1"),1,"cached data 1 are (almost) empty";
is DoFn("select exim_id from exim_cache_1"),"1BS1C3-0004Fa-5k","cached data 1";
# 1BS1C3-0004Fa-5k
 
is DoFn("select count(*) from exim_cache_2"),0,"cached data 2 are empty";

is DoFn("select count(*) from radacct"),1,"RADIUS accounting";
is DoFn("select sum(bytes_in) from radacct"),10876,"RADIUS bytes_in";
is DoFn("select sum(bytes_out) from radacct"),53918,"RADIUS bytes_out";
