1#!/usr/local/bin/perl 2# 3# Run tv_split on some input files and check the output looks 4# reasonable. This is not done by diffing against expected output but 5# by reading the files generated and making sure channels and dates 6# seem to match. 7# 8# -- Ed Avis, ed@membled.com, 2003-10-04 9# $Id: test_tv_split.t,v 1.8 2015/07/12 00:46:37 knowledgejunkie Exp $ 10# 11 12use warnings; 13use strict; 14use Getopt::Long; 15use Cwd; 16use File::Temp qw(tempdir); 17use File::Copy; 18use XMLTV::Usage <<END 19$0: test suite for tv_split 20usage: $0 [--tests-dir DIR] [--verbose] 21END 22 ; 23 24my $tests_dir = 't/data'; # where to find input XML files 25die "no directory $tests_dir" if not -d $tests_dir; 26my $cmds_dir = 'blib/script'; # directory tv_split lives in 27die "no directory $cmds_dir" if not -d $cmds_dir; 28my $verbose = 0; 29 30GetOptions('tests-dir=s' => \$tests_dir, 'cmds-dir=s' => \$cmds_dir, 31 'verbose' => \$verbose) 32 or usage(0); 33usage(0) if @ARGV; 34 35my @inputs = <$tests_dir/*.xml>; 36my @inputs_gz = <$tests_dir/*.xml.gz>; s/\.gz$// foreach @inputs_gz; 37@inputs = sort (@inputs, @inputs_gz); 38die "no test cases (*.xml, *.xml.gz) found in $tests_dir" 39 if not @inputs; 40 41print '1..', (scalar @inputs), "\n"; 42my $n = 0; 43my $old_cwd; 44INPUT: foreach my $input (@inputs) { 45 ++$n; 46 47 if (defined $old_cwd) { 48 chdir $old_cwd or die "cannot chdir to $old_cwd: $!"; 49 } 50 else { 51 $old_cwd = cwd; 52 } 53 54 # Quick and dirty checking of XML files. Before we start, read 55 # the input XML and note how many programmes of each kind. 56 # 57 my %input; 58 open(FH, $input) or die "cannot open $input: $!"; 59 while (<FH>) { 60 next unless /<programme/; 61 62 /start="(.+?)"/ or die "$input:$.: no start\n"; 63 my $start = $1; 64 $start =~ /^\d{4}(\d{2})/ 65 or die "$input:$.: don't understand start time $start\n"; 66 my $month = $1; 67 68 /channel="(.+?)"/ or die "$input:$.: no channel\n"; 69 my $channel = $1; 70 ++$input{"channel$channel-month$month"}; 71 } 72 close FH or warn "cannot close $input: $!"; 73 74 # Make temporary directory and split into it. 75 my $dir = tempdir(CLEANUP => 1); 76 die if not -d $dir; 77 die 'gzipped files not supported (could add)' 78 if $input =~ /[.]gz$/; 79 my @cmd = ("$cmds_dir/tv_split", 80 '--output', "$dir/channel%channel%-month%m.out", 81 $input); 82 my $r = system @cmd; 83 84 # Check command return status. 85 if ($r) { 86 my ($status, $sig, $core) = ($? >> 8, $? & 127, $? & 128); 87 if ($sig) { 88 die "@cmd killed by signal $sig, aborting"; 89 } 90 warn "@cmd failed: $status, $sig, $core\n"; 91 print "not ok $n\n"; 92 next; 93 } 94 95 # Read the files generated. 96 chdir $dir or die "cannot chdir to $dir: $!"; 97 my %found; 98 foreach my $f (<*.out>) { 99 open(FH, $f) or die "cannot open $f: $!"; 100 (my $template = $f) =~ s/[.]out$// or die; 101 my (%seen_channel_elem, %used_channel); 102 while (<FH>) { 103 if (/<channel/) { 104 /id="(.+?)"/ or die "$f:$.: no id\n"; 105 $seen_channel_elem{$1} = 1; 106 } 107 elsif (/<programme/) { 108 /start="(.+?)"/ or die "$f:$.: no start\n"; 109 my $start = $1; 110 $start =~ /^\d{4}(\d{2})/ 111 or die "$f:$.: don't understand start time $start\n"; 112 my $month = $1; 113 114 /channel="(.+?)"/ or die "$f:$.: no channel\n"; 115 my $channel = $1; 116 $used_channel{$channel} = 1; 117 118 if ("channel$channel-month$month" ne $template) { 119 warn "in $f saw what should be channel$channel-month$month\n"; 120 print "not ok $n\n"; 121 next INPUT; 122 } 123 124 ++$found{$template}; 125 } 126 } 127 close FH or warn "cannot close $f: $!"; 128 129 # We don't check that every channel used has a <channel> 130 # element (it might not have been in the input files) but we 131 # do check that every <channel> written is used for at least 132 # one programme. 133 # 134 # (We shouldn't do this if tv_split has not been asked to 135 # split by channel, but at present all the tests we run do 136 # have %channel.) 137 # 138 foreach (sort keys %seen_channel_elem) { 139 if (not $used_channel{$_}) { 140 warn "in $f saw <channel> for $_ but it's used for no programmes\n"; 141 print "not ok $n\n"; 142 next INPUT; 143 } 144 } 145 } 146 147 148 # We've read each output file and checked the programmes it does 149 # contain have the right times; now check that every programme in 150 # the input has been given to an output file. 151 # 152 # (We don't check the contents of the programme elements or other 153 # details of the XML - we assume that if XMLTV.pm had a serious 154 # bug it would have been caught in the tests of other filter 155 # programs.) 156 # 157 foreach (keys %input) { 158 if ($input{$_} != $found{$_}) { 159 warn "different number of programmes for template $_\n"; 160 print "not ok $n\n"; 161 next INPUT; 162 } 163 } 164 foreach (keys %found) { 165 if (not exists $input{$_}) { 166 warn "generated template $_ not in input\n"; 167 print "not ok $n\n"; 168 next INPUT; 169 } 170 } 171 172 print "ok $n\n"; 173} 174 175