]> git.proxmox.com Git - pve-firewall.git/blob - test/fwtester.pl
add test for aliases inside vm firewall configuration
[pve-firewall.git] / test / fwtester.pl
1 #!/usr/bin/perl
2
3 use lib '../src';
4 use strict;
5 use warnings;
6 use Data::Dumper;
7 use PVE::FirewallSimulator;
8 use Getopt::Long;
9 use File::Basename;
10 use Net::IP;
11
12 my $debug = 0;
13
14 sub print_usage_and_exit {
15 die "usage: $0 [--debug] [testfile [testid]]\n";
16 }
17
18 if (!GetOptions ('debug' => \$debug)) {
19 print_usage_and_exit();
20 }
21
22 PVE::FirewallSimulator::debug($debug);
23
24 my $testfilename = shift;
25 my $testid = shift;
26
27 sub run_tests {
28 my ($vmdata, $testdir, $testfile, $testid) = @_;
29
30 $testfile = 'tests' if !$testfile;
31
32
33 $vmdata->{testdir} = $testdir;
34
35 my $host_ip = '172.16.1.2';
36
37 PVE::Firewall::local_network('172.16.1.0/24');
38
39 my ($ruleset, $ipset_ruleset) =
40 PVE::Firewall::compile(undef, undef, $vmdata, 1);
41
42 print PVE::FirewallSimulator::get_trace() . "\n" if !$debug;
43
44 my $filename = "$testdir/$testfile";
45 my $fh = IO::File->new($filename) ||
46 die "unable to open '$filename' - $!\n";
47
48 my $testcount = 0;
49 while (defined(my $line = <$fh>)) {
50 next if $line =~ m/^\s*$/;
51 next if $line =~ m/^#.*$/;
52 if ($line =~ m/^\{.*\}\s*$/) {
53 my $test = eval $line;
54 die $@ if $@;
55 next if defined($testid) && (!defined($test->{id}) || ($testid ne $test->{id}));
56 PVE::FirewallSimulator::reset_trace();
57 print Dumper($ruleset) if $debug;
58 $testcount++;
59 eval {
60 my @test_zones = qw(host outside nfvm vm100 ct200);
61 if (!defined($test->{from}) && !defined($test->{to})) {
62 die "missing zone speification (from, to)\n";
63 } elsif (!defined($test->{to})) {
64 foreach my $zone (@test_zones) {
65 next if $zone eq $test->{from};
66 $test->{to} = $zone;
67 PVE::FirewallSimulator::add_trace("Set Zone: to => '$zone'\n");
68 PVE::FirewallSimulator::simulate_firewall($ruleset, $ipset_ruleset,
69 $host_ip, $vmdata, $test);
70 }
71 } elsif (!defined($test->{from})) {
72 foreach my $zone (@test_zones) {
73 next if $zone eq $test->{to};
74 $test->{from} = $zone;
75 PVE::FirewallSimulator::add_trace("Set Zone: from => '$zone'\n");
76 PVE::FirewallSimulator::simulate_firewall($ruleset, $ipset_ruleset,
77 $host_ip, $vmdata, $test);
78 }
79 } else {
80 PVE::FirewallSimulator::simulate_firewall($ruleset, $ipset_ruleset,
81 $host_ip, $vmdata, $test);
82 }
83 };
84 if (my $err = $@) {
85
86 print Dumper($ruleset) if !$debug;
87
88 print PVE::FirewallSimulator::get_trace() . "\n" if !$debug;
89
90 print "$filename line $.: $line";
91
92 print "test failed: $err\n";
93
94 exit(-1);
95 }
96 } else {
97 die "parse error";
98 }
99 }
100
101 die "no tests found\n" if $testcount <= 0;
102
103 print "PASS: $filename\n";
104
105 return undef;
106 }
107
108 my $vmdata = {
109 qemu => {
110 100 => {
111 net0 => "e1000=0E:0B:38:B8:B3:21,bridge=vmbr0,firewall=1",
112 },
113 101 => {
114 net0 => "e1000=0E:0B:38:B8:B3:22,bridge=vmbr0,firewall=1",
115 },
116 # on bridge vmbr1
117 110 => {
118 net0 => "e1000=0E:0B:38:B8:B4:21,bridge=vmbr1,firewall=1",
119 },
120 },
121 openvz => {
122 200 => {
123 ip_address => { value => '10.0.200.1' },
124 },
125 201 => {
126 ip_address => { value => '10.0.200.2' },
127 },
128 },
129 };
130
131 if ($testfilename) {
132 my $testfile;
133 my $dir;
134
135 if (-d $testfilename) {
136 $dir = $testfilename;
137 } elsif (-f $testfilename) {
138 $dir = dirname($testfilename);
139 $testfile = basename($testfilename);
140 } else {
141 die "no such file/dir '$testfilename'\n";
142 }
143
144 run_tests($vmdata, $dir, $testfile, $testid);
145
146 } else {
147 foreach my $dir (<test-*>) {
148 next if ! -d $dir;
149 run_tests($vmdata, $dir);
150 }
151 }
152
153 print "OK - all tests passed\n";
154
155 exit(0);